@marimo-team/frontend 0.25.2-dev97 → 0.25.2
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/{CellStatus-Bj7PvY_u.js → CellStatus-BP2mavAq.js} +1 -1
- package/dist/assets/{ConnectedDataExplorerComponent-C5UW0p9I.js → ConnectedDataExplorerComponent-t8fH_TNc.js} +1 -1
- package/dist/assets/{ErrorBoundary-CG6gtgym.js → ErrorBoundary-Gl5nCA8C.js} +2 -2
- package/dist/assets/{I18nProvider-BFOBKCJB.js → I18nProvider-Cg2I_s1_.js} +1 -1
- package/dist/assets/{ImageComparisonComponent-pCLPT6RA.js → ImageComparisonComponent-Bq-l26rq.js} +1 -1
- package/dist/assets/{Inputs-BlygJyl1.js → Inputs-BsQm29hD.js} +1 -1
- package/dist/assets/JsonOutput-D6HIIsCb.js +11 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-CeTd_wFt.js → LazyAnyLanguageCodeMirror-CKcCbG2G.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-BEsxXqp6.js → MarimoErrorOutput-D60XkCny.js} +1 -1
- package/dist/assets/{Plot-CNtRAZBG.js → Plot-B8w5_jU-.js} +1 -1
- package/dist/assets/{RenderHTML-C7QcdAgB.js → RenderHTML-BbOqmHy3.js} +1 -1
- package/dist/assets/{RunButton-A__3wcpF.js → RunButton-CK3LhnP5.js} +1 -1
- package/dist/assets/__vite-browser-external-CYO_P3S8.js +1 -0
- package/dist/assets/__vite-browser-external-FeDVGZU8.js +1 -0
- package/dist/assets/{abnfDiagram-VCTEODGH-BuHNQB7l.js → abnfDiagram-VCTEODGH-3eD1PSvc.js} +1 -1
- package/dist/assets/add-cell-with-ai-8UBC0xwR.js +76 -0
- package/dist/assets/{add-connection-dialog-bl8dqCVs.js → add-connection-dialog-DXQnd6eB.js} +1 -1
- package/dist/assets/{agent-panel-BPLrf7mA.js → agent-panel-D7kMZLG-.js} +5 -5
- package/dist/assets/ai-model-dropdown-B0z6-zhp.js +5 -0
- package/dist/assets/{alert-MrQXRIin.js → alert-DTaqCu_d.js} +1 -1
- package/dist/assets/{alert-dialog-DlL1c-bx.js → alert-dialog-BaPGzeOK.js} +1 -1
- package/dist/assets/{any-language-editor-DtOWujZJ.js → any-language-editor-BLCAD3yx.js} +1 -1
- package/dist/assets/{api-DVLtXyp7.js → api-BeC_VSGv.js} +1 -1
- package/dist/assets/app-config-button-BKEG4x9u.js +1 -0
- package/dist/assets/{architectureDiagram-5GKGNRK7-DvIXijdN.js → architectureDiagram-5GKGNRK7-Bx_zXJUH.js} +1 -1
- package/dist/assets/arrow-down-C9Bslqr3.js +1 -0
- package/dist/assets/arrow-left-BaPN-xbg.js +1 -0
- package/dist/assets/arrow-right-Cgit4Nk2.js +1 -0
- package/dist/assets/{badge-DFf033uX.js → badge-crT3E0Rm.js} +1 -1
- package/dist/assets/ban-YzvUro5I.js +1 -0
- package/dist/assets/{blob-Bx8A10xl.js → blob-D5nfNHOo.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-DGAMO17L.js → blockDiagram-I7D4REHJ-CuwUGEGQ.js} +1 -1
- package/dist/assets/{bot-message-square-BfGaNy9r.js → bot-message-square-8xmbrehG.js} +1 -1
- package/dist/assets/{bundle.esm-CklCb9AD.js → bundle.esm-D3tw5rqW.js} +1 -1
- package/dist/assets/{button-M49xxKoi.js → button-COI-NGrx.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-qqO5IOnV.js → c4Diagram-7LVT6UL2-nj0NbEUh.js} +1 -1
- package/dist/assets/{cache-panel-BNPF4X5e.js → cache-panel-DTY1dqvi.js} +1 -1
- package/dist/assets/{capabilities-BScjbYOK.js → capabilities-BJvf-MD4.js} +1 -1
- package/dist/assets/{card-BYZGhhhx.js → card-DOABds5l.js} +1 -1
- package/dist/assets/{cell-editor-C3818WlB.js → cell-editor-ADVfycpN.js} +12 -12
- package/dist/assets/{cell-link-DC1UZQr_.js → cell-link-LSth_8hT.js} +1 -1
- package/dist/assets/cells-BRkCaSsh.js +220 -0
- package/dist/assets/channel-DtckUh1_.js +1 -0
- package/dist/assets/{chart-no-axes-column-B6FT5Xvu.js → chart-no-axes-column-C4_v6fQW.js} +1 -1
- package/dist/assets/{chat-display-YETh6yXV.js → chat-display-Dnagy4Nv.js} +1 -1
- package/dist/assets/chat-panel-DQ6HkWEF.js +4 -0
- package/dist/assets/{chat-ui-D_QL46qM.js → chat-ui-Df8Vcj6n.js} +1 -1
- package/dist/assets/check-BQNapYaf.js +1 -0
- package/dist/assets/chevron-right-eAtVhbNZ.js +1 -0
- package/dist/assets/{chunk-2E4U76K2-DqA2CBL0.js → chunk-2E4U76K2-dDf4JvCq.js} +1 -1
- package/dist/assets/{chunk-4HAMMTFA-DaFOJTOO.js → chunk-4HAMMTFA-Bhjs7H7G.js} +1 -1
- package/dist/assets/{chunk-75Z2AOVW-DEp7Wbaj.js → chunk-75Z2AOVW-DlSlUzCU.js} +1 -1
- package/dist/assets/{chunk-CLGD4ZFX-BxW11Imt.js → chunk-CLGD4ZFX-CvGMvSe-.js} +1 -1
- package/dist/assets/{chunk-DU6HZSFF-CDmPCRkr.js → chunk-DU6HZSFF-BxQd02hX.js} +2 -2
- package/dist/assets/{chunk-F27PBJKO-455JWNM3.js → chunk-F27PBJKO-DL9FG-iN.js} +1 -1
- package/dist/assets/{chunk-GMAD6QVW-ahdTJvh0.js → chunk-GMAD6QVW-B1Ai6qbk.js} +1 -1
- package/dist/assets/{chunk-GVQU2GXP-CPkYne1h.js → chunk-GVQU2GXP-a_N0QLD4.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-fARccL86.js → chunk-IMKFNOWR-7KbFyW3C.js} +1 -1
- package/dist/assets/{chunk-L3NEJ4N5-BOK6HmaY.js → chunk-L3NEJ4N5-BcHj9aiN.js} +1 -1
- package/dist/assets/{chunk-OSK3NFVY-CEcyPnHo.js → chunk-OSK3NFVY-Dc7tMbN9.js} +1 -1
- package/dist/assets/{chunk-P2QGCYS3-Bw5LRT6S.js → chunk-P2QGCYS3-G6pmnA0z.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-C--NLIXc.js → chunk-POPQ4Y6H-C3iw1mOR.js} +1 -1
- package/dist/assets/{chunk-PWAF6VOD-B1mxlptQ.js → chunk-PWAF6VOD-Dy1Fp4eJ.js} +1 -1
- package/dist/assets/{chunk-SHT3W25Y-Diet96b1.js → chunk-SHT3W25Y-B3kFJuvo.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-BbcEGfNl.js → chunk-SVP7TREG-BNmfcKnL.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-BypOyFjf.js → chunk-TICWLB2K-CI3x9ENh.js} +1 -1
- package/dist/assets/{chunk-TLUHSLCS-DvvqZUl_.js → chunk-TLUHSLCS-Q72uYeUY.js} +2 -2
- package/dist/assets/{chunk-YOKDWASO-84E-_nIR.js → chunk-YOKDWASO-BIpRENEC.js} +4 -4
- package/dist/assets/{circle-Bb1IbBVn.js → circle-DXf-VWZG.js} +1 -1
- package/dist/assets/circle-check-BCurAHEb.js +1 -0
- package/dist/assets/{circle-play-X3K8DkEc.js → circle-play-CYIb0qT6.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-vm4wDTPy.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-vm4wDTPy.js +1 -0
- package/dist/assets/{clear-button-BGfeXcJ3.js → clear-button-p6YcvzLy.js} +1 -1
- package/dist/assets/{click-outside-container-CHoodRk9.js → click-outside-container-D_Dy5sZY.js} +1 -1
- package/dist/assets/{clipboard-paste-D0gau9Xw.js → clipboard-paste-HVpozQmt.js} +1 -1
- package/dist/assets/code-BEiQP4pS.js +1 -0
- package/dist/assets/{code-visibility-DNzJgrTz.js → code-visibility-B-_GvwR5.js} +1 -1
- package/dist/assets/{code-xml-CW65k2pN.js → code-xml-SQaZqvcO.js} +1 -1
- package/dist/assets/coerce-CpE6kUdX.js +1 -0
- package/dist/assets/{column-preview-fD3qW2B5.js → column-preview-Cm2D6vyX.js} +1 -1
- package/dist/assets/command-palette-DTSQ7gOC.js +1 -0
- package/dist/assets/{common-Cy3lJDvJ.js → common-Cu6CDbuw.js} +1 -1
- package/dist/assets/{compiler-runtime-BQ9S8nyo.js → compiler-runtime-BrajqUja.js} +1 -1
- package/dist/assets/{components-D9ZIJGG8.js → components-CGw16R_N.js} +1 -1
- package/dist/assets/{components-M5WFQ0gs.js → components-CP_UoFtT.js} +1 -1
- package/dist/assets/{components-ufN33X-R.js → components-CXfO-F47.js} +1 -1
- package/dist/assets/{config-CR2d-XsP.js → config-BOKzA3tF.js} +1 -1
- package/dist/assets/{config-D_c_6ce1.js → config-DX8Y2WbJ.js} +1 -1
- package/dist/assets/{config-Cyum2gRs.js → config-VPSq73n8.js} +1 -1
- package/dist/assets/{copy-D03Y7IMR.js → copy-D8O_CYCG.js} +1 -1
- package/dist/assets/{copy-RyCOE8jo.js → copy-Djr5m5ac.js} +1 -1
- package/dist/assets/{copy-icon-wfSGfX8v.js → copy-icon-BIiRXh_3.js} +1 -1
- package/dist/assets/{createLucideIcon-rHn2EdoM.js → createLucideIcon-DfJ2oMlA.js} +1 -1
- package/dist/assets/{createReducer-W5dowuCe.js → createReducer-DgRODTW6.js} +1 -1
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-BW3uXbHa.js → cynefinDiagram-5FMLGOSQ-Cy86eSwK.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-DIV0whJf.js → dagre-GXQ25YYZ-CcWiU9Wf.js} +1 -1
- package/dist/assets/{data-grid-overlay-editor-DuYKABwo.js → data-grid-overlay-editor-CMnBpfPb.js} +1 -1
- package/dist/assets/{database-zap-CrkOvbyN.js → database-zap-B_PMVg8T.js} +1 -1
- package/dist/assets/{datasource-Tst92Pzi.js → datasource-Cq6x_5ML.js} +1 -1
- package/dist/assets/dates-BbFQ2oE4.js +1 -0
- package/dist/assets/{dependency-graph-panel-CLrAZrHA.js → dependency-graph-panel--Kgtktcw.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-BzoPaaoH.js → diagram-S7CK7UJ4-hmuvh6TI.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-BnOSn29R.js → diagram-UQ7AKVKN-CM3XDKRP.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-DAz8vger.js → diagram-VSXAHHWV-B8HedxR3.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-BQOZxgYE.js → diagram-VX7I27RA-D_5dmdWD.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-B_OF69Ac.js → diagram-Z3DM3KII-DWHvDoOc.js} +1 -1
- package/dist/assets/{dist-DoyTOIOd.js → dist-D6KQW558.js} +1 -1
- package/dist/assets/{dist-Cm7MoInu.js → dist-DR-Kwzb9.js} +1 -1
- package/dist/assets/{dist-Bqtq4wYM.js → dist-iaThVDkA.js} +1 -1
- package/dist/assets/{documentation-panel-OMUbXgKW.js → documentation-panel-BHmbeznw.js} +1 -1
- package/dist/assets/{download-CPMAf7re.js → download-DCJXy66H.js} +1 -1
- package/dist/assets/{dropdown-menu-B2JUUcK7.js → dropdown-menu-C1rnl-0o.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-BbkBTazy.js → ebnfDiagram-PWID7BFC-2XbadxRe.js} +1 -1
- package/dist/assets/{edit-page-Ctwp3mZE.js → edit-page-ChcSgpke.js} +6 -6
- package/dist/assets/{ellipsis-CLMWXUqY.js → ellipsis-63DyBLHQ.js} +1 -1
- package/dist/assets/{empty-state-CzxjZqGW.js → empty-state-BaCKb7o3.js} +1 -1
- package/dist/assets/{en-US-B4U3zuiu.js → en-US-Buu61juQ.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-DxDHwsU0.js → erDiagram-RLTQ6QDP-DbTcKdOV.js} +1 -1
- package/dist/assets/{error-banner-D1_bPN9u.js → error-banner-Cd69vvyX.js} +1 -1
- package/dist/assets/{error-entries-DBpwg0GC.js → error-entries-Dk3VZ-OK.js} +1 -1
- package/dist/assets/{error-panel-BgYJTJpA.js → error-panel-BPRYmC5J.js} +1 -1
- package/dist/assets/{errors-D9vyuMar.js → errors-DCrsa1nH.js} +1 -1
- package/dist/assets/{es-KNLgCZL4.js → es-Cqst59WX.js} +1 -1
- package/dist/assets/{esm-3WkPrffD.js → esm-CI_o7NhW.js} +1 -1
- package/dist/assets/{external-link-D2lKwXyB.js → external-link-UrX9KO36.js} +1 -1
- package/dist/assets/{eye-off-CfkK-QS3.js → eye-off-CxVozGAC.js} +1 -1
- package/dist/assets/feedback-button-B2gKC5cn.js +1 -0
- package/dist/assets/{feedback-button-7KY7nL-j.js → feedback-button-Bik2-e33.js} +1 -1
- package/dist/assets/{file-mCR_SMtq.js → file-BPBVl9pl.js} +1 -1
- package/dist/assets/{file-explorer-panel-HvVNt0Qs.js → file-explorer-panel-BEEK5lcl.js} +1 -1
- package/dist/assets/{file-headphone-DKocX1z0.js → file-headphone-Dl35U6h3.js} +1 -1
- package/dist/assets/{file-icons-e7tmeyP-.js → file-icons-CdJgUy-I.js} +1 -1
- package/dist/assets/{file-name-input-DZehOHLA.js → file-name-input-Cdc-TVqO.js} +1 -1
- package/dist/assets/{fileToBase64-aqhlf6Jj.js → fileToBase64-BgBraYAr.js} +1 -1
- package/dist/assets/{floating-outline-K7cVdOlC.js → floating-outline-XD9FAV-f.js} +1 -1
- package/dist/assets/flowDiagram-HODETNUW-DR34jHUd.js +1 -0
- package/dist/assets/{formats-DkOlpVdf.js → formats-yZ06h1Pl.js} +1 -1
- package/dist/assets/{formatting-Civx9FAg.js → formatting-BqrP-n49.js} +1 -1
- package/dist/assets/{fullscreen-DEBblJKh.js → fullscreen-B9tHcfpV.js} +1 -1
- package/dist/assets/{gallery-page-DoriMrLH.js → gallery-page-Dm6mGwBi.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-BzkL5tY7.js → ganttDiagram-EL5Y4UJY-2n7Ig5Jm.js} +1 -1
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-DqtmYSBS.js → gitGraphDiagram-WWUBYQGX-DxR7RNkL.js} +1 -1
- package/dist/assets/{github-khsXwCtv.js → github-DQZhN3La.js} +1 -1
- package/dist/assets/{glide-data-editor-DWyeHe3u.js → glide-data-editor-J9CAb70d.js} +4 -4
- package/dist/assets/{glide-utils-BzwA3q-e.js → glide-utils-CIrAxdjv.js} +1 -1
- package/dist/assets/{globe-CmFhHoL1.js → globe-UdPdIbF7.js} +1 -1
- package/dist/assets/{hat-glasses-DVgK5i5l.js → hat-glasses-C8RhSVii.js} +1 -1
- package/dist/assets/{highlighted-body-KPVGNVTW-DxcqwMAu.js → highlighted-body-KPVGNVTW-BBA_Oaqj.js} +1 -1
- package/dist/assets/{home-page-BcJJsD_Q.js → home-page-DMHnsRxm.js} +1 -1
- package/dist/assets/{hooks-Qxjt0Ypd.js → hooks-93IwHd2u.js} +1 -1
- package/dist/assets/{house-CbkYoQ5W.js → house-CpsMWsLL.js} +1 -1
- package/dist/assets/{html-to-image-CFVIG1VZ.js → html-to-image-DK9Zl1lU.js} +1 -1
- package/dist/assets/{icons-CVdkfEA3.js → icons-CiZ_8zS-.js} +1 -1
- package/dist/assets/{image-CTch9x2I.js → image-wZvTj8WY.js} +1 -1
- package/dist/assets/{index-Xxay17E9.css → index-Bcdzex-3.css} +1 -1
- package/dist/assets/{index-B5XWyg6n.js → index-s-M1OXjs.js} +6 -6
- package/dist/assets/{infoDiagram-27XIBGKW-7rLCp1UQ.js → infoDiagram-27XIBGKW-U5Oqw16-.js} +1 -1
- package/dist/assets/{input-DPd57MDP.js → input-BoBxR50a.js} +1 -1
- package/dist/assets/{isValid-BEbe1fFs.js → isValid-q_Ad80ug.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-BH7XUtkN.js → ishikawaDiagram-5VMMS53U-Bob74yfq.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-BOj0kV6v.js → journeyDiagram-3NMN7TZE-CO3wos0F.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-CPrudFOv.js → kanban-definition-UXKFOSKX-HnyRfUfJ.js} +1 -1
- package/dist/assets/katex-C9vVdkK0.js +1 -0
- package/dist/assets/{katex-DUp2KybH.js → katex-CF1UBJcr.js} +5 -5
- package/dist/assets/{kbd-BnUiViRu.js → kbd-pdKBv96t.js} +1 -1
- package/dist/assets/kiosk-mode-BZECfg9k.js +1 -0
- package/dist/assets/{layout-CSLw6wGo.js → layout-DmcNEu3P.js} +4 -4
- package/dist/assets/{link-BF4dGmOQ.js → link-NuFVR7G9.js} +1 -1
- package/dist/assets/links-DkkL9DVa.js +1 -0
- package/dist/assets/{logs-panel-OkoO5mbN.js → logs-panel-ABM16htT.js} +1 -1
- package/dist/assets/loro_wasm_bg-C2Fqi8D-.js +1 -0
- package/dist/assets/loro_wasm_bg-CSolyDSZ.wasm +0 -0
- package/dist/assets/loro_wasm_bg-Ctp2cNI9.js +1 -0
- package/dist/assets/{marimo-icons-B_1oPpIE.js → marimo-icons-CqliHyTr.js} +1 -1
- package/dist/assets/{markdown-renderer-mDlWBE1M.js → markdown-renderer-BG3sp2rs.js} +2 -2
- package/dist/assets/{menu-items-DAaNKHJF.js → menu-items-BrwnTgyK.js} +1 -1
- package/dist/assets/mermaid-HWGCJPDP-B7ByBG-a.js +1 -0
- package/dist/assets/{mermaid-CX6aTquk.js → mermaid-a3xYymTy.js} +3 -3
- package/dist/assets/{message-circle-OTHnVlxO.js → message-circle-C3rKm8_a.js} +1 -1
- package/dist/assets/{mhchem-hMh9XtQZ.js → mhchem-B6WrVrmp.js} +1 -1
- package/dist/assets/{mindmap-definition-YA3MSWOX-kWyI8sXl.js → mindmap-definition-YA3MSWOX-Tl5cqnHr.js} +1 -1
- package/dist/assets/{multi-icon-DWzZu-9u.js → multi-icon-DL465pPF.js} +1 -1
- package/dist/assets/{name-cell-input-D_Q2IhP9.js → name-cell-input-BgEBmqyL.js} +1 -1
- package/dist/assets/{number-overlay-editor-myrryj7o.js → number-overlay-editor-DS8xi0jE.js} +1 -1
- package/dist/assets/{numbers-BEfBaQtu.js → numbers-Mk3-CcoU.js} +1 -1
- package/dist/assets/{outline-panel-Dy2cmYDF.js → outline-panel-DCXQ3_F6.js} +1 -1
- package/dist/assets/{package-BeYhVWvM.js → package-GSoSTiIK.js} +1 -1
- package/dist/assets/{package-data-BwaspaKJ.js → package-data-dv4FBHxR.js} +1 -1
- package/dist/assets/{packages-panel-CIvhx0hb.js → packages-panel-BMGOmZkR.js} +1 -1
- package/dist/assets/pair-CaQyK6En.js +1 -0
- package/dist/assets/{panel-accordion-state-BI4SU22L.js → panel-accordion-state-C1sdPp0m.js} +1 -1
- package/dist/assets/{panel-context-BPaQeOuV.js → panel-context-C2QXpKfx.js} +1 -1
- package/dist/assets/{panels-BdsXFz1w.js → panels-CxVG8-v2.js} +1 -1
- package/dist/assets/{pathUtils-BKesuhdv.js → pathUtils-DPmlLd-r.js} +1 -1
- package/dist/assets/{paths-CzfpItSz.js → paths-bkIFVj8h.js} +1 -1
- package/dist/assets/{pegDiagram-XKGWAZYB-CiBJGPte.js → pegDiagram-XKGWAZYB-a0itOiYa.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-RpjpKhU6.js → pieDiagram-E7YTZNPT-DFve8H9P.js} +1 -1
- package/dist/assets/plus-C5silF6g.js +1 -0
- package/dist/assets/process-output-D0KGq04R.js +1 -0
- package/dist/assets/{quadrantDiagram-AXDQQJYC-Ci_qzCqs.js → quadrantDiagram-AXDQQJYC-yBhCDI7E.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-B2IWK3fJ.js → railroadDiagram-O6MQD6OU-CgwdYhrd.js} +1 -1
- package/dist/assets/react-DVplv7_D.js +1 -0
- package/dist/assets/react-dom-_LrxgvjW.js +1 -0
- package/dist/assets/{react-icons.esm-C6SMwKZH.js → react-icons.esm-D6tfmvq8.js} +1 -1
- package/dist/assets/{react-resizable-panels.browser.esm-BL2E7f5c.js → react-resizable-panels.browser.esm-Dbe0MrFr.js} +1 -1
- package/dist/assets/{react-vega-Jq3Jd7eX.js → react-vega-C3rYGtP6.js} +1 -1
- package/dist/assets/{readonly-code-display-CNbw6v1-.js → readonly-code-display-Do50PHI8.js} +1 -1
- package/dist/assets/{readonly-python-code-DcYhdd1B.js → readonly-python-code-DCSMIsTX.js} +1 -1
- package/dist/assets/{refresh-cw-CEGpOrzd.js → refresh-cw-Qw1f8Jhy.js} +1 -1
- package/dist/assets/{renderShortcut-BnRfkbwf.js → renderShortcut-BkVJQ_Zh.js} +1 -1
- package/dist/assets/requests-CgSY1X4a.js +1 -0
- package/dist/assets/{requests-yTHMxhVa.js → requests-lt0JK8Jt.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-B0_CyV0T.js → requirementDiagram-BXWQKSXE-BCDzS-aV.js} +1 -1
- package/dist/assets/{reveal-component-wEV_sB3u.css → reveal-component-DMRR6gKy.css} +1 -1
- package/dist/assets/reveal-component-ltaepAqw.js +1069 -0
- package/dist/assets/{rotate-ccw-se3Oa1US.js → rotate-ccw-D8WCVWNE.js} +1 -1
- package/dist/assets/{rotate-cw-BcRERxHa.js → rotate-cw-CZ2syZTu.js} +1 -1
- package/dist/assets/{run-page-CVWospEP.js → run-page-DF3c5cDk.js} +1 -1
- package/dist/assets/{runs-DyluVj69.js → runs-BLp5jezv.js} +1 -1
- package/dist/assets/{runtime-details-state-lxXYwJcI.js → runtime-details-state-CSPobEdR.js} +1 -1
- package/dist/assets/{sankeyDiagram-P5KCCOFB-BekzhMvv.js → sankeyDiagram-P5KCCOFB-byYeKbB2.js} +1 -1
- package/dist/assets/{save-D4cG4pP2.js → save-Dgoim6QF.js} +1 -1
- package/dist/assets/save-worker-BbUSwZRG.js +118 -0
- package/dist/assets/schemas-Dv42wLFq.js +56 -0
- package/dist/assets/{scratchpad-panel-B4qlmwP-.js → scratchpad-panel-Dwd6W5PE.js} +1 -1
- package/dist/assets/{scroll-to-bottom-button-Dmrd5bjQ.js → scroll-to-bottom-button-1FyowpWV.js} +1 -1
- package/dist/assets/{secrets-panel-DT1Nansx.js → secrets-panel-Bctbtkrp.js} +1 -1
- package/dist/assets/{select-BwRFbZty.js → select-DTBn5eTb.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-DELi1Kz5.js → sequenceDiagram-WJ2MYXX4-CLLPBM4B.js} +1 -1
- package/dist/assets/{session-BykGt6S3.js → session-DqoWmb7X.js} +1 -1
- package/dist/assets/{session-panel-Ch5jQNj0.js → session-panel-VdDhEBa-.js} +1 -1
- package/dist/assets/{settings-DlKTeV_0.js → settings-BpdQZRgT.js} +1 -1
- package/dist/assets/{shell-BSnvn9t7.js → shell-Fj8a65ii.js} +1 -1
- package/dist/assets/{shim-5li_pJY_.js → shim-CjjJUhDo.js} +1 -1
- package/dist/assets/{skeleton-CKpBjoLm.js → skeleton-Cqh4O9g1.js} +1 -1
- package/dist/assets/{snippets-panel-YttkYAW9.js → snippets-panel-Bh1oTw4m.js} +1 -1
- package/dist/assets/{spec-D9d9nT0z.js → spec-BfSBcO5B.js} +1 -1
- package/dist/assets/{spinner-CGdRKCnw.js → spinner-DyNE-o8o.js} +1 -1
- package/dist/assets/square-BPmgQFnh.js +1 -0
- package/dist/assets/{square-function-DyFIOFp5.js → square-function-_W_Lo0P4.js} +1 -1
- package/dist/assets/state-BAJYRhmO.js +1 -0
- package/dist/assets/{state-ja7GWeCS.js → state-C3oDoyFe.js} +1 -1
- package/dist/assets/{state-B2ZbImvm.js → state-DxQnC_1I.js} +1 -1
- package/dist/assets/{state-BI0fn_YF.js → state-XsPO8hNi.js} +1 -1
- package/dist/assets/{state-sbCCk7ZP.js → state-_Qai_QyX.js} +2 -2
- package/dist/assets/{state-BxLm8vme.js → state-uwRvJLb8.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-udui7EYS.js → stateDiagram-D77RDMKH-BeIsqkgQ.js} +1 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-YdOj4q4D.js +1 -0
- package/dist/assets/{strings-hlCLC-K1.js → strings-B2vv-ENv.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-C-iTrYJs.js → swimlanes-42K2YHIH-CIhaeNCx.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-BLZbCKkx.js +8 -0
- package/dist/assets/{swiper-component-eXUBvFuA.js → swiper-component-a07domrZ.js} +1 -1
- package/dist/assets/{switch-C-83e2fG.js → switch-CTaiAjrz.js} +1 -1
- package/dist/assets/{table-B7KYyTxw.js → table-DG7Ap4H4.js} +1 -1
- package/dist/assets/{table-Dg1KxH-q.js → table-vrvqpuKJ.js} +1 -1
- package/dist/assets/{tabs-QRT1DYjj.js → tabs-BuQlZFbt.js} +1 -1
- package/dist/assets/{terminal-3hxM6K9q.js → terminal-Ck_vK-34.js} +1 -1
- package/dist/assets/{timeline-definition-24CTP7MA-D2u0nOZp.js → timeline-definition-24CTP7MA-BSH7-Tss.js} +1 -1
- package/dist/assets/toDate-DOj9Q6uC.js +1 -0
- package/dist/assets/{toast-BRwEbWb6.js → toast-BGzLGnvw.js} +1 -1
- package/dist/assets/{tooltip-B5pI8o2n.js → tooltip-C9TuY18o.js} +1 -1
- package/dist/assets/{tooltip-BeP4eX87.js → tooltip-mT3CGest.js} +1 -1
- package/dist/assets/{tracing-DZYfCw6p.js → tracing-Di6pUmX8.js} +1 -1
- package/dist/assets/tracing-panel-PeRXHD8_.js +2 -0
- package/dist/assets/{trash-2-BJG-7Qob.js → trash-2-DcgaW8fn.js} +1 -1
- package/dist/assets/{trash-BKbZYRHl.js → trash-ChRHEGfM.js} +1 -1
- package/dist/assets/{tree-actions-D5clvgKl.js → tree-actions-GM5E_bUs.js} +1 -1
- package/dist/assets/{triangle-alert-BeRqoThc.js → triangle-alert-DmIqR8sY.js} +1 -1
- package/dist/assets/{use-restore-focus-GUh2Nd8Z.js → use-restore-focus-BxEGwIbk.js} +1 -1
- package/dist/assets/{use-toast-CC89xOwH.js → use-toast-Wu434mLr.js} +1 -1
- package/dist/assets/{use-vega-container-remeasure-CS3c8wGN.js → use-vega-container-remeasure-BpmHehNK.js} +1 -1
- package/dist/assets/{useAddCell-Bhv6GT3m.js → useAddCell-GR7eEQrT.js} +1 -1
- package/dist/assets/{useAsyncData-DucTwMkf.js → useAsyncData-C7aJJz0Y.js} +1 -1
- package/dist/assets/{useBoolean-Co-_MyFz.js → useBoolean-BDD6_xQQ.js} +1 -1
- package/dist/assets/{useCellActionButton-BTsPn8Dv.js → useCellActionButton-B-9eG5z_.js} +1 -1
- package/dist/assets/{useDateFormatter-CTYCgKB-.js → useDateFormatter-DA-62E-Y.js} +1 -1
- package/dist/assets/{useDebounce-DMbg9X18.js → useDebounce-B_ccBZTp.js} +1 -1
- package/dist/assets/useDeepCompareMemoize-DFIVN9dn.js +1 -0
- package/dist/assets/{useDeleteCell-BKN7t4DH.js → useDeleteCell-2_bMClHd.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-BTsnw2rN.js → useDependencyPanelTab-k3C3M18S.js} +1 -1
- package/dist/assets/{useEvent-Dc9HkKI2.js → useEvent-Dfcbgjhg.js} +1 -1
- package/dist/assets/{useEventListener-IRzG-0mH.js → useEventListener-D9cftcHj.js} +1 -1
- package/dist/assets/useIframeCapabilities-CwTkczVN.js +1 -0
- package/dist/assets/{useInstallPackage-HTUlGg0U.js → useInstallPackage-iX1eufdl.js} +1 -1
- package/dist/assets/{useInterval-D1QGqQ_I.js → useInterval--x3s1VpI.js} +1 -1
- package/dist/assets/{useLifecycle-DKSBdWUf.js → useLifecycle-Mq4gc5kS.js} +1 -1
- package/dist/assets/useNotebookActions-NHN6A-cN.js +1 -0
- package/dist/assets/{useNumberFormatter-BP99Zbyy.js → useNumberFormatter-D7O_26UI.js} +1 -1
- package/dist/assets/{useRunCells-zMO43eNR.js → useRunCells-B2vUhREg.js} +1 -1
- package/dist/assets/useSplitCell-DEb03htp.js +1 -0
- package/dist/assets/{useTheme-BkPLyRl9.js → useTheme-COhSHkCj.js} +1 -1
- package/dist/assets/{vega-component-Chbfi__Q.js → vega-component-CnadTgoE.js} +1 -1
- package/dist/assets/vega-embed-container-DJPNkHPb.js +1 -0
- package/dist/assets/{vennDiagram-4TSXK5OY-BKSHsv-w.js → vennDiagram-4TSXK5OY-DsmfChmC.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-CUDQDDoy.js → wardleyDiagram-VM6X3IG4-BDZlVpJI.js} +1 -1
- package/dist/assets/worker-DTQ7oH2A.js +158 -0
- package/dist/assets/{workflow-nBi9HGeO.js → workflow-cw-0b9g5.js} +1 -1
- package/dist/assets/{write-secret-modal-BcosCmZy.js → write-secret-modal-DzKAInL2.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-BXDsTxGu.js → xychartDiagram-S5SC5T6Z-KbGzG6-u.js} +1 -1
- package/dist/assets/{youtube-2MBs34oQ.js → youtube-CbJhsgLy.js} +1 -1
- package/dist/index.html +123 -123
- package/package.json +23 -22
- package/src/components/data-table/__tests__/column_formatting.test.ts +30 -0
- package/src/components/data-table/__tests__/columns.test.tsx +70 -0
- package/src/components/data-table/column-formatting/feature.ts +20 -1
- package/src/components/data-table/columns.tsx +25 -18
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +4 -3
- package/src/components/editor/output/console/ConsoleOutput.tsx +5 -3
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +18 -0
- package/src/components/storage/__tests__/storage-file-viewer.test.tsx +2 -1
- package/src/core/cells/__tests__/document-roundtrip.test.ts +16 -0
- package/src/core/codemirror/copilot/__tests__/completion-integration.test.ts +447 -0
- package/src/core/codemirror/copilot/__tests__/inline-completion.test.ts +395 -0
- package/src/core/codemirror/copilot/__tests__/language-server.test.ts +511 -2
- package/src/core/codemirror/copilot/__tests__/rpc-cancellation.test.ts +201 -0
- package/src/core/codemirror/copilot/extension.ts +22 -11
- package/src/core/codemirror/copilot/language-server.ts +109 -60
- package/src/core/codemirror/language/__tests__/sql.test.ts +4 -3
- package/src/core/codemirror/language/embedded/__tests__/embedded-python.test.ts +138 -26
- package/src/core/codemirror/language/embedded/embedded-python.ts +47 -13
- package/src/core/codemirror/language/embedded/latex.ts +20 -13
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +18 -11
- package/src/core/islands/bridge.ts +2 -2
- package/src/core/kernel/messages.ts +4 -7
- package/src/core/network/__tests__/api.test.ts +114 -1
- package/src/core/network/api.ts +3 -2
- package/src/core/wasm/bridge.ts +2 -2
- package/src/core/wasm/worker/types.ts +2 -2
- package/src/css/katex-css.test.ts +166 -0
- package/src/css/katex.min.css +33 -28
- package/src/hooks/__tests__/useEventListener.test.tsx +45 -1
- package/src/hooks/useEventListener.ts +6 -1
- package/src/plugins/impl/NumberPlugin.tsx +20 -3
- package/src/plugins/impl/__tests__/NumberPlugin.test.tsx +159 -1
- package/dist/assets/JsonOutput-DCGUcLVV.js +0 -11
- package/dist/assets/__vite-browser-external-BgsHWynV.js +0 -1
- package/dist/assets/__vite-browser-external-DMJaCYJh.js +0 -1
- package/dist/assets/add-cell-with-ai-Wyt6GBhk.js +0 -76
- package/dist/assets/ai-model-dropdown-CvJsRj9y.js +0 -5
- package/dist/assets/app-config-button-C7QrZbqr.js +0 -1
- package/dist/assets/arrow-down-BFFrjzad.js +0 -1
- package/dist/assets/arrow-left-DzPJ79ZB.js +0 -1
- package/dist/assets/arrow-right-xoNT7eIQ.js +0 -1
- package/dist/assets/ban-3HAzm9Fj.js +0 -1
- package/dist/assets/cells-CxY8RSp7.js +0 -220
- package/dist/assets/channel-DXBvxHxq.js +0 -1
- package/dist/assets/chat-panel-BZipGUZV.js +0 -4
- package/dist/assets/check-Wea4hZ6R.js +0 -1
- package/dist/assets/chevron-right-DOPs2jx8.js +0 -1
- package/dist/assets/circle-check-BF80fXZd.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV--9ShP1h2.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY--9ShP1h2.js +0 -1
- package/dist/assets/code-DW4kNwKG.js +0 -1
- package/dist/assets/coerce-CZiN7rQ_.js +0 -1
- package/dist/assets/command-palette-BM9fUfEe.js +0 -1
- package/dist/assets/dates-BgcKUsHb.js +0 -1
- package/dist/assets/feedback-button-DxjoRfo3.js +0 -1
- package/dist/assets/flowDiagram-HODETNUW-BGVnBaF-.js +0 -1
- package/dist/assets/katex-CQIbPNPT.js +0 -1
- package/dist/assets/kiosk-mode-DCHo0R3W.js +0 -1
- package/dist/assets/links-BJx6KCyC.js +0 -1
- package/dist/assets/loro_wasm_bg-PyJsS6iH.wasm +0 -0
- package/dist/assets/loro_wasm_bg-Vo2IoHaL.js +0 -1
- package/dist/assets/loro_wasm_bg-oTW3uoGB.js +0 -1
- package/dist/assets/mermaid-HWGCJPDP-Bk1fR60Q.js +0 -1
- package/dist/assets/pair-_FSgYVX4.js +0 -1
- package/dist/assets/plus-gbN72xHe.js +0 -1
- package/dist/assets/process-output-Crm0vqbi.js +0 -1
- package/dist/assets/react-CUdNIagt.js +0 -1
- package/dist/assets/react-dom-CKsE8sC1.js +0 -1
- package/dist/assets/requests-DFPPfagc.js +0 -1
- package/dist/assets/reveal-component-B5GUiD5Q.js +0 -1069
- package/dist/assets/save-worker-C880NC3o.js +0 -113
- package/dist/assets/schemas-BL-NsLlF.js +0 -51
- package/dist/assets/square-DvOKKLHZ.js +0 -1
- package/dist/assets/state-YaAkDV8S.js +0 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-BhduIvF1.js +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-WC2Zewqb.js +0 -8
- package/dist/assets/toDate-BbJ1_N2T.js +0 -1
- package/dist/assets/tracing-panel-BUPJ77jB.js +0 -2
- package/dist/assets/useDeepCompareMemoize-DSlTt6u_.js +0 -1
- package/dist/assets/useIframeCapabilities-yd8sMuIo.js +0 -1
- package/dist/assets/useNotebookActions-BzJtySGp.js +0 -1
- package/dist/assets/useSplitCell-xEtFLByO.js +0 -1
- package/dist/assets/vega-embed-container-CRZZ4FTx.js +0 -1
- package/dist/assets/worker-B5tVfGoh.js +0 -153
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
JSONRPCClient,
|
|
5
|
+
type JSONRPCMessage,
|
|
6
|
+
type Transport,
|
|
7
|
+
} from "@marimo-team/codemirror-languageserver";
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
9
|
+
|
|
10
|
+
describe("LSP request cancellation", () => {
|
|
11
|
+
let client: JSONRPCClient;
|
|
12
|
+
let emit: (message: JSONRPCMessage) => void;
|
|
13
|
+
let disconnect: (error: Error) => void;
|
|
14
|
+
let connected: ReturnType<typeof Promise.withResolvers<undefined>>;
|
|
15
|
+
let transport: Transport & {
|
|
16
|
+
send: ReturnType<typeof vi.fn<(message: JSONRPCMessage) => void>>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
vi.useFakeTimers();
|
|
21
|
+
connected = Promise.withResolvers<undefined>();
|
|
22
|
+
transport = {
|
|
23
|
+
connect: () => connected.promise,
|
|
24
|
+
close: vi.fn(),
|
|
25
|
+
send: vi.fn<(message: JSONRPCMessage) => void>(),
|
|
26
|
+
onMessage: (handler) => {
|
|
27
|
+
emit = handler;
|
|
28
|
+
return vi.fn();
|
|
29
|
+
},
|
|
30
|
+
onClose: (handler) => {
|
|
31
|
+
disconnect = handler;
|
|
32
|
+
return vi.fn();
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
client = new JSONRPCClient(transport);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
afterEach(() => {
|
|
39
|
+
client.close();
|
|
40
|
+
vi.useRealTimers();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
async function connect() {
|
|
44
|
+
connected.resolve(undefined);
|
|
45
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
it("does not send an already-aborted request", async () => {
|
|
49
|
+
await connect();
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
controller.abort();
|
|
52
|
+
await expect(
|
|
53
|
+
client.request("complete", {}, 1000, controller.signal),
|
|
54
|
+
).rejects.toMatchObject({ name: "AbortError" });
|
|
55
|
+
expect(transport.send).not.toHaveBeenCalled();
|
|
56
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("cancels while connecting without sending either request or cancellation", async () => {
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
const response = client.request("complete", {}, 1000, controller.signal);
|
|
62
|
+
controller.abort();
|
|
63
|
+
await expect(response).rejects.toMatchObject({ name: "AbortError" });
|
|
64
|
+
await connect();
|
|
65
|
+
expect(transport.send).not.toHaveBeenCalled();
|
|
66
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("rejects a failed connection and removes the waiting request's abort listener", async () => {
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const remove = vi.spyOn(controller.signal, "removeEventListener");
|
|
72
|
+
const response = client.request("complete", {}, 1000, controller.signal);
|
|
73
|
+
const settled = response.catch((error: unknown) => error);
|
|
74
|
+
connected.reject(new Error("connection refused"));
|
|
75
|
+
await expect(settled).resolves.toMatchObject({
|
|
76
|
+
message: "connection refused",
|
|
77
|
+
});
|
|
78
|
+
expect(remove).toHaveBeenCalledExactlyOnceWith(
|
|
79
|
+
"abort",
|
|
80
|
+
expect.any(Function),
|
|
81
|
+
);
|
|
82
|
+
controller.abort();
|
|
83
|
+
expect(transport.send).not.toHaveBeenCalled();
|
|
84
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("cancels exactly the matching request, ignores late replies, and leaves others active", async () => {
|
|
88
|
+
await connect();
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
const first = client.request(
|
|
91
|
+
"complete",
|
|
92
|
+
{ position: 1 },
|
|
93
|
+
1000,
|
|
94
|
+
controller.signal,
|
|
95
|
+
);
|
|
96
|
+
const second = client.request("complete", { position: 2 }, 1000);
|
|
97
|
+
controller.abort();
|
|
98
|
+
controller.abort();
|
|
99
|
+
await expect(first).rejects.toMatchObject({ name: "AbortError" });
|
|
100
|
+
emit({ jsonrpc: "2.0", id: 0, result: "stale" });
|
|
101
|
+
emit({ jsonrpc: "2.0", id: 1, result: "latest" });
|
|
102
|
+
await expect(second).resolves.toBe("latest");
|
|
103
|
+
expect(transport.send.mock.calls).toEqual([
|
|
104
|
+
[{ jsonrpc: "2.0", id: 0, method: "complete", params: { position: 1 } }],
|
|
105
|
+
[{ jsonrpc: "2.0", id: 1, method: "complete", params: { position: 2 } }],
|
|
106
|
+
[{ jsonrpc: "2.0", method: "$/cancelRequest", params: { id: 0 } }],
|
|
107
|
+
]);
|
|
108
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it.each([
|
|
112
|
+
"success",
|
|
113
|
+
"error",
|
|
114
|
+
"timeout",
|
|
115
|
+
"disconnect",
|
|
116
|
+
"close",
|
|
117
|
+
"send failure",
|
|
118
|
+
])("removes the abort listener and timer after %s", async (outcome) => {
|
|
119
|
+
await connect();
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
const remove = vi.spyOn(controller.signal, "removeEventListener");
|
|
122
|
+
if (outcome === "send failure") {
|
|
123
|
+
transport.send.mockImplementationOnce(() => {
|
|
124
|
+
throw new Error("send failed");
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const response = client.request("complete", {}, 1000, controller.signal);
|
|
128
|
+
// Attach the rejection handler before advancing timers or dropping the connection.
|
|
129
|
+
const settled = response.then(
|
|
130
|
+
(value) => ({ status: "fulfilled", value }),
|
|
131
|
+
(error: unknown) => ({ status: "rejected", error }),
|
|
132
|
+
);
|
|
133
|
+
if (outcome === "success") {
|
|
134
|
+
emit({ jsonrpc: "2.0", id: 0, result: "ok" });
|
|
135
|
+
}
|
|
136
|
+
if (outcome === "error") {
|
|
137
|
+
emit({
|
|
138
|
+
jsonrpc: "2.0",
|
|
139
|
+
id: 0,
|
|
140
|
+
error: { code: -32603, message: "failed" },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
if (outcome === "timeout") {
|
|
144
|
+
await vi.advanceTimersByTimeAsync(1000);
|
|
145
|
+
}
|
|
146
|
+
if (outcome === "disconnect") {
|
|
147
|
+
disconnect(new Error("disconnected"));
|
|
148
|
+
}
|
|
149
|
+
if (outcome === "close") {
|
|
150
|
+
client.close();
|
|
151
|
+
}
|
|
152
|
+
const expectedError = expect.any(Error);
|
|
153
|
+
expect(await settled).toEqual(
|
|
154
|
+
outcome === "success"
|
|
155
|
+
? { status: "fulfilled", value: "ok" }
|
|
156
|
+
: { status: "rejected", error: expectedError },
|
|
157
|
+
);
|
|
158
|
+
expect(remove).toHaveBeenCalledExactlyOnceWith(
|
|
159
|
+
"abort",
|
|
160
|
+
expect.any(Function),
|
|
161
|
+
);
|
|
162
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
163
|
+
const calls = transport.send.mock.calls.length;
|
|
164
|
+
controller.abort();
|
|
165
|
+
expect(transport.send).toHaveBeenCalledTimes(calls);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("sends exactly one cancellation at the timeout boundary and ignores a late reply", async () => {
|
|
169
|
+
await connect();
|
|
170
|
+
const controller = new AbortController();
|
|
171
|
+
const settled = client
|
|
172
|
+
.request("complete", {}, 1000, controller.signal)
|
|
173
|
+
.catch((error: unknown) => error);
|
|
174
|
+
await vi.advanceTimersByTimeAsync(999);
|
|
175
|
+
expect(transport.send.mock.calls).toEqual([
|
|
176
|
+
[{ jsonrpc: "2.0", id: 0, method: "complete", params: {} }],
|
|
177
|
+
]);
|
|
178
|
+
await vi.advanceTimersByTimeAsync(1);
|
|
179
|
+
expect(transport.send.mock.calls).toEqual([
|
|
180
|
+
[{ jsonrpc: "2.0", id: 0, method: "complete", params: {} }],
|
|
181
|
+
[{ jsonrpc: "2.0", method: "$/cancelRequest", params: { id: 0 } }],
|
|
182
|
+
]);
|
|
183
|
+
emit({ jsonrpc: "2.0", id: 0, result: "late" });
|
|
184
|
+
controller.abort();
|
|
185
|
+
await expect(settled).resolves.toMatchObject({ code: -32001 });
|
|
186
|
+
expect(transport.send).toHaveBeenCalledTimes(2);
|
|
187
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("settles cancellation even if sending the cancellation notification fails", async () => {
|
|
191
|
+
await connect();
|
|
192
|
+
const controller = new AbortController();
|
|
193
|
+
const response = client.request("complete", {}, 1000, controller.signal);
|
|
194
|
+
transport.send.mockImplementationOnce(() => {
|
|
195
|
+
throw new Error("connection gone");
|
|
196
|
+
});
|
|
197
|
+
controller.abort();
|
|
198
|
+
await expect(response).rejects.toMatchObject({ name: "AbortError" });
|
|
199
|
+
expect(vi.getTimerCount()).toBe(0);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
@@ -39,7 +39,7 @@ const copilotCompartment = new Compartment();
|
|
|
39
39
|
const logger = Logger.get("@github/copilot-language-server");
|
|
40
40
|
|
|
41
41
|
const commonInlineCompletionConfig = {
|
|
42
|
-
delay:
|
|
42
|
+
delay: 150,
|
|
43
43
|
includeKeymap: true,
|
|
44
44
|
events: {
|
|
45
45
|
// Only show suggestions when the editor is focused
|
|
@@ -79,7 +79,7 @@ export const copilotBundle = (config: CompletionConfig): Extension => {
|
|
|
79
79
|
extensions.push(
|
|
80
80
|
inlineCompletion({
|
|
81
81
|
...commonInlineCompletionConfig,
|
|
82
|
-
fetchFn: async (state,
|
|
82
|
+
fetchFn: async (state, signal, view) => {
|
|
83
83
|
const currentPosition = state.selection.main.head;
|
|
84
84
|
if (!isCopilotEnabled()) {
|
|
85
85
|
return "";
|
|
@@ -94,16 +94,22 @@ export const copilotBundle = (config: CompletionConfig): Extension => {
|
|
|
94
94
|
return "";
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
const client = getCopilotClient();
|
|
98
|
+
const allCode = await client.flushDocumentChanges(
|
|
99
|
+
state.doc.toString(),
|
|
100
|
+
);
|
|
101
|
+
if (signal.aborted || state.doc !== view.state.doc) {
|
|
102
|
+
return "";
|
|
103
|
+
}
|
|
102
104
|
const request = getCopilotRequest(state, allCode);
|
|
103
|
-
const response = await
|
|
105
|
+
const response = await client.getCompletion(request, signal);
|
|
104
106
|
|
|
105
107
|
// If we are at a new position, ignore the response
|
|
106
|
-
if (
|
|
108
|
+
if (
|
|
109
|
+
signal.aborted ||
|
|
110
|
+
state.doc !== view.state.doc ||
|
|
111
|
+
currentPosition !== view.state.selection.main.head
|
|
112
|
+
) {
|
|
107
113
|
Logger.debug("ignoring response because of new position");
|
|
108
114
|
return "";
|
|
109
115
|
}
|
|
@@ -119,7 +125,7 @@ export const copilotBundle = (config: CompletionConfig): Extension => {
|
|
|
119
125
|
extensions.push(
|
|
120
126
|
inlineCompletion({
|
|
121
127
|
...commonInlineCompletionConfig,
|
|
122
|
-
fetchFn: async (state,
|
|
128
|
+
fetchFn: async (state, signal, view) => {
|
|
123
129
|
const currentPosition = state.selection.main.head;
|
|
124
130
|
|
|
125
131
|
if (state.doc.length === 0) {
|
|
@@ -146,10 +152,15 @@ export const copilotBundle = (config: CompletionConfig): Extension => {
|
|
|
146
152
|
let res = await API.post<AiInlineCompletionRequest, string>(
|
|
147
153
|
"/ai/inline_completion",
|
|
148
154
|
{ prefix, suffix, language },
|
|
155
|
+
{ signal },
|
|
149
156
|
);
|
|
150
157
|
|
|
151
158
|
// If we are at a new position, ignore the response
|
|
152
|
-
if (
|
|
159
|
+
if (
|
|
160
|
+
signal.aborted ||
|
|
161
|
+
state.doc !== view.state.doc ||
|
|
162
|
+
currentPosition !== view.state.selection.main.head
|
|
163
|
+
) {
|
|
153
164
|
Logger.debug("ignoring response because of new position");
|
|
154
165
|
return "";
|
|
155
166
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { LanguageServerClient } from "@marimo-team/codemirror-languageserver";
|
|
4
|
-
import { throttle } from "lodash-es";
|
|
5
4
|
import type {
|
|
6
5
|
CompletionItem,
|
|
7
6
|
CompletionList,
|
|
@@ -58,6 +57,7 @@ interface UntypedLanguageServerMethods {
|
|
|
58
57
|
method: string,
|
|
59
58
|
params: unknown,
|
|
60
59
|
timeout: number,
|
|
60
|
+
signal?: AbortSignal,
|
|
61
61
|
) => Promise<unknown>;
|
|
62
62
|
notify: (method: string, params: unknown) => Promise<void>;
|
|
63
63
|
}
|
|
@@ -113,6 +113,8 @@ function isLogMessageParams(
|
|
|
113
113
|
*/
|
|
114
114
|
export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
115
115
|
private documentVersion = 0;
|
|
116
|
+
private pendingChange: DidChangeTextDocumentParams | undefined;
|
|
117
|
+
private completionController: AbortController | undefined;
|
|
116
118
|
private openDocumentCount = 0;
|
|
117
119
|
private lastOpenedDocument: DidOpenTextDocumentParams | undefined;
|
|
118
120
|
private copilotSettings: Record<string, unknown> = {};
|
|
@@ -142,9 +144,11 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
142
144
|
*/
|
|
143
145
|
public async reInitialize(): Promise<void> {
|
|
144
146
|
logger.log("#reInitialize: Re-initializing LSP connection");
|
|
147
|
+
this.completionController?.abort();
|
|
145
148
|
this.initializePromise = this.initialize();
|
|
146
149
|
await this.initializePromise;
|
|
147
150
|
await this.sendConfiguration();
|
|
151
|
+
this.applyPendingChange();
|
|
148
152
|
if (this.openDocumentCount > 0 && this.lastOpenedDocument) {
|
|
149
153
|
await this.sendNotification(
|
|
150
154
|
"textDocument/didOpen",
|
|
@@ -168,12 +172,14 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
168
172
|
private async _request<Method extends keyof LSPRequestMap>(
|
|
169
173
|
method: Method,
|
|
170
174
|
params: LSPRequestMap[Method][0],
|
|
175
|
+
signal?: AbortSignal,
|
|
171
176
|
): Promise<LSPRequestMap[Method][1]> {
|
|
172
177
|
assertHasLanguageServerRpc(this);
|
|
173
178
|
return (await this.request(
|
|
174
179
|
method,
|
|
175
180
|
params,
|
|
176
181
|
REQUEST_TIMEOUT_MS,
|
|
182
|
+
signal,
|
|
177
183
|
)) as LSPRequestMap[Method][1];
|
|
178
184
|
}
|
|
179
185
|
|
|
@@ -230,6 +236,10 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
230
236
|
return;
|
|
231
237
|
}
|
|
232
238
|
this.openDocumentCount--;
|
|
239
|
+
if (this.openDocumentCount === 0) {
|
|
240
|
+
this.pendingChange = undefined;
|
|
241
|
+
this.completionController?.abort();
|
|
242
|
+
}
|
|
233
243
|
return super.textDocumentDidClose(params);
|
|
234
244
|
}
|
|
235
245
|
|
|
@@ -281,27 +291,72 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
281
291
|
);
|
|
282
292
|
}
|
|
283
293
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
294
|
+
this.completionController?.abort();
|
|
295
|
+
this.pendingChange = {
|
|
296
|
+
...params,
|
|
297
|
+
textDocument: VersionedTextDocumentIdentifier.create(
|
|
298
|
+
params.textDocument.uri,
|
|
299
|
+
++this.documentVersion,
|
|
300
|
+
),
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
private applyPendingChange(
|
|
305
|
+
assembledText?: string,
|
|
306
|
+
): DidChangeTextDocumentParams | undefined {
|
|
307
|
+
const pending = this.pendingChange;
|
|
308
|
+
if (!pending) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
this.pendingChange = undefined;
|
|
312
|
+
const text = assembledText ?? getCodes(pending.contentChanges[0].text);
|
|
287
313
|
this.lastOpenedDocument = {
|
|
288
314
|
textDocument: {
|
|
289
|
-
|
|
315
|
+
...pending.textDocument,
|
|
290
316
|
languageId:
|
|
291
317
|
this.lastOpenedDocument?.textDocument.languageId ??
|
|
292
318
|
DEFAULT_LANGUAGE_ID,
|
|
293
|
-
version,
|
|
294
319
|
text,
|
|
295
320
|
},
|
|
296
321
|
};
|
|
297
|
-
return
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
322
|
+
return { ...pending, contentChanges: [{ text }] };
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/** Assemble and send the latest notebook once, just before requesting a suggestion. */
|
|
326
|
+
public async flushDocumentChanges(currentCode?: string): Promise<string> {
|
|
327
|
+
// Another cell may have changed since the focused editor last typed.
|
|
328
|
+
// The focused cell must be last in the shared document for cursor mapping.
|
|
329
|
+
const assembledText =
|
|
330
|
+
currentCode !== undefined && this.lastOpenedDocument
|
|
331
|
+
? getCodes(currentCode)
|
|
332
|
+
: undefined;
|
|
333
|
+
if (
|
|
334
|
+
currentCode !== undefined &&
|
|
335
|
+
this.lastOpenedDocument &&
|
|
336
|
+
(this.pendingChange
|
|
337
|
+
? this.pendingChange.contentChanges[0].text !== currentCode
|
|
338
|
+
: assembledText !== this.lastOpenedDocument.textDocument.text)
|
|
339
|
+
) {
|
|
340
|
+
this.pendingChange = {
|
|
341
|
+
textDocument: VersionedTextDocumentIdentifier.create(
|
|
342
|
+
this.lastOpenedDocument.textDocument.uri,
|
|
343
|
+
++this.documentVersion,
|
|
344
|
+
),
|
|
345
|
+
contentChanges: [{ text: currentCode }],
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
const pending = this.pendingChange;
|
|
349
|
+
const change = this.applyPendingChange(assembledText);
|
|
350
|
+
if (change) {
|
|
351
|
+
try {
|
|
352
|
+
await super.textDocumentDidChange(change);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
// Preserve newer edits if the send failed while another change arrived.
|
|
355
|
+
this.pendingChange ??= pending;
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return this.lastOpenedDocument?.textDocument.text ?? "";
|
|
305
360
|
}
|
|
306
361
|
|
|
307
362
|
public override textDocumentHover(params: HoverParams): Promise<Hover> {
|
|
@@ -351,49 +406,32 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
351
406
|
}
|
|
352
407
|
}
|
|
353
408
|
|
|
354
|
-
private getCompletionInternal = async (
|
|
355
|
-
params: InlineCompletionParams,
|
|
356
|
-
version: number,
|
|
357
|
-
): Promise<InlineCompletionList | InlineCompletionItem[] | null> => {
|
|
358
|
-
return await this._request("textDocument/inlineCompletion", {
|
|
359
|
-
...params,
|
|
360
|
-
textDocument: {
|
|
361
|
-
...VersionedTextDocumentIdentifier.create(
|
|
362
|
-
params.textDocument.uri,
|
|
363
|
-
version,
|
|
364
|
-
),
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
// Even though the copilot extension has a debounce,
|
|
370
|
-
// there are multiple requests sent at the same time
|
|
371
|
-
// when multiple Codemirror instances are mounted at the same time.
|
|
372
|
-
// So we throttle it to ignore multiple requests at the same time.
|
|
373
|
-
private throttledGetCompletionInternal = throttle(
|
|
374
|
-
this.getCompletionInternal,
|
|
375
|
-
200,
|
|
376
|
-
);
|
|
377
|
-
|
|
378
409
|
public async getCompletion(
|
|
379
410
|
params: InlineCompletionParams,
|
|
411
|
+
signal?: AbortSignal,
|
|
380
412
|
): Promise<InlineCompletionList | InlineCompletionItem[] | null> {
|
|
381
|
-
if (this.isDisabled()) {
|
|
413
|
+
if (this.isDisabled() || signal?.aborted || this.openDocumentCount === 0) {
|
|
382
414
|
return null;
|
|
383
415
|
}
|
|
384
416
|
|
|
417
|
+
this.completionController?.abort();
|
|
418
|
+
const controller = new AbortController();
|
|
419
|
+
this.completionController = controller;
|
|
420
|
+
const abort = () => controller.abort();
|
|
421
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
385
422
|
const requestVersion = this.documentVersion;
|
|
386
|
-
|
|
387
|
-
// If version is 0, it means the document hasn't been opened yet
|
|
388
|
-
if (requestVersion === 0) {
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// Start a loading indicator
|
|
393
423
|
setGitHubCopilotLoadingVersion(requestVersion);
|
|
394
|
-
let response: InlineCompletionList | InlineCompletionItem[] | null;
|
|
395
424
|
try {
|
|
396
|
-
|
|
425
|
+
await this.flushDocumentChanges();
|
|
426
|
+
if (
|
|
427
|
+
controller.signal.aborted ||
|
|
428
|
+
this.isDisabled() ||
|
|
429
|
+
requestVersion === 0
|
|
430
|
+
) {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const response = await this._request(
|
|
434
|
+
"textDocument/inlineCompletion",
|
|
397
435
|
{
|
|
398
436
|
...params,
|
|
399
437
|
textDocument: VersionedTextDocumentIdentifier.create(
|
|
@@ -401,24 +439,35 @@ export class CopilotLanguageServerClient extends LanguageServerClient {
|
|
|
401
439
|
requestVersion,
|
|
402
440
|
),
|
|
403
441
|
},
|
|
404
|
-
|
|
442
|
+
controller.signal,
|
|
405
443
|
);
|
|
444
|
+
if (
|
|
445
|
+
controller.signal.aborted ||
|
|
446
|
+
this.isDisabled() ||
|
|
447
|
+
requestVersion !== this.documentVersion
|
|
448
|
+
) {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
return response;
|
|
406
452
|
} catch (error) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
453
|
+
if (!controller.signal.aborted) {
|
|
454
|
+
logger.warn("#getCompletion: Failed to fetch completions", error);
|
|
455
|
+
}
|
|
410
456
|
return null;
|
|
411
457
|
} finally {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
return null;
|
|
458
|
+
signal?.removeEventListener("abort", abort);
|
|
459
|
+
// A superseded request can have the same document version as its successor.
|
|
460
|
+
if (this.completionController === controller) {
|
|
461
|
+
this.completionController = undefined;
|
|
462
|
+
clearGitHubCopilotLoadingVersion(requestVersion);
|
|
463
|
+
}
|
|
419
464
|
}
|
|
465
|
+
}
|
|
420
466
|
|
|
421
|
-
|
|
467
|
+
public override close(): void {
|
|
468
|
+
this.pendingChange = undefined;
|
|
469
|
+
this.completionController?.abort();
|
|
470
|
+
super.close();
|
|
422
471
|
}
|
|
423
472
|
|
|
424
473
|
/**
|
|
@@ -8,6 +8,7 @@ import { EditorState, type Extension } from "@codemirror/state";
|
|
|
8
8
|
import { EditorView } from "@codemirror/view";
|
|
9
9
|
import { DuckDBDialect } from "@marimo-team/codemirror-sql/dialects";
|
|
10
10
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
11
|
+
import { requestId } from "@/__tests__/branded";
|
|
11
12
|
import type { CellId } from "@/core/cells/ids";
|
|
12
13
|
import type {
|
|
13
14
|
CompletionConfig,
|
|
@@ -1106,7 +1107,7 @@ describe("CustomSqlParser", () => {
|
|
|
1106
1107
|
const request = vi.spyOn(ValidateSQL, "request").mockResolvedValue({
|
|
1107
1108
|
error: null,
|
|
1108
1109
|
parse_result: { success: false, errors: [error] },
|
|
1109
|
-
request_id: "request-id",
|
|
1110
|
+
request_id: requestId("request-id"),
|
|
1110
1111
|
validate_result: null,
|
|
1111
1112
|
});
|
|
1112
1113
|
const state = EditorState.create({
|
|
@@ -1150,7 +1151,7 @@ describe("CustomSqlParser", () => {
|
|
|
1150
1151
|
vi.spyOn(ValidateSQL, "request").mockResolvedValue({
|
|
1151
1152
|
error: null,
|
|
1152
1153
|
parse_result: { success: false, errors: [error] },
|
|
1153
|
-
request_id: "request-id",
|
|
1154
|
+
request_id: requestId("request-id"),
|
|
1154
1155
|
validate_result: null,
|
|
1155
1156
|
});
|
|
1156
1157
|
const state = EditorState.create({
|
|
@@ -1194,7 +1195,7 @@ describe("CustomSqlParser", () => {
|
|
|
1194
1195
|
const request = vi.spyOn(ValidateSQL, "request").mockResolvedValue({
|
|
1195
1196
|
error: null,
|
|
1196
1197
|
parse_result: { success: false, errors: [error] },
|
|
1197
|
-
request_id: "request-id",
|
|
1198
|
+
request_id: requestId("request-id"),
|
|
1198
1199
|
validate_result: null,
|
|
1199
1200
|
});
|
|
1200
1201
|
const state = createNamedConnectionState({
|