@marimo-team/frontend 0.25.3-dev4 → 0.25.3-dev42
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-BpOBz-8m.js +1 -0
- package/dist/assets/{ConnectedDataExplorerComponent-t8fH_TNc.js → ConnectedDataExplorerComponent-D9UK8o9A.js} +1 -1
- package/dist/assets/{ErrorBoundary-Gl5nCA8C.js → ErrorBoundary-DmXl4Nre.js} +2 -2
- package/dist/assets/JsonOutput-BJraU9kp.js +11 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-CKcCbG2G.js → LazyAnyLanguageCodeMirror-BPYE76jR.js} +2 -2
- package/dist/assets/MarimoErrorOutput-DVjK8RgY.js +10 -0
- package/dist/assets/{RenderHTML-BbOqmHy3.js → RenderHTML-BFaztTR0.js} +1 -1
- package/dist/assets/{RunButton-CK3LhnP5.js → RunButton-B44xE_d5.js} +1 -1
- package/dist/assets/{add-cell-with-ai-8UBC0xwR.js → add-cell-with-ai-CkjslziO.js} +13 -13
- package/dist/assets/{add-connection-dialog-DXQnd6eB.js → add-connection-dialog-CWLLVKju.js} +2 -2
- package/dist/assets/{agent-panel-DdkVL-Kx.js → agent-panel-DYdQ_2pp.js} +5 -5
- package/dist/assets/ai-model-dropdown-F3mm17Wa.js +13 -0
- package/dist/assets/{alert-dialog-BaPGzeOK.js → alert-dialog-C-sWmKva.js} +1 -1
- package/dist/assets/any-language-editor-DUMe1UCk.js +1 -0
- package/dist/assets/{app-config-button-BKEG4x9u.js → app-config-button-D0uDs5nC.js} +1 -1
- package/dist/assets/arrays-0R2reF2y.js +1 -0
- package/dist/assets/{blob-D5nfNHOo.js → blob-BSfsdCNF.js} +1 -1
- package/dist/assets/{button-COI-NGrx.js → button-D8gVKwe-.js} +1 -1
- package/dist/assets/{cache-panel-DTY1dqvi.js → cache-panel-Byolv2ht.js} +1 -1
- package/dist/assets/{capabilities-BJvf-MD4.js → capabilities-Pq1YNPlK.js} +1 -1
- package/dist/assets/{cell-editor-32lVhib7.js → cell-editor-DzvvHs9g.js} +9 -9
- package/dist/assets/{cell-link-LSth_8hT.js → cell-link-DFPHORAO.js} +1 -1
- package/dist/assets/{cells-BRkCaSsh.js → cells-BdgzY0of.js} +31 -31
- package/dist/assets/{chat-display-Dnagy4Nv.js → chat-display-BrcwdhKJ.js} +1 -1
- package/dist/assets/{chat-panel-DN9vsbgS.js → chat-panel-C__3iSyI.js} +2 -2
- package/dist/assets/{chat-ui-Df8Vcj6n.js → chat-ui-NlBK3kK6.js} +1 -1
- package/dist/assets/{circle-DXf-VWZG.js → circle-B6D_6D8w.js} +1 -1
- package/dist/assets/code-visibility-Cs-Vv3jV.js +1 -0
- package/dist/assets/coerce-DWjFeXOY.js +1 -0
- package/dist/assets/{column-preview-CHK_DNrs.js → column-preview-ivm1b-GY.js} +1 -1
- package/dist/assets/command-palette-TgwswwvD.js +1 -0
- package/dist/assets/{common-Cu6CDbuw.js → common-BcEY1yDS.js} +1 -1
- package/dist/assets/{components-CP_UoFtT.js → components-DrU8dOzy.js} +1 -1
- package/dist/assets/{components-CXfO-F47.js → components-lDm0qi2t.js} +1 -1
- package/dist/assets/{components-CGw16R_N.js → components-lkCfd2vy.js} +1 -1
- package/dist/assets/config-BwHT0yGp.js +104 -0
- package/dist/assets/config-DGX7JYor.js +1 -0
- package/dist/assets/config-DXjnAwtL.js +1 -0
- package/dist/assets/{copy-D8O_CYCG.js → copy-KlhazlhB.js} +1 -1
- package/dist/assets/{copy-icon-BIiRXh_3.js → copy-icon-8-a5vovc.js} +1 -1
- package/dist/assets/{createReducer-DgRODTW6.js → createReducer-HKXUbqyz.js} +1 -1
- package/dist/assets/{datasource-Cq6x_5ML.js → datasource-dKk3JHSQ.js} +1 -1
- package/dist/assets/{dates-CfmdTL6B.js → dates-CQMwFko2.js} +1 -1
- package/dist/assets/{dependency-graph-panel--Kgtktcw.js → dependency-graph-panel-BaisS9Zt.js} +1 -1
- package/dist/assets/{dist-iaThVDkA.js → dist-jlhMTKo_.js} +1 -1
- package/dist/assets/{documentation-panel-BHmbeznw.js → documentation-panel-CpSUoM8r.js} +1 -1
- package/dist/assets/{download-DCJXy66H.js → download-RV4i1fWI.js} +1 -1
- package/dist/assets/{dropdown-menu-C1rnl-0o.js → dropdown-menu-DS6umAnH.js} +1 -1
- package/dist/assets/edit-page-C8RUVAaO.js +9 -0
- package/dist/assets/{error-banner-Cd69vvyX.js → error-banner-B5kzVf_0.js} +1 -1
- package/dist/assets/{error-entries-Dk3VZ-OK.js → error-entries-CJS0gOId.js} +1 -1
- package/dist/assets/{error-panel-BPRYmC5J.js → error-panel-BxCKpZtN.js} +1 -1
- package/dist/assets/{errors-DCrsa1nH.js → errors-CNsgAw6m.js} +1 -1
- package/dist/assets/{es-Cqst59WX.js → es-N9SHpmG7.js} +1 -1
- package/dist/assets/feedback-button-BLvwvndE.js +1 -0
- package/dist/assets/{feedback-button-Bik2-e33.js → feedback-button-DYjae3_b.js} +2 -2
- package/dist/assets/{file-explorer-panel-BmekFu7T.js → file-explorer-panel-BmjAJusg.js} +1 -1
- package/dist/assets/{file-name-input-Cdc-TVqO.js → file-name-input-BpfSzvEB.js} +1 -1
- package/dist/assets/{floating-outline-XD9FAV-f.js → floating-outline-CrWdiNQ2.js} +1 -1
- package/dist/assets/{formats-yZ06h1Pl.js → formats-zylfwejq.js} +1 -1
- package/dist/assets/{formatting-BqrP-n49.js → formatting-uom1es4b.js} +1 -1
- package/dist/assets/{fullscreen-B9tHcfpV.js → fullscreen-BWTs8pYZ.js} +1 -1
- package/dist/assets/{gallery-page-Dm6mGwBi.js → gallery-page-W_b-XWq6.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-2n7Ig5Jm.js → ganttDiagram-EL5Y4UJY-CYqkCfFG.js} +1 -1
- package/dist/assets/{glide-data-editor-J9CAb70d.js → glide-data-editor-C_bIL30J.js} +2 -2
- package/dist/assets/{glide-utils-CIrAxdjv.js → glide-utils-HFqhvWHI.js} +2 -2
- package/dist/assets/{home-page-s3LUizSn.js → home-page-D1teQDdF.js} +3 -3
- package/dist/assets/hooks-CZF85I2f.js +1 -0
- package/dist/assets/{html-to-image-DK9Zl1lU.js → html-to-image-D_0rd3_B.js} +1 -1
- package/dist/assets/index-4Nwpioic.js +30 -0
- package/dist/assets/index-ChfDZJzP.css +2 -0
- package/dist/assets/{input-BoBxR50a.js → input-ByHt6aoV.js} +1 -1
- package/dist/assets/{kiosk-mode-BZECfg9k.js → kiosk-mode-BGmMSc7A.js} +1 -1
- package/dist/assets/{layout-B_GMOySr.js → layout-ByZveRPN.js} +5 -5
- package/dist/assets/linear-Bma8J3iM.js +1 -0
- package/dist/assets/links-CXcpNIM0.js +1 -0
- package/dist/assets/{logs-panel-ABM16htT.js → logs-panel-DVSgfMgv.js} +1 -1
- package/dist/assets/{markdown-renderer-BG3sp2rs.js → markdown-renderer-DX2O5YiE.js} +1 -1
- package/dist/assets/{menu-items-BrwnTgyK.js → menu-items-BgUyNUpu.js} +1 -1
- package/dist/assets/{mermaid-a3xYymTy.js → mermaid-B6mqMm5_.js} +2 -2
- package/dist/assets/{name-cell-input-BgEBmqyL.js → name-cell-input-DL1i8Mj0.js} +1 -1
- package/dist/assets/numbers-CsZVw3Dc.js +1 -0
- package/dist/assets/{objects-snlMn4yk.js → objects-rLPlQ3X_.js} +1 -1
- package/dist/assets/{once-Haz_uxEL.js → once-6KNTRW0u.js} +1 -1
- package/dist/assets/{outline-panel-DCXQ3_F6.js → outline-panel-DPKPT2eg.js} +1 -1
- package/dist/assets/{packages-panel-BMGOmZkR.js → packages-panel-CZZwD9YV.js} +1 -1
- package/dist/assets/{panel-accordion-state-C1sdPp0m.js → panel-accordion-state-C7vvsYz1.js} +1 -1
- package/dist/assets/panels-BT2oosq8.js +4 -0
- package/dist/assets/precisionRound-BxlUs8G4.js +1 -0
- package/dist/assets/process-output-BKhybJBb.js +1 -0
- package/dist/assets/{quadrantDiagram-AXDQQJYC-yBhCDI7E.js → quadrantDiagram-AXDQQJYC-D9KH5Zge.js} +1 -1
- package/dist/assets/react-vega-BTNeboR2.js +189 -0
- package/dist/assets/{readonly-code-display-Do50PHI8.js → readonly-code-display-9QrSm_7D.js} +1 -1
- package/dist/assets/{readonly-python-code-DCSMIsTX.js → readonly-python-code-BLotL3XP.js} +1 -1
- package/dist/assets/{renderShortcut-BkVJQ_Zh.js → renderShortcut-H60uiHBp.js} +1 -1
- package/dist/assets/{reveal-component-CLE6vB1Z.js → reveal-component-2QaMbLNx.js} +3 -3
- package/dist/assets/{run-page-Depd6lEE.js → run-page-DyZ8JFKU.js} +1 -1
- package/dist/assets/{runs-BLp5jezv.js → runs-6lJxKV1w.js} +1 -1
- package/dist/assets/{runtime-details-state-CSPobEdR.js → runtime-details-state-B25uM-Ps.js} +1 -1
- package/dist/assets/{schemas-Dv42wLFq.js → schemas-ChRqMOTL.js} +1 -1
- package/dist/assets/{scratchpad-panel-lc6jmpjv.js → scratchpad-panel-Dt83MaaA.js} +1 -1
- package/dist/assets/{scroll-to-bottom-button-1FyowpWV.js → scroll-to-bottom-button-CIkON2WJ.js} +1 -1
- package/dist/assets/{secrets-panel-Bctbtkrp.js → secrets-panel-CmLZsNfp.js} +1 -1
- package/dist/assets/{select-DTBn5eTb.js → select-3CVGlYrC.js} +1 -1
- package/dist/assets/{session-DqoWmb7X.js → session-B8Y-GJnS.js} +1 -1
- package/dist/assets/session-panel-xVWVwa1U.js +1 -0
- package/dist/assets/{snippets-panel-Bh1oTw4m.js → snippets-panel-IxIxfxNc.js} +1 -1
- package/dist/assets/{spec-BfSBcO5B.js → spec-uCpVvaAR.js} +1 -1
- package/dist/assets/state-BHuYDaxs.js +3 -0
- package/dist/assets/{state-uwRvJLb8.js → state-BY4_P6ko.js} +1 -1
- package/dist/assets/{state-BAJYRhmO.js → state-C0irhlOZ.js} +1 -1
- package/dist/assets/{state-XsPO8hNi.js → state-CVgqwwCU.js} +1 -1
- package/dist/assets/{state-DxQnC_1I.js → state-Ck7FMD5A.js} +1 -1
- package/dist/assets/{state-C3oDoyFe.js → state-DaWgt-rn.js} +1 -1
- package/dist/assets/{strings-B2vv-ENv.js → strings-C25fhMR_.js} +1 -1
- package/dist/assets/{swiper-component-a07domrZ.js → swiper-component-CRGRy5_O.js} +1 -1
- package/dist/assets/{switch-CTaiAjrz.js → switch-1h011wlH.js} +1 -1
- package/dist/assets/{tabs-BuQlZFbt.js → tabs-CY8E4r9U.js} +1 -1
- package/dist/assets/{terminal-Ck_vK-34.js → terminal-CjvCrRrA.js} +3 -3
- package/dist/assets/{time-MgToa8VM.js → time-DswSXBDk.js} +1 -1
- package/dist/assets/{toast-BGzLGnvw.js → toast-Gzxi-le_.js} +1 -1
- package/dist/assets/tooltip-Brya4Ghn.js +61 -0
- package/dist/assets/{tooltip-C9TuY18o.js → tooltip-CkGm8X7m.js} +1 -1
- package/dist/assets/tracing-V5zejPsw.js +1 -0
- package/dist/assets/{tracing-panel-PeRXHD8_.js → tracing-panel-DLS3iwK6.js} +2 -2
- package/dist/assets/{tree-actions-GM5E_bUs.js → tree-actions-Be_mzC1C.js} +1 -1
- package/dist/assets/{use-restore-focus-BxEGwIbk.js → use-restore-focus-DdS7Tl0F.js} +1 -1
- package/dist/assets/{useAddCell-GR7eEQrT.js → useAddCell-DK79W1vA.js} +1 -1
- package/dist/assets/useAsyncData-DhhdOGGd.js +1 -0
- package/dist/assets/{useBoolean-BDD6_xQQ.js → useBoolean-j0qHaJxu.js} +1 -1
- package/dist/assets/{useCellActionButton-B-9eG5z_.js → useCellActionButton-Cw9Ob12j.js} +1 -1
- package/dist/assets/{useDeleteCell-2_bMClHd.js → useDeleteCell-BNqX6PPu.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-k3C3M18S.js → useDependencyPanelTab-GnTnqKJo.js} +1 -1
- package/dist/assets/{useEventListener-D9cftcHj.js → useEventListener-CjDeLqFC.js} +1 -1
- package/dist/assets/{useIframeCapabilities-CwTkczVN.js → useIframeCapabilities-Czr9e4uG.js} +1 -1
- package/dist/assets/{useInstallPackage-iX1eufdl.js → useInstallPackage-CVItDn1e.js} +1 -1
- package/dist/assets/{useInterval--x3s1VpI.js → useInterval-DJdQmXnq.js} +1 -1
- package/dist/assets/useNotebookActions-_qJ1Sjtj.js +1 -0
- package/dist/assets/{useRunCells-B2vUhREg.js → useRunCells-DP09DHT6.js} +1 -1
- package/dist/assets/{useSplitCell-DEb03htp.js → useSplitCell-IfumZ4sm.js} +1 -1
- package/dist/assets/{useTheme-COhSHkCj.js → useTheme-DLtPc-39.js} +1 -1
- package/dist/assets/{utils-CaQYvazl.js → utils-DfElfBpz.js} +1 -1
- package/dist/assets/vega-component-CMn031HF.js +1 -0
- package/dist/assets/{vega-embed-container-DJPNkHPb.js → vega-embed-container-DtArSJz1.js} +1 -1
- package/dist/assets/vega-loader.browser-Bu25TKax.js +6 -0
- package/dist/assets/{write-secret-modal-DzKAInL2.js → write-secret-modal-usRSi1bb.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-KbGzG6-u.js → xychartDiagram-S5SC5T6Z-CeRnBS5e.js} +1 -1
- package/dist/index.html +76 -77
- package/package.json +4 -4
- package/src/__tests__/fixtures/{pair-preview.ts → pair-config.ts} +3 -2
- package/src/__tests__/host-imports.test.ts +1 -0
- package/src/__tests__/mount.test.ts +28 -8
- package/src/components/app-config/ai-config.tsx +5 -1
- package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
- package/src/components/data-table/__tests__/export-actions.test.tsx +329 -6
- package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
- package/src/components/data-table/columns.tsx +2 -1
- package/src/components/data-table/date-popover.tsx +6 -4
- package/src/components/data-table/export-actions.tsx +192 -116
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +2 -2
- package/src/components/data-table/schemas.ts +14 -36
- package/src/components/editor/Output.tsx +9 -2
- package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
- package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +80 -252
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +186 -34
- package/src/components/editor/actions/pair-with-agent-commands.ts +42 -51
- package/src/components/editor/actions/pair-with-agent-modal.tsx +96 -36
- package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
- package/src/components/editor/chrome/panels/error-panel.tsx +1 -0
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +366 -0
- package/src/components/editor/chrome/wrapper/footer-item.tsx +32 -24
- package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +237 -0
- package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
- package/src/components/editor/connections/components.tsx +1 -1
- package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
- package/src/components/editor/controls/command-palette.tsx +22 -10
- package/src/components/editor/dynamic-favicon.tsx +21 -40
- package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +537 -0
- package/src/components/editor/errors/send-error-report-button.tsx +69 -0
- package/src/components/editor/output/MarimoErrorOutput.tsx +21 -5
- package/src/components/editor/output/MarimoTracebackOutput.tsx +36 -21
- package/src/components/editor/output/__tests__/ansi-reduce.test.ts +18 -0
- package/src/components/editor/output/ansi-reduce.ts +6 -0
- package/src/components/pages/home-page.tsx +4 -4
- package/src/components/tracing/tracing.tsx +2 -2
- package/src/core/attachments/__tests__/toast.test.tsx +58 -0
- package/src/core/attachments/state.ts +18 -0
- package/src/core/attachments/toast.ts +15 -0
- package/src/core/cells/__tests__/cells.test.ts +52 -0
- package/src/core/cells/__tests__/error-report.test.ts +139 -0
- package/src/core/cells/__tests__/notebook-outline.test.ts +113 -0
- package/src/core/cells/__tests__/session.test.ts +50 -1
- package/src/core/cells/cells.ts +2 -1
- package/src/core/cells/error-report.ts +63 -0
- package/src/core/cells/pending-delete-service.ts +2 -6
- package/src/core/cells/session.ts +28 -1
- package/src/core/config/pair.ts +5 -3
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +4 -4
- package/src/core/datasets/data-source-discovery.ts +4 -6
- package/src/core/edit-app.tsx +2 -2
- package/src/core/host/AGENTS.md +11 -2
- package/src/core/host/__tests__/attachments.test.ts +56 -0
- package/src/core/host/__tests__/document.test.ts +126 -0
- package/src/core/host/__tests__/events.test.ts +49 -0
- package/src/core/host/__tests__/fixtures.ts +41 -0
- package/src/core/host/__tests__/notebook-client.test.ts +433 -0
- package/src/core/host/connection.ts +81 -0
- package/src/core/host/events.ts +77 -0
- package/src/core/host/notebook-client.ts +323 -0
- package/src/core/host/resources/attachments.ts +19 -0
- package/src/core/host/resources/document.ts +101 -0
- package/src/core/hotkeys/actions.ts +2 -4
- package/src/core/network/connection.ts +4 -2
- package/src/core/run-app.tsx +2 -2
- package/src/core/runtime/__tests__/runtime.test.ts +55 -11
- package/src/core/runtime/runtime.ts +18 -5
- package/src/core/runtime/types.ts +2 -0
- package/src/core/websocket/__tests__/{useMarimoKernelConnection.test.ts → connection-state.test.ts} +15 -17
- package/src/core/websocket/__tests__/{useWebSocket.test.ts → createConnectionTransport.test.ts} +1 -1
- package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +170 -0
- package/src/core/websocket/__tests__/{useMarimoKernelConnection.hook.test.tsx → useNotebookSession.hook.test.tsx} +181 -65
- package/src/core/websocket/connection-state.ts +70 -0
- package/src/core/websocket/state.ts +7 -0
- package/src/core/websocket/transports/__tests__/sse.test.ts +1 -4
- package/src/core/websocket/transports/create.ts +31 -0
- package/src/core/websocket/transports/transport.ts +12 -23
- package/src/core/websocket/types.ts +9 -39
- package/src/core/websocket/useNotebookClient.ts +88 -0
- package/src/core/websocket/{useMarimoKernelConnection.tsx → useNotebookSession.tsx} +59 -225
- package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
- package/src/hooks/useAsyncData.ts +3 -3
- package/src/hooks/useDataSourceDiscovery.ts +6 -4
- package/src/hooks/useElapsedTime.ts +3 -3
- package/src/mount.tsx +7 -3
- package/src/plugins/core/registerReactComponent.tsx +1 -1
- package/src/plugins/impl/DropdownPlugin.tsx +2 -6
- package/src/plugins/impl/FormPlugin.tsx +1 -1
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +84 -0
- package/src/plugins/impl/code/any-language-editor.tsx +2 -2
- package/src/plugins/impl/data-editor/glide-data-editor.tsx +8 -5
- package/src/plugins/impl/data-editor/glide-utils.ts +3 -1
- package/src/plugins/impl/vega/make-selectable.ts +3 -6
- package/src/utils/__tests__/arrays.test.ts +35 -0
- package/src/utils/__tests__/numbers.test.ts +48 -1
- package/src/utils/__tests__/objects.test.ts +21 -0
- package/src/utils/arrays.ts +10 -0
- package/src/utils/numbers.ts +28 -17
- package/src/utils/objects.ts +3 -7
- package/src/utils/once.ts +19 -19
- package/dist/assets/CellStatus-BP2mavAq.js +0 -1
- package/dist/assets/JsonOutput-DxHKOpPG.js +0 -11
- package/dist/assets/MarimoErrorOutput-D60XkCny.js +0 -6
- package/dist/assets/ai-model-dropdown-B0z6-zhp.js +0 -5
- package/dist/assets/any-language-editor-BLCAD3yx.js +0 -1
- package/dist/assets/api-BeC_VSGv.js +0 -1
- package/dist/assets/arrays-BqUx5USx.js +0 -1
- package/dist/assets/code-visibility-B-_GvwR5.js +0 -1
- package/dist/assets/coerce-CpE6kUdX.js +0 -1
- package/dist/assets/command-palette-Cf7WX-nr.js +0 -1
- package/dist/assets/config-BOKzA3tF.js +0 -1
- package/dist/assets/config-DX8Y2WbJ.js +0 -1
- package/dist/assets/config-VPSq73n8.js +0 -1
- package/dist/assets/edit-page-BT74CF4G.js +0 -9
- package/dist/assets/feedback-button-B2gKC5cn.js +0 -1
- package/dist/assets/hooks-RnjuFmEx.js +0 -1
- package/dist/assets/index-Bcdzex-3.css +0 -2
- package/dist/assets/index-D-kY3FU1.js +0 -29
- package/dist/assets/linear-0eij_aAG.js +0 -1
- package/dist/assets/links-DkkL9DVa.js +0 -1
- package/dist/assets/numbers-Mk3-CcoU.js +0 -1
- package/dist/assets/pair-CaQyK6En.js +0 -1
- package/dist/assets/panels-Dn59o8ay.js +0 -4
- package/dist/assets/precisionRound-Bq_nmf5u.js +0 -1
- package/dist/assets/process-output-D0KGq04R.js +0 -1
- package/dist/assets/react-vega-C3rYGtP6.js +0 -189
- package/dist/assets/session-panel-BxS5hiG2.js +0 -1
- package/dist/assets/state-_Qai_QyX.js +0 -3
- package/dist/assets/tooltip-mT3CGest.js +0 -61
- package/dist/assets/tracing-Di6pUmX8.js +0 -1
- package/dist/assets/useAsyncData-C7aJJz0Y.js +0 -1
- package/dist/assets/useNotebookActions-DIc4xTzY.js +0 -1
- package/dist/assets/vega-component-CnadTgoE.js +0 -1
- package/dist/assets/vega-loader.browser-CLRkNgm7.js +0 -6
- package/src/core/host/__tests__/protocol.test.ts +0 -214
- package/src/core/host/protocol.ts +0 -1943
- package/src/core/websocket/useWebSocket.tsx +0 -88
|
@@ -108,8 +108,6 @@ describe("SseTransport", () => {
|
|
|
108
108
|
transport.reconnect();
|
|
109
109
|
await vi.waitFor(() => expect(opens).toHaveLength(1));
|
|
110
110
|
|
|
111
|
-
// Stop retrying when the consumer treats the close as terminal,
|
|
112
|
-
// mirroring useMarimoKernelConnection's terminal path.
|
|
113
111
|
transport.addEventListener("close", () => transport.close());
|
|
114
112
|
push('event: close\ndata: {"code": 1000, "reason": "MARIMO_SHUTDOWN"}\n\n');
|
|
115
113
|
await vi.waitFor(() => expect(closes).toHaveLength(1));
|
|
@@ -146,8 +144,7 @@ describe("SseTransport", () => {
|
|
|
146
144
|
fetchMock
|
|
147
145
|
.mockResolvedValueOnce(sseResponse(first.stream))
|
|
148
146
|
.mockResolvedValueOnce(sseResponse(second.stream));
|
|
149
|
-
//
|
|
150
|
-
// synchronously from inside the close handler.
|
|
147
|
+
// Reconnect synchronously from the close handler.
|
|
151
148
|
transport.addEventListener("close", () => transport.reconnect());
|
|
152
149
|
|
|
153
150
|
transport.reconnect();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { createPyodideConnection } from "../../wasm/bridge";
|
|
4
|
+
import { isWasm } from "../../wasm/utils";
|
|
5
|
+
import { BasicTransport } from "./basic";
|
|
6
|
+
import { SseTransport } from "./sse";
|
|
7
|
+
import { WsTransport } from "./ws";
|
|
8
|
+
import type { IConnectionTransport } from "./transport";
|
|
9
|
+
|
|
10
|
+
export interface ConnectionTransportOptions {
|
|
11
|
+
url: () => string;
|
|
12
|
+
static: boolean;
|
|
13
|
+
transportType: "websocket" | "sse";
|
|
14
|
+
headers: () => Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function createConnectionTransport(
|
|
18
|
+
options: ConnectionTransportOptions,
|
|
19
|
+
): IConnectionTransport {
|
|
20
|
+
if (options.static) {
|
|
21
|
+
return BasicTransport.empty();
|
|
22
|
+
}
|
|
23
|
+
if (isWasm()) {
|
|
24
|
+
return createPyodideConnection();
|
|
25
|
+
}
|
|
26
|
+
// Read the URL lazily to follow runtime redirects.
|
|
27
|
+
if (options.transportType === "sse") {
|
|
28
|
+
return new SseTransport(options.url, options.headers);
|
|
29
|
+
}
|
|
30
|
+
return new WsTransport(options.url);
|
|
31
|
+
}
|
|
@@ -1,30 +1,19 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
export type ConnectionEvent = "open" | "close" | "message" | "error";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
import type {
|
|
4
|
+
NotebookTransport,
|
|
5
|
+
ConnectionEvent,
|
|
6
|
+
ConnectionTransportCallback,
|
|
7
|
+
IConnectionTransportMap,
|
|
8
|
+
} from "../../host/connection";
|
|
9
|
+
export type {
|
|
10
|
+
ConnectionEvent,
|
|
11
|
+
ConnectionTransportCallback,
|
|
12
|
+
IConnectionTransportMap,
|
|
13
|
+
} from "../../host/connection";
|
|
14
14
|
|
|
15
|
-
export interface IConnectionTransport {
|
|
16
|
-
reconnect(code?: number | undefined, reason?: string | undefined): void;
|
|
17
|
-
close(): void;
|
|
15
|
+
export interface IConnectionTransport extends NotebookTransport {
|
|
18
16
|
send(data: string | ArrayBuffer | Blob | ArrayBufferView<ArrayBuffer>): void;
|
|
19
|
-
addEventListener<T extends ConnectionEvent>(
|
|
20
|
-
event: T,
|
|
21
|
-
callback: ConnectionTransportCallback<T>,
|
|
22
|
-
): void;
|
|
23
|
-
removeEventListener<T extends ConnectionEvent>(
|
|
24
|
-
event: T,
|
|
25
|
-
callback: ConnectionTransportCallback<T>,
|
|
26
|
-
): void;
|
|
27
|
-
readyState: WebSocket["readyState"];
|
|
28
17
|
}
|
|
29
18
|
|
|
30
19
|
export class ConnectionSubscriptions {
|
|
@@ -1,47 +1,17 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import type { ConnectionStatus as HostConnectionStatus } from "../host/connection";
|
|
3
4
|
import type { NotificationMessageData } from "../kernel/messages";
|
|
4
5
|
|
|
6
|
+
export {
|
|
7
|
+
ConnectionState,
|
|
8
|
+
ConnectionClosedReason as WebSocketClosedReason,
|
|
9
|
+
} from "../host/connection";
|
|
10
|
+
|
|
5
11
|
export type ConnectionPhase =
|
|
6
12
|
| NotificationMessageData<"startup-progress">["phase"]
|
|
7
13
|
| "reconnecting";
|
|
8
14
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
OPEN: "OPEN",
|
|
13
|
-
CLOSING: "CLOSING",
|
|
14
|
-
CLOSED: "CLOSED",
|
|
15
|
-
} as const;
|
|
16
|
-
|
|
17
|
-
export type ConnectionState =
|
|
18
|
-
(typeof ConnectionState)[keyof typeof ConnectionState];
|
|
19
|
-
|
|
20
|
-
export const WebSocketClosedReason = {
|
|
21
|
-
KERNEL_DISCONNECTED: "KERNEL_DISCONNECTED",
|
|
22
|
-
KERNEL_STARTUP_ERROR: "KERNEL_STARTUP_ERROR",
|
|
23
|
-
} as const;
|
|
24
|
-
|
|
25
|
-
export type WebSocketClosedReason =
|
|
26
|
-
(typeof WebSocketClosedReason)[keyof typeof WebSocketClosedReason];
|
|
27
|
-
|
|
28
|
-
export type ConnectionStatus =
|
|
29
|
-
| {
|
|
30
|
-
state: typeof ConnectionState.CLOSED;
|
|
31
|
-
code: WebSocketClosedReason;
|
|
32
|
-
/**
|
|
33
|
-
* Human-readable reason for closing the connection.
|
|
34
|
-
*/
|
|
35
|
-
reason: string;
|
|
36
|
-
phase?: ConnectionPhase;
|
|
37
|
-
}
|
|
38
|
-
| {
|
|
39
|
-
state: typeof ConnectionState.CONNECTING;
|
|
40
|
-
phase?: ConnectionPhase;
|
|
41
|
-
}
|
|
42
|
-
| {
|
|
43
|
-
state:
|
|
44
|
-
| typeof ConnectionState.OPEN
|
|
45
|
-
| typeof ConnectionState.CLOSING
|
|
46
|
-
| typeof ConnectionState.NOT_STARTED;
|
|
47
|
-
};
|
|
15
|
+
export type ConnectionStatus = HostConnectionStatus & {
|
|
16
|
+
phase?: ConnectionPhase;
|
|
17
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { useStore } from "jotai";
|
|
4
|
+
import { useEffect, useMemo } from "react";
|
|
5
|
+
import useEvent from "react-use-event-hook";
|
|
6
|
+
import { jsonParseWithSpecialChar } from "@/utils/json/json-parser";
|
|
7
|
+
import type {
|
|
8
|
+
NotificationMessage,
|
|
9
|
+
NotificationPayload,
|
|
10
|
+
} from "../kernel/messages";
|
|
11
|
+
import {
|
|
12
|
+
createNotebookClient,
|
|
13
|
+
type NotebookClient,
|
|
14
|
+
type NotebookConnection,
|
|
15
|
+
} from "../host/notebook-client";
|
|
16
|
+
import { classifyCloseEvent } from "./connection-state";
|
|
17
|
+
import { notebookClientAtom } from "./state";
|
|
18
|
+
import {
|
|
19
|
+
createConnectionTransport,
|
|
20
|
+
type ConnectionTransportOptions,
|
|
21
|
+
} from "./transports/create";
|
|
22
|
+
|
|
23
|
+
type Options = ConnectionTransportOptions & {
|
|
24
|
+
sessionId: string;
|
|
25
|
+
messageFormat: NotebookConnection["messageFormat"];
|
|
26
|
+
waitUntilReady: () => Promise<void>;
|
|
27
|
+
checkHealth: () => Promise<boolean>;
|
|
28
|
+
onNotification: (notification: NotificationPayload) => void;
|
|
29
|
+
onMessageError: NotebookConnection["onMessageError"];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function useNotebookClient(options: Options): NotebookClient {
|
|
33
|
+
const store = useStore();
|
|
34
|
+
const { sessionId, static: isStatic, transportType, messageFormat } = options;
|
|
35
|
+
const controller = useMemo(() => createNotebookClient(store), [store]);
|
|
36
|
+
const url = useEvent(options.url);
|
|
37
|
+
const headers = useEvent(options.headers);
|
|
38
|
+
const waitUntilReady = useEvent(options.waitUntilReady);
|
|
39
|
+
const checkHealth = useEvent(options.checkHealth);
|
|
40
|
+
const onNotification = useEvent(options.onNotification);
|
|
41
|
+
const onMessageError = useEvent(options.onMessageError);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const lifetime = new AbortController();
|
|
45
|
+
store.set(notebookClientAtom, controller.client);
|
|
46
|
+
controller.connect({
|
|
47
|
+
createTransport: (url) =>
|
|
48
|
+
createConnectionTransport({
|
|
49
|
+
url,
|
|
50
|
+
headers,
|
|
51
|
+
static: isStatic,
|
|
52
|
+
transportType,
|
|
53
|
+
}),
|
|
54
|
+
url,
|
|
55
|
+
messageFormat,
|
|
56
|
+
signal: lifetime.signal,
|
|
57
|
+
waitUntilReady,
|
|
58
|
+
checkHealth,
|
|
59
|
+
onMessageError,
|
|
60
|
+
// The host validates the envelope, not the native notification contents.
|
|
61
|
+
onNotification: (notification) =>
|
|
62
|
+
onNotification({ data: notification as NotificationMessage }),
|
|
63
|
+
decodeJson: jsonParseWithSpecialChar,
|
|
64
|
+
classifyClose: classifyCloseEvent,
|
|
65
|
+
});
|
|
66
|
+
return () => {
|
|
67
|
+
lifetime.abort();
|
|
68
|
+
if (store.get(notebookClientAtom) === controller.client) {
|
|
69
|
+
store.set(notebookClientAtom, null);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}, [
|
|
73
|
+
controller,
|
|
74
|
+
store,
|
|
75
|
+
sessionId,
|
|
76
|
+
isStatic,
|
|
77
|
+
transportType,
|
|
78
|
+
messageFormat,
|
|
79
|
+
url,
|
|
80
|
+
headers,
|
|
81
|
+
waitUntilReady,
|
|
82
|
+
checkHealth,
|
|
83
|
+
onNotification,
|
|
84
|
+
onMessageError,
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
return controller.client;
|
|
88
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { invalidatePackageData } from "@/core/packages/package-data";
|
|
4
|
-
import { useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
5
|
-
import {
|
|
4
|
+
import { useAtom, useAtomValue, useSetAtom, useStore } from "jotai";
|
|
5
|
+
import { useLayoutEffect } from "react";
|
|
6
6
|
import { useErrorBoundary } from "react-error-boundary";
|
|
7
7
|
import { toast } from "@/components/ui/use-toast";
|
|
8
8
|
import { getNotebook, useCellActions } from "@/core/cells/cells";
|
|
@@ -12,8 +12,7 @@ import type {
|
|
|
12
12
|
NotificationMessageData,
|
|
13
13
|
NotificationPayload,
|
|
14
14
|
} from "@/core/kernel/messages";
|
|
15
|
-
import {
|
|
16
|
-
import { useConnectionTransport } from "@/core/websocket/useWebSocket";
|
|
15
|
+
import { useNotebookClient } from "@/core/websocket/useNotebookClient";
|
|
17
16
|
import { renderHTML } from "@/plugins/core/RenderHTML";
|
|
18
17
|
import {
|
|
19
18
|
handleWidgetMessage,
|
|
@@ -21,11 +20,7 @@ import {
|
|
|
21
20
|
} from "@/plugins/impl/anywidget/registry";
|
|
22
21
|
import { logNever } from "@/utils/assertNever";
|
|
23
22
|
import { prettyError } from "@/utils/errors";
|
|
24
|
-
import {
|
|
25
|
-
type JsonString,
|
|
26
|
-
safeExtractSetUIElementMessageBuffers,
|
|
27
|
-
} from "@/utils/json/base64";
|
|
28
|
-
import { jsonParseWithSpecialChar } from "@/utils/json/json-parser";
|
|
23
|
+
import { safeExtractSetUIElementMessageBuffers } from "@/utils/json/base64";
|
|
29
24
|
import { Logger } from "@/utils/Logger";
|
|
30
25
|
import { reloadSafe } from "@/utils/reload-safe";
|
|
31
26
|
import { useAlertActions } from "../alerts/state";
|
|
@@ -70,7 +65,7 @@ import { type LayoutState, useLayoutActions } from "../layout/state";
|
|
|
70
65
|
import { kioskModeAtom } from "../mode";
|
|
71
66
|
import { connectionAtom, startupProgressAtom } from "../network/connection";
|
|
72
67
|
import type { RequestId } from "../network/DeferredRequestRegistry";
|
|
73
|
-
import { useRuntimeManager } from "../runtime/config";
|
|
68
|
+
import { runtimeConfigAtom, useRuntimeManager } from "../runtime/config";
|
|
74
69
|
import { SECRETS_REGISTRY } from "../secrets/request-registry";
|
|
75
70
|
import { isStaticNotebook } from "../static/static-state";
|
|
76
71
|
import {
|
|
@@ -81,104 +76,10 @@ import { useStorageActions } from "../storage/state";
|
|
|
81
76
|
import { useVariablesActions } from "../variables/state";
|
|
82
77
|
import type { VariableName } from "../variables/types";
|
|
83
78
|
import { isWasm } from "../wasm/utils";
|
|
84
|
-
import {
|
|
85
|
-
type ConnectionStatus,
|
|
86
|
-
WebSocketClosedReason,
|
|
87
|
-
ConnectionState,
|
|
88
|
-
} from "./types";
|
|
79
|
+
import { WebSocketClosedReason, ConnectionState } from "./types";
|
|
89
80
|
|
|
90
81
|
const SUPPORTS_LAZY_KERNELS = true;
|
|
91
82
|
|
|
92
|
-
// All MARIMO_* reasons except TRANSPORT_EXHAUSTED are emitted by the backend
|
|
93
|
-
// (marimo/_server/api/endpoints/ws_endpoint.py and ws/*.py). Keep in sync with
|
|
94
|
-
// the backend literals. Over the SSE transport these arrive as in-band
|
|
95
|
-
// `close` events rather than WebSocket close frames, so every terminal
|
|
96
|
-
// reason must be classified here — an unclassified reason falls into the
|
|
97
|
-
// retry path.
|
|
98
|
-
export type CloseReason =
|
|
99
|
-
| "MARIMO_NO_FILE_KEY"
|
|
100
|
-
| "MARIMO_NO_SESSION_ID"
|
|
101
|
-
| "MARIMO_NO_SESSION"
|
|
102
|
-
| "MARIMO_SHUTDOWN"
|
|
103
|
-
| "MARIMO_KERNEL_STARTUP_ERROR"
|
|
104
|
-
| "MARIMO_UNAUTHORIZED"
|
|
105
|
-
| "MARIMO_KIOSK_NOT_ALLOWED"
|
|
106
|
-
| typeof TRANSPORT_EXHAUSTED_REASON;
|
|
107
|
-
|
|
108
|
-
export type CloseDecision =
|
|
109
|
-
| { kind: "terminal"; status: ConnectionStatus; closeTransport: boolean }
|
|
110
|
-
| { kind: "gave-up"; status: ConnectionStatus }
|
|
111
|
-
| { kind: "retry"; status: ConnectionStatus };
|
|
112
|
-
|
|
113
|
-
export function classifyCloseEvent(event: { reason?: string }): CloseDecision {
|
|
114
|
-
switch (event.reason as CloseReason | undefined) {
|
|
115
|
-
case TRANSPORT_EXHAUSTED_REASON:
|
|
116
|
-
return {
|
|
117
|
-
kind: "gave-up",
|
|
118
|
-
status: {
|
|
119
|
-
state: ConnectionState.CLOSED,
|
|
120
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
121
|
-
reason: "kernel not found",
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
case "MARIMO_NO_FILE_KEY":
|
|
125
|
-
case "MARIMO_NO_SESSION_ID":
|
|
126
|
-
case "MARIMO_NO_SESSION":
|
|
127
|
-
case "MARIMO_SHUTDOWN":
|
|
128
|
-
return {
|
|
129
|
-
kind: "terminal",
|
|
130
|
-
status: {
|
|
131
|
-
state: ConnectionState.CLOSED,
|
|
132
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
133
|
-
reason: "kernel not found",
|
|
134
|
-
},
|
|
135
|
-
closeTransport: true,
|
|
136
|
-
};
|
|
137
|
-
case "MARIMO_UNAUTHORIZED":
|
|
138
|
-
return {
|
|
139
|
-
kind: "terminal",
|
|
140
|
-
status: {
|
|
141
|
-
state: ConnectionState.CLOSED,
|
|
142
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
143
|
-
reason: "not authorized",
|
|
144
|
-
},
|
|
145
|
-
closeTransport: true,
|
|
146
|
-
};
|
|
147
|
-
case "MARIMO_KIOSK_NOT_ALLOWED":
|
|
148
|
-
return {
|
|
149
|
-
kind: "terminal",
|
|
150
|
-
status: {
|
|
151
|
-
state: ConnectionState.CLOSED,
|
|
152
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
153
|
-
reason: "kiosk mode is not available for this session",
|
|
154
|
-
},
|
|
155
|
-
closeTransport: true,
|
|
156
|
-
};
|
|
157
|
-
case "MARIMO_KERNEL_STARTUP_ERROR":
|
|
158
|
-
return {
|
|
159
|
-
kind: "terminal",
|
|
160
|
-
status: {
|
|
161
|
-
state: ConnectionState.CLOSED,
|
|
162
|
-
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
163
|
-
reason: "Failed to start kernel sandbox",
|
|
164
|
-
},
|
|
165
|
-
closeTransport: true,
|
|
166
|
-
};
|
|
167
|
-
default:
|
|
168
|
-
// Empty/undefined reasons are normal transient closes. Anything else is
|
|
169
|
-
// an unknown server reason; warn so a new MARIMO_* reason doesn't fall
|
|
170
|
-
// silently into the retry path.
|
|
171
|
-
if (event.reason) {
|
|
172
|
-
logNever(event.reason as never);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
kind: "retry",
|
|
178
|
-
status: { state: ConnectionState.CONNECTING },
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
|
|
182
83
|
function getExistingCells(): CellData[] | undefined {
|
|
183
84
|
if (!SUPPORTS_LAZY_KERNELS) {
|
|
184
85
|
return undefined;
|
|
@@ -190,16 +91,12 @@ function getExistingCells(): CellData[] | undefined {
|
|
|
190
91
|
);
|
|
191
92
|
}
|
|
192
93
|
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
*/
|
|
196
|
-
export function useMarimoKernelConnection(opts: {
|
|
94
|
+
/** Coordinate session startup and apply notifications to the editor. */
|
|
95
|
+
export function useNotebookSession(opts: {
|
|
197
96
|
sessionId: SessionId;
|
|
198
97
|
autoInstantiate: boolean;
|
|
199
98
|
setCells: (cells: CellData[], layout: LayoutState) => void;
|
|
200
99
|
}) {
|
|
201
|
-
// Track whether we want to try reconnecting.
|
|
202
|
-
const shouldTryReconnecting = useRef<boolean>(true);
|
|
203
100
|
const { autoInstantiate, sessionId, setCells } = opts;
|
|
204
101
|
const { showBoundary } = useErrorBoundary();
|
|
205
102
|
|
|
@@ -238,6 +135,7 @@ export function useMarimoKernelConnection(opts: {
|
|
|
238
135
|
const setStableSessionId = useSetAtom(stableSessionIdAtom);
|
|
239
136
|
const setCapabilities = useSetAtom(capabilitiesAtom);
|
|
240
137
|
const runtimeManager = useRuntimeManager();
|
|
138
|
+
const { notebookId } = useAtomValue(runtimeConfigAtom);
|
|
241
139
|
const transportType = useAtomValue(connectionTransportTypeAtom);
|
|
242
140
|
const setCacheInfo = useSetAtom(cacheInfoAtom);
|
|
243
141
|
const setKernelStartupError = useSetAtom(kernelStartupErrorAtom);
|
|
@@ -246,8 +144,7 @@ export function useMarimoKernelConnection(opts: {
|
|
|
246
144
|
filterFromVariables: filterStorageFromVariables,
|
|
247
145
|
} = useStorageActions();
|
|
248
146
|
|
|
249
|
-
const
|
|
250
|
-
const msg = jsonParseWithSpecialChar(e.data);
|
|
147
|
+
const handleNotification = (msg: NotificationPayload) => {
|
|
251
148
|
switch (msg.data.op) {
|
|
252
149
|
case "reload":
|
|
253
150
|
reloadSafe();
|
|
@@ -505,107 +402,58 @@ export function useMarimoKernelConnection(opts: {
|
|
|
505
402
|
}
|
|
506
403
|
};
|
|
507
404
|
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
// Manual reconnect. Probes /health first to fail fast when the runtime
|
|
519
|
-
// is unreachable, instead of waiting on partysocket's retry budget.
|
|
520
|
-
const reconnect = async () => {
|
|
521
|
-
if (
|
|
522
|
-
ws.readyState === WebSocket.OPEN ||
|
|
523
|
-
ws.readyState === WebSocket.CONNECTING
|
|
524
|
-
) {
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
shouldTryReconnecting.current = true;
|
|
528
|
-
setKernelStartupError(null);
|
|
529
|
-
setConnection({ state: ConnectionState.CONNECTING });
|
|
530
|
-
const healthy = await runtimeManager.reconcileFromHealth();
|
|
531
|
-
if (!healthy) {
|
|
532
|
-
shouldTryReconnecting.current = false;
|
|
533
|
-
setConnection({
|
|
534
|
-
state: ConnectionState.CLOSED,
|
|
535
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
536
|
-
reason: "kernel not found",
|
|
537
|
-
});
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
ws.reconnect();
|
|
405
|
+
const store = useStore();
|
|
406
|
+
const onMessageError = (error: unknown) => {
|
|
407
|
+
toast({
|
|
408
|
+
title: "Failed to handle message",
|
|
409
|
+
description: prettyError(error),
|
|
410
|
+
variant: "danger",
|
|
411
|
+
});
|
|
541
412
|
};
|
|
542
|
-
|
|
543
|
-
|
|
413
|
+
const notebook = useNotebookClient({
|
|
414
|
+
sessionId,
|
|
544
415
|
static: isStaticNotebook(),
|
|
545
416
|
transportType,
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
*/
|
|
417
|
+
messageFormat:
|
|
418
|
+
notebookId && transportType === "websocket" ? "host" : "session",
|
|
549
419
|
url: () =>
|
|
550
420
|
transportType === "sse"
|
|
551
421
|
? runtimeManager.getSseURL(sessionId).toString()
|
|
552
422
|
: runtimeManager.getWsURL(sessionId).toString(),
|
|
553
|
-
|
|
554
|
-
* Auth headers for the SSE transport. WebSockets cannot send headers
|
|
555
|
-
* and instead put the access token in the URL.
|
|
556
|
-
*/
|
|
423
|
+
// SSE uses headers for auth. WebSockets carry the token in the URL.
|
|
557
424
|
headers: () => runtimeManager.headers(),
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
*/
|
|
562
|
-
onOpen: async () => {
|
|
563
|
-
updateStartupProgress(null);
|
|
564
|
-
// If we are open, we can reset our reconnecting flag.
|
|
565
|
-
shouldTryReconnecting.current = true;
|
|
566
|
-
},
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* Wait to connect, in case the remote kernel still starting up.
|
|
570
|
-
*/
|
|
571
|
-
waitToConnect: async () => {
|
|
572
|
-
if (isStaticNotebook()) {
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
if (isWasm()) {
|
|
576
|
-
return;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
if (runtimeManager.isSameOrigin) {
|
|
580
|
-
return;
|
|
425
|
+
waitUntilReady: async () => {
|
|
426
|
+
if (!isStaticNotebook() && !isWasm() && !runtimeManager.isSameOrigin) {
|
|
427
|
+
await runtimeManager.waitForHealthy();
|
|
581
428
|
}
|
|
582
|
-
await runtimeManager.waitForHealthy();
|
|
583
429
|
},
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
*/
|
|
588
|
-
onMessage: (e) => {
|
|
430
|
+
checkHealth: () => runtimeManager.reconcileFromHealth(),
|
|
431
|
+
onMessageError,
|
|
432
|
+
onNotification: (notification) => {
|
|
589
433
|
try {
|
|
590
|
-
|
|
434
|
+
handleNotification(notification);
|
|
591
435
|
} catch (error) {
|
|
592
|
-
Logger.error("Failed to handle
|
|
593
|
-
|
|
594
|
-
title: "Failed to handle message",
|
|
595
|
-
description: prettyError(error),
|
|
596
|
-
variant: "danger",
|
|
597
|
-
});
|
|
436
|
+
Logger.error("Failed to handle notification", notification, error);
|
|
437
|
+
onMessageError(error);
|
|
598
438
|
}
|
|
599
439
|
},
|
|
440
|
+
});
|
|
600
441
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
442
|
+
// Subscribe before passive connection setup: static/WASM transports can emit synchronously.
|
|
443
|
+
useLayoutEffect(() => {
|
|
444
|
+
const updateConnection = () => {
|
|
445
|
+
const status = store.get(notebook.connectionAtom);
|
|
446
|
+
if (status.state === ConnectionState.NOT_STARTED) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (status.state === ConnectionState.OPEN) {
|
|
450
|
+
updateStartupProgress(null);
|
|
451
|
+
return; // kernel-ready, not the socket, establishes session readiness.
|
|
452
|
+
}
|
|
453
|
+
if (status.state === ConnectionState.CONNECTING) {
|
|
454
|
+
setKernelStartupError(null);
|
|
455
|
+
}
|
|
607
456
|
setConnection((previous) => {
|
|
608
|
-
const status = decision.status;
|
|
609
457
|
if (
|
|
610
458
|
status.state === ConnectionState.CLOSED &&
|
|
611
459
|
status.code === WebSocketClosedReason.KERNEL_STARTUP_ERROR &&
|
|
@@ -624,31 +472,17 @@ export function useMarimoKernelConnection(opts: {
|
|
|
624
472
|
}
|
|
625
473
|
return status;
|
|
626
474
|
});
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
* When we encounter an error, we should close the connection.
|
|
641
|
-
*/
|
|
642
|
-
onError: (e) => {
|
|
643
|
-
Logger.warn("WebSocket error", e);
|
|
644
|
-
setConnection({
|
|
645
|
-
state: ConnectionState.CLOSED,
|
|
646
|
-
code: WebSocketClosedReason.KERNEL_DISCONNECTED,
|
|
647
|
-
reason: "kernel not found",
|
|
648
|
-
});
|
|
649
|
-
tryReconnecting();
|
|
650
|
-
},
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
return { connection, reconnect };
|
|
475
|
+
};
|
|
476
|
+
const unsubscribe = store.sub(notebook.connectionAtom, updateConnection);
|
|
477
|
+
updateConnection();
|
|
478
|
+
return unsubscribe;
|
|
479
|
+
}, [
|
|
480
|
+
notebook,
|
|
481
|
+
store,
|
|
482
|
+
setConnection,
|
|
483
|
+
setKernelStartupError,
|
|
484
|
+
updateStartupProgress,
|
|
485
|
+
]);
|
|
486
|
+
|
|
487
|
+
return { notebook, connection, reconnect: notebook.reconnect };
|
|
654
488
|
}
|