@marimo-team/frontend 0.25.2-dev66 → 0.25.2-dev89
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-CRFBVGjI.js → CellStatus-Bj7PvY_u.js} +1 -1
- package/dist/assets/{ErrorBoundary-BKmN7zye.js → ErrorBoundary-CG6gtgym.js} +2 -2
- package/dist/assets/{JsonOutput-nqqzL-n0.js → JsonOutput-NVH7GWyC.js} +1 -1
- package/dist/assets/{MarimoErrorOutput-DCu6fm2y.js → MarimoErrorOutput-z5iFryzf.js} +1 -1
- package/dist/assets/{RenderHTML-DRMkieKn.js → RenderHTML-C7QcdAgB.js} +1 -1
- package/dist/assets/{RunButton-CPZWjCL9.js → RunButton-A__3wcpF.js} +1 -1
- package/dist/assets/{add-cell-with-ai-D20NyZO4.js → add-cell-with-ai-Wyt6GBhk.js} +1 -1
- package/dist/assets/{add-connection-dialog-pQcdKIlO.js → add-connection-dialog-bl8dqCVs.js} +1 -1
- package/dist/assets/{agent-panel-tNErBgmq.js → agent-panel-BcoO8S6Q.js} +1 -1
- package/dist/assets/{ai-model-dropdown-BIeRPKed.js → ai-model-dropdown-CvJsRj9y.js} +1 -1
- package/dist/assets/{api-DYL9A86_.js → api-DVLtXyp7.js} +1 -1
- package/dist/assets/{app-config-button-DkNGV0b1.js → app-config-button-C7QrZbqr.js} +1 -1
- package/dist/assets/{blob-BIYte8oT.js → blob-Bx8A10xl.js} +1 -1
- package/dist/assets/{cell-editor-C5RTy4Y0.js → cell-editor-CevZDS63.js} +4 -4
- package/dist/assets/cell-link-DC1UZQr_.js +1 -0
- package/dist/assets/{cells-h5u00Nz8.js → cells-CxY8RSp7.js} +2 -2
- package/dist/assets/{chat-display-DzTkUWMw.js → chat-display-YETh6yXV.js} +1 -1
- package/dist/assets/{chat-panel-CKqEpnjN.js → chat-panel-DyaePe7B.js} +1 -1
- package/dist/assets/{chat-ui-CGzOsYVb.js → chat-ui-D_QL46qM.js} +1 -1
- package/dist/assets/code-visibility-DNzJgrTz.js +1 -0
- package/dist/assets/{column-preview-DtrgJzVI.js → column-preview-sL_Jo0hX.js} +1 -1
- package/dist/assets/{command-palette-BKYGTfS5.js → command-palette-DMQFuWz1.js} +1 -1
- package/dist/assets/{common-BMeq0Bqi.js → common-Cy3lJDvJ.js} +1 -1
- package/dist/assets/{components-CWcf8098.js → components-D9ZIJGG8.js} +1 -1
- package/dist/assets/{config-BAnYSdpO.js → config-D_c_6ce1.js} +1 -1
- package/dist/assets/{datasource-BLHGFSsT.js → datasource-Tst92Pzi.js} +1 -1
- package/dist/assets/{dependency-graph-panel-C8X3Nn8W.js → dependency-graph-panel-BwMayTyZ.js} +1 -1
- package/dist/assets/{documentation-panel-C8wrSKlX.js → documentation-panel-OMUbXgKW.js} +1 -1
- package/dist/assets/{download-CUgiCx7s.js → download-CPMAf7re.js} +1 -1
- package/dist/assets/{edit-page-CqPNBpAP.js → edit-page-DD1NFkiu.js} +6 -6
- package/dist/assets/{error-entries-DQD4A9cx.js → error-entries-DBpwg0GC.js} +1 -1
- package/dist/assets/{error-panel-BJYkwYEY.js → error-panel-ByOEJuZN.js} +1 -1
- package/dist/assets/{feedback-button-DbTjGwcX.js → feedback-button-7KY7nL-j.js} +2 -2
- package/dist/assets/feedback-button-DxjoRfo3.js +1 -0
- package/dist/assets/{file-explorer-panel-BQi88S1o.js → file-explorer-panel-B92ugwxr.js} +1 -1
- package/dist/assets/{file-name-input-DPJSxW_X.js → file-name-input-DZehOHLA.js} +1 -1
- package/dist/assets/{floating-outline-3PlTr0K1.js → floating-outline-K7cVdOlC.js} +1 -1
- package/dist/assets/{gallery-page-BqvVmwde.js → gallery-page-DoriMrLH.js} +1 -1
- package/dist/assets/{glide-data-editor-CAa14cIr.js → glide-data-editor-DWyeHe3u.js} +1 -1
- package/dist/assets/{home-page-Bg-WqjiD.js → home-page-BcJJsD_Q.js} +1 -1
- package/dist/assets/{hooks-DLBvBo8c.js → hooks-DNPsQf79.js} +1 -1
- package/dist/assets/index-B7ZZVUcj.css +2 -0
- package/dist/assets/{index-BtV91sqJ.js → index-CqJKdR1j.js} +5 -5
- package/dist/assets/{layout-mWXZofX2.js → layout-BaluekG6.js} +3 -3
- package/dist/assets/{logs-panel-IKL6F2OX.js → logs-panel-OkoO5mbN.js} +1 -1
- package/dist/assets/{markdown-renderer-DHvAXF8E.js → markdown-renderer-mDlWBE1M.js} +1 -1
- package/dist/assets/{name-cell-input-j4eGLLyd.js → name-cell-input-D_Q2IhP9.js} +1 -1
- package/dist/assets/{outline-panel-CprDWmxn.js → outline-panel-Dy2cmYDF.js} +1 -1
- package/dist/assets/packages-panel-CIvhx0hb.js +1 -0
- package/dist/assets/{panel-accordion-state-8xXVhawu.js → panel-accordion-state-BI4SU22L.js} +1 -1
- package/dist/assets/panels-CO6Clgel.js +4 -0
- package/dist/assets/{process-output-DOmeJ1VR.js → process-output-Crm0vqbi.js} +1 -1
- package/dist/assets/{readonly-code-display-xvH6MyT6.js → readonly-code-display-CNbw6v1-.js} +1 -1
- package/dist/assets/{readonly-python-code-D4YGmSvB.js → readonly-python-code-DcYhdd1B.js} +1 -1
- package/dist/assets/{reveal-component-CDUG1x74.js → reveal-component-DeZTBbnn.js} +1 -1
- package/dist/assets/{run-page-BAqLgcq9.js → run-page-BNEg-Ro9.js} +1 -1
- package/dist/assets/runtime-details-state-lxXYwJcI.js +1 -0
- package/dist/assets/{scratchpad-panel-BFbUuzdn.js → scratchpad-panel-lDJWcpVs.js} +1 -1
- package/dist/assets/{session-panel-BdN43Lzi.js → session-panel-BqutyoYd.js} +1 -1
- package/dist/assets/{snippets-panel-5_jR08Zd.js → snippets-panel-YttkYAW9.js} +1 -1
- package/dist/assets/state-B2ZbImvm.js +1 -0
- package/dist/assets/{state-BxJ_FX3k.js → state-B85OOscw.js} +1 -1
- package/dist/assets/{state-7os84dnI.js → state-sbCCk7ZP.js} +1 -1
- package/dist/assets/{terminal-DHWTOXu3.js → terminal-3hxM6K9q.js} +1 -1
- package/dist/assets/{tracing-CRkNpBaH.js → tracing-DZYfCw6p.js} +1 -1
- package/dist/assets/{tracing-panel-DV2-2TUI.js → tracing-panel-BUPJ77jB.js} +2 -2
- package/dist/assets/{tree-actions-CShqSonp.js → tree-actions-D5clvgKl.js} +1 -1
- package/dist/assets/{useAddCell-DesMfnE4.js → useAddCell-Bhv6GT3m.js} +1 -1
- package/dist/assets/{useBoolean-BofUVeKg.js → useBoolean-Co-_MyFz.js} +1 -1
- package/dist/assets/{useCellActionButton-BO5SFMxA.js → useCellActionButton-DwAUf_Cn.js} +1 -1
- package/dist/assets/{useDeleteCell-DSbUjpSC.js → useDeleteCell-BKN7t4DH.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-JIFiQrr2.js → useDependencyPanelTab-CbcGEmqM.js} +1 -1
- package/dist/assets/{useInstallPackage-CCQcFc6U.js → useInstallPackage-HTUlGg0U.js} +1 -1
- package/dist/assets/{useNotebookActions-CjjED3t-.js → useNotebookActions-pXzVjrlk.js} +1 -1
- package/dist/assets/{useRunCells-Bx3wXUWO.js → useRunCells-zMO43eNR.js} +1 -1
- package/dist/assets/{useSplitCell-BRmQP02b.js → useSplitCell-xEtFLByO.js} +1 -1
- package/dist/assets/{vega-component-C28fL5fD.js → vega-component-Chbfi__Q.js} +1 -1
- package/dist/index.html +24 -24
- package/package.json +1 -1
- package/src/__tests__/mount.test.ts +6 -6
- package/src/components/editor/actions/useRestartKernel.tsx +2 -2
- package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +224 -17
- package/src/components/editor/alerts/connection-details.tsx +61 -0
- package/src/components/editor/alerts/connection-notice.tsx +46 -53
- package/src/components/editor/alerts/startup-progress.tsx +73 -129
- package/src/components/editor/app-container.tsx +2 -2
- package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +2 -2
- package/src/components/editor/cell/CreateCellButton.tsx +2 -2
- package/src/components/editor/cell/DeleteButton.tsx +2 -2
- package/src/components/editor/cell/RunButton.tsx +3 -3
- package/src/components/editor/cell/StopButton.tsx +2 -2
- package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +4 -4
- package/src/components/editor/chrome/components/feedback-button.tsx +3 -3
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +8 -8
- package/src/components/editor/chrome/panels/__tests__/{sandbox-details.test.tsx → runtime-details.test.tsx} +94 -22
- package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +4 -4
- package/src/components/editor/chrome/panels/packages-panel.tsx +8 -29
- package/src/components/editor/chrome/panels/{sandbox-details-state.ts → runtime-details-state.ts} +1 -1
- package/src/components/editor/chrome/panels/{sandbox-panel.tsx → runtime-panel.tsx} +38 -66
- package/src/components/editor/chrome/panels/runtime-status-toggle.tsx +56 -0
- package/src/components/editor/chrome/panels/sandbox-controller.tsx +2 -2
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +3 -3
- package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +2 -2
- package/src/components/editor/controls/Controls.tsx +3 -3
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +2 -2
- package/src/components/editor/header/__tests__/status.test.tsx +4 -4
- package/src/components/editor/header/app-header.tsx +2 -2
- package/src/components/editor/header/status.tsx +3 -3
- package/src/components/ui/progress-stages.tsx +114 -0
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +106 -5
- package/src/core/codemirror/lsp/notebook-lsp.ts +16 -2
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +6 -6
- package/src/core/codemirror/readonly/extension.ts +2 -2
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +2 -2
- package/src/core/edit-app.tsx +5 -1
- package/src/core/export/hooks.ts +2 -2
- package/src/core/network/__tests__/connection.test.ts +3 -3
- package/src/core/network/connection-notice.ts +5 -5
- package/src/core/network/connection.ts +9 -9
- package/src/core/network/requests-lazy.ts +2 -2
- package/src/core/packages/__tests__/useSandboxController.test.tsx +2 -2
- package/src/core/packages/useSandboxController.ts +6 -6
- package/src/core/runtime/__tests__/adapter.test.ts +6 -6
- package/src/core/runtime/adapter.ts +7 -7
- package/src/core/runtime/config.ts +2 -2
- package/src/core/saving/filename.ts +2 -2
- package/src/core/saving/save-component.tsx +5 -5
- package/src/core/saving/useAutoSave.ts +2 -2
- package/src/core/websocket/__tests__/useMarimoKernelConnection.hook.test.tsx +30 -25
- package/src/core/websocket/__tests__/useMarimoKernelConnection.test.ts +5 -5
- package/src/core/websocket/connection-utils.ts +21 -21
- package/src/core/websocket/types.ts +8 -9
- package/src/core/websocket/useMarimoKernelConnection.tsx +21 -21
- package/src/mount.tsx +2 -2
- package/src/plugins/core/__test__/registerReactComponent.test.ts +55 -0
- package/src/plugins/core/registerReactComponent.tsx +3 -1
- package/src/stories/cell.stories.tsx +2 -2
- package/src/stories/layout/vertical/one-column.stories.tsx +5 -5
- package/src/stories/progress-stages.stories.tsx +62 -0
- package/src/stories/runtime-existing.stories.tsx +44 -0
- package/src/stories/runtime-maintenance.stories.tsx +40 -0
- package/src/stories/runtime-pixi.stories.tsx +28 -0
- package/src/stories/{sandbox.stories.tsx → runtime-story.tsx} +191 -152
- package/src/stories/runtime-uv.stories.tsx +56 -0
- package/dist/assets/cell-link-BeZAiE1D.js +0 -1
- package/dist/assets/code-visibility-B5QjA0ie.js +0 -1
- package/dist/assets/feedback-button-JqvnTSfN.js +0 -1
- package/dist/assets/index-CF8Gfz1R.css +0 -2
- package/dist/assets/packages-panel-CDDChziK.js +0 -1
- package/dist/assets/panels-CU7deLqc.js +0 -4
- package/dist/assets/sandbox-panel-D5bRunTM.js +0 -1
- package/dist/assets/state-Bo8h64Rn.js +0 -1
- package/src/components/editor/chrome/panels/sandbox-toggle.tsx +0 -52
package/dist/index.html
CHANGED
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
<marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
|
|
67
67
|
<!-- /TODO -->
|
|
68
68
|
<title>{{ title }}</title>
|
|
69
|
-
<script type="module" crossorigin src="./assets/index-
|
|
69
|
+
<script type="module" crossorigin src="./assets/index-CqJKdR1j.js"></script>
|
|
70
70
|
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
|
|
71
71
|
<link rel="modulepreload" crossorigin href="./assets/react-CUdNIagt.js">
|
|
72
72
|
<link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BQ9S8nyo.js">
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
<link rel="modulepreload" crossorigin href="./assets/utils-B4K466FK.js">
|
|
87
87
|
<link rel="modulepreload" crossorigin href="./assets/session-BykGt6S3.js">
|
|
88
88
|
<link rel="modulepreload" crossorigin href="./assets/Deferred-CrTnjj37.js">
|
|
89
|
-
<link rel="modulepreload" crossorigin href="./assets/config-
|
|
89
|
+
<link rel="modulepreload" crossorigin href="./assets/config-D_c_6ce1.js">
|
|
90
90
|
<link rel="modulepreload" crossorigin href="./assets/clsx-DB0hHKMi.js">
|
|
91
91
|
<link rel="modulepreload" crossorigin href="./assets/cn-ldLVeaqm.js">
|
|
92
92
|
<link rel="modulepreload" crossorigin href="./assets/jsx-runtime-B74pBk57.js">
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
<link rel="modulepreload" crossorigin href="./assets/useTheme-BkPLyRl9.js">
|
|
140
140
|
<link rel="modulepreload" crossorigin href="./assets/useAsyncData-DucTwMkf.js">
|
|
141
141
|
<link rel="modulepreload" crossorigin href="./assets/purify.es--06brOip.js">
|
|
142
|
-
<link rel="modulepreload" crossorigin href="./assets/cells-
|
|
142
|
+
<link rel="modulepreload" crossorigin href="./assets/cells-CxY8RSp7.js">
|
|
143
143
|
<link rel="modulepreload" crossorigin href="./assets/coerce-CZiN7rQ_.js">
|
|
144
144
|
<link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
|
|
145
145
|
<link rel="modulepreload" crossorigin href="./assets/_hasPath-BmRQipI0.js">
|
|
@@ -152,43 +152,43 @@
|
|
|
152
152
|
<link rel="modulepreload" crossorigin href="./assets/copy-D03Y7IMR.js">
|
|
153
153
|
<link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
|
|
154
154
|
<link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-84E-_nIR.js">
|
|
155
|
-
<link rel="modulepreload" crossorigin href="./assets/markdown-renderer-
|
|
155
|
+
<link rel="modulepreload" crossorigin href="./assets/markdown-renderer-mDlWBE1M.js">
|
|
156
156
|
<link rel="modulepreload" crossorigin href="./assets/copy-RyCOE8jo.js">
|
|
157
157
|
<link rel="modulepreload" crossorigin href="./assets/copy-icon-wfSGfX8v.js">
|
|
158
|
-
<link rel="modulepreload" crossorigin href="./assets/useRunCells-
|
|
159
|
-
<link rel="modulepreload" crossorigin href="./assets/RenderHTML-
|
|
160
|
-
<link rel="modulepreload" crossorigin href="./assets/blob-
|
|
158
|
+
<link rel="modulepreload" crossorigin href="./assets/useRunCells-zMO43eNR.js">
|
|
159
|
+
<link rel="modulepreload" crossorigin href="./assets/RenderHTML-C7QcdAgB.js">
|
|
160
|
+
<link rel="modulepreload" crossorigin href="./assets/blob-Bx8A10xl.js">
|
|
161
161
|
<link rel="modulepreload" crossorigin href="./assets/kbd-BnUiViRu.js">
|
|
162
|
-
<link rel="modulepreload" crossorigin href="./assets/useInstallPackage-
|
|
162
|
+
<link rel="modulepreload" crossorigin href="./assets/useInstallPackage-HTUlGg0U.js">
|
|
163
163
|
<link rel="modulepreload" crossorigin href="./assets/errors-D9vyuMar.js">
|
|
164
|
-
<link rel="modulepreload" crossorigin href="./assets/api-
|
|
164
|
+
<link rel="modulepreload" crossorigin href="./assets/api-DVLtXyp7.js">
|
|
165
165
|
<link rel="modulepreload" crossorigin href="./assets/share-BZW3tzEX.js">
|
|
166
166
|
<link rel="modulepreload" crossorigin href="./assets/events-CbeVJ6OD.js">
|
|
167
|
-
<link rel="modulepreload" crossorigin href="./assets/state-
|
|
167
|
+
<link rel="modulepreload" crossorigin href="./assets/state-sbCCk7ZP.js">
|
|
168
168
|
<link rel="modulepreload" crossorigin href="./assets/pair-_FSgYVX4.js">
|
|
169
|
-
<link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-
|
|
169
|
+
<link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-CG6gtgym.js">
|
|
170
170
|
<link rel="modulepreload" crossorigin href="./assets/config-CR2d-XsP.js">
|
|
171
171
|
<link rel="modulepreload" crossorigin href="./assets/chevron-right-DOPs2jx8.js">
|
|
172
172
|
<link rel="modulepreload" crossorigin href="./assets/dropdown-menu-B2JUUcK7.js">
|
|
173
173
|
<link rel="modulepreload" crossorigin href="./assets/html-to-image-CFVIG1VZ.js">
|
|
174
|
-
<link rel="modulepreload" crossorigin href="./assets/download-
|
|
174
|
+
<link rel="modulepreload" crossorigin href="./assets/download-CPMAf7re.js">
|
|
175
175
|
<link rel="modulepreload" crossorigin href="./assets/switch-C-83e2fG.js">
|
|
176
176
|
<link rel="modulepreload" crossorigin href="./assets/tabs-QRT1DYjj.js">
|
|
177
177
|
<link rel="modulepreload" crossorigin href="./assets/table-B7KYyTxw.js">
|
|
178
178
|
<link rel="modulepreload" crossorigin href="./assets/eye-off-CfkK-QS3.js">
|
|
179
179
|
<link rel="modulepreload" crossorigin href="./assets/refresh-cw-CEGpOrzd.js">
|
|
180
|
-
<link rel="modulepreload" crossorigin href="./assets/tree-actions-
|
|
180
|
+
<link rel="modulepreload" crossorigin href="./assets/tree-actions-D5clvgKl.js">
|
|
181
181
|
<link rel="modulepreload" crossorigin href="./assets/ellipsis-CLMWXUqY.js">
|
|
182
182
|
<link rel="modulepreload" crossorigin href="./assets/external-link-D2lKwXyB.js">
|
|
183
183
|
<link rel="modulepreload" crossorigin href="./assets/spinner-CGdRKCnw.js">
|
|
184
184
|
<link rel="modulepreload" crossorigin href="./assets/message-circle-OTHnVlxO.js">
|
|
185
185
|
<link rel="modulepreload" crossorigin href="./assets/hat-glasses-DVgK5i5l.js">
|
|
186
186
|
<link rel="modulepreload" crossorigin href="./assets/package-BeYhVWvM.js">
|
|
187
|
-
<link rel="modulepreload" crossorigin href="./assets/datasource-
|
|
187
|
+
<link rel="modulepreload" crossorigin href="./assets/datasource-Tst92Pzi.js">
|
|
188
188
|
<link rel="modulepreload" crossorigin href="./assets/alert-MrQXRIin.js">
|
|
189
|
-
<link rel="modulepreload" crossorigin href="./assets/state-
|
|
190
|
-
<link rel="modulepreload" crossorigin href="./assets/cell-link-
|
|
191
|
-
<link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-
|
|
189
|
+
<link rel="modulepreload" crossorigin href="./assets/state-B85OOscw.js">
|
|
190
|
+
<link rel="modulepreload" crossorigin href="./assets/cell-link-DC1UZQr_.js">
|
|
191
|
+
<link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-z5iFryzf.js">
|
|
192
192
|
<link rel="modulepreload" crossorigin href="./assets/useDateFormatter-CTYCgKB-.js">
|
|
193
193
|
<link rel="modulepreload" crossorigin href="./assets/en-US-B4U3zuiu.js">
|
|
194
194
|
<link rel="modulepreload" crossorigin href="./assets/isValid-BEbe1fFs.js">
|
|
@@ -207,13 +207,13 @@
|
|
|
207
207
|
<link rel="modulepreload" crossorigin href="./assets/formats-DkOlpVdf.js">
|
|
208
208
|
<link rel="modulepreload" crossorigin href="./assets/table-Dg1KxH-q.js">
|
|
209
209
|
<link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-BL2E7f5c.js">
|
|
210
|
-
<link rel="modulepreload" crossorigin href="./assets/JsonOutput-
|
|
210
|
+
<link rel="modulepreload" crossorigin href="./assets/JsonOutput-NVH7GWyC.js">
|
|
211
211
|
<link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-B6FT5Xvu.js">
|
|
212
212
|
<link rel="modulepreload" crossorigin href="./assets/square-function-DyFIOFp5.js">
|
|
213
213
|
<link rel="modulepreload" crossorigin href="./assets/spec-D9d9nT0z.js">
|
|
214
214
|
<link rel="modulepreload" crossorigin href="./assets/semaphore-BjoL5P0h.js">
|
|
215
215
|
<link rel="modulepreload" crossorigin href="./assets/fileToBase64-aqhlf6Jj.js">
|
|
216
|
-
<link rel="modulepreload" crossorigin href="./assets/useBoolean-
|
|
216
|
+
<link rel="modulepreload" crossorigin href="./assets/useBoolean-Co-_MyFz.js">
|
|
217
217
|
<link rel="modulepreload" crossorigin href="./assets/code-xml-CW65k2pN.js">
|
|
218
218
|
<link rel="modulepreload" crossorigin href="./assets/file-headphone-DKocX1z0.js">
|
|
219
219
|
<link rel="modulepreload" crossorigin href="./assets/file-mCR_SMtq.js">
|
|
@@ -221,11 +221,11 @@
|
|
|
221
221
|
<link rel="modulepreload" crossorigin href="./assets/file-icons-e7tmeyP-.js">
|
|
222
222
|
<link rel="modulepreload" crossorigin href="./assets/globe-CmFhHoL1.js">
|
|
223
223
|
<link rel="modulepreload" crossorigin href="./assets/esm-3WkPrffD.js">
|
|
224
|
-
<link rel="modulepreload" crossorigin href="./assets/useAddCell-
|
|
225
|
-
<link rel="modulepreload" crossorigin href="./assets/readonly-python-code-
|
|
224
|
+
<link rel="modulepreload" crossorigin href="./assets/useAddCell-Bhv6GT3m.js">
|
|
225
|
+
<link rel="modulepreload" crossorigin href="./assets/readonly-python-code-DcYhdd1B.js">
|
|
226
226
|
<link rel="modulepreload" crossorigin href="./assets/data-grid-types-DgHVN_Zz.js">
|
|
227
227
|
<link rel="modulepreload" crossorigin href="./assets/glide-utils-BzwA3q-e.js">
|
|
228
|
-
<link rel="modulepreload" crossorigin href="./assets/column-preview-
|
|
228
|
+
<link rel="modulepreload" crossorigin href="./assets/column-preview-sL_Jo0hX.js">
|
|
229
229
|
<link rel="modulepreload" crossorigin href="./assets/square-DvOKKLHZ.js">
|
|
230
230
|
<link rel="modulepreload" crossorigin href="./assets/triangle-alert-BeRqoThc.js">
|
|
231
231
|
<link rel="modulepreload" crossorigin href="./assets/prop-types-Djf4O40e.js">
|
|
@@ -237,11 +237,11 @@
|
|
|
237
237
|
<link rel="modulepreload" crossorigin href="./assets/icons-CVdkfEA3.js">
|
|
238
238
|
<link rel="modulepreload" crossorigin href="./assets/useDeepCompareMemoize-DSlTt6u_.js">
|
|
239
239
|
<link rel="modulepreload" crossorigin href="./assets/pathUtils-BKesuhdv.js">
|
|
240
|
-
<link rel="modulepreload" crossorigin href="./assets/floating-outline-
|
|
240
|
+
<link rel="modulepreload" crossorigin href="./assets/floating-outline-K7cVdOlC.js">
|
|
241
241
|
<link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
|
|
242
242
|
<link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DjIHoF9Z.css">
|
|
243
243
|
<link rel="stylesheet" crossorigin href="./assets/JsonOutput-B0GmlMnR.css">
|
|
244
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
244
|
+
<link rel="stylesheet" crossorigin href="./assets/index-B7ZZVUcj.css">
|
|
245
245
|
</head>
|
|
246
246
|
<body>
|
|
247
247
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@ import { kioskModeAtom } from "@/core/mode";
|
|
|
7
7
|
import { connectionAtom } from "@/core/network/connection";
|
|
8
8
|
import { store } from "@/core/state/jotai";
|
|
9
9
|
import { isStaticNotebook } from "@/core/static/static-state";
|
|
10
|
-
import {
|
|
10
|
+
import { ConnectionState } from "@/core/websocket/types";
|
|
11
11
|
import { pairPreviewAtom } from "@/core/config/pair";
|
|
12
12
|
import { PAIR_PREVIEW } from "./fixtures/pair-preview";
|
|
13
13
|
import { mount, visibleForTesting } from "../mount";
|
|
@@ -59,7 +59,7 @@ describe("mount", () => {
|
|
|
59
59
|
store.set(layoutStateAtom, initialLayoutState());
|
|
60
60
|
store.set(kioskModeAtom, false);
|
|
61
61
|
// Reset connection atom to initial state
|
|
62
|
-
store.set(connectionAtom, { state:
|
|
62
|
+
store.set(connectionAtom, { state: ConnectionState.NOT_STARTED });
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
afterEach(() => {
|
|
@@ -111,7 +111,7 @@ describe("mount", () => {
|
|
|
111
111
|
);
|
|
112
112
|
|
|
113
113
|
const connection = store.get(connectionAtom);
|
|
114
|
-
expect(connection.state).toBe(
|
|
114
|
+
expect(connection.state).toBe(ConnectionState.CONNECTING);
|
|
115
115
|
});
|
|
116
116
|
|
|
117
117
|
it("should keep connection as NOT_STARTED when runtimeConfig has lazy=true", () => {
|
|
@@ -124,7 +124,7 @@ describe("mount", () => {
|
|
|
124
124
|
);
|
|
125
125
|
|
|
126
126
|
const connection = store.get(connectionAtom);
|
|
127
|
-
expect(connection.state).toBe(
|
|
127
|
+
expect(connection.state).toBe(ConnectionState.NOT_STARTED);
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
it("should keep connection as NOT_STARTED when no runtimeConfig is provided", () => {
|
|
@@ -137,7 +137,7 @@ describe("mount", () => {
|
|
|
137
137
|
);
|
|
138
138
|
|
|
139
139
|
const connection = store.get(connectionAtom);
|
|
140
|
-
expect(connection.state).toBe(
|
|
140
|
+
expect(connection.state).toBe(ConnectionState.NOT_STARTED);
|
|
141
141
|
});
|
|
142
142
|
|
|
143
143
|
it("should keep connection as NOT_STARTED for static notebooks even with lazy=false", () => {
|
|
@@ -155,7 +155,7 @@ describe("mount", () => {
|
|
|
155
155
|
);
|
|
156
156
|
|
|
157
157
|
const connection = store.get(connectionAtom);
|
|
158
|
-
expect(connection.state).toBe(
|
|
158
|
+
expect(connection.state).toBe(ConnectionState.NOT_STARTED);
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
161
|
|
|
@@ -5,7 +5,7 @@ import { useImperativeModal } from "@/components/modal/ImperativeModal";
|
|
|
5
5
|
import { AlertDialogDestructiveAction } from "@/components/ui/alert-dialog";
|
|
6
6
|
import { connectionAtom } from "@/core/network/connection";
|
|
7
7
|
import { useRequestClient } from "@/core/network/requests";
|
|
8
|
-
import {
|
|
8
|
+
import { ConnectionState } from "@/core/websocket/types";
|
|
9
9
|
import { reloadSafe } from "@/utils/reload-safe";
|
|
10
10
|
|
|
11
11
|
export function useRestartKernel() {
|
|
@@ -22,7 +22,7 @@ export function useRestartKernel() {
|
|
|
22
22
|
confirmAction: (
|
|
23
23
|
<AlertDialogDestructiveAction
|
|
24
24
|
onClick={async () => {
|
|
25
|
-
setConnection({ state:
|
|
25
|
+
setConnection({ state: ConnectionState.CLOSING });
|
|
26
26
|
await sendRestart();
|
|
27
27
|
reloadSafe();
|
|
28
28
|
}}
|
|
@@ -8,16 +8,22 @@ import { alertAtom, getPackageAlert } from "@/core/alerts/state";
|
|
|
8
8
|
import { notebookAtom } from "@/core/cells/cells";
|
|
9
9
|
import { CellId } from "@/core/cells/ids";
|
|
10
10
|
import { AppConfigSchema } from "@/core/config/config-schema";
|
|
11
|
+
import { kernelStartupErrorAtom } from "@/core/errors/state";
|
|
11
12
|
import { connectionAtom } from "@/core/network/connection";
|
|
12
13
|
import { sandboxAtom, sandboxSyncAtom } from "@/core/packages/sandbox-state";
|
|
13
|
-
import { WebSocketClosedReason,
|
|
14
|
+
import { WebSocketClosedReason, ConnectionState } from "@/core/websocket/types";
|
|
14
15
|
import { chromeAtom } from "../../chrome/state";
|
|
16
|
+
import { runtimeDetailsExpandedAtom } from "../../chrome/panels/runtime-details-state";
|
|
15
17
|
import { ConnectionNotice } from "../connection-notice";
|
|
16
18
|
|
|
17
19
|
beforeEach(() => vi.useFakeTimers());
|
|
18
20
|
afterEach(() => vi.useRealTimers());
|
|
19
21
|
|
|
20
|
-
function mount(
|
|
22
|
+
function mount({
|
|
23
|
+
existingCells = false,
|
|
24
|
+
onRetry = vi.fn(),
|
|
25
|
+
canOpenPackages = true,
|
|
26
|
+
} = {}) {
|
|
21
27
|
const store = createStore();
|
|
22
28
|
store.set(sandboxAtom, {
|
|
23
29
|
backend: "pixi",
|
|
@@ -25,7 +31,7 @@ function mount(existingCells = false) {
|
|
|
25
31
|
filename: "notebook.py",
|
|
26
32
|
});
|
|
27
33
|
store.set(connectionAtom, {
|
|
28
|
-
state:
|
|
34
|
+
state: ConnectionState.CONNECTING,
|
|
29
35
|
phase: "preparing-environment",
|
|
30
36
|
});
|
|
31
37
|
if (existingCells) {
|
|
@@ -40,7 +46,8 @@ function mount(existingCells = false) {
|
|
|
40
46
|
<Provider store={store}>
|
|
41
47
|
<ConnectionNotice
|
|
42
48
|
appConfig={AppConfigSchema.parse({})}
|
|
43
|
-
onRetry={
|
|
49
|
+
onRetry={onRetry}
|
|
50
|
+
canOpenPackages={canOpenPackages}
|
|
44
51
|
/>
|
|
45
52
|
</Provider>,
|
|
46
53
|
);
|
|
@@ -57,13 +64,13 @@ it("shows both stages in an empty notebook, checks them off, then dismisses Read
|
|
|
57
64
|
expect(steps.getByText("Start kernel")).toBeInTheDocument();
|
|
58
65
|
act(() =>
|
|
59
66
|
store.set(connectionAtom, {
|
|
60
|
-
state:
|
|
67
|
+
state: ConnectionState.CONNECTING,
|
|
61
68
|
phase: "starting-kernel",
|
|
62
69
|
}),
|
|
63
70
|
);
|
|
64
71
|
expect(steps.getByText("Environment prepared")).toBeInTheDocument();
|
|
65
72
|
expect(steps.getByText("Starting kernel")).toBeInTheDocument();
|
|
66
|
-
act(() => store.set(connectionAtom, { state:
|
|
73
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
67
74
|
expect(
|
|
68
75
|
screen.getByRole("heading", { name: "Your notebook is ready" }),
|
|
69
76
|
).toBeInTheDocument();
|
|
@@ -78,8 +85,122 @@ it("shows both stages in an empty notebook, checks them off, then dismisses Read
|
|
|
78
85
|
).not.toBeInTheDocument();
|
|
79
86
|
});
|
|
80
87
|
|
|
88
|
+
it("uses the shared kernel stage for an ordinary connection and dismisses it when connected", () => {
|
|
89
|
+
const store = mount();
|
|
90
|
+
act(() => {
|
|
91
|
+
store.set(sandboxAtom, null);
|
|
92
|
+
store.set(connectionAtom, { state: ConnectionState.CONNECTING });
|
|
93
|
+
});
|
|
94
|
+
act(() => vi.advanceTimersByTime(500));
|
|
95
|
+
const stages = within(
|
|
96
|
+
screen.getByRole("list", {
|
|
97
|
+
name: "Notebook startup stages",
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
expect(stages.getAllByRole("listitem")).toHaveLength(1);
|
|
101
|
+
expect(stages.getByText("Starting kernel")).toBeVisible();
|
|
102
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
103
|
+
expect(screen.queryByRole("region", { name: "Notebook startup" })).toBeNull();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("shows connection status until a sandbox reports its startup phase", () => {
|
|
107
|
+
const store = mount();
|
|
108
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.CONNECTING }));
|
|
109
|
+
act(() => vi.advanceTimersByTime(500));
|
|
110
|
+
expect(screen.getByRole("heading", { name: "Connecting…" })).toBeVisible();
|
|
111
|
+
expect(screen.queryByRole("list")).not.toBeInTheDocument();
|
|
112
|
+
|
|
113
|
+
act(() =>
|
|
114
|
+
store.set(connectionAtom, {
|
|
115
|
+
state: ConnectionState.CLOSED,
|
|
116
|
+
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
117
|
+
reason: "Kernel startup failed",
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
120
|
+
expect(
|
|
121
|
+
screen.getByRole("heading", { name: "Kernel failed to start" }),
|
|
122
|
+
).toBeVisible();
|
|
123
|
+
expect(screen.queryByRole("list")).not.toBeInTheDocument();
|
|
124
|
+
|
|
125
|
+
act(() =>
|
|
126
|
+
store.set(connectionAtom, {
|
|
127
|
+
state: ConnectionState.CONNECTING,
|
|
128
|
+
phase: "preparing-environment",
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
act(() => vi.advanceTimersByTime(500));
|
|
132
|
+
expect(screen.getByRole("list")).toHaveTextContent("Preparing environment");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("shows kernel startup while sandbox metadata is loading, then adds environment preparation", () => {
|
|
136
|
+
const store = mount();
|
|
137
|
+
const sandbox = store.get(sandboxAtom);
|
|
138
|
+
act(() => store.set(sandboxAtom, null));
|
|
139
|
+
act(() => vi.advanceTimersByTime(500));
|
|
140
|
+
expect(screen.getByText("Starting kernel")).toBeVisible();
|
|
141
|
+
expect(screen.getAllByRole("listitem")).toHaveLength(1);
|
|
142
|
+
|
|
143
|
+
act(() => store.set(sandboxAtom, sandbox));
|
|
144
|
+
const stages = within(screen.getByRole("list"));
|
|
145
|
+
expect(stages.getByText("Preparing environment")).toBeVisible();
|
|
146
|
+
expect(stages.getByText("Start kernel")).toBeVisible();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("shows ordinary environment preparation failures in the kernel stage", () => {
|
|
150
|
+
const store = mount();
|
|
151
|
+
act(() => store.set(sandboxAtom, null));
|
|
152
|
+
act(() => vi.advanceTimersByTime(500));
|
|
153
|
+
expect(screen.getByText("Starting kernel")).toBeVisible();
|
|
154
|
+
expect(screen.getAllByRole("listitem")).toHaveLength(1);
|
|
155
|
+
act(() => {
|
|
156
|
+
store.set(
|
|
157
|
+
kernelStartupErrorAtom,
|
|
158
|
+
"Configured Python environment is missing",
|
|
159
|
+
);
|
|
160
|
+
store.set(connectionAtom, {
|
|
161
|
+
state: ConnectionState.CLOSED,
|
|
162
|
+
phase: "preparing-environment",
|
|
163
|
+
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
164
|
+
reason: "Kernel startup failed",
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
expect(screen.getByRole("listitem")).toHaveTextContent(
|
|
168
|
+
"Kernel failed to start",
|
|
169
|
+
);
|
|
170
|
+
expect(screen.getByRole("status")).toHaveTextContent(
|
|
171
|
+
"Kernel failed to start",
|
|
172
|
+
);
|
|
173
|
+
expect(screen.getByLabelText("Error details")).toHaveTextContent(
|
|
174
|
+
"Configured Python environment is missing",
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("reports the inline disclosure as expanded only when Packages and runtime details are open", () => {
|
|
179
|
+
const store = mount({ existingCells: true });
|
|
180
|
+
act(() => {
|
|
181
|
+
store.set(chromeAtom, (value) => ({
|
|
182
|
+
...value,
|
|
183
|
+
isSidebarOpen: true,
|
|
184
|
+
selectedPanel: "packages",
|
|
185
|
+
}));
|
|
186
|
+
store.set(runtimeDetailsExpandedAtom, false);
|
|
187
|
+
});
|
|
188
|
+
act(() => vi.advanceTimersByTime(500));
|
|
189
|
+
const toggle = screen.getByRole("button", { name: /Open Packages/ });
|
|
190
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
191
|
+
fireEvent.click(toggle);
|
|
192
|
+
expect(toggle).toHaveAttribute("aria-expanded", "true");
|
|
193
|
+
act(() => store.set(runtimeDetailsExpandedAtom, false));
|
|
194
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
195
|
+
act(() => {
|
|
196
|
+
store.set(runtimeDetailsExpandedAtom, true);
|
|
197
|
+
store.set(chromeAtom, (value) => ({ ...value, isSidebarOpen: false }));
|
|
198
|
+
});
|
|
199
|
+
expect(toggle).toHaveAttribute("aria-expanded", "false");
|
|
200
|
+
});
|
|
201
|
+
|
|
81
202
|
it("opens Packages from the minimal inline status when cells exist", () => {
|
|
82
|
-
const store = mount(true);
|
|
203
|
+
const store = mount({ existingCells: true });
|
|
83
204
|
act(() => vi.advanceTimersByTime(500));
|
|
84
205
|
expect(screen.queryByRole("list")).not.toBeInTheDocument();
|
|
85
206
|
fireEvent.click(screen.getByRole("button", { name: /Open Packages/ }));
|
|
@@ -87,14 +208,100 @@ it("opens Packages from the minimal inline status when cells exist", () => {
|
|
|
87
208
|
isSidebarOpen: true,
|
|
88
209
|
selectedPanel: "packages",
|
|
89
210
|
});
|
|
90
|
-
act(() => store.set(connectionAtom, { state:
|
|
211
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
91
212
|
expect(screen.getByRole("status")).toHaveTextContent(/^Ready$/);
|
|
92
213
|
});
|
|
93
214
|
|
|
215
|
+
it("uses an inline notice for an existing ordinary notebook, opens collapsed details, and offers retry on failure", () => {
|
|
216
|
+
const onRetry = vi.fn();
|
|
217
|
+
const store = mount({ existingCells: true, onRetry });
|
|
218
|
+
act(() => {
|
|
219
|
+
store.set(sandboxAtom, null);
|
|
220
|
+
store.set(connectionAtom, { state: ConnectionState.CONNECTING });
|
|
221
|
+
store.set(runtimeDetailsExpandedAtom, false);
|
|
222
|
+
});
|
|
223
|
+
act(() => vi.advanceTimersByTime(500));
|
|
224
|
+
const statusRow = screen.getByRole("region", {
|
|
225
|
+
name: "Notebook startup",
|
|
226
|
+
}).parentElement;
|
|
227
|
+
fireEvent.click(screen.getByRole("button", { name: /Open Packages/ }));
|
|
228
|
+
expect(store.get(chromeAtom)).toMatchObject({
|
|
229
|
+
isSidebarOpen: true,
|
|
230
|
+
selectedPanel: "packages",
|
|
231
|
+
});
|
|
232
|
+
expect(store.get(runtimeDetailsExpandedAtom)).toBe(true);
|
|
233
|
+
act(() =>
|
|
234
|
+
store.set(connectionAtom, {
|
|
235
|
+
state: ConnectionState.CLOSED,
|
|
236
|
+
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
237
|
+
reason: "Kernel startup failed",
|
|
238
|
+
}),
|
|
239
|
+
);
|
|
240
|
+
expect(
|
|
241
|
+
screen.getByRole("button", {
|
|
242
|
+
name: /Kernel failed to start Open Packages/,
|
|
243
|
+
}),
|
|
244
|
+
).toBeVisible();
|
|
245
|
+
fireEvent.click(screen.getByRole("button", { name: "Try again" }));
|
|
246
|
+
expect(onRetry).toHaveBeenCalledOnce();
|
|
247
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
248
|
+
expect(screen.queryByRole("region", { name: "Notebook startup" })).toBeNull();
|
|
249
|
+
expect(statusRow).not.toBeInTheDocument();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it.each([
|
|
253
|
+
{ existingCells: false, sandbox: false },
|
|
254
|
+
{ existingCells: true, sandbox: false },
|
|
255
|
+
{ existingCells: false, sandbox: true },
|
|
256
|
+
{ existingCells: true, sandbox: true },
|
|
257
|
+
])(
|
|
258
|
+
"keeps errors in the notebook without chrome (cells=$existingCells, sandbox=$sandbox)",
|
|
259
|
+
({ existingCells, sandbox }) => {
|
|
260
|
+
const onRetry = vi.fn();
|
|
261
|
+
const store = mount({ existingCells, onRetry, canOpenPackages: false });
|
|
262
|
+
act(() => {
|
|
263
|
+
if (!sandbox) {
|
|
264
|
+
store.set(sandboxAtom, null);
|
|
265
|
+
}
|
|
266
|
+
store.set(connectionAtom, {
|
|
267
|
+
state: ConnectionState.CONNECTING,
|
|
268
|
+
phase: "starting-kernel",
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
act(() => vi.advanceTimersByTime(500));
|
|
272
|
+
expect(screen.getByText("Starting kernel")).toBeVisible();
|
|
273
|
+
expect(screen.getByRole("status")).toHaveTextContent("Starting kernel…");
|
|
274
|
+
expect(screen.queryByRole("button")).not.toBeInTheDocument();
|
|
275
|
+
|
|
276
|
+
act(() => {
|
|
277
|
+
store.set(kernelStartupErrorAtom, "Could not import the runtime");
|
|
278
|
+
store.set(connectionAtom, {
|
|
279
|
+
state: ConnectionState.CLOSED,
|
|
280
|
+
phase: "starting-kernel",
|
|
281
|
+
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
282
|
+
reason: "Kernel startup failed",
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
expect(screen.getByLabelText("Error details")).toHaveTextContent(
|
|
286
|
+
"Could not import the runtime",
|
|
287
|
+
);
|
|
288
|
+
expect(screen.getByRole("status")).toHaveTextContent(
|
|
289
|
+
"Kernel failed to start",
|
|
290
|
+
);
|
|
291
|
+
expect(
|
|
292
|
+
screen.queryByRole("button", { name: /Open Packages/ }),
|
|
293
|
+
).not.toBeInTheDocument();
|
|
294
|
+
if (!sandbox) {
|
|
295
|
+
fireEvent.click(screen.getByRole("button", { name: "Try again" }));
|
|
296
|
+
}
|
|
297
|
+
expect(onRetry).toHaveBeenCalledTimes(sandbox ? 0 : 1);
|
|
298
|
+
},
|
|
299
|
+
);
|
|
300
|
+
|
|
94
301
|
it("does not flash Ready for a startup that finished before the notice appeared", () => {
|
|
95
|
-
const store = mount(true);
|
|
302
|
+
const store = mount({ existingCells: true });
|
|
96
303
|
act(() => vi.advanceTimersByTime(200));
|
|
97
|
-
act(() => store.set(connectionAtom, { state:
|
|
304
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
98
305
|
expect(screen.queryByRole("status")).not.toBeInTheDocument();
|
|
99
306
|
act(() => vi.advanceTimersByTime(2000));
|
|
100
307
|
expect(screen.queryByRole("status")).not.toBeInTheDocument();
|
|
@@ -103,11 +310,11 @@ it("does not flash Ready for a startup that finished before the notice appeared"
|
|
|
103
310
|
it("replaces Ready with a new attempt and never dismisses a failure", () => {
|
|
104
311
|
const store = mount();
|
|
105
312
|
act(() => vi.advanceTimersByTime(500));
|
|
106
|
-
act(() => store.set(connectionAtom, { state:
|
|
313
|
+
act(() => store.set(connectionAtom, { state: ConnectionState.OPEN }));
|
|
107
314
|
act(() => vi.advanceTimersByTime(1000));
|
|
108
315
|
act(() =>
|
|
109
316
|
store.set(connectionAtom, {
|
|
110
|
-
state:
|
|
317
|
+
state: ConnectionState.CONNECTING,
|
|
111
318
|
phase: "starting-kernel",
|
|
112
319
|
}),
|
|
113
320
|
);
|
|
@@ -115,7 +322,7 @@ it("replaces Ready with a new attempt and never dismisses a failure", () => {
|
|
|
115
322
|
expect(screen.getByText("Starting kernel")).toBeInTheDocument();
|
|
116
323
|
act(() =>
|
|
117
324
|
store.set(connectionAtom, {
|
|
118
|
-
state:
|
|
325
|
+
state: ConnectionState.CLOSED,
|
|
119
326
|
code: WebSocketClosedReason.KERNEL_STARTUP_ERROR,
|
|
120
327
|
phase: "starting-kernel",
|
|
121
328
|
reason: "Kernel startup failed",
|
|
@@ -128,9 +335,9 @@ it("replaces Ready with a new attempt and never dismisses a failure", () => {
|
|
|
128
335
|
});
|
|
129
336
|
|
|
130
337
|
it("shows a sync as a single operation, without pretending to restart the kernel", () => {
|
|
131
|
-
const store = mount(true);
|
|
338
|
+
const store = mount({ existingCells: true });
|
|
132
339
|
act(() => {
|
|
133
|
-
store.set(connectionAtom, { state:
|
|
340
|
+
store.set(connectionAtom, { state: ConnectionState.OPEN });
|
|
134
341
|
store.set(sandboxSyncAtom, { kind: "running" });
|
|
135
342
|
});
|
|
136
343
|
act(() => vi.advanceTimersByTime(500));
|
|
@@ -141,7 +348,7 @@ it("shows a sync as a single operation, without pretending to restart the kernel
|
|
|
141
348
|
});
|
|
142
349
|
|
|
143
350
|
it("restores syncing in the existing status and stays quiet for a completed snapshot", () => {
|
|
144
|
-
const store = mount(true);
|
|
351
|
+
const store = mount({ existingCells: true });
|
|
145
352
|
const operation: EnvironmentOperation = {
|
|
146
353
|
operation_id: "sync",
|
|
147
354
|
action: "sync",
|
|
@@ -162,7 +369,7 @@ it("restores syncing in the existing status and stays quiet for a completed snap
|
|
|
162
369
|
},
|
|
163
370
|
}));
|
|
164
371
|
act(() => {
|
|
165
|
-
store.set(connectionAtom, { state:
|
|
372
|
+
store.set(connectionAtom, { state: ConnectionState.OPEN });
|
|
166
373
|
restore({ kind: "succeeded" });
|
|
167
374
|
});
|
|
168
375
|
act(() => vi.advanceTimersByTime(2000));
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
import type { PropsWithChildren } from "react";
|
|
3
|
+
import type { DisplayConnectionNotice } from "@/core/network/useConnectionNotice";
|
|
4
|
+
import { cn } from "@/utils/cn";
|
|
5
|
+
import {
|
|
6
|
+
ConnectionStatusIcon,
|
|
7
|
+
hasStartupStages,
|
|
8
|
+
StartupProgress,
|
|
9
|
+
} from "./startup-progress";
|
|
10
|
+
|
|
11
|
+
export function ConnectionErrorOutput({ error }: { error: string }) {
|
|
12
|
+
return (
|
|
13
|
+
<pre
|
|
14
|
+
tabIndex={0}
|
|
15
|
+
aria-label="Error details"
|
|
16
|
+
className="mt-3 p-3 rounded border bg-muted/30 text-xs text-muted-foreground whitespace-pre min-w-0 max-w-full max-h-52 overflow-auto"
|
|
17
|
+
>
|
|
18
|
+
{error}
|
|
19
|
+
</pre>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function ConnectionDetails({
|
|
24
|
+
notice,
|
|
25
|
+
surface = "sidebar",
|
|
26
|
+
children,
|
|
27
|
+
}: PropsWithChildren<{
|
|
28
|
+
notice: DisplayConnectionNotice;
|
|
29
|
+
surface?: "notebook" | "sidebar";
|
|
30
|
+
}>) {
|
|
31
|
+
const showSteps = hasStartupStages(notice);
|
|
32
|
+
const failed = !notice.pending && !notice.ready;
|
|
33
|
+
return (
|
|
34
|
+
<div className="min-w-0 text-sm">
|
|
35
|
+
{showSteps ? (
|
|
36
|
+
<StartupProgress notice={notice} surface={surface} />
|
|
37
|
+
) : (
|
|
38
|
+
<div className="flex items-center gap-2" role="status">
|
|
39
|
+
<ConnectionStatusIcon notice={notice} />
|
|
40
|
+
<h2
|
|
41
|
+
className={cn(
|
|
42
|
+
surface === "notebook" && "text-base",
|
|
43
|
+
failed ? "font-medium text-(--red-11)" : "text-foreground",
|
|
44
|
+
)}
|
|
45
|
+
>
|
|
46
|
+
{notice.title}
|
|
47
|
+
</h2>
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
50
|
+
{(failed || (!showSteps && surface === "notebook")) && (
|
|
51
|
+
<p className={cn("mt-2", failed && "text-foreground")}>
|
|
52
|
+
{notice.description}
|
|
53
|
+
</p>
|
|
54
|
+
)}
|
|
55
|
+
{notice.error && (surface === "sidebar" || !notice.sandbox) && (
|
|
56
|
+
<ConnectionErrorOutput error={notice.error} />
|
|
57
|
+
)}
|
|
58
|
+
{children}
|
|
59
|
+
</div>
|
|
60
|
+
);
|
|
61
|
+
}
|