@marimo-team/frontend 0.25.3-dev96 → 0.25.3-dev97
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-Dc8AR1al.js → CellStatus-fK4n2NPc.js} +1 -1
- package/dist/assets/{ErrorBoundary-DBQW23V4.js → ErrorBoundary-CAEGdoFW.js} +2 -2
- package/dist/assets/{JsonOutput-nLzWQ-0V.js → JsonOutput-CyAKmZDD.js} +1 -1
- package/dist/assets/{MarimoErrorOutput-DAFgeK_G.js → MarimoErrorOutput-CgZvP0p0.js} +1 -1
- package/dist/assets/{RenderHTML-DwolbpuI.js → RenderHTML-DQvxDDNS.js} +1 -1
- package/dist/assets/{RunButton-BN3_mnoU.js → RunButton-BBDnDL6G.js} +1 -1
- package/dist/assets/{add-cell-with-ai-CRbG5cTT.js → add-cell-with-ai-Clg5FELx.js} +1 -1
- package/dist/assets/{add-connection-dialog-CzCmVM_b.js → add-connection-dialog-BqdWmD-7.js} +1 -1
- package/dist/assets/{agent-panel-zpTxANfi.js → agent-panel-5RxG5Y82.js} +3 -3
- package/dist/assets/{ai-model-dropdown-DL56ImUU.js → ai-model-dropdown-Bvl1ktQq.js} +1 -1
- package/dist/assets/{app-config-button-BRBtaFi_.js → app-config-button-0QTeQ2Mv.js} +1 -1
- package/dist/assets/{blob-CuL-H1JC.js → blob-5VcB8K_t.js} +1 -1
- package/dist/assets/{cell-editor-C6QIY1Q-.js → cell-editor-Byw5y-oI.js} +1 -1
- package/dist/assets/{cell-link-C9tkvy6x.js → cell-link-C5yYyzuF.js} +1 -1
- package/dist/assets/{cells-B23_t5uX.js → cells-D_11MjVB.js} +13 -13
- package/dist/assets/{chat-display-DSezZ1qo.js → chat-display-BCR_ySiV.js} +1 -1
- package/dist/assets/{chat-panel-CocbwA2Q.js → chat-panel-RPRvBsaU.js} +1 -1
- package/dist/assets/{chat-ui-DXvDBccG.js → chat-ui-CGviVaRA.js} +2 -2
- package/dist/assets/{column-preview-BUQ_YMaE.js → column-preview-xe533-Cn.js} +1 -1
- package/dist/assets/{command-palette-HbIlNTLD.js → command-palette-BB9bWdWp.js} +1 -1
- package/dist/assets/{common-XXWicvmo.js → common-CaeItbcI.js} +1 -1
- package/dist/assets/{components-D1a5GeNf.js → components-G6frbw0c.js} +1 -1
- package/dist/assets/{datasource-Qo_t5PqI.js → datasource-deuXnlU-.js} +1 -1
- package/dist/assets/{dependency-graph-panel-DHrm4LUL.js → dependency-graph-panel-CIykLnJe.js} +1 -1
- package/dist/assets/{documentation-panel-BoNI3vXT.js → documentation-panel-2PQ8kQLa.js} +1 -1
- package/dist/assets/{download-Cm3InGht.js → download-dK52bLxZ.js} +1 -1
- package/dist/assets/{edit-page-BVkC2MyU.js → edit-page-C2phWLKH.js} +5 -5
- package/dist/assets/{error-entries-DEkB-8EY.js → error-entries-3GVk2KjS.js} +1 -1
- package/dist/assets/{error-panel-D7GInT--.js → error-panel-CzDRGPeC.js} +1 -1
- package/dist/assets/{feedback-button-sC38i-D1.js → feedback-button-C5NgWpFg.js} +1 -1
- package/dist/assets/feedback-button-CONwLFpw.js +1 -0
- package/dist/assets/{file-explorer-panel-2XFMubVM.js → file-explorer-panel-B50xDnTZ.js} +1 -1
- package/dist/assets/{file-name-input-DPs3KKM-.js → file-name-input-DqwMSgGU.js} +1 -1
- package/dist/assets/{floating-outline-C7MSAu6q.js → floating-outline-ChmAuvxz.js} +1 -1
- package/dist/assets/{gallery-page-B3fJlerH.js → gallery-page-CiL8aMS1.js} +1 -1
- package/dist/assets/{glide-data-editor-DrhzXms_.js → glide-data-editor-CqRclBkp.js} +1 -1
- package/dist/assets/{home-page-CajAhF9Q.js → home-page-BgZVl4dP.js} +1 -1
- package/dist/assets/{hooks-DteA-neM.js → hooks-DM5n7Osw.js} +1 -1
- package/dist/assets/{index-YQHSwyF3.js → index-vCxv6WVQ.js} +18 -18
- package/dist/assets/{layout-DEFRD3k3.js → layout-BpP8nTjb.js} +4 -4
- package/dist/assets/{logs-panel-BpM3pLdf.js → logs-panel-B5eVAZtH.js} +1 -1
- package/dist/assets/{markdown-renderer-C5aIPuRT.js → markdown-renderer-BWUzqkJM.js} +1 -1
- package/dist/assets/{name-cell-input-Dd8oSXnd.js → name-cell-input-DXW68gRW.js} +1 -1
- package/dist/assets/{outline-panel-kFr3Fo2d.js → outline-panel-DPxJhJ_A.js} +1 -1
- package/dist/assets/{packages-panel-Ce_wBuIJ.js → packages-panel-gBE2FWQr.js} +1 -1
- package/dist/assets/{panel-accordion-state-BO2rN4A5.js → panel-accordion-state-CCF5Gxnc.js} +1 -1
- package/dist/assets/{panels-Cy18qaTN.js → panels-BQYMF6p_.js} +1 -1
- package/dist/assets/{process-output-CDhnnF3f.js → process-output-Cw9IDcKQ.js} +1 -1
- package/dist/assets/{readonly-code-display-ChOK6mhE.js → readonly-code-display-DYcZQ28T.js} +1 -1
- package/dist/assets/{readonly-python-code-CVwB1OHZ.js → readonly-python-code-RFuQP50v.js} +1 -1
- package/dist/assets/{reveal-component-DE-4w0ik.js → reveal-component-yRrDmCQz.js} +2 -2
- package/dist/assets/{run-page-C6qwGqj6.js → run-page-CY65WUOu.js} +1 -1
- package/dist/assets/{runtime-details-state-BRSVs8um.js → runtime-details-state-pobtu6TO.js} +1 -1
- package/dist/assets/scratchpad-panel-H44_pvb_.js +1 -0
- package/dist/assets/{session-panel-B0CkZ3wl.js → session-panel-Bnd1iXkO.js} +1 -1
- package/dist/assets/{snippets-panel-CN-U1niV.js → snippets-panel-DKApxKx9.js} +1 -1
- package/dist/assets/{state-BRL89qqy.js → state-Bl9BiY_s.js} +1 -1
- package/dist/assets/{state-BoRCcWOg.js → state-Dv059B3A.js} +1 -1
- package/dist/assets/{tracing-CqxmObxN.js → tracing-Clwy4SlW.js} +1 -1
- package/dist/assets/{tracing-panel-Bn8xJSPi.js → tracing-panel-BwjLG_aC.js} +2 -2
- package/dist/assets/{tree-actions-DoPCJTpj.js → tree-actions-BZNTQ12N.js} +1 -1
- package/dist/assets/{useAddCell-DKb7o70l.js → useAddCell-Cjuqk2YR.js} +1 -1
- package/dist/assets/{useCellActionButton-CSNFulkR.js → useCellActionButton-MoWLvuGe.js} +1 -1
- package/dist/assets/{useDeleteCell-BPQ6Xcbj.js → useDeleteCell-BC-MW7d1.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-4SMlwjEg.js → useDependencyPanelTab-CZU7i-B3.js} +1 -1
- package/dist/assets/{useNotebookActions-B4kq9-P4.js → useNotebookActions-wFxVdRXQ.js} +1 -1
- package/dist/assets/{useRunCells-BV6nl_Ok.js → useRunCells-ByaWxoIt.js} +1 -1
- package/dist/assets/{useSplitCell-Ca364Rrx.js → useSplitCell-YJIystwv.js} +1 -1
- package/dist/index.html +20 -20
- package/package.json +1 -1
- package/src/components/chat/acp/blocks.tsx +2 -2
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
- package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
- package/src/components/data-table/charts/charts.tsx +21 -6
- package/src/components/data-table/charts/storage.ts +16 -5
- package/src/components/editor/output/ansi-reduce.ts +6 -0
- package/src/components/editor/output/console/ConsoleOutput.tsx +11 -7
- package/src/components/editor/package-alert.tsx +4 -4
- package/src/components/scratchpad/scratchpad.tsx +2 -2
- package/src/components/slides/reveal-component.tsx +4 -2
- package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -0
- package/src/core/cells/__tests__/cell.test.ts +39 -0
- package/src/core/cells/__tests__/cells.test.ts +3 -1
- package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
- package/src/core/cells/cell.ts +14 -3
- package/src/core/cells/cells.ts +1 -0
- package/src/core/cells/types.ts +10 -1
- package/src/plugins/impl/chat/chat-ui.tsx +1 -1
- package/dist/assets/feedback-button-Cz9BdS49.js +0 -1
- package/dist/assets/scratchpad-panel--SxH2dnk.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as e,t,u as n}from"./useEvent-BDjgaBtz.js";import{D as r,da as i,dt as a,h as o,ia as s,ri as c}from"./cells-
|
|
1
|
+
import{f as e,t,u as n}from"./useEvent-BDjgaBtz.js";import{D as r,da as i,dt as a,h as o,ia as s,ri as c}from"./cells-D_11MjVB.js";import{t as l}from"./compiler-runtime-BrajqUja.js";import{g as u}from"./useEventListener-CjDeLqFC.js";import{o as d}from"./dist-qhAY4L2r.js";import{r as f}from"./requests-BIFR-h4M.js";var p=l(),m=e(!1);function h(){let e=(0,p.c)(2),n=v(),r;return e[0]===n?r=e[1]:(r=()=>n(i(o())),e[0]=n,e[1]=r),t(r)}function g(e){let n=(0,p.c)(3),r=v(),i;return n[0]!==e||n[1]!==r?(i=()=>{e!==void 0&&r([e])},n[0]=e,n[1]=r,n[2]=i):i=n[2],t(i)}function _(){let e=(0,p.c)(2),n=v(),r;return e[0]===n?r=e[1]:(r=()=>n(s(o())),e[0]=n,e[1]=r),t(r)}function v(){let e=(0,p.c)(4),{prepareForRun:i}=r(),{sendRun:a}=f(),s=n(m),c;return e[0]!==i||e[1]!==a||e[2]!==s?(c=async e=>{if(e.length===0)return;let t=o();return s(!0),y({cellIds:e,sendRun:a,prepareForRun:i,notebook:t})},e[0]=i,e[1]=a,e[2]=s,e[3]=c):c=e[3],t(c)}async function y({cellIds:e,sendRun:t,prepareForRun:n,notebook:r}){if(e.length===0)return;let{cellHandles:i,cellData:o}=r,s=[];for(let t of e){let e=i[t]?.current?.editorView,r;e?(c(e)!==`markdown`&&d(e),r=a(e)):r=o[t]?.code||``,s.push(r),n({cellId:t})}await t({cellIds:e,codes:s}).catch(e=>{u.error(e)})}export{v as a,g as i,y as n,h as o,_ as r,m as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./useEvent-BDjgaBtz.js";import{D as t,dt as n,f as r}from"./cells-
|
|
1
|
+
import{t as e}from"./useEvent-BDjgaBtz.js";import{D as t,dt as n,f as r}from"./cells-D_11MjVB.js";import{t as i}from"./compiler-runtime-BrajqUja.js";import{t as a}from"./jsx-runtime-B74pBk57.js";import{r as o}from"./useDeleteCell-BC-MW7d1.js";import{t as s}from"./use-toast-Wu434mLr.js";var c=i(),l=a();function u(){let i=(0,c.c)(3),{splitCell:a,undoSplitCell:u}=t(),d;return i[0]!==a||i[1]!==u?(d=e=>{let t=r(e.cellId);if(!t)return;let i=n(t);a(e);let{dismiss:c}=s({title:`Cell split`,action:(0,l.jsx)(o,{"data-testid":`undo-split-button`,size:`sm`,variant:`outline`,onClick:()=>{u({...e,snapshot:i}),d()},children:`Undo`})}),d=c},i[0]=a,i[1]=u,i[2]=d):d=i[2],e(d)}export{u as t};
|
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-vCxv6WVQ.js"></script>
|
|
70
70
|
<link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
|
|
71
71
|
<link rel="modulepreload" crossorigin href="./assets/react-DVplv7_D.js">
|
|
72
72
|
<link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BrajqUja.js">
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
<link rel="modulepreload" crossorigin href="./assets/useTheme-BAA27lh7.js">
|
|
140
140
|
<link rel="modulepreload" crossorigin href="./assets/useAsyncData-qvoPYHtx.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-D_11MjVB.js">
|
|
143
143
|
<link rel="modulepreload" crossorigin href="./assets/coerce-DWjFeXOY.js">
|
|
144
144
|
<link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
|
|
145
145
|
<link rel="modulepreload" crossorigin href="./assets/_hasPath-BmRQipI0.js">
|
|
@@ -154,40 +154,40 @@
|
|
|
154
154
|
<link rel="modulepreload" crossorigin href="./assets/copy-KlhazlhB.js">
|
|
155
155
|
<link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
|
|
156
156
|
<link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-BIpRENEC.js">
|
|
157
|
-
<link rel="modulepreload" crossorigin href="./assets/markdown-renderer-
|
|
157
|
+
<link rel="modulepreload" crossorigin href="./assets/markdown-renderer-BWUzqkJM.js">
|
|
158
158
|
<link rel="modulepreload" crossorigin href="./assets/copy-Djr5m5ac.js">
|
|
159
159
|
<link rel="modulepreload" crossorigin href="./assets/copy-icon-8-a5vovc.js">
|
|
160
|
-
<link rel="modulepreload" crossorigin href="./assets/useRunCells-
|
|
161
|
-
<link rel="modulepreload" crossorigin href="./assets/RenderHTML-
|
|
162
|
-
<link rel="modulepreload" crossorigin href="./assets/blob-
|
|
160
|
+
<link rel="modulepreload" crossorigin href="./assets/useRunCells-ByaWxoIt.js">
|
|
161
|
+
<link rel="modulepreload" crossorigin href="./assets/RenderHTML-DQvxDDNS.js">
|
|
162
|
+
<link rel="modulepreload" crossorigin href="./assets/blob-5VcB8K_t.js">
|
|
163
163
|
<link rel="modulepreload" crossorigin href="./assets/kbd-pdKBv96t.js">
|
|
164
164
|
<link rel="modulepreload" crossorigin href="./assets/useInstallPackage-wcDq9hYT.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-
|
|
168
|
-
<link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-
|
|
167
|
+
<link rel="modulepreload" crossorigin href="./assets/state-Bl9BiY_s.js">
|
|
168
|
+
<link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-CAEGdoFW.js">
|
|
169
169
|
<link rel="modulepreload" crossorigin href="./assets/chevron-right-eAtVhbNZ.js">
|
|
170
170
|
<link rel="modulepreload" crossorigin href="./assets/dropdown-menu-DS6umAnH.js">
|
|
171
171
|
<link rel="modulepreload" crossorigin href="./assets/html-to-image-D_0rd3_B.js">
|
|
172
|
-
<link rel="modulepreload" crossorigin href="./assets/download-
|
|
172
|
+
<link rel="modulepreload" crossorigin href="./assets/download-dK52bLxZ.js">
|
|
173
173
|
<link rel="modulepreload" crossorigin href="./assets/switch-DYjBfpNJ.js">
|
|
174
174
|
<link rel="modulepreload" crossorigin href="./assets/tabs-CY8E4r9U.js">
|
|
175
175
|
<link rel="modulepreload" crossorigin href="./assets/table-DG7Ap4H4.js">
|
|
176
176
|
<link rel="modulepreload" crossorigin href="./assets/eye-off-CxVozGAC.js">
|
|
177
177
|
<link rel="modulepreload" crossorigin href="./assets/refresh-cw-Qw1f8Jhy.js">
|
|
178
|
-
<link rel="modulepreload" crossorigin href="./assets/tree-actions-
|
|
178
|
+
<link rel="modulepreload" crossorigin href="./assets/tree-actions-BZNTQ12N.js">
|
|
179
179
|
<link rel="modulepreload" crossorigin href="./assets/ellipsis-63DyBLHQ.js">
|
|
180
180
|
<link rel="modulepreload" crossorigin href="./assets/external-link-UrX9KO36.js">
|
|
181
181
|
<link rel="modulepreload" crossorigin href="./assets/spinner-DyNE-o8o.js">
|
|
182
182
|
<link rel="modulepreload" crossorigin href="./assets/message-circle-C3rKm8_a.js">
|
|
183
183
|
<link rel="modulepreload" crossorigin href="./assets/hat-glasses-C8RhSVii.js">
|
|
184
184
|
<link rel="modulepreload" crossorigin href="./assets/package-GSoSTiIK.js">
|
|
185
|
-
<link rel="modulepreload" crossorigin href="./assets/datasource-
|
|
186
|
-
<link rel="modulepreload" crossorigin href="./assets/error-entries-
|
|
185
|
+
<link rel="modulepreload" crossorigin href="./assets/datasource-deuXnlU-.js">
|
|
186
|
+
<link rel="modulepreload" crossorigin href="./assets/error-entries-3GVk2KjS.js">
|
|
187
187
|
<link rel="modulepreload" crossorigin href="./assets/alert-DTaqCu_d.js">
|
|
188
|
-
<link rel="modulepreload" crossorigin href="./assets/state-
|
|
189
|
-
<link rel="modulepreload" crossorigin href="./assets/cell-link-
|
|
190
|
-
<link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-
|
|
188
|
+
<link rel="modulepreload" crossorigin href="./assets/state-Dv059B3A.js">
|
|
189
|
+
<link rel="modulepreload" crossorigin href="./assets/cell-link-C5yYyzuF.js">
|
|
190
|
+
<link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-CgZvP0p0.js">
|
|
191
191
|
<link rel="modulepreload" crossorigin href="./assets/useDateFormatter-DA-62E-Y.js">
|
|
192
192
|
<link rel="modulepreload" crossorigin href="./assets/en-US-Buu61juQ.js">
|
|
193
193
|
<link rel="modulepreload" crossorigin href="./assets/isValid-q_Ad80ug.js">
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
<link rel="modulepreload" crossorigin href="./assets/table-vrvqpuKJ.js">
|
|
208
208
|
<link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-Dbe0MrFr.js">
|
|
209
209
|
<link rel="modulepreload" crossorigin href="./assets/useStateForKey-CGMJQT8x.js">
|
|
210
|
-
<link rel="modulepreload" crossorigin href="./assets/JsonOutput-
|
|
210
|
+
<link rel="modulepreload" crossorigin href="./assets/JsonOutput-CyAKmZDD.js">
|
|
211
211
|
<link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-C4_v6fQW.js">
|
|
212
212
|
<link rel="modulepreload" crossorigin href="./assets/square-function-_W_Lo0P4.js">
|
|
213
213
|
<link rel="modulepreload" crossorigin href="./assets/spec-uCpVvaAR.js">
|
|
@@ -221,11 +221,11 @@
|
|
|
221
221
|
<link rel="modulepreload" crossorigin href="./assets/file-icons-CdJgUy-I.js">
|
|
222
222
|
<link rel="modulepreload" crossorigin href="./assets/globe-UdPdIbF7.js">
|
|
223
223
|
<link rel="modulepreload" crossorigin href="./assets/esm-CI_o7NhW.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-Cjuqk2YR.js">
|
|
225
|
+
<link rel="modulepreload" crossorigin href="./assets/readonly-python-code-RFuQP50v.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-HFqhvWHI.js">
|
|
228
|
-
<link rel="modulepreload" crossorigin href="./assets/column-preview-
|
|
228
|
+
<link rel="modulepreload" crossorigin href="./assets/column-preview-xe533-Cn.js">
|
|
229
229
|
<link rel="modulepreload" crossorigin href="./assets/square-BPmgQFnh.js">
|
|
230
230
|
<link rel="modulepreload" crossorigin href="./assets/triangle-alert-DmIqR8sY.js">
|
|
231
231
|
<link rel="modulepreload" crossorigin href="./assets/prop-types-Djf4O40e.js">
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
<link rel="modulepreload" crossorigin href="./assets/useDeepCompareMemoize-B2DVK2De.js">
|
|
239
239
|
<link rel="modulepreload" crossorigin href="./assets/useDelayElapsed-BlsDT4TV.js">
|
|
240
240
|
<link rel="modulepreload" crossorigin href="./assets/pathUtils-DPmlLd-r.js">
|
|
241
|
-
<link rel="modulepreload" crossorigin href="./assets/floating-outline-
|
|
241
|
+
<link rel="modulepreload" crossorigin href="./assets/floating-outline-ChmAuvxz.js">
|
|
242
242
|
<link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
|
|
243
243
|
<link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DjIHoF9Z.css">
|
|
244
244
|
<link rel="stylesheet" crossorigin href="./assets/JsonOutput-B0GmlMnR.css">
|
package/package.json
CHANGED
|
@@ -328,9 +328,9 @@ export const PlansBlock = (props: { data: PlanNotificationEvent[] }) => {
|
|
|
328
328
|
</span>
|
|
329
329
|
</div>
|
|
330
330
|
<ul className="flex flex-col gap-1">
|
|
331
|
-
{plans.map((item
|
|
331
|
+
{plans.map((item) => (
|
|
332
332
|
<li
|
|
333
|
-
key={
|
|
333
|
+
key={item.content}
|
|
334
334
|
className={`
|
|
335
335
|
flex items-center gap-2 px-2 py-1 rounded
|
|
336
336
|
`}
|
|
@@ -10,13 +10,27 @@ import { cellId } from "@/__tests__/branded";
|
|
|
10
10
|
import { LazyVegaEmbed } from "@/components/charts/lazy";
|
|
11
11
|
import { vegaLoader } from "@/plugins/impl/vega/loader";
|
|
12
12
|
import { ChartPanel, TablePanel, type TablePanelProps } from "../charts";
|
|
13
|
-
import { getChartTabName, tabsStorageAtom } from "../storage";
|
|
13
|
+
import { createTabId, getChartTabName, tabsStorageAtom } from "../storage";
|
|
14
14
|
import { ChartType, NONE_VALUE } from "../types";
|
|
15
|
+
import { TOO_MANY_ROWS } from "../../types";
|
|
15
16
|
|
|
16
17
|
vi.mock("@/components/charts/lazy", () => ({
|
|
17
18
|
LazyVegaEmbed: vi.fn(() => null),
|
|
18
19
|
}));
|
|
19
20
|
|
|
21
|
+
vi.mock("../components/chart-items", async (importOriginal) => ({
|
|
22
|
+
...(await importOriginal<typeof import("../components/chart-items")>()),
|
|
23
|
+
ChartTypeSelect: ({
|
|
24
|
+
onValueChange,
|
|
25
|
+
}: {
|
|
26
|
+
onValueChange: (value: string) => void;
|
|
27
|
+
}) => (
|
|
28
|
+
<button type="button" onClick={() => onValueChange("line")}>
|
|
29
|
+
Change chart type
|
|
30
|
+
</button>
|
|
31
|
+
),
|
|
32
|
+
}));
|
|
33
|
+
|
|
20
34
|
beforeAll(() => {
|
|
21
35
|
SetupMocks.resizeObserver();
|
|
22
36
|
});
|
|
@@ -38,6 +52,7 @@ describe("ChartPanel", () => {
|
|
|
38
52
|
id,
|
|
39
53
|
[
|
|
40
54
|
{
|
|
55
|
+
id: createTabId(),
|
|
41
56
|
tabName,
|
|
42
57
|
chartType: ChartType.BAR,
|
|
43
58
|
config: {
|
|
@@ -283,4 +298,62 @@ describe("ChartPanel", () => {
|
|
|
283
298
|
});
|
|
284
299
|
},
|
|
285
300
|
);
|
|
301
|
+
it("keeps panel state when a chart type change renames the tab", async () => {
|
|
302
|
+
const store = createStore();
|
|
303
|
+
const id = cellId("rename-keeps-state");
|
|
304
|
+
const tabName = getChartTabName(0, ChartType.BAR);
|
|
305
|
+
store.set(
|
|
306
|
+
tabsStorageAtom,
|
|
307
|
+
new Map([
|
|
308
|
+
[
|
|
309
|
+
id,
|
|
310
|
+
[
|
|
311
|
+
{
|
|
312
|
+
id: createTabId(),
|
|
313
|
+
tabName,
|
|
314
|
+
chartType: ChartType.BAR,
|
|
315
|
+
config: {
|
|
316
|
+
general: {
|
|
317
|
+
xColumn: { field: "value", type: "number" },
|
|
318
|
+
yColumn: {
|
|
319
|
+
field: "value",
|
|
320
|
+
type: "integer",
|
|
321
|
+
aggregate: NONE_VALUE,
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
],
|
|
328
|
+
]),
|
|
329
|
+
);
|
|
330
|
+
const sample = [{ value: 1 }];
|
|
331
|
+
const props: TablePanelProps = {
|
|
332
|
+
cellId: id,
|
|
333
|
+
data: sample,
|
|
334
|
+
dataTable: <div />,
|
|
335
|
+
totalRows: TOO_MANY_ROWS,
|
|
336
|
+
columns: 1,
|
|
337
|
+
displayHeader: true,
|
|
338
|
+
fieldTypes: [["value", ["number", "float64"]]],
|
|
339
|
+
};
|
|
340
|
+
const { getByRole, findByRole, queryByRole } = render(
|
|
341
|
+
<Provider store={store}>
|
|
342
|
+
<Tooltip.Provider>
|
|
343
|
+
<TablePanel {...props} />
|
|
344
|
+
</Tooltip.Provider>
|
|
345
|
+
</Provider>,
|
|
346
|
+
);
|
|
347
|
+
fireEvent.click(getByRole("tab", { name: tabName }));
|
|
348
|
+
fireEvent.click(await findByRole("button", { name: "Proceed" }));
|
|
349
|
+
await waitFor(() => {
|
|
350
|
+
expect(queryByRole("button", { name: "Proceed" })).toBeNull();
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
fireEvent.click(getByRole("button", { name: "Change chart type" }));
|
|
354
|
+
|
|
355
|
+
const renamed = getChartTabName(0, ChartType.LINE);
|
|
356
|
+
await findByRole("tab", { name: renamed });
|
|
357
|
+
expect(queryByRole("button", { name: "Proceed" })).toBeNull();
|
|
358
|
+
});
|
|
286
359
|
});
|
|
@@ -16,7 +16,7 @@ import { cellId } from "@/__tests__/branded";
|
|
|
16
16
|
import { availableStorage } from "@/utils/storage/storage";
|
|
17
17
|
import { ChartSchema } from "../schemas";
|
|
18
18
|
import type { TabName } from "../storage";
|
|
19
|
-
import { KEY, tabsStorageAtom } from "../storage";
|
|
19
|
+
import { createTabId, KEY, tabsStorageAtom } from "../storage";
|
|
20
20
|
import { ChartType } from "../types";
|
|
21
21
|
|
|
22
22
|
describe("Chart Transforms Storage", () => {
|
|
@@ -39,6 +39,7 @@ describe("Chart Transforms Storage", () => {
|
|
|
39
39
|
const store = getDefaultStore();
|
|
40
40
|
const cid = cellId("cell-1");
|
|
41
41
|
const tabData = {
|
|
42
|
+
id: createTabId(),
|
|
42
43
|
tabName: "Tab 1" as TabName,
|
|
43
44
|
chartType: ChartType.LINE,
|
|
44
45
|
config: ChartSchema.parse({
|
|
@@ -63,6 +64,7 @@ describe("Chart Transforms Storage", () => {
|
|
|
63
64
|
const store = getDefaultStore();
|
|
64
65
|
const cid = cellId("cell-1");
|
|
65
66
|
const tabData1 = {
|
|
67
|
+
id: createTabId(),
|
|
66
68
|
tabName: "Tab 1" as TabName,
|
|
67
69
|
chartType: ChartType.LINE,
|
|
68
70
|
config: ChartSchema.parse({
|
|
@@ -73,6 +75,7 @@ describe("Chart Transforms Storage", () => {
|
|
|
73
75
|
}),
|
|
74
76
|
};
|
|
75
77
|
const tabData2 = {
|
|
78
|
+
id: createTabId(),
|
|
76
79
|
tabName: "Tab 2" as TabName,
|
|
77
80
|
chartType: ChartType.BAR,
|
|
78
81
|
config: ChartSchema.parse({
|
|
@@ -48,7 +48,12 @@ import { HeatmapForm } from "./forms/heatmap";
|
|
|
48
48
|
import { PieForm } from "./forms/pie";
|
|
49
49
|
import { LazyChart } from "./lazy-chart";
|
|
50
50
|
import { ChartSchema, type ChartSchemaType, getChartDefaults } from "./schemas";
|
|
51
|
-
import {
|
|
51
|
+
import {
|
|
52
|
+
createTabId,
|
|
53
|
+
getChartTabName,
|
|
54
|
+
type TabName,
|
|
55
|
+
tabsStorageAtom,
|
|
56
|
+
} from "./storage";
|
|
52
57
|
import { ChartType } from "./types";
|
|
53
58
|
|
|
54
59
|
const NEW_CHART_TYPE = "bar" as ChartType;
|
|
@@ -114,7 +119,12 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
114
119
|
const tabName = getChartTabName(0, NEW_CHART_TYPE);
|
|
115
120
|
const newTabs = new Map(tabsMap);
|
|
116
121
|
newTabs.set(cellId, [
|
|
117
|
-
{
|
|
122
|
+
{
|
|
123
|
+
id: createTabId(),
|
|
124
|
+
tabName,
|
|
125
|
+
chartType: NEW_CHART_TYPE,
|
|
126
|
+
config: getChartDefaults(),
|
|
127
|
+
},
|
|
118
128
|
]);
|
|
119
129
|
saveTabsMap(newTabs);
|
|
120
130
|
setTabCounter(1);
|
|
@@ -135,6 +145,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
135
145
|
newTabs.set(cellId, [
|
|
136
146
|
...tabs,
|
|
137
147
|
{
|
|
148
|
+
id: createTabId(),
|
|
138
149
|
tabName,
|
|
139
150
|
chartType: NEW_CHART_TYPE,
|
|
140
151
|
config: getChartDefaults(),
|
|
@@ -233,9 +244,9 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
233
244
|
>
|
|
234
245
|
Table
|
|
235
246
|
</TabsTrigger>
|
|
236
|
-
{tabs.map((tab
|
|
247
|
+
{tabs.map((tab) => (
|
|
237
248
|
<TabsTrigger
|
|
238
|
-
key={
|
|
249
|
+
key={tab.id}
|
|
239
250
|
className="text-xs"
|
|
240
251
|
value={tab.tabName}
|
|
241
252
|
onClick={() => setSelectedTab(tab.tabName)}
|
|
@@ -263,7 +274,7 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
263
274
|
<TabsContent className="mt-1 overflow-hidden" value={DEFAULT_TAB_NAME}>
|
|
264
275
|
{dataTable}
|
|
265
276
|
</TabsContent>
|
|
266
|
-
{tabs.map((tab
|
|
277
|
+
{tabs.map((tab) => {
|
|
267
278
|
const saveChart = (formValues: ChartSchemaType) => {
|
|
268
279
|
saveTabChart({
|
|
269
280
|
tabName: tab.tabName,
|
|
@@ -275,7 +286,11 @@ export const TablePanel: React.FC<TablePanelProps> = ({
|
|
|
275
286
|
saveTabChartType(tab.tabName, chartType);
|
|
276
287
|
};
|
|
277
288
|
return (
|
|
278
|
-
<TabsContent
|
|
289
|
+
<TabsContent
|
|
290
|
+
key={tab.id}
|
|
291
|
+
value={tab.tabName}
|
|
292
|
+
className="h-[400px] mt-0"
|
|
293
|
+
>
|
|
279
294
|
<ChartPanel
|
|
280
295
|
tableData={data}
|
|
281
296
|
chartConfig={tab.config}
|
|
@@ -7,13 +7,16 @@ import { Logger } from "@/utils/Logger";
|
|
|
7
7
|
import { NotebookScopedLocalStorage } from "@/utils/storage/typed";
|
|
8
8
|
import { capitalize } from "@/utils/strings";
|
|
9
9
|
import type { TypedString } from "@/utils/typed";
|
|
10
|
+
import { generateUUID } from "@/utils/uuid";
|
|
10
11
|
import { ChartSchema, type ChartSchemaType } from "./schemas";
|
|
11
12
|
import type { ChartType } from "./types";
|
|
12
13
|
|
|
13
14
|
export type TabName = TypedString<"TabName">;
|
|
15
|
+
export type TabId = TypedString<"TabId">;
|
|
14
16
|
export const KEY = "marimo:charts:v2";
|
|
15
17
|
|
|
16
18
|
interface TabStorage {
|
|
19
|
+
id: TabId;
|
|
17
20
|
tabName: TabName; // unique within cell
|
|
18
21
|
chartType: ChartType;
|
|
19
22
|
config: ChartSchemaType;
|
|
@@ -21,11 +24,15 @@ interface TabStorage {
|
|
|
21
24
|
|
|
22
25
|
type TabStorageMap = Map<CellId, TabStorage[]>;
|
|
23
26
|
|
|
24
|
-
const TabStorageSchema = z
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const TabStorageSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
id: z.string().optional(),
|
|
30
|
+
tabName: z.string().transform((name) => name as TabName),
|
|
31
|
+
chartType: z.string().transform((type) => type as ChartType),
|
|
32
|
+
config: ChartSchema,
|
|
33
|
+
})
|
|
34
|
+
// Stored tabs without an id use their name, which is unique within a cell.
|
|
35
|
+
.transform((tab) => ({ ...tab, id: (tab.id ?? tab.tabName) as TabId }));
|
|
29
36
|
const TabStorageEntriesSchema = z.array(
|
|
30
37
|
z.tuple([
|
|
31
38
|
z.string().transform((name) => name as CellId),
|
|
@@ -64,6 +71,10 @@ export const tabsStorageAtom = atomWithStorage<TabStorageMap>(
|
|
|
64
71
|
mapStorage,
|
|
65
72
|
);
|
|
66
73
|
|
|
74
|
+
export function createTabId(): TabId {
|
|
75
|
+
return generateUUID() as TabId;
|
|
76
|
+
}
|
|
77
|
+
|
|
67
78
|
/**
|
|
68
79
|
* Convenience function to get the tab name for a given tab number and chart type
|
|
69
80
|
*/
|
|
@@ -358,6 +358,7 @@ export class AnsiReducer {
|
|
|
358
358
|
|
|
359
359
|
export type StringOutputMessage = Omit<OutputMessage, "data"> & {
|
|
360
360
|
data: string;
|
|
361
|
+
id?: number;
|
|
361
362
|
};
|
|
362
363
|
|
|
363
364
|
/**
|
|
@@ -369,6 +370,7 @@ export class StatefulOutputMessage implements OutputMessage {
|
|
|
369
370
|
public readonly channel: OutputMessage["channel"];
|
|
370
371
|
public readonly timestamp: OutputMessage["timestamp"];
|
|
371
372
|
public readonly code: OutputMessage["code"];
|
|
373
|
+
public readonly id: StringOutputMessage["id"];
|
|
372
374
|
private ansiReducer = new AnsiReducer();
|
|
373
375
|
private _data: string;
|
|
374
376
|
|
|
@@ -385,6 +387,7 @@ export class StatefulOutputMessage implements OutputMessage {
|
|
|
385
387
|
message.timestamp,
|
|
386
388
|
ansiReducer,
|
|
387
389
|
message.code,
|
|
390
|
+
message.id,
|
|
388
391
|
);
|
|
389
392
|
}
|
|
390
393
|
|
|
@@ -394,11 +397,13 @@ export class StatefulOutputMessage implements OutputMessage {
|
|
|
394
397
|
timestamp: OutputMessage["timestamp"],
|
|
395
398
|
ansiReducer: AnsiReducer,
|
|
396
399
|
code: OutputMessage["code"],
|
|
400
|
+
id: StringOutputMessage["id"],
|
|
397
401
|
) {
|
|
398
402
|
this.mimetype = mimetype;
|
|
399
403
|
this.channel = channel;
|
|
400
404
|
this.timestamp = timestamp;
|
|
401
405
|
this.code = code;
|
|
406
|
+
this.id = id;
|
|
402
407
|
this.ansiReducer = ansiReducer;
|
|
403
408
|
this._data = this.ansiReducer.render();
|
|
404
409
|
}
|
|
@@ -411,6 +416,7 @@ export class StatefulOutputMessage implements OutputMessage {
|
|
|
411
416
|
this.timestamp,
|
|
412
417
|
this.ansiReducer,
|
|
413
418
|
this.code,
|
|
419
|
+
this.id,
|
|
414
420
|
);
|
|
415
421
|
}
|
|
416
422
|
|
|
@@ -16,8 +16,7 @@ import { Tooltip } from "@/components/ui/tooltip";
|
|
|
16
16
|
import type { CellId } from "@/core/cells/ids";
|
|
17
17
|
import { isInternalCellName } from "@/core/cells/names";
|
|
18
18
|
import { useExpandedConsoleOutput } from "@/core/cells/outputs";
|
|
19
|
-
import type {
|
|
20
|
-
import type { OutputMessage } from "@/core/kernel/messages";
|
|
19
|
+
import type { ConsoleOutputMessage } from "@/core/cells/types";
|
|
21
20
|
import {
|
|
22
21
|
type UseInputHistoryReturn,
|
|
23
22
|
useInputHistory,
|
|
@@ -73,7 +72,7 @@ interface Props {
|
|
|
73
72
|
cellId: CellId;
|
|
74
73
|
cellName: string;
|
|
75
74
|
className?: string;
|
|
76
|
-
consoleOutputs:
|
|
75
|
+
consoleOutputs: ConsoleOutputMessage[];
|
|
77
76
|
stale: boolean;
|
|
78
77
|
interrupted: boolean;
|
|
79
78
|
debuggerActive: boolean;
|
|
@@ -241,19 +240,24 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
241
240
|
return null;
|
|
242
241
|
}
|
|
243
242
|
|
|
243
|
+
const originalIdx = consoleOutputs.length - idx - 1;
|
|
244
|
+
// Outputs render in reverse, so the reversed index shifts on every
|
|
245
|
+
// new line. The assigned id survives collapse and truncation. The
|
|
246
|
+
// original position is the fallback for outputs without one.
|
|
247
|
+
const key = output.id ?? `position-${originalIdx}`;
|
|
248
|
+
|
|
244
249
|
if (output.channel === "stdin") {
|
|
245
250
|
invariant(
|
|
246
251
|
typeof output.data === "string",
|
|
247
252
|
"Expected data to be a string",
|
|
248
253
|
);
|
|
249
254
|
|
|
250
|
-
const originalIdx = consoleOutputs.length - idx - 1;
|
|
251
255
|
const isPassword = output.mimetype === "text/password";
|
|
252
256
|
|
|
253
257
|
if (output.response == null && lastStdInputIdx === idx) {
|
|
254
258
|
return (
|
|
255
259
|
<StdInput
|
|
256
|
-
key={
|
|
260
|
+
key={key}
|
|
257
261
|
output={output.data}
|
|
258
262
|
isPdb={isPdb}
|
|
259
263
|
isPassword={isPassword}
|
|
@@ -268,7 +272,7 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
268
272
|
|
|
269
273
|
return (
|
|
270
274
|
<StdInputWithResponse
|
|
271
|
-
key={
|
|
275
|
+
key={key}
|
|
272
276
|
output={output.data}
|
|
273
277
|
response={output.response}
|
|
274
278
|
isPassword={isPassword}
|
|
@@ -278,7 +282,7 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
278
282
|
}
|
|
279
283
|
|
|
280
284
|
return (
|
|
281
|
-
<React.Fragment key={
|
|
285
|
+
<React.Fragment key={key}>
|
|
282
286
|
<OutputRenderer
|
|
283
287
|
cellId={cellId}
|
|
284
288
|
onRefactorWithAI={onRefactorWithAI}
|
|
@@ -172,12 +172,12 @@ export const PackageAlert: React.FC = () => {
|
|
|
172
172
|
<p>The following packages were not found:</p>
|
|
173
173
|
<table className="list-disc ml-2 mt-1">
|
|
174
174
|
<tbody>
|
|
175
|
-
{packageAlert.packages.map((pkg
|
|
175
|
+
{packageAlert.packages.map((pkg) => {
|
|
176
176
|
const parsed = parsePackageSpecifier(pkg);
|
|
177
177
|
const currentExtras = selectedExtras[pkg] || parsed.extras;
|
|
178
178
|
|
|
179
179
|
return (
|
|
180
|
-
<tr className="font-mono text-sm" key={
|
|
180
|
+
<tr className="font-mono text-sm" key={pkg}>
|
|
181
181
|
<td className="pr-2 py-1 align-middle">
|
|
182
182
|
<BoxIcon size="1rem" />
|
|
183
183
|
</td>
|
|
@@ -296,7 +296,7 @@ export const PackageAlert: React.FC = () => {
|
|
|
296
296
|
</>
|
|
297
297
|
)}
|
|
298
298
|
<ul className="list-disc ml-2 mt-1">
|
|
299
|
-
{Object.entries(packageAlert.packages).map(([pkg, st]
|
|
299
|
+
{Object.entries(packageAlert.packages).map(([pkg, st]) => (
|
|
300
300
|
<li
|
|
301
301
|
className={cn(
|
|
302
302
|
"flex items-center gap-1 font-mono text-sm",
|
|
@@ -307,7 +307,7 @@ export const PackageAlert: React.FC = () => {
|
|
|
307
307
|
status === "failed" &&
|
|
308
308
|
"text-muted-foreground",
|
|
309
309
|
)}
|
|
310
|
-
key={
|
|
310
|
+
key={pkg}
|
|
311
311
|
>
|
|
312
312
|
<ProgressIcon status={st} />
|
|
313
313
|
{pkg}
|
|
@@ -135,9 +135,9 @@ export const ScratchPad: React.FC = () => {
|
|
|
135
135
|
return (
|
|
136
136
|
<div className="absolute inset-0 z-100 bg-background p-3 border-none overflow-auto">
|
|
137
137
|
<div className="overflow-auto flex flex-col gap-3">
|
|
138
|
-
{history.map((item
|
|
138
|
+
{history.map((item) => (
|
|
139
139
|
<div
|
|
140
|
-
key={
|
|
140
|
+
key={item}
|
|
141
141
|
className="border rounded-md hover:shadow-sm cursor-pointer hover:border-input overflow-hidden"
|
|
142
142
|
onClick={() => handleSelectHistoryItem(item)}
|
|
143
143
|
>
|
|
@@ -404,13 +404,15 @@ const SubslideView = ({
|
|
|
404
404
|
if (block.isFragment) {
|
|
405
405
|
const cumulative = cumulativeByBlock.get(i);
|
|
406
406
|
return (
|
|
407
|
-
<Fragment key={
|
|
407
|
+
<Fragment key={block.cells[0].id} as="div">
|
|
408
408
|
{rendered}
|
|
409
409
|
{cumulative && <NotesAside text={cumulative} />}
|
|
410
410
|
</Fragment>
|
|
411
411
|
);
|
|
412
412
|
}
|
|
413
|
-
return
|
|
413
|
+
return (
|
|
414
|
+
<ReactFragment key={block.cells[0].id}>{rendered}</ReactFragment>
|
|
415
|
+
);
|
|
414
416
|
})}
|
|
415
417
|
</div>
|
|
416
418
|
</SlideScrollContainer>
|
|
@@ -139,6 +139,7 @@ exports[`cell reducer > can initialize stdin > second stdin requested 1`] = `
|
|
|
139
139
|
{
|
|
140
140
|
"channel": "stdin",
|
|
141
141
|
"data": "what is your name?",
|
|
142
|
+
"id": 2,
|
|
142
143
|
"mimetype": "text/plain",
|
|
143
144
|
"response": "Marimo!",
|
|
144
145
|
"timestamp": 2,
|
|
@@ -146,6 +147,7 @@ exports[`cell reducer > can initialize stdin > second stdin requested 1`] = `
|
|
|
146
147
|
{
|
|
147
148
|
"channel": "stdin",
|
|
148
149
|
"data": "how old are you?",
|
|
150
|
+
"id": 3,
|
|
149
151
|
"mimetype": "text/plain",
|
|
150
152
|
"timestamp": 3,
|
|
151
153
|
},
|
|
@@ -189,6 +191,7 @@ exports[`cell reducer > can initialize stdin > stdin answered 1`] = `
|
|
|
189
191
|
{
|
|
190
192
|
"channel": "stdin",
|
|
191
193
|
"data": "what is your name?",
|
|
194
|
+
"id": 2,
|
|
192
195
|
"mimetype": "text/plain",
|
|
193
196
|
"response": "Marimo!",
|
|
194
197
|
"timestamp": 2,
|
|
@@ -233,6 +236,7 @@ exports[`cell reducer > can initialize stdin > stdin requested 1`] = `
|
|
|
233
236
|
{
|
|
234
237
|
"channel": "stdin",
|
|
235
238
|
"data": "what is your name?",
|
|
239
|
+
"id": 2,
|
|
236
240
|
"mimetype": "text/plain",
|
|
237
241
|
"timestamp": 2,
|
|
238
242
|
},
|
|
@@ -219,6 +219,45 @@ describe("transitionCell serialization", () => {
|
|
|
219
219
|
});
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
+
describe("transitionCell console output ids", () => {
|
|
223
|
+
const output = (
|
|
224
|
+
data: string,
|
|
225
|
+
channel: OutputMessage["channel"] = "stdout",
|
|
226
|
+
): OutputMessage => ({
|
|
227
|
+
channel,
|
|
228
|
+
mimetype: "text/plain",
|
|
229
|
+
data,
|
|
230
|
+
timestamp: 0,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("assigns increasing ids to appended outputs", () => {
|
|
234
|
+
let cell = createCellRuntimeState({ status: "running" });
|
|
235
|
+
cell = transitionCell(cell, { console: output("a") } as CellMessage);
|
|
236
|
+
cell = transitionCell(cell, {
|
|
237
|
+
console: output("b", "stderr"),
|
|
238
|
+
} as CellMessage);
|
|
239
|
+
expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("continues from the surviving maximum after a collapse", () => {
|
|
243
|
+
let cell = createCellRuntimeState({ status: "running" });
|
|
244
|
+
cell = transitionCell(cell, { console: output("a") } as CellMessage);
|
|
245
|
+
cell = transitionCell(cell, { console: output("b") } as CellMessage);
|
|
246
|
+
expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1]);
|
|
247
|
+
cell = transitionCell(cell, {
|
|
248
|
+
console: output("c", "stderr"),
|
|
249
|
+
} as CellMessage);
|
|
250
|
+
expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("assigns ids when the kernel replaces the whole console", () => {
|
|
254
|
+
const cell = transitionCell(createCellRuntimeState({ status: "running" }), {
|
|
255
|
+
console: [output("a"), output("b", "stderr")],
|
|
256
|
+
} as CellMessage);
|
|
257
|
+
expect(cell.consoleOutputs.map((o) => o.id)).toEqual([1, 2]);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
222
261
|
describe("transitionCell stdin resolution", () => {
|
|
223
262
|
describe.each([
|
|
224
263
|
{
|