@marimo-team/islands 0.25.3-dev19 → 0.25.3-dev191
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/{ConnectedDataExplorerComponent-CNMliVzw.js → ConnectedDataExplorerComponent-BBbOElk3.js} +21 -19
- package/dist/{ErrorBoundary-CBHB755J.js → ErrorBoundary--X0z83Yx.js} +19 -19
- package/dist/{abnfDiagram-VCTEODGH-D-Ez91gV.js → abnfDiagram-VCTEODGH-DhMT6Uhd.js} +2 -2
- package/dist/any-language-editor-BVFHDDQ3.js +75 -0
- package/dist/{architectureDiagram-5GKGNRK7-CTpcNtO8.js → architectureDiagram-5GKGNRK7-BVbEiJLq.js} +1 -1
- package/dist/{arrays-CN1djC4k.js → arrays-R6JsImiT.js} +8 -0
- package/dist/assets/__vite-browser-external-C8gQho07.js +1 -0
- package/dist/assets/worker-C6e9ERyd.js +113 -0
- package/dist/{button-CvjkwdSk.js → button-BQRdqQi1.js} +199 -192
- package/dist/{capabilities-CQ5IjhzL.js → capabilities-CI4xUPsp.js} +2 -2
- package/dist/{chat-ui-DaHynk8g.js → chat-ui-BguxTQEL.js} +541 -540
- package/dist/{check-EDwSwP89.js → check-C9Mp9eCK.js} +1 -1
- package/dist/{chunk-IMKFNOWR-DGxi-zeo.js → chunk-IMKFNOWR-By5hSbJJ.js} +1 -1
- package/dist/{chunk-SHT3W25Y-CV9J3rAB.js → chunk-SHT3W25Y-DFrEYG54.js} +1 -1
- package/dist/{chunk-SVP7TREG-BL-9Fqgg.js → chunk-SVP7TREG-DFXGc9ew.js} +1 -1
- package/dist/{chunk-TICWLB2K-Cu_XMjDM.js → chunk-TICWLB2K-DZdNIpoZ.js} +1 -1
- package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
- package/dist/{classDiagram-ZZMXUADV-BXXV13Hq.js → classDiagram-ZZMXUADV-Cgj_eEQA.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-B7FXJ1Cp.js → classDiagram-v2-VYDZK3BY-DLAUrSqj.js} +2 -2
- package/dist/{code-visibility-CEXXuuOE.js → code-visibility-uDyLo9_i.js} +25 -25
- package/dist/{common-OLE92qsR.js → common-DWKY45Md.js} +6994 -6819
- package/dist/{copy-icon-Ft7t9bqz.js → copy-icon-De584pZ4.js} +3 -3
- package/dist/{cynefinDiagram-5FMLGOSQ-CH96rwba.js → cynefinDiagram-5FMLGOSQ-Cikf9AKa.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-BD3PmpFY.js → dagre-GXQ25YYZ-C5KEi5_l.js} +1 -1
- package/dist/{data-grid-overlay-editor-CpHX98zN.js → data-grid-overlay-editor-CRnYWD1L.js} +5 -5
- package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-BsSJJldB.js → diagram-S7CK7UJ4-BaoBTQjR.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-muQtNZc4.js → diagram-UQ7AKVKN-DDufBsUA.js} +1 -1
- package/dist/{diagram-VX7I27RA-CdhuZAqR.js → diagram-VX7I27RA-CY6RALJ8.js} +1 -1
- package/dist/{diagram-Z3DM3KII-BD8mXjOj.js → diagram-Z3DM3KII-Bc-LHsD6.js} +1 -1
- package/dist/{dialog-CEBFZNyc.js → dialog-DVRfQuhD.js} +25 -25
- package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
- package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
- package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
- package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
- package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
- package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
- package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
- package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
- package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
- package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
- package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
- package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
- package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
- package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
- package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
- package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
- package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
- package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
- package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
- package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
- package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
- package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
- package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
- package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
- package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
- package/dist/{dropdown-menu-CP_qCYHC.js → dropdown-menu-drDjxJyV.js} +1481 -1433
- package/dist/{ebnfDiagram-PWID7BFC-BIN1sweE.js → ebnfDiagram-PWID7BFC-Cz0J-tcC.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-Ctp5cfoN.js → erDiagram-RLTQ6QDP-DTXTDgFu.js} +1 -1
- package/dist/{error-banner-D-WCIiMt.js → error-banner-DxJ3s8YO.js} +86 -86
- package/dist/{error-entries-Bv6bZPF3.js → error-entries-CZ1NQ6Kv.js} +4771 -4702
- package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
- package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
- package/dist/{feedback-button-_f7fx7zj.js → feedback-button-CDf1yRm_.js} +37 -37
- package/dist/{flowDiagram-HODETNUW-3EfLrlFb.js → flowDiagram-HODETNUW-RbwWf2zc.js} +2 -2
- package/dist/{formats-27CW_UP4.js → formats-DbXnijtH.js} +3 -3
- package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
- package/dist/{glide-data-editor-Cmu4vWKD.js → glide-data-editor-CvRiA49N.js} +370 -368
- package/dist/{glide-utils-DJyqh0EM.js → glide-utils-D98laidb.js} +16 -16
- package/dist/{globals-1Hfhz6Dx.js → globals-BR4CmGOS.js} +3 -3
- package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
- package/dist/{html-to-image-Bf8QMGi4.js → html-to-image-D_4_hQ8U.js} +668 -622
- package/dist/{infoDiagram-27XIBGKW-DipQoHxl.js → infoDiagram-27XIBGKW-DlmzZjmI.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-DgFMjSGz.js → ishikawaDiagram-5VMMS53U-EN3TYP_q.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-w1ACVjgl.js → kanban-definition-UXKFOSKX-CK_-Ru7Q.js} +1 -1
- package/dist/{label-BDKF3Afc.js → label-Qvw1E97W.js} +3 -3
- package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
- package/dist/{loader-BQOfjTIJ.js → loader-DOVB0Syl.js} +12 -12
- package/dist/main.js +9822 -7824
- package/dist/{mermaid-CHo49Yv-.js → mermaid-DU9ZRmkG.js} +38 -38
- package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
- package/dist/{mindmap-definition-YA3MSWOX-CrT0KSfX.js → mindmap-definition-YA3MSWOX-C-hqgUvF.js} +1 -1
- package/dist/{number-overlay-editor-BQN3-Nye.js → number-overlay-editor-DiYGbxNa.js} +3 -3
- package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
- package/dist/{once-BtE-wKRL.js → once-eG8Vmvjd.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-BqvywNJA.js → pegDiagram-XKGWAZYB-BiMejYPB.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-BfxJ_XCc.js → pieDiagram-E7YTZNPT-B1zCZ1eq.js} +1 -1
- package/dist/precisionRound-DhAzeRcm.js +49 -0
- package/dist/{process-output-BZg56CCb.js → process-output-DxSCHBWp.js} +4 -4
- package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
- package/dist/{railroadDiagram-O6MQD6OU-8vFLVTPu.js → railroadDiagram-O6MQD6OU-BLcfaASl.js} +2 -2
- package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
- package/dist/{requirementDiagram-BXWQKSXE-a_MxGvxe.js → requirementDiagram-BXWQKSXE-DtBOf52-.js} +1 -1
- package/dist/{reveal-component-nqUW7zgn.js → reveal-component-D3DsXPIm.js} +734 -711
- package/dist/{select-BButFi-d.js → select-2KOiReNY.js} +536 -457
- package/dist/{sequenceDiagram-WJ2MYXX4-CXFMnxGh.js → sequenceDiagram-WJ2MYXX4-DIwF19_n.js} +1 -1
- package/dist/{spec-BwarBpUJ.js → spec-DZDnnlgT.js} +41 -11
- package/dist/{stateDiagram-D77RDMKH-DQeA_CwI.js → stateDiagram-D77RDMKH-sWk1AdYL.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-BxxQucm1.js → stateDiagram-v2-MP3YSRHH-CiNo-OI7.js} +2 -2
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-Do6L-cYg.js → swimlanes-42K2YHIH-Bj3hiOY5.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-DUzPvSVU.js → swimlanesDiagram-VR7AAH4N-BzEo2r_N.js} +2 -2
- package/dist/{swiper-component-DKntyn8p.js → swiper-component-BkCm-kLg.js} +2 -2
- package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
- package/dist/{timeline-definition-24CTP7MA-D3c46WM5.js → timeline-definition-24CTP7MA-CrPQk42H.js} +1 -1
- package/dist/{toDate-UtiwmnH2.js → toDate-Cu2pIZcC.js} +37 -36
- package/dist/{toast-B9UMEi8u.js → toast-B5t9o6s_.js} +219 -201
- package/dist/{tooltip-BO1REbqs.js → tooltip-s4zZxwKe.js} +325 -301
- package/dist/{use-restore-focus-BEM7sFWl.js → use-restore-focus-BgDTd2tc.js} +1482 -1433
- package/dist/{useAsyncData-Deh5kszT.js → useAsyncData-DEhLdRIu.js} +15 -14
- package/dist/{useDateFormatter-D8XruNGG.js → useDateFormatter-D3Tkfzej.js} +2 -2
- package/dist/{useDeepCompareMemoize-DXwzRINI.js → useDeepCompareMemoize-RjZGVhBV.js} +1 -1
- package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-CSdWn6NP.js} +1 -1
- package/dist/{useLifecycle-j7D9uD1o.js → useLifecycle-DtcB2s1z.js} +28 -25
- package/dist/{useTheme-CRnjkku0.js → useTheme-CoEtr4mK.js} +301 -297
- package/dist/{vega-component-BeF9dfyO.js → vega-component-BhjTrP9-.js} +148 -148
- package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container--LYZqguO.js} +2 -2
- package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-B9Pz0EGP.js} +298 -507
- package/dist/{vennDiagram-4TSXK5OY-BSZD8JcZ.js → vennDiagram-4TSXK5OY-BaYMoIpj.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-48cUWkfA.js → wardleyDiagram-VM6X3IG4-DjHeuj8p.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-CswYgYeu.js → xychartDiagram-S5SC5T6Z-Bc_hcuXS.js} +2 -2
- package/package.json +16 -16
- package/src/__mocks__/document.tsx +54 -0
- package/src/__mocks__/notebook.ts +2 -1
- package/src/__mocks__/requests.ts +0 -3
- package/src/__tests__/module-entry.test.ts +44 -0
- package/src/__tests__/mount.test.ts +1 -21
- package/src/__tests__/{host-imports.test.ts → replica-imports.test.ts} +12 -11
- package/src/components/ai/__tests__/ai-model-dropdown.test.tsx +63 -0
- package/src/components/ai/ai-model-dropdown.tsx +11 -6
- package/src/components/app-config/ai-config.tsx +7 -2
- package/src/components/app-config/user-config-form.tsx +35 -0
- package/src/components/chat/__tests__/message-queue.test.tsx +17 -0
- package/src/components/chat/__tests__/notebook-access-selector.test.tsx +64 -0
- package/src/components/chat/acp/__tests__/session-tabs.test.tsx +43 -0
- package/src/components/chat/acp/__tests__/state.test.ts +2 -2
- package/src/components/chat/acp/blocks.tsx +3 -2
- package/src/components/chat/acp/session-tabs.tsx +8 -3
- package/src/components/chat/chat-components.tsx +2 -0
- package/src/components/chat/chat-panel.tsx +20 -101
- package/src/components/chat/chat-utils.ts +4 -8
- package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
- package/src/components/chat/notebook-access-selector.tsx +100 -0
- package/src/components/data-table/TableBottomBar.tsx +4 -1
- package/src/components/data-table/TableTopBar.tsx +2 -0
- package/src/components/data-table/__tests__/chart-spec-model.test.ts +195 -195
- package/src/components/data-table/__tests__/column-explorer.test.tsx +27 -1
- package/src/components/data-table/__tests__/columns.test.tsx +105 -0
- package/src/components/data-table/__tests__/context-menu-interaction.test.tsx +130 -0
- package/src/components/data-table/__tests__/data-table.test.tsx +1 -0
- package/src/components/data-table/__tests__/date-popover.test.tsx +72 -0
- package/src/components/data-table/__tests__/export-actions.test.tsx +105 -0
- package/src/components/data-table/__tests__/keyboard-selection.test.tsx +188 -0
- package/src/components/data-table/__tests__/pagination.test.tsx +28 -1
- package/src/components/data-table/__tests__/search-highlight.test.tsx +109 -0
- package/src/components/data-table/__tests__/url-detector.test.tsx +74 -0
- package/src/components/data-table/cell-selection/feature.ts +2 -2
- package/src/components/data-table/cell-selection/types.ts +2 -2
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +74 -1
- package/src/components/data-table/charts/__tests__/spec-snapshot.test.ts +20 -20
- package/src/components/data-table/charts/__tests__/spec.test.ts +78 -52
- package/src/components/data-table/charts/__tests__/storage.test.ts +4 -1
- package/src/components/data-table/charts/chart-spec/spec.ts +68 -43
- package/src/components/data-table/charts/charts.tsx +40 -30
- package/src/components/data-table/charts/storage.ts +16 -5
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-summary/chart-spec-model.tsx +23 -16
- package/src/components/data-table/column-summary/column-summary.tsx +2 -4
- package/src/components/data-table/column-visibility-dropdown.tsx +8 -13
- package/src/components/data-table/columns.tsx +45 -46
- package/src/components/data-table/context-menu.tsx +36 -20
- package/src/components/data-table/data-table.tsx +17 -1
- package/src/components/data-table/date-popover.tsx +6 -4
- package/src/components/data-table/export-actions.tsx +76 -48
- package/src/components/data-table/pagination.tsx +44 -33
- package/src/components/data-table/range-focus/atoms.ts +4 -6
- package/src/components/data-table/range-focus/use-cell-range-selection.ts +65 -38
- package/src/components/data-table/range-focus/use-scroll-into-view.ts +21 -2
- package/src/components/data-table/renderers.tsx +16 -7
- package/src/components/data-table/row-viewer-panel/__tests__/row-viewer.test.tsx +24 -1
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +4 -4
- package/src/components/data-table/search-highlight.tsx +79 -0
- package/src/components/data-table/types.ts +1 -0
- package/src/components/data-table/url-detector.tsx +49 -9
- package/src/components/datasources/__tests__/column-actions.test.tsx +97 -0
- package/src/components/datasources/__tests__/column-preview.test.tsx +96 -5
- package/src/components/datasources/__tests__/datasources-interactions.test.tsx +181 -0
- package/src/components/datasources/__tests__/table-list.test.tsx +118 -0
- package/src/components/datasources/__tests__/utils.test.ts +57 -6
- package/src/components/datasources/column-preview.tsx +17 -12
- package/src/components/datasources/datasources.tsx +55 -42
- package/src/components/datasources/utils.ts +32 -23
- package/src/components/debugger/debugger-code.tsx +5 -0
- package/src/components/dependency-graph/dependency-graph-tree.tsx +8 -8
- package/src/components/dependency-graph/elements.ts +24 -21
- package/src/components/dependency-graph/minimap-content.tsx +2 -6
- package/src/components/dependency-graph/panels.tsx +4 -2
- package/src/components/dependency-graph/utils/__tests__/layout.test.ts +18 -11
- package/src/components/editor/SortableCell.tsx +1 -3
- package/src/components/editor/__tests__/Output.test.tsx +50 -32
- package/src/{core/attachments/__tests__/toast.test.tsx → components/editor/__tests__/agent-toast.test.tsx} +1 -1
- package/src/components/editor/__tests__/data-attributes.test.tsx +28 -13
- package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
- package/src/components/editor/__tests__/output-persistence.test.tsx +6 -1
- package/src/components/editor/__tests__/package-alert.test.tsx +22 -1
- package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +34 -8
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +2 -6
- package/src/components/editor/actions/name-cell-input.tsx +4 -3
- package/src/components/editor/actions/pair-with-agent-commands.ts +2 -2
- package/src/components/editor/actions/pair-with-agent-modal.tsx +19 -16
- package/src/components/editor/actions/useCellActionButton.tsx +20 -26
- package/src/components/editor/actions/useNotebookActions.tsx +14 -19
- package/src/components/editor/actions/useRestartKernel.tsx +1 -1
- package/src/components/editor/actions/useSetCodeVisibility.ts +10 -11
- package/src/components/editor/actions/useSetOutputsExpanded.ts +13 -18
- package/src/components/editor/ai/add-cell-with-ai.tsx +3 -3
- package/src/components/editor/ai/ai-completion-editor.tsx +1 -0
- package/src/components/editor/alerts/__tests__/connection-notice.test.tsx +1 -1
- package/src/components/editor/alerts/connection-notice.tsx +1 -1
- package/src/components/editor/alerts/startup-logs-alert.tsx +1 -0
- package/src/components/editor/app-container.tsx +1 -1
- package/src/components/editor/boundary/__tests__/ErrorBoundary.test.tsx +1 -1
- package/src/components/editor/cell/CreateCellButton.tsx +15 -21
- package/src/components/editor/cell/DeleteButton.tsx +3 -2
- package/src/components/editor/cell/RunButton.tsx +2 -2
- package/src/components/editor/cell/StagedAICell.tsx +10 -2
- package/src/components/editor/cell/StopButton.tsx +2 -2
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
- package/src/components/editor/cell/__tests__/useShouldShowInterrupt.test.ts +39 -0
- package/src/components/editor/cell/cell-actions.tsx +12 -1
- package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
- package/src/components/editor/cell/code/cell-editor.tsx +22 -36
- package/src/components/editor/cell/code/language-toggle.tsx +8 -7
- package/src/components/editor/cell/collapse.tsx +5 -3
- package/src/components/editor/cell/useAddCell.ts +4 -8
- package/src/components/editor/cell/useDeleteCell.tsx +10 -36
- package/src/components/editor/cell/useRunCells.ts +2 -5
- package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
- package/src/components/editor/cell/useSplitCell.tsx +2 -1
- package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
- package/src/components/editor/chrome/components/feedback-button.tsx +1 -1
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +31 -2
- package/src/components/editor/chrome/panels/__tests__/runtime-details.test.tsx +1 -1
- package/src/components/editor/chrome/panels/__tests__/sandbox-recovery.test.tsx +1 -1
- package/src/components/editor/chrome/panels/cache-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
- package/src/components/editor/chrome/panels/outline/__tests__/outline-keyboard.test.tsx +84 -0
- package/src/components/editor/chrome/panels/outline/floating-outline.tsx +39 -14
- package/src/components/editor/chrome/panels/outline/useActiveOutline.tsx +3 -2
- package/src/components/editor/chrome/panels/packages-panel.tsx +4 -7
- package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +9 -18
- package/src/components/editor/chrome/wrapper/__tests__/document-sync-status.test.tsx +92 -0
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +61 -2
- package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +4 -4
- package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/document-sync-status.tsx +54 -0
- package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +1 -1
- package/src/components/editor/chrome/wrapper/footer-items/runtime-settings.tsx +1 -7
- package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +12 -2
- package/src/components/editor/chrome/wrapper/storage.ts +1 -1
- package/src/components/editor/columns/sortable-column.tsx +1 -1
- package/src/components/editor/connections/components.tsx +5 -10
- package/src/components/editor/controls/Controls.tsx +3 -3
- package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
- package/src/components/editor/controls/__tests__/keyboard-shortcuts.test.tsx +61 -0
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +10 -4
- package/src/components/editor/controls/command-palette.tsx +22 -10
- package/src/components/editor/controls/keyboard-shortcuts.tsx +14 -5
- package/src/components/editor/documentation.css +34 -11
- package/src/components/editor/dynamic-favicon.tsx +21 -40
- package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +9 -23
- package/src/components/editor/errors/auto-fix.tsx +4 -8
- package/src/components/editor/errors/send-error-report-button.tsx +3 -6
- package/src/components/editor/file-tree/__tests__/file-explorer-interactions.test.tsx +6 -0
- package/src/components/editor/file-tree/__tests__/file-explorer-navigation.test.tsx +47 -0
- package/src/components/editor/file-tree/__tests__/use-file-search.test.tsx +91 -0
- package/src/components/editor/file-tree/file-explorer.tsx +48 -15
- package/src/components/editor/file-tree/file-name-input.tsx +1 -0
- package/src/components/editor/file-tree/file-viewer.tsx +4 -2
- package/src/components/editor/file-tree/use-file-search.ts +35 -21
- package/src/components/editor/header/__tests__/status.test.tsx +5 -3
- package/src/components/editor/header/app-header.tsx +1 -1
- package/src/components/editor/header/status.tsx +40 -20
- package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
- package/src/components/editor/links/cell-link.tsx +16 -6
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
- package/src/components/editor/navigation/__tests__/navigation.test.ts +73 -64
- package/src/components/editor/navigation/clipboard.ts +12 -11
- package/src/components/editor/navigation/focus-utils.ts +4 -4
- package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +11 -20
- package/src/components/editor/navigation/navigation.ts +20 -28
- package/src/components/editor/notebook-banner.tsx +1 -0
- package/src/components/editor/notebook-cell.tsx +19 -13
- package/src/components/editor/output/MarimoErrorOutput.tsx +2 -1
- package/src/components/editor/output/MarimoTracebackOutput.tsx +19 -17
- package/src/components/editor/output/Outputs.css +8 -0
- package/src/components/editor/output/__tests__/traceback.test.tsx +27 -1
- package/src/components/editor/output/ansi-reduce.ts +33 -20
- package/src/components/editor/output/console/ConsoleOutput.tsx +19 -25
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
- package/src/components/editor/package-alert.tsx +14 -7
- package/src/components/editor/renderers/cell-array.tsx +10 -17
- package/src/components/editor/renderers/grid-layout/grid-layout.tsx +12 -6
- package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
- package/src/components/home/components.tsx +17 -31
- package/src/components/icons/__tests__/large-spinner.test.tsx +39 -0
- package/src/components/icons/large-spinner.tsx +3 -14
- package/src/components/icons/spinner.tsx +1 -1
- package/src/components/markdown/markdown-renderer.tsx +4 -8
- package/src/components/mcp/mcp-status-indicator.tsx +1 -1
- package/src/components/pages/__tests__/home-page.test.tsx +116 -0
- package/src/components/pages/edit-page.tsx +32 -17
- package/src/components/pages/home-page.tsx +164 -91
- package/src/components/scratchpad/scratchpad.test.tsx +97 -0
- package/src/components/scratchpad/scratchpad.tsx +20 -10
- package/src/components/slides/__tests__/minimap-actions.test.tsx +9 -25
- package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
- package/src/components/slides/minimap.tsx +7 -3
- package/src/components/slides/reveal-component.tsx +57 -25
- package/src/components/slides/reveal-slides.css +5 -4
- package/src/components/slides/slide-cell-view.tsx +4 -4
- package/src/components/slides/slide-form.tsx +1 -0
- package/src/components/slides/slide-scroll-hint.tsx +3 -1
- package/src/components/sort/SortableCellsProvider.tsx +2 -1
- package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
- package/src/components/tracing/tracing.tsx +45 -41
- package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
- package/src/components/ui/__tests__/range-slider.test.tsx +165 -0
- package/src/components/ui/alert-dialog.tsx +1 -1
- package/src/components/ui/draggable-popover.tsx +24 -2
- package/src/components/ui/range-slider.tsx +22 -9
- package/src/core/ai/__tests__/staged-cells.test.ts +26 -25
- package/src/core/ai/context/providers/datasource.ts +6 -2
- package/src/core/ai/staged-cells.ts +15 -18
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +6 -22
- package/src/core/ai/tools/__tests__/registry.test.ts +17 -0
- package/src/core/ai/tools/base.ts +18 -15
- package/src/core/ai/tools/edit-notebook-tool.ts +75 -71
- package/src/core/ai/tools/registry.ts +13 -10
- package/src/core/ai/tools/sample-tool.ts +6 -7
- package/src/core/cells/__tests__/__snapshots__/cells.test.ts.snap +4 -0
- package/src/core/cells/__tests__/actions.test.ts +474 -34
- package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
- package/src/core/cells/__tests__/cell.test.ts +39 -0
- package/src/core/cells/__tests__/cells.test.ts +260 -1165
- package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
- package/src/core/cells/__tests__/document.test.ts +414 -0
- package/src/core/cells/__tests__/flush-document.test.ts +40 -0
- package/src/core/cells/__tests__/notebook-outline.test.ts +114 -0
- package/src/core/cells/__tests__/outputs.test.tsx +71 -53
- package/src/core/cells/__tests__/session.test.ts +117 -36
- package/src/core/cells/__tests__/with-document-save.test.ts +67 -0
- package/src/core/cells/actions.ts +391 -3
- package/src/core/cells/add-missing-import.ts +46 -42
- package/src/core/cells/cell.ts +14 -3
- package/src/core/cells/cells.ts +99 -599
- package/src/core/cells/columns.ts +38 -0
- package/src/core/cells/document.ts +392 -0
- package/src/core/cells/outputs.ts +12 -28
- package/src/core/cells/pending-delete-service.ts +2 -6
- package/src/core/cells/session.ts +1 -1
- package/src/core/cells/types.ts +22 -1
- package/src/core/codemirror/__tests__/setup.test.ts +29 -29
- package/src/core/codemirror/ai/__tests__/resources.test.ts +117 -0
- package/src/core/codemirror/ai/resources.ts +1 -1
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +42 -1
- package/src/core/codemirror/cells/extensions.ts +27 -9
- package/src/core/codemirror/cells/state.ts +1 -1
- package/src/core/codemirror/format.ts +6 -5
- package/src/core/codemirror/keymaps/vim.ts +4 -8
- package/src/core/codemirror/language/__tests__/sql.test.ts +22 -20
- package/src/core/codemirror/language/__tests__/utils.test.ts +187 -15
- package/src/core/codemirror/language/cell-code.ts +114 -0
- package/src/core/codemirror/language/extension.ts +52 -35
- package/src/core/codemirror/language/languages/markdown.ts +8 -6
- package/src/core/codemirror/language/languages/python.ts +16 -10
- package/src/core/codemirror/language/languages/sql/sql.ts +16 -24
- package/src/core/codemirror/language/panel/panel.tsx +1 -0
- package/src/core/codemirror/language/types.ts +7 -7
- package/src/core/codemirror/language/utils.ts +9 -39
- package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
- package/src/core/codemirror/readonly/extension.ts +2 -2
- package/src/core/codemirror/rtc/extension.ts +24 -13
- package/src/core/codemirror/rtc/loro/awareness.ts +34 -19
- package/src/core/codemirror/rtc/loro/sync.ts +1 -0
- package/src/core/codemirror/utils.ts +1 -0
- package/src/core/config/__tests__/config-schema.test.ts +12 -5
- package/src/core/config/config-schema.ts +7 -1
- package/src/core/datasets/__tests__/data-source-discovery.test.ts +5 -5
- package/src/core/datasets/data-source-discovery.ts +4 -6
- package/src/core/edit-app.tsx +19 -23
- package/src/core/errors/error-entries.ts +3 -0
- package/src/core/export/hooks.ts +1 -1
- package/src/core/export/layout.ts +2 -2
- package/src/core/hotkeys/actions.ts +2 -4
- package/src/core/islands/__tests__/bootstrap.test.ts +73 -43
- package/src/core/islands/__tests__/bridge.test.ts +72 -25
- package/src/core/islands/bootstrap.ts +46 -53
- package/src/core/islands/bridge.ts +74 -23
- package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
- package/src/core/islands/worker/__tests__/controller.test.ts +62 -4
- package/src/core/islands/worker/controller.ts +4 -10
- package/src/core/islands/worker/worker.tsx +33 -33
- package/src/core/kernel/__tests__/RuntimeState.test.ts +1 -1
- package/src/core/kernel/__tests__/handlers.test.ts +7 -153
- package/src/core/kernel/handlers.ts +18 -59
- package/src/core/network/__tests__/connection.test.ts +1 -1
- package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
- package/src/core/network/connection-notice.ts +1 -1
- package/src/core/network/connection.ts +1 -1
- package/src/core/network/requests-lazy.ts +1 -4
- package/src/core/network/requests-network.ts +0 -25
- package/src/core/network/requests-static.ts +0 -3
- package/src/core/network/requests-toasting.tsx +0 -3
- package/src/core/network/types.ts +0 -12
- package/src/core/network/useConnectionNotice.ts +8 -2
- package/src/core/notebook/attachments.ts +38 -0
- package/src/core/notebook/document/__tests__/codemirror.test.ts +552 -0
- package/src/core/notebook/document/__tests__/draft.test.ts +363 -0
- package/src/core/notebook/document/__tests__/fixtures.ts +92 -0
- package/src/core/notebook/document/__tests__/hold.test.ts +88 -0
- package/src/core/notebook/document/__tests__/hooks.test.tsx +391 -0
- package/src/core/notebook/document/__tests__/lifecycle-scenarios.test.ts +61 -0
- package/src/core/notebook/document/__tests__/model.test.ts +247 -0
- package/src/core/notebook/document/__tests__/protocol-fixtures.ts +38 -0
- package/src/core/notebook/document/__tests__/recovery-scenarios.test.ts +230 -0
- package/src/core/notebook/document/__tests__/scenario-fixture.ts +43 -0
- package/src/core/notebook/document/__tests__/scenarios.test.ts +205 -0
- package/src/core/notebook/document/__tests__/state.test.ts +459 -0
- package/src/core/notebook/document/__tests__/submission.test.ts +203 -0
- package/src/core/notebook/document/__tests__/test-host.test.ts +92 -0
- package/src/core/notebook/document/__tests__/test-host.ts +247 -0
- package/src/core/notebook/document/__tests__/test-notebook.ts +149 -0
- package/src/core/notebook/document/__tests__/user.ts +61 -0
- package/src/core/notebook/document/codemirror.ts +216 -0
- package/src/core/notebook/document/draft.ts +502 -0
- package/src/core/notebook/document/hooks.tsx +118 -0
- package/src/core/notebook/document/index.ts +24 -0
- package/src/core/notebook/document/model.ts +105 -0
- package/src/core/notebook/document/select.ts +41 -0
- package/src/core/notebook/document/state.ts +378 -0
- package/src/core/notebook/document/sync.ts +418 -0
- package/src/core/notebook/index.ts +18 -0
- package/src/core/notebook/replica/AGENTS.md +11 -0
- package/src/core/notebook/replica/__tests__/attachments.test.ts +56 -0
- package/src/core/notebook/replica/__tests__/document.test.ts +126 -0
- package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
- package/src/core/notebook/replica/__tests__/replica.test.ts +550 -0
- package/src/core/notebook/replica/backend.ts +19 -0
- package/src/core/notebook/replica/connection.ts +42 -0
- package/src/core/notebook/replica/index.ts +13 -0
- package/src/core/notebook/replica/replica.ts +286 -0
- package/src/core/notebook/replica/resources/attachments.ts +22 -0
- package/src/core/notebook/replica/resources/document.ts +101 -0
- package/src/core/packages/__tests__/useSandboxController.test.tsx +1 -1
- package/src/core/packages/useSandboxController.ts +1 -1
- package/src/core/run-app.tsx +48 -51
- package/src/core/runtime/__tests__/adapter.test.ts +1 -1
- package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
- package/src/core/runtime/__tests__/runtime.test.ts +32 -58
- package/src/core/runtime/adapter.ts +1 -1
- package/src/core/runtime/config.ts +2 -2
- package/src/core/runtime/runtime.ts +38 -42
- package/src/core/runtime/types.ts +0 -2
- package/src/core/saving/filename.ts +1 -1
- package/src/core/saving/save-component.tsx +10 -4
- package/src/core/saving/useAutoSave.ts +1 -1
- package/src/core/session/__tests__/backend.test.ts +235 -0
- package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +183 -0
- package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +663 -0
- package/src/core/session/active-notebook.ts +11 -0
- package/src/core/session/backend.ts +125 -0
- package/src/core/{websocket → session}/types.ts +2 -2
- package/src/core/session/useNotebookReplica.ts +72 -0
- package/src/core/{websocket → session}/useNotebookSession.tsx +74 -68
- package/src/core/state/__tests__/jotai.test.tsx +108 -0
- package/src/core/state/jotai.ts +1 -1
- package/src/core/static/__tests__/files.test.ts +38 -10
- package/src/core/static/files.ts +2 -0
- package/src/core/{websocket → transports}/__tests__/connection-state.test.ts +1 -13
- package/src/core/transports/__tests__/server.test.ts +408 -0
- package/src/core/transports/__tests__/static.test.ts +175 -0
- package/src/core/transports/__tests__/wasm.test.ts +166 -0
- package/src/core/{websocket → transports}/connection-state.ts +9 -16
- package/src/core/transports/server.ts +152 -0
- package/src/core/transports/static.ts +84 -0
- package/src/core/transports/wasm.ts +97 -0
- package/src/core/wasm/__tests__/bridge.test.ts +213 -50
- package/src/core/wasm/__tests__/worker.test.ts +187 -0
- package/src/core/wasm/bridge.ts +75 -69
- package/src/core/wasm/rpc.ts +15 -3
- package/src/core/wasm/store.ts +3 -3
- package/src/core/wasm/worker/bootstrap.ts +55 -51
- package/src/core/wasm/worker/getMarimoWheel.ts +1 -1
- package/src/core/wasm/worker/save-worker.ts +9 -10
- package/src/core/wasm/worker/types.ts +29 -18
- package/src/core/wasm/worker/worker.ts +88 -44
- package/src/css/globals.css +66 -22
- package/src/hooks/__tests__/useAsyncData.test.tsx +148 -0
- package/src/hooks/__tests__/useDebounce.test.tsx +51 -0
- package/src/hooks/__tests__/useDeepCompareMemoize.test.tsx +39 -0
- package/src/hooks/__tests__/useDelayElapsed.test.tsx +28 -0
- package/src/hooks/__tests__/useInternalStateWithSync.test.tsx +20 -0
- package/src/hooks/__tests__/useScript.test.tsx +77 -0
- package/src/hooks/__tests__/useStateForKey.test.tsx +257 -0
- package/src/hooks/useAsyncData.ts +3 -3
- package/src/hooks/useDataSourceDiscovery.ts +6 -4
- package/src/hooks/useDebounce.ts +6 -10
- package/src/hooks/useDeepCompareMemoize.ts +1 -1
- package/src/hooks/useDelayElapsed.ts +14 -10
- package/src/hooks/useElapsedTime.ts +3 -3
- package/src/hooks/useEventListener.ts +1 -2
- package/src/hooks/useInputHistory.ts +4 -7
- package/src/hooks/useInternalStateWithSync.ts +6 -6
- package/src/hooks/useResizeObserver.ts +4 -7
- package/src/hooks/useScript.ts +67 -70
- package/src/hooks/useStateForKey.ts +93 -0
- package/src/mount.tsx +1 -5
- package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
- package/src/plugins/core/registerReactComponent.tsx +1 -1
- package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataTablePlugin.tsx +69 -37
- package/src/plugins/impl/DropdownPlugin.tsx +2 -6
- package/src/plugins/impl/FileBrowserPlugin.tsx +4 -16
- package/src/plugins/impl/FormPlugin.tsx +1 -1
- package/src/plugins/impl/RangeSliderPlugin.tsx +16 -2
- package/src/plugins/impl/RefreshPlugin.tsx +1 -0
- package/src/plugins/impl/SliderPlugin.tsx +6 -8
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +387 -1
- package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +45 -0
- package/src/plugins/impl/__tests__/RangeSliderPlugin.test.tsx +109 -0
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +24 -3
- package/src/plugins/impl/anywidget/__tests__/registry.test.ts +153 -0
- package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +241 -2
- package/src/plugins/impl/anywidget/model.ts +3 -1
- package/src/plugins/impl/anywidget/registry.ts +18 -14
- package/src/plugins/impl/anywidget/runtime.ts +21 -9
- package/src/plugins/impl/anywidget/widget-binding.ts +160 -82
- package/src/plugins/impl/chat/__tests__/chat-prompts.test.tsx +93 -0
- package/src/plugins/impl/chat/chat-ui.tsx +14 -11
- 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/data-explorer/ConnectedDataExplorerComponent.tsx +1 -1
- package/src/plugins/impl/data-explorer/components/column-summary.tsx +4 -2
- package/src/plugins/impl/data-explorer/state/reducer.ts +1 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +1 -2
- package/src/plugins/impl/data-frames/__tests__/sidebar.test.tsx +160 -0
- package/src/plugins/impl/data-frames/forms/__tests__/__snapshots__/form.test.tsx.snap +66 -66
- package/src/plugins/impl/data-frames/panel.tsx +43 -16
- package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +5 -3
- package/src/plugins/impl/panel/PanelPlugin.tsx +16 -17
- package/src/plugins/impl/panel/__tests__/utils.test.ts +39 -1
- package/src/plugins/impl/panel/utils.ts +17 -0
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +2 -5
- package/src/plugins/impl/plotly/selection.ts +25 -19
- package/src/plugins/impl/vega/VegaPlugin.tsx +2 -3
- package/src/plugins/impl/vega/make-selectable.ts +4 -7
- package/src/plugins/layout/RoutesPlugin.tsx +1 -1
- package/src/stories/__tests__/editor-story.test.tsx +33 -0
- package/src/stories/button.stories.tsx +1 -0
- package/src/stories/cell.stories.tsx +1 -1
- package/src/stories/data-table.stories.tsx +31 -0
- package/src/stories/editor.stories.tsx +24 -17
- package/src/stories/form-wrapper.stories.tsx +2 -2
- package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
- package/src/stories/runtime-story.tsx +23 -16
- package/src/stories/select.stories.tsx +2 -2
- package/src/stories/switchable-multi-select.stories.tsx +1 -1
- package/src/utils/__tests__/arrays.test.ts +35 -0
- package/src/utils/__tests__/batch-requests.test.ts +3 -3
- package/src/utils/__tests__/{createReducer.test.ts → createReducer.test.tsx} +29 -0
- package/src/utils/__tests__/numbers.test.ts +105 -1
- package/src/utils/__tests__/objects.test.ts +21 -0
- package/src/utils/arrays.ts +11 -2
- package/src/utils/blob.ts +1 -1
- package/src/utils/createReducer.ts +53 -26
- package/src/utils/maps.ts +0 -3
- package/src/utils/numbers.ts +79 -18
- package/src/utils/objects.ts +4 -9
- package/src/utils/once.ts +19 -19
- package/src/utils/tracer.ts +9 -5
- package/src/utils/zod-utils.ts +1 -3
- package/dist/any-language-editor-DZ_YTVus.js +0 -76
- package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
- package/dist/assets/worker-HPY9fbhz.js +0 -114
- package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
- package/dist/precisionRound-DMIVQrt2.js +0 -97
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +0 -656
- package/src/core/ai/tools/run-cells-tool.ts +0 -303
- package/src/core/attachments/state.ts +0 -21
- package/src/core/cells/__tests__/apply-transaction.test.ts +0 -991
- package/src/core/cells/__tests__/document-changes.test.ts +0 -1140
- package/src/core/cells/__tests__/document-roundtrip.test.ts +0 -392
- package/src/core/cells/document-changes.ts +0 -944
- package/src/core/host/AGENTS.md +0 -6
- package/src/core/host/__tests__/events.test.ts +0 -46
- package/src/core/host/__tests__/notebook-client.test.ts +0 -191
- package/src/core/host/__tests__/protocol.test.ts +0 -214
- package/src/core/host/connection.ts +0 -81
- package/src/core/host/events.ts +0 -60
- package/src/core/host/notebook-client.ts +0 -226
- package/src/core/host/protocol.ts +0 -1943
- package/src/core/state/__tests__/jotai.test.ts +0 -25
- package/src/core/wasm/worker/message-buffer.ts +0 -33
- package/src/core/websocket/__tests__/createConnectionTransport.test.ts +0 -49
- package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +0 -140
- package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +0 -883
- package/src/core/websocket/transports/__tests__/basic.test.ts +0 -275
- package/src/core/websocket/transports/__tests__/sse.test.ts +0 -335
- package/src/core/websocket/transports/__tests__/transport.test.ts +0 -308
- package/src/core/websocket/transports/__tests__/ws.test.ts +0 -125
- package/src/core/websocket/transports/basic.ts +0 -102
- package/src/core/websocket/transports/create.ts +0 -31
- package/src/core/websocket/transports/sse.ts +0 -308
- package/src/core/websocket/transports/transport.ts +0 -50
- package/src/core/websocket/transports/ws.ts +0 -98
- package/src/core/websocket/useNotebookClient.ts +0 -80
- /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
- /package/src/core/{websocket → session}/connection-utils.ts +0 -0
|
@@ -4,10 +4,11 @@ import { python } from "@codemirror/lang-python";
|
|
|
4
4
|
import { EditorState } from "@codemirror/state";
|
|
5
5
|
import { EditorView } from "@codemirror/view";
|
|
6
6
|
import { createStore } from "jotai";
|
|
7
|
+
import { createRef } from "react";
|
|
7
8
|
import {
|
|
8
9
|
afterAll,
|
|
9
|
-
afterEach,
|
|
10
10
|
beforeAll,
|
|
11
|
+
afterEach,
|
|
11
12
|
beforeEach,
|
|
12
13
|
describe,
|
|
13
14
|
expect,
|
|
@@ -17,11 +18,12 @@ import {
|
|
|
17
18
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
18
19
|
import { cellId } from "@/__tests__/branded";
|
|
19
20
|
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
20
|
-
import { CellId, SCRATCH_CELL_ID
|
|
21
|
+
import { CellId, SCRATCH_CELL_ID } from "@/core/cells/ids";
|
|
21
22
|
import { foldAllBulk, unfoldAllBulk } from "@/core/codemirror/editing/commands";
|
|
22
23
|
import { adaptiveLanguageConfiguration } from "@/core/codemirror/language/extension";
|
|
23
24
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
24
25
|
import type { OutputMessage } from "@/core/kernel/messages";
|
|
26
|
+
import type { CellConfig } from "@/core/network/types";
|
|
25
27
|
import {
|
|
26
28
|
type CollapsibleTree,
|
|
27
29
|
MultiColumn,
|
|
@@ -34,13 +36,17 @@ import {
|
|
|
34
36
|
type NotebookState,
|
|
35
37
|
notebookAtom,
|
|
36
38
|
} from "../cells";
|
|
37
|
-
import { exportedForTesting as documentTransactionTestExports } from "../document-changes";
|
|
38
39
|
import {
|
|
39
40
|
focusAndScrollCellIntoView,
|
|
40
41
|
scrollToBottom,
|
|
41
42
|
scrollToTop,
|
|
42
43
|
} from "../scrollCellIntoView";
|
|
43
|
-
import
|
|
44
|
+
import {
|
|
45
|
+
type CellData,
|
|
46
|
+
createCell,
|
|
47
|
+
createCellConfig,
|
|
48
|
+
createCellRuntimeState,
|
|
49
|
+
} from "../types";
|
|
44
50
|
|
|
45
51
|
vi.mock("@/core/codemirror/editing/commands", () => ({
|
|
46
52
|
foldAllBulk: vi.fn(),
|
|
@@ -121,8 +127,7 @@ describe("cell reducer", () => {
|
|
|
121
127
|
let cells: ReturnType<typeof flattenTopLevelNotebookCells>;
|
|
122
128
|
let firstCellId: CellId;
|
|
123
129
|
|
|
124
|
-
const
|
|
125
|
-
state = reducer(state, action);
|
|
130
|
+
const mountEditors = () => {
|
|
126
131
|
for (const [cellIdString, handle] of Object.entries(state.cellHandles)) {
|
|
127
132
|
// @ts-expect-error - Typescript Object.entries doesn't know that keys are CellId
|
|
128
133
|
const cid: CellId = cellIdString;
|
|
@@ -136,7 +141,76 @@ describe("cell reducer", () => {
|
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
cells = flattenTopLevelNotebookCells(state);
|
|
139
|
-
}
|
|
144
|
+
};
|
|
145
|
+
const actions = createActions((action) => {
|
|
146
|
+
state = reducer(state, action);
|
|
147
|
+
mountEditors();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
/** Put a cell into the notebook the way the document would. */
|
|
151
|
+
function seedCell({
|
|
152
|
+
cellId,
|
|
153
|
+
before,
|
|
154
|
+
code = "",
|
|
155
|
+
name,
|
|
156
|
+
config,
|
|
157
|
+
newCellId,
|
|
158
|
+
hideCode,
|
|
159
|
+
autoFocus = true,
|
|
160
|
+
}: {
|
|
161
|
+
cellId: CellId | "__end__" | { type: "__end__"; columnId: CellColumnId };
|
|
162
|
+
before: boolean;
|
|
163
|
+
code?: string;
|
|
164
|
+
name?: string;
|
|
165
|
+
config?: CellConfig;
|
|
166
|
+
newCellId?: CellId;
|
|
167
|
+
hideCode?: boolean;
|
|
168
|
+
autoFocus?: boolean;
|
|
169
|
+
}): CellId {
|
|
170
|
+
let column: CollapsibleTree<CellId>;
|
|
171
|
+
let cellIndex: number;
|
|
172
|
+
if (cellId === "__end__") {
|
|
173
|
+
column = state.cellIds.atOrThrow(0);
|
|
174
|
+
cellIndex = column.length;
|
|
175
|
+
} else if (typeof cellId === "string") {
|
|
176
|
+
column = state.cellIds.findWithId(cellId);
|
|
177
|
+
cellIndex = column.topLevelIds.indexOf(cellId);
|
|
178
|
+
} else {
|
|
179
|
+
column = state.cellIds.get(cellId.columnId) ?? state.cellIds.atOrThrow(0);
|
|
180
|
+
cellIndex = column.length;
|
|
181
|
+
}
|
|
182
|
+
const id = newCellId ?? CellId.create();
|
|
183
|
+
state = {
|
|
184
|
+
...state,
|
|
185
|
+
cellIds: state.cellIds.insertId(
|
|
186
|
+
id,
|
|
187
|
+
column.id,
|
|
188
|
+
before ? cellIndex : cellIndex + 1,
|
|
189
|
+
),
|
|
190
|
+
cellData: {
|
|
191
|
+
...state.cellData,
|
|
192
|
+
[id]: createCell({
|
|
193
|
+
id,
|
|
194
|
+
code,
|
|
195
|
+
name,
|
|
196
|
+
config: createCellConfig({
|
|
197
|
+
...config,
|
|
198
|
+
...(hideCode != null && { hide_code: hideCode }),
|
|
199
|
+
}),
|
|
200
|
+
edited: Boolean(code),
|
|
201
|
+
}),
|
|
202
|
+
},
|
|
203
|
+
cellRuntime: { ...state.cellRuntime, [id]: createCellRuntimeState() },
|
|
204
|
+
cellHandles: { ...state.cellHandles, [id]: createRef() },
|
|
205
|
+
scrollKey: autoFocus ? id : null,
|
|
206
|
+
untouchedNewCells:
|
|
207
|
+
hideCode && autoFocus
|
|
208
|
+
? new Set([...state.untouchedNewCells, id])
|
|
209
|
+
: state.untouchedNewCells,
|
|
210
|
+
};
|
|
211
|
+
mountEditors();
|
|
212
|
+
return id;
|
|
213
|
+
}
|
|
140
214
|
|
|
141
215
|
let i = 0;
|
|
142
216
|
const originalCreate = CellId.create.bind(CellId);
|
|
@@ -152,193 +226,14 @@ describe("cell reducer", () => {
|
|
|
152
226
|
|
|
153
227
|
state = initialNotebookState();
|
|
154
228
|
state.cellIds = MultiColumn.from([]);
|
|
155
|
-
|
|
229
|
+
seedCell({ cellId: "__end__", before: false });
|
|
156
230
|
firstCellId = state.cellIds.inOrderIds[0];
|
|
157
231
|
});
|
|
158
232
|
|
|
159
|
-
afterEach(() => {
|
|
160
|
-
documentTransactionTestExports.cancelPendingChanges();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
233
|
afterAll(() => {
|
|
164
234
|
CellId.create = originalCreate;
|
|
165
235
|
});
|
|
166
236
|
|
|
167
|
-
it("can add a cell after another cell", () => {
|
|
168
|
-
actions.createNewCell({
|
|
169
|
-
cellId: firstCellId,
|
|
170
|
-
before: false,
|
|
171
|
-
});
|
|
172
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
173
|
-
"
|
|
174
|
-
[0] ''
|
|
175
|
-
|
|
176
|
-
[1] ''
|
|
177
|
-
"
|
|
178
|
-
`);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("can add a cell to the end with code", () => {
|
|
182
|
-
actions.createNewCell({
|
|
183
|
-
cellId: "__end__",
|
|
184
|
-
code: "import numpy as np",
|
|
185
|
-
before: false,
|
|
186
|
-
});
|
|
187
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
188
|
-
"
|
|
189
|
-
[0] ''
|
|
190
|
-
|
|
191
|
-
[1] 'import numpy as np'
|
|
192
|
-
"
|
|
193
|
-
`);
|
|
194
|
-
|
|
195
|
-
// Cell should be added to the end and edited
|
|
196
|
-
expect(cells[1].code).toBe("import numpy as np");
|
|
197
|
-
expect(cells[1].edited).toBe(true);
|
|
198
|
-
expect(cells[1].lastCodeRun).toBe(null);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("can add a cell before another cell", () => {
|
|
202
|
-
actions.createNewCell({
|
|
203
|
-
cellId: firstCellId,
|
|
204
|
-
before: true,
|
|
205
|
-
});
|
|
206
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
207
|
-
"
|
|
208
|
-
[1] ''
|
|
209
|
-
|
|
210
|
-
[0] ''
|
|
211
|
-
"
|
|
212
|
-
`);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("can add a cell with name and config", () => {
|
|
216
|
-
actions.createNewCell({
|
|
217
|
-
cellId: firstCellId,
|
|
218
|
-
before: false,
|
|
219
|
-
code: "x = 1",
|
|
220
|
-
name: "My Cell",
|
|
221
|
-
config: { hide_code: true, disabled: false },
|
|
222
|
-
});
|
|
223
|
-
const newCellId = state.cellIds.inOrderIds[1];
|
|
224
|
-
expect(state.cellData[newCellId].name).toBe("My Cell");
|
|
225
|
-
expect(state.cellData[newCellId].config.hide_code).toBe(true);
|
|
226
|
-
expect(state.cellData[newCellId].config.disabled).toBe(false);
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
it("can delete a Python cell and undo delete", () => {
|
|
230
|
-
actions.createNewCell({
|
|
231
|
-
cellId: firstCellId,
|
|
232
|
-
before: false,
|
|
233
|
-
});
|
|
234
|
-
actions.deleteCell({
|
|
235
|
-
cellId: firstCellId,
|
|
236
|
-
});
|
|
237
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
238
|
-
"
|
|
239
|
-
[1] ''
|
|
240
|
-
"
|
|
241
|
-
`);
|
|
242
|
-
|
|
243
|
-
// undo
|
|
244
|
-
actions.undoDeleteCell();
|
|
245
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
246
|
-
"
|
|
247
|
-
[2] ''
|
|
248
|
-
|
|
249
|
-
[1] ''
|
|
250
|
-
"
|
|
251
|
-
`);
|
|
252
|
-
|
|
253
|
-
// Verify scrollKey is set to the restored cell
|
|
254
|
-
expect(state.scrollKey).toBe("2");
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
it("can delete a SQL cell and undo delete", () => {
|
|
258
|
-
actions.createNewCell({
|
|
259
|
-
cellId: firstCellId,
|
|
260
|
-
before: false,
|
|
261
|
-
code: `df = mo.sql("""SELECT * FROM table""")`,
|
|
262
|
-
});
|
|
263
|
-
const newCellId = state.cellIds.getColumns()[0].atOrThrow(1);
|
|
264
|
-
actions.deleteCell({
|
|
265
|
-
cellId: newCellId,
|
|
266
|
-
});
|
|
267
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
268
|
-
"
|
|
269
|
-
[0] ''
|
|
270
|
-
"
|
|
271
|
-
`);
|
|
272
|
-
|
|
273
|
-
// undo
|
|
274
|
-
actions.undoDeleteCell();
|
|
275
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
276
|
-
"
|
|
277
|
-
[0] ''
|
|
278
|
-
|
|
279
|
-
[2] 'df = mo.sql("""SELECT * FROM table""")'
|
|
280
|
-
"
|
|
281
|
-
`);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it("can delete a Markdown cell and undo delete", () => {
|
|
285
|
-
const text = "The quick brown fox jumps over the lazy dog.";
|
|
286
|
-
actions.createNewCell({
|
|
287
|
-
cellId: firstCellId,
|
|
288
|
-
before: false,
|
|
289
|
-
code: `mo.md(r"""${text}""")`,
|
|
290
|
-
});
|
|
291
|
-
const newCellId = state.cellIds.getColumns()[0].atOrThrow(1);
|
|
292
|
-
actions.deleteCell({
|
|
293
|
-
cellId: newCellId,
|
|
294
|
-
});
|
|
295
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
296
|
-
"
|
|
297
|
-
[0] ''
|
|
298
|
-
"
|
|
299
|
-
`);
|
|
300
|
-
|
|
301
|
-
// undo
|
|
302
|
-
actions.undoDeleteCell();
|
|
303
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
304
|
-
"
|
|
305
|
-
[0] ''
|
|
306
|
-
|
|
307
|
-
[2] 'mo.md(r"""The quick brown fox jumps over the lazy dog.""")'
|
|
308
|
-
"
|
|
309
|
-
`);
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it("undo delete restores cell config (hide_code, disabled)", () => {
|
|
313
|
-
actions.createNewCell({
|
|
314
|
-
cellId: firstCellId,
|
|
315
|
-
before: false,
|
|
316
|
-
code: "x = 1",
|
|
317
|
-
});
|
|
318
|
-
const newCellId = state.cellIds.getColumns()[0].atOrThrow(1);
|
|
319
|
-
|
|
320
|
-
// Set config to hidden and disabled
|
|
321
|
-
actions.updateCellConfig({
|
|
322
|
-
cellId: newCellId,
|
|
323
|
-
config: { hide_code: true, disabled: true },
|
|
324
|
-
});
|
|
325
|
-
expect(state.cellData[newCellId].config.hide_code).toBe(true);
|
|
326
|
-
expect(state.cellData[newCellId].config.disabled).toBe(true);
|
|
327
|
-
|
|
328
|
-
// Delete the cell
|
|
329
|
-
actions.deleteCell({ cellId: newCellId });
|
|
330
|
-
expect(state.cellIds.inOrderIds).not.toContain(newCellId);
|
|
331
|
-
|
|
332
|
-
// Undo delete
|
|
333
|
-
actions.undoDeleteCell();
|
|
334
|
-
const restoredCellId =
|
|
335
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
336
|
-
|
|
337
|
-
// Config should be preserved
|
|
338
|
-
expect(state.cellData[restoredCellId].config.hide_code).toBe(true);
|
|
339
|
-
expect(state.cellData[restoredCellId].config.disabled).toBe(true);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
237
|
it("can update a cell", () => {
|
|
343
238
|
actions.updateCellCode({
|
|
344
239
|
cellId: firstCellId,
|
|
@@ -353,7 +248,7 @@ describe("cell reducer", () => {
|
|
|
353
248
|
});
|
|
354
249
|
|
|
355
250
|
it("can move a cell", () => {
|
|
356
|
-
|
|
251
|
+
seedCell({
|
|
357
252
|
cellId: firstCellId,
|
|
358
253
|
before: false,
|
|
359
254
|
});
|
|
@@ -467,11 +362,11 @@ describe("cell reducer", () => {
|
|
|
467
362
|
});
|
|
468
363
|
|
|
469
364
|
it("can drag and drop a cell", () => {
|
|
470
|
-
|
|
365
|
+
seedCell({
|
|
471
366
|
cellId: firstCellId,
|
|
472
367
|
before: false,
|
|
473
368
|
});
|
|
474
|
-
|
|
369
|
+
seedCell({
|
|
475
370
|
cellId: cellId("1"),
|
|
476
371
|
before: false,
|
|
477
372
|
});
|
|
@@ -517,11 +412,11 @@ describe("cell reducer", () => {
|
|
|
517
412
|
});
|
|
518
413
|
|
|
519
414
|
it("can move a cell to an exact index within a column", () => {
|
|
520
|
-
|
|
415
|
+
seedCell({
|
|
521
416
|
cellId: firstCellId,
|
|
522
417
|
before: false,
|
|
523
418
|
});
|
|
524
|
-
|
|
419
|
+
seedCell({
|
|
525
420
|
cellId: cellId("1"),
|
|
526
421
|
before: false,
|
|
527
422
|
});
|
|
@@ -545,11 +440,11 @@ describe("cell reducer", () => {
|
|
|
545
440
|
});
|
|
546
441
|
|
|
547
442
|
it("can move a cell to an exact index across columns", () => {
|
|
548
|
-
|
|
443
|
+
seedCell({
|
|
549
444
|
cellId: firstCellId,
|
|
550
445
|
before: false,
|
|
551
446
|
});
|
|
552
|
-
|
|
447
|
+
seedCell({
|
|
553
448
|
cellId: cellId("1"),
|
|
554
449
|
before: false,
|
|
555
450
|
});
|
|
@@ -578,11 +473,11 @@ describe("cell reducer", () => {
|
|
|
578
473
|
});
|
|
579
474
|
|
|
580
475
|
it("moveCellToIndex is a no-op when moving to the same position", () => {
|
|
581
|
-
|
|
476
|
+
seedCell({
|
|
582
477
|
cellId: firstCellId,
|
|
583
478
|
before: false,
|
|
584
479
|
});
|
|
585
|
-
|
|
480
|
+
seedCell({
|
|
586
481
|
cellId: cellId("1"),
|
|
587
482
|
before: false,
|
|
588
483
|
});
|
|
@@ -600,7 +495,7 @@ describe("cell reducer", () => {
|
|
|
600
495
|
});
|
|
601
496
|
|
|
602
497
|
it("moveCellToIndex is a no-op for an invalid columnId", () => {
|
|
603
|
-
|
|
498
|
+
seedCell({
|
|
604
499
|
cellId: firstCellId,
|
|
605
500
|
before: false,
|
|
606
501
|
});
|
|
@@ -617,11 +512,11 @@ describe("cell reducer", () => {
|
|
|
617
512
|
});
|
|
618
513
|
|
|
619
514
|
it("can move multiple cells relative to target", () => {
|
|
620
|
-
|
|
515
|
+
seedCell({
|
|
621
516
|
cellId: firstCellId,
|
|
622
517
|
before: false,
|
|
623
518
|
});
|
|
624
|
-
|
|
519
|
+
seedCell({
|
|
625
520
|
cellId: cellId("1"),
|
|
626
521
|
before: false,
|
|
627
522
|
});
|
|
@@ -652,143 +547,6 @@ describe("cell reducer", () => {
|
|
|
652
547
|
`);
|
|
653
548
|
});
|
|
654
549
|
|
|
655
|
-
it("can undo cut-paste (move with previousPlacements)", () => {
|
|
656
|
-
actions.createNewCell({
|
|
657
|
-
cellId: firstCellId,
|
|
658
|
-
before: false,
|
|
659
|
-
});
|
|
660
|
-
actions.createNewCell({
|
|
661
|
-
cellId: cellId("1"),
|
|
662
|
-
before: false,
|
|
663
|
-
});
|
|
664
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
665
|
-
"
|
|
666
|
-
[0] ''
|
|
667
|
-
|
|
668
|
-
[1] ''
|
|
669
|
-
|
|
670
|
-
[2] ''
|
|
671
|
-
"
|
|
672
|
-
`);
|
|
673
|
-
|
|
674
|
-
const col = state.cellIds.findWithId(firstCellId);
|
|
675
|
-
const previousPlacements = [
|
|
676
|
-
{
|
|
677
|
-
columnId: col.id,
|
|
678
|
-
index: col.indexOfOrThrow(
|
|
679
|
-
firstCellId,
|
|
680
|
-
) as import("@/utils/id-tree").CellIndex,
|
|
681
|
-
},
|
|
682
|
-
{
|
|
683
|
-
columnId: col.id,
|
|
684
|
-
index: col.indexOfOrThrow(
|
|
685
|
-
cellId("1"),
|
|
686
|
-
) as import("@/utils/id-tree").CellIndex,
|
|
687
|
-
},
|
|
688
|
-
];
|
|
689
|
-
|
|
690
|
-
actions.moveCellsRelativeTo({
|
|
691
|
-
cellIds: [firstCellId, cellId("1")],
|
|
692
|
-
targetCellId: cellId("2"),
|
|
693
|
-
position: "after",
|
|
694
|
-
previousPlacements,
|
|
695
|
-
});
|
|
696
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
697
|
-
"
|
|
698
|
-
[2] ''
|
|
699
|
-
|
|
700
|
-
[0] ''
|
|
701
|
-
|
|
702
|
-
[1] ''
|
|
703
|
-
"
|
|
704
|
-
`);
|
|
705
|
-
|
|
706
|
-
actions.undoDeleteCell();
|
|
707
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
708
|
-
"
|
|
709
|
-
[0] ''
|
|
710
|
-
|
|
711
|
-
[1] ''
|
|
712
|
-
|
|
713
|
-
[2] ''
|
|
714
|
-
"
|
|
715
|
-
`);
|
|
716
|
-
});
|
|
717
|
-
|
|
718
|
-
it("undo order: cut-paste then delete — first undo restores delete, second undo undoes move", () => {
|
|
719
|
-
actions.createNewCell({
|
|
720
|
-
cellId: firstCellId,
|
|
721
|
-
before: false,
|
|
722
|
-
});
|
|
723
|
-
actions.createNewCell({
|
|
724
|
-
cellId: cellId("1"),
|
|
725
|
-
before: false,
|
|
726
|
-
});
|
|
727
|
-
|
|
728
|
-
const col = state.cellIds.findWithId(firstCellId);
|
|
729
|
-
const previousPlacements = [
|
|
730
|
-
{
|
|
731
|
-
columnId: col.id,
|
|
732
|
-
index: col.indexOfOrThrow(
|
|
733
|
-
firstCellId,
|
|
734
|
-
) as import("@/utils/id-tree").CellIndex,
|
|
735
|
-
},
|
|
736
|
-
{
|
|
737
|
-
columnId: col.id,
|
|
738
|
-
index: col.indexOfOrThrow(
|
|
739
|
-
cellId("1"),
|
|
740
|
-
) as import("@/utils/id-tree").CellIndex,
|
|
741
|
-
},
|
|
742
|
-
];
|
|
743
|
-
|
|
744
|
-
actions.moveCellsRelativeTo({
|
|
745
|
-
cellIds: [firstCellId, cellId("1")],
|
|
746
|
-
targetCellId: cellId("2"),
|
|
747
|
-
position: "after",
|
|
748
|
-
previousPlacements,
|
|
749
|
-
});
|
|
750
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
751
|
-
"
|
|
752
|
-
[2] ''
|
|
753
|
-
|
|
754
|
-
[0] ''
|
|
755
|
-
|
|
756
|
-
[1] ''
|
|
757
|
-
"
|
|
758
|
-
`);
|
|
759
|
-
|
|
760
|
-
actions.deleteCell({ cellId: cellId("2") });
|
|
761
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
762
|
-
"
|
|
763
|
-
[0] ''
|
|
764
|
-
|
|
765
|
-
[1] ''
|
|
766
|
-
"
|
|
767
|
-
`);
|
|
768
|
-
|
|
769
|
-
actions.undoDeleteCell();
|
|
770
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
771
|
-
"
|
|
772
|
-
[3] ''
|
|
773
|
-
|
|
774
|
-
[0] ''
|
|
775
|
-
|
|
776
|
-
[1] ''
|
|
777
|
-
"
|
|
778
|
-
`);
|
|
779
|
-
|
|
780
|
-
actions.undoDeleteCell();
|
|
781
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
782
|
-
"
|
|
783
|
-
[0] ''
|
|
784
|
-
|
|
785
|
-
[1] ''
|
|
786
|
-
|
|
787
|
-
[3] ''
|
|
788
|
-
"
|
|
789
|
-
`);
|
|
790
|
-
});
|
|
791
|
-
|
|
792
550
|
it("keeps error evidence after an edit and a new queued run", () => {
|
|
793
551
|
const code = "raise ValueError('old failure')";
|
|
794
552
|
const output: OutputMessage = {
|
|
@@ -1172,7 +930,7 @@ describe("cell reducer", () => {
|
|
|
1172
930
|
formattingChange: false,
|
|
1173
931
|
});
|
|
1174
932
|
// Add cell
|
|
1175
|
-
|
|
933
|
+
seedCell({
|
|
1176
934
|
cellId: firstCellId,
|
|
1177
935
|
before: false,
|
|
1178
936
|
});
|
|
@@ -1277,33 +1035,6 @@ describe("cell reducer", () => {
|
|
|
1277
1035
|
expect(cell.edited).toBe(false);
|
|
1278
1036
|
});
|
|
1279
1037
|
|
|
1280
|
-
it("can update a cells config", () => {
|
|
1281
|
-
const firstCellId = cells[0].id;
|
|
1282
|
-
let cell = cells[0];
|
|
1283
|
-
// Starts empty
|
|
1284
|
-
expect(cell.config).toEqual({
|
|
1285
|
-
disabled: false,
|
|
1286
|
-
hide_code: false,
|
|
1287
|
-
column: null,
|
|
1288
|
-
expand_output: false,
|
|
1289
|
-
});
|
|
1290
|
-
|
|
1291
|
-
actions.updateCellConfig({
|
|
1292
|
-
cellId: firstCellId,
|
|
1293
|
-
config: { disabled: true },
|
|
1294
|
-
});
|
|
1295
|
-
cell = cells[0];
|
|
1296
|
-
expect(cell.config.disabled).toBe(true);
|
|
1297
|
-
|
|
1298
|
-
// Revert
|
|
1299
|
-
actions.updateCellConfig({
|
|
1300
|
-
cellId: firstCellId,
|
|
1301
|
-
config: { disabled: false },
|
|
1302
|
-
});
|
|
1303
|
-
cell = cells[0];
|
|
1304
|
-
expect(cell.config.disabled).toBe(false);
|
|
1305
|
-
});
|
|
1306
|
-
|
|
1307
1038
|
it("can run a stopped cell", () => {
|
|
1308
1039
|
// Update code of first cell
|
|
1309
1040
|
actions.updateCellCode({
|
|
@@ -1579,7 +1310,9 @@ describe("cell reducer", () => {
|
|
|
1579
1310
|
response: secret,
|
|
1580
1311
|
});
|
|
1581
1312
|
|
|
1582
|
-
expect(cells[0].consoleOutputs).toEqual([
|
|
1313
|
+
expect(cells[0].consoleOutputs).toEqual([
|
|
1314
|
+
{ ...prompt, id: 1, response: "" },
|
|
1315
|
+
]);
|
|
1583
1316
|
expect(JSON.stringify(cells[0].consoleOutputs)).not.toContain(secret);
|
|
1584
1317
|
});
|
|
1585
1318
|
|
|
@@ -1707,8 +1440,8 @@ describe("cell reducer", () => {
|
|
|
1707
1440
|
});
|
|
1708
1441
|
|
|
1709
1442
|
it("can send a cell to the top", () => {
|
|
1710
|
-
|
|
1711
|
-
|
|
1443
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1444
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
1712
1445
|
actions.sendToTop({ cellId: cellId("2") });
|
|
1713
1446
|
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
1714
1447
|
"
|
|
@@ -1722,8 +1455,8 @@ describe("cell reducer", () => {
|
|
|
1722
1455
|
});
|
|
1723
1456
|
|
|
1724
1457
|
it("can send a cell to the bottom", () => {
|
|
1725
|
-
|
|
1726
|
-
|
|
1458
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1459
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
1727
1460
|
actions.sendToBottom({ cellId: firstCellId });
|
|
1728
1461
|
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
1729
1462
|
"
|
|
@@ -1737,8 +1470,8 @@ describe("cell reducer", () => {
|
|
|
1737
1470
|
});
|
|
1738
1471
|
|
|
1739
1472
|
it("can focus cells", () => {
|
|
1740
|
-
|
|
1741
|
-
|
|
1473
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1474
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
1742
1475
|
|
|
1743
1476
|
actions.focusCell({ cellId: cellId("1"), where: "before" });
|
|
1744
1477
|
expect(focusAndScrollCellIntoView).toHaveBeenCalledWith(
|
|
@@ -1754,199 +1487,13 @@ describe("cell reducer", () => {
|
|
|
1754
1487
|
expect(scrollToBottom).toHaveBeenCalled();
|
|
1755
1488
|
});
|
|
1756
1489
|
|
|
1757
|
-
it("can
|
|
1758
|
-
actions.
|
|
1759
|
-
expect(
|
|
1760
|
-
});
|
|
1761
|
-
|
|
1762
|
-
it("can set cell IDs and codes", () => {
|
|
1763
|
-
const newIds = [cellId("3"), cellId("4"), cellId("5")];
|
|
1764
|
-
const newCodes = ["code1", "code2", "code3"];
|
|
1765
|
-
|
|
1766
|
-
actions.setCellIds({ cellIds: newIds });
|
|
1767
|
-
expect(state.cellIds.atOrThrow(FIRST_COLUMN).topLevelIds).toEqual(newIds);
|
|
1490
|
+
it("can fold and unfold all cells", () => {
|
|
1491
|
+
actions.foldAll();
|
|
1492
|
+
expect(foldAllBulk).toHaveBeenCalled();
|
|
1768
1493
|
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
ids: newIds,
|
|
1773
|
-
codeIsStale: false,
|
|
1774
|
-
});
|
|
1775
|
-
newIds.forEach((id, index) => {
|
|
1776
|
-
expect(state.cellData[id].code).toBe(newCodes[index]);
|
|
1777
|
-
expect(state.cellData[id].lastCodeRun).toBe(newCodes[index]);
|
|
1778
|
-
expect(state.cellData[id].edited).toBe(false);
|
|
1779
|
-
});
|
|
1780
|
-
|
|
1781
|
-
// When codeIsStale is true, lastCodeRun should not change
|
|
1782
|
-
const staleCodes = ["stale1", "stale2", "stale3"];
|
|
1783
|
-
actions.setCellCodes({
|
|
1784
|
-
codes: staleCodes,
|
|
1785
|
-
ids: newIds,
|
|
1786
|
-
codeIsStale: true,
|
|
1787
|
-
});
|
|
1788
|
-
newIds.forEach((id, index) => {
|
|
1789
|
-
expect(state.cellData[id].code).toBe(staleCodes[index]);
|
|
1790
|
-
expect(state.cellData[id].lastCodeRun).toBe(newCodes[index]);
|
|
1791
|
-
expect(state.cellData[id].edited).toBe(true);
|
|
1792
|
-
});
|
|
1793
|
-
});
|
|
1794
|
-
|
|
1795
|
-
it("can can add a new cell with/without stale code", () => {
|
|
1796
|
-
actions.setCellCodes({
|
|
1797
|
-
codes: ["new code"],
|
|
1798
|
-
ids: [cellId("2")],
|
|
1799
|
-
codeIsStale: false,
|
|
1800
|
-
});
|
|
1801
|
-
|
|
1802
|
-
expect(state.cellData[cellId("2")].code).toBe("new code");
|
|
1803
|
-
expect(state.cellData[cellId("2")].edited).toBe(false);
|
|
1804
|
-
expect(state.cellData[cellId("2")].lastCodeRun).toBe("new code");
|
|
1805
|
-
|
|
1806
|
-
actions.setCellCodes({
|
|
1807
|
-
codes: ["new code 2"],
|
|
1808
|
-
ids: [cellId("9")],
|
|
1809
|
-
codeIsStale: true,
|
|
1810
|
-
});
|
|
1811
|
-
|
|
1812
|
-
expect(state.cellData[cellId("9")].code).toBe("new code 2");
|
|
1813
|
-
expect(state.cellData[cellId("9")].edited).toBe(true);
|
|
1814
|
-
expect(state.cellData[cellId("9")].lastCodeRun).toBe(null);
|
|
1815
|
-
});
|
|
1816
|
-
|
|
1817
|
-
it("can partial update cell codes", () => {
|
|
1818
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
1819
|
-
actions.createNewCell({ cellId: cellId("1"), before: false });
|
|
1820
|
-
|
|
1821
|
-
expect(state.cellIds.inOrderIds).toEqual([
|
|
1822
|
-
cellId("0"),
|
|
1823
|
-
cellId("1"),
|
|
1824
|
-
cellId("2"),
|
|
1825
|
-
]);
|
|
1826
|
-
expect(state.cellData[cellId("0")].code).toBe("");
|
|
1827
|
-
expect(state.cellData[cellId("1")].code).toBe("");
|
|
1828
|
-
expect(state.cellData[cellId("2")].code).toBe("");
|
|
1829
|
-
|
|
1830
|
-
// Update cell 1
|
|
1831
|
-
actions.setCellCodes({
|
|
1832
|
-
codes: ["new code 2"],
|
|
1833
|
-
ids: [cellId("1")],
|
|
1834
|
-
codeIsStale: false,
|
|
1835
|
-
});
|
|
1836
|
-
|
|
1837
|
-
expect(state.cellIds.inOrderIds).toEqual([
|
|
1838
|
-
cellId("0"),
|
|
1839
|
-
cellId("1"),
|
|
1840
|
-
cellId("2"),
|
|
1841
|
-
]);
|
|
1842
|
-
expect(state.cellData[cellId("0")].code).toBe("");
|
|
1843
|
-
expect(state.cellData[cellId("1")].code).toBe("new code 2");
|
|
1844
|
-
expect(state.cellData[cellId("1")].edited).toBe(false);
|
|
1845
|
-
expect(state.cellData[cellId("2")].code).toBe("");
|
|
1846
|
-
});
|
|
1847
|
-
|
|
1848
|
-
it("can set cell codes with new cell ids, while preserving the old cell data", () => {
|
|
1849
|
-
actions.setCellCodes({
|
|
1850
|
-
codes: ["code1", "code2", "code3"],
|
|
1851
|
-
ids: [cellId("3"), cellId("4"), cellId("5")],
|
|
1852
|
-
codeIsStale: false,
|
|
1853
|
-
});
|
|
1854
|
-
expect(state.cellData[cellId("3")].code).toBe("code1");
|
|
1855
|
-
expect(state.cellData[cellId("4")].code).toBe("code2");
|
|
1856
|
-
expect(state.cellData[cellId("5")].code).toBe("code3");
|
|
1857
|
-
|
|
1858
|
-
// Update with some new cell ids and some old cell ids
|
|
1859
|
-
actions.setCellIds({
|
|
1860
|
-
cellIds: [cellId("1"), cellId("2"), cellId("3"), cellId("4")],
|
|
1861
|
-
});
|
|
1862
|
-
actions.setCellCodes({
|
|
1863
|
-
codes: ["new1", "new2", "code1", "code2"],
|
|
1864
|
-
ids: [cellId("1"), cellId("2"), cellId("3"), cellId("4")],
|
|
1865
|
-
codeIsStale: false,
|
|
1866
|
-
});
|
|
1867
|
-
expect(state.cellData[cellId("1")].code).toBe("new1");
|
|
1868
|
-
expect(state.cellData[cellId("2")].code).toBe("new2");
|
|
1869
|
-
expect(state.cellData[cellId("3")].code).toBe("code1");
|
|
1870
|
-
expect(state.cellData[cellId("4")].code).toBe("code2");
|
|
1871
|
-
expect(state.cellIds.inOrderIds).toEqual([
|
|
1872
|
-
cellId("1"),
|
|
1873
|
-
cellId("2"),
|
|
1874
|
-
cellId("3"),
|
|
1875
|
-
cellId("4"),
|
|
1876
|
-
]);
|
|
1877
|
-
// Cell 5 data is preserved (possibly used for tracing), but it's not in the cellIds
|
|
1878
|
-
expect(state.cellData[cellId("5")]).not.toBeUndefined();
|
|
1879
|
-
});
|
|
1880
|
-
|
|
1881
|
-
it("can set cell codes with names and configs", () => {
|
|
1882
|
-
const newIds = [cellId("3"), cellId("4")];
|
|
1883
|
-
actions.setCellIds({ cellIds: newIds });
|
|
1884
|
-
actions.setCellCodes({
|
|
1885
|
-
codes: ["code1", "code2"],
|
|
1886
|
-
ids: newIds,
|
|
1887
|
-
codeIsStale: false,
|
|
1888
|
-
names: ["setup_cell", "analysis"],
|
|
1889
|
-
configs: [
|
|
1890
|
-
{ hide_code: true, disabled: false, column: null },
|
|
1891
|
-
{ hide_code: false, disabled: true, column: null },
|
|
1892
|
-
],
|
|
1893
|
-
});
|
|
1894
|
-
|
|
1895
|
-
expect(state.cellData[cellId("3")].name).toBe("setup_cell");
|
|
1896
|
-
expect(state.cellData[cellId("3")].config.hide_code).toBe(true);
|
|
1897
|
-
expect(state.cellData[cellId("3")].config.disabled).toBe(false);
|
|
1898
|
-
|
|
1899
|
-
expect(state.cellData[cellId("4")].name).toBe("analysis");
|
|
1900
|
-
expect(state.cellData[cellId("4")].config.hide_code).toBe(false);
|
|
1901
|
-
expect(state.cellData[cellId("4")].config.disabled).toBe(true);
|
|
1902
|
-
});
|
|
1903
|
-
|
|
1904
|
-
it("can set cell codes without names/configs (backward compat)", () => {
|
|
1905
|
-
const newIds = [cellId("3")];
|
|
1906
|
-
actions.setCellIds({ cellIds: newIds });
|
|
1907
|
-
actions.setCellCodes({
|
|
1908
|
-
codes: ["code1"],
|
|
1909
|
-
ids: newIds,
|
|
1910
|
-
codeIsStale: false,
|
|
1911
|
-
});
|
|
1912
|
-
|
|
1913
|
-
// Should use defaults when names/configs not provided
|
|
1914
|
-
expect(state.cellData[cellId("3")].code).toBe("code1");
|
|
1915
|
-
expect(state.cellData[cellId("3")].config.hide_code).toBe(false);
|
|
1916
|
-
expect(state.cellData[cellId("3")].config.disabled).toBe(false);
|
|
1917
|
-
});
|
|
1918
|
-
|
|
1919
|
-
it("can update names and configs on existing cells via setCellCodes", () => {
|
|
1920
|
-
// Set initial state
|
|
1921
|
-
actions.setCellCodes({
|
|
1922
|
-
codes: ["x = 1"],
|
|
1923
|
-
ids: [firstCellId],
|
|
1924
|
-
codeIsStale: false,
|
|
1925
|
-
names: ["old_name"],
|
|
1926
|
-
configs: [{ hide_code: false, disabled: false, column: null }],
|
|
1927
|
-
});
|
|
1928
|
-
expect(state.cellData[firstCellId].name).toBe("old_name");
|
|
1929
|
-
expect(state.cellData[firstCellId].config.hide_code).toBe(false);
|
|
1930
|
-
|
|
1931
|
-
// Update with new name and config (same code)
|
|
1932
|
-
actions.setCellCodes({
|
|
1933
|
-
codes: ["x = 1"],
|
|
1934
|
-
ids: [firstCellId],
|
|
1935
|
-
codeIsStale: true,
|
|
1936
|
-
names: ["new_name"],
|
|
1937
|
-
configs: [{ hide_code: true, disabled: false, column: null }],
|
|
1938
|
-
});
|
|
1939
|
-
expect(state.cellData[firstCellId].name).toBe("new_name");
|
|
1940
|
-
expect(state.cellData[firstCellId].config.hide_code).toBe(true);
|
|
1941
|
-
});
|
|
1942
|
-
|
|
1943
|
-
it("can fold and unfold all cells", () => {
|
|
1944
|
-
actions.foldAll();
|
|
1945
|
-
expect(foldAllBulk).toHaveBeenCalled();
|
|
1946
|
-
|
|
1947
|
-
actions.unfoldAll();
|
|
1948
|
-
expect(unfoldAllBulk).toHaveBeenCalled();
|
|
1949
|
-
});
|
|
1494
|
+
actions.unfoldAll();
|
|
1495
|
+
expect(unfoldAllBulk).toHaveBeenCalled();
|
|
1496
|
+
});
|
|
1950
1497
|
|
|
1951
1498
|
it("can clear logs", () => {
|
|
1952
1499
|
state.cellLogs = [
|
|
@@ -1968,13 +1515,13 @@ describe("cell reducer", () => {
|
|
|
1968
1515
|
});
|
|
1969
1516
|
|
|
1970
1517
|
it("can collapse and expand cells", () => {
|
|
1971
|
-
|
|
1972
|
-
|
|
1518
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1519
|
+
seedCell({
|
|
1973
1520
|
cellId: cellId("1"),
|
|
1974
1521
|
before: false,
|
|
1975
1522
|
code: "# Header",
|
|
1976
1523
|
});
|
|
1977
|
-
|
|
1524
|
+
seedCell({
|
|
1978
1525
|
cellId: cellId("2"),
|
|
1979
1526
|
before: false,
|
|
1980
1527
|
code: "## Subheader",
|
|
@@ -1996,13 +1543,13 @@ describe("cell reducer", () => {
|
|
|
1996
1543
|
});
|
|
1997
1544
|
|
|
1998
1545
|
it("can collapse and expand all cells in multiple columns", () => {
|
|
1999
|
-
|
|
2000
|
-
|
|
1546
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1547
|
+
seedCell({
|
|
2001
1548
|
cellId: cellId("1"),
|
|
2002
1549
|
before: false,
|
|
2003
1550
|
code: "# First Column Header",
|
|
2004
1551
|
});
|
|
2005
|
-
|
|
1552
|
+
seedCell({
|
|
2006
1553
|
cellId: cellId("2"),
|
|
2007
1554
|
before: false,
|
|
2008
1555
|
code: "## First Column Subheader",
|
|
@@ -2010,12 +1557,12 @@ describe("cell reducer", () => {
|
|
|
2010
1557
|
|
|
2011
1558
|
actions.addColumnBreakpoint({ cellId: cellId("2") });
|
|
2012
1559
|
|
|
2013
|
-
|
|
1560
|
+
seedCell({
|
|
2014
1561
|
cellId: cellId("3"),
|
|
2015
1562
|
before: false,
|
|
2016
1563
|
code: "# Second Column Header",
|
|
2017
1564
|
});
|
|
2018
|
-
|
|
1565
|
+
seedCell({
|
|
2019
1566
|
cellId: cellId("4"),
|
|
2020
1567
|
before: false,
|
|
2021
1568
|
code: "## Second Column Subheader",
|
|
@@ -2063,18 +1610,18 @@ describe("cell reducer", () => {
|
|
|
2063
1610
|
});
|
|
2064
1611
|
|
|
2065
1612
|
it("can collapse and expand nested cells in one call", () => {
|
|
2066
|
-
|
|
2067
|
-
|
|
1613
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1614
|
+
seedCell({
|
|
2068
1615
|
cellId: cellId("1"),
|
|
2069
1616
|
before: false,
|
|
2070
1617
|
code: "# Header",
|
|
2071
1618
|
});
|
|
2072
|
-
|
|
1619
|
+
seedCell({
|
|
2073
1620
|
cellId: cellId("2"),
|
|
2074
1621
|
before: false,
|
|
2075
1622
|
code: "## Subheader",
|
|
2076
1623
|
});
|
|
2077
|
-
|
|
1624
|
+
seedCell({
|
|
2078
1625
|
cellId: cellId("3"),
|
|
2079
1626
|
before: false,
|
|
2080
1627
|
code: "### Subsubheader",
|
|
@@ -2118,18 +1665,18 @@ describe("cell reducer", () => {
|
|
|
2118
1665
|
});
|
|
2119
1666
|
|
|
2120
1667
|
it("can collapse all cells when nested heading ranges end at the same cell", () => {
|
|
2121
|
-
|
|
2122
|
-
|
|
1668
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1669
|
+
seedCell({
|
|
2123
1670
|
cellId: cellId("1"),
|
|
2124
1671
|
before: false,
|
|
2125
1672
|
code: "# Header",
|
|
2126
1673
|
});
|
|
2127
|
-
|
|
1674
|
+
seedCell({
|
|
2128
1675
|
cellId: cellId("2"),
|
|
2129
1676
|
before: false,
|
|
2130
1677
|
code: "## Subheader",
|
|
2131
1678
|
});
|
|
2132
|
-
|
|
1679
|
+
seedCell({
|
|
2133
1680
|
cellId: cellId("3"),
|
|
2134
1681
|
before: false,
|
|
2135
1682
|
code: "### Subsubheader",
|
|
@@ -2183,23 +1730,23 @@ describe("cell reducer", () => {
|
|
|
2183
1730
|
});
|
|
2184
1731
|
|
|
2185
1732
|
it("can collapse all cells when a deep chain is followed by a later section", () => {
|
|
2186
|
-
|
|
2187
|
-
|
|
1733
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1734
|
+
seedCell({
|
|
2188
1735
|
cellId: cellId("1"),
|
|
2189
1736
|
before: false,
|
|
2190
1737
|
code: "# Header",
|
|
2191
1738
|
});
|
|
2192
|
-
|
|
1739
|
+
seedCell({
|
|
2193
1740
|
cellId: cellId("2"),
|
|
2194
1741
|
before: false,
|
|
2195
1742
|
code: "## Section A",
|
|
2196
1743
|
});
|
|
2197
|
-
|
|
1744
|
+
seedCell({
|
|
2198
1745
|
cellId: cellId("3"),
|
|
2199
1746
|
before: false,
|
|
2200
1747
|
code: "### Sub of A",
|
|
2201
1748
|
});
|
|
2202
|
-
|
|
1749
|
+
seedCell({
|
|
2203
1750
|
cellId: cellId("4"),
|
|
2204
1751
|
before: false,
|
|
2205
1752
|
code: "## Section B",
|
|
@@ -2262,8 +1809,8 @@ describe("cell reducer", () => {
|
|
|
2262
1809
|
});
|
|
2263
1810
|
|
|
2264
1811
|
it("can show hidden cells", () => {
|
|
2265
|
-
|
|
2266
|
-
|
|
1812
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1813
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2267
1814
|
actions.collapseCell({ cellId: firstCellId });
|
|
2268
1815
|
|
|
2269
1816
|
actions.showCellIfHidden({ cellId: cellId("1") });
|
|
@@ -2273,7 +1820,7 @@ describe("cell reducer", () => {
|
|
|
2273
1820
|
});
|
|
2274
1821
|
|
|
2275
1822
|
it("can split and undo split cells", () => {
|
|
2276
|
-
|
|
1823
|
+
seedCell({
|
|
2277
1824
|
cellId: firstCellId,
|
|
2278
1825
|
before: false,
|
|
2279
1826
|
code: "line1\nline2",
|
|
@@ -2340,9 +1887,9 @@ describe("cell reducer", () => {
|
|
|
2340
1887
|
});
|
|
2341
1888
|
|
|
2342
1889
|
it("can add a column breakpoint", () => {
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
1890
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1891
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
1892
|
+
seedCell({ cellId: cellId("2"), before: false });
|
|
2346
1893
|
|
|
2347
1894
|
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2348
1895
|
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
@@ -2387,16 +1934,16 @@ describe("cell reducer", () => {
|
|
|
2387
1934
|
|
|
2388
1935
|
it("cannot add a column breakpoint before the first cell", () => {
|
|
2389
1936
|
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2390
|
-
|
|
2391
|
-
|
|
1937
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1938
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2392
1939
|
actions.addColumnBreakpoint({ cellId: firstCellId });
|
|
2393
1940
|
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2394
1941
|
});
|
|
2395
1942
|
|
|
2396
1943
|
it("can delete a column", () => {
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
1944
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1945
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
1946
|
+
seedCell({ cellId: cellId("2"), before: false });
|
|
2400
1947
|
actions.addColumnBreakpoint({ cellId: cellId("2") });
|
|
2401
1948
|
|
|
2402
1949
|
expect(state.cellIds.getColumns().length).toBe(2);
|
|
@@ -2440,8 +1987,8 @@ describe("cell reducer", () => {
|
|
|
2440
1987
|
});
|
|
2441
1988
|
|
|
2442
1989
|
it("deleting the last column does nothing", () => {
|
|
2443
|
-
|
|
2444
|
-
|
|
1990
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
1991
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2445
1992
|
|
|
2446
1993
|
const initialState = { ...state };
|
|
2447
1994
|
|
|
@@ -2452,9 +1999,9 @@ describe("cell reducer", () => {
|
|
|
2452
1999
|
});
|
|
2453
2000
|
|
|
2454
2001
|
it("can drop a cell over another cell", () => {
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2002
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
2003
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2004
|
+
seedCell({ cellId: cellId("2"), before: false });
|
|
2458
2005
|
|
|
2459
2006
|
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
2460
2007
|
"
|
|
@@ -2487,8 +2034,8 @@ describe("cell reducer", () => {
|
|
|
2487
2034
|
});
|
|
2488
2035
|
|
|
2489
2036
|
it("can drop a cell over a new column", () => {
|
|
2490
|
-
|
|
2491
|
-
|
|
2037
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
2038
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2492
2039
|
|
|
2493
2040
|
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2494
2041
|
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
@@ -2525,9 +2072,9 @@ describe("cell reducer", () => {
|
|
|
2525
2072
|
});
|
|
2526
2073
|
|
|
2527
2074
|
it("can drop a column over another column", () => {
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2075
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
2076
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2077
|
+
seedCell({ cellId: cellId("2"), before: false });
|
|
2531
2078
|
actions.addColumnBreakpoint({ cellId: cellId("2") });
|
|
2532
2079
|
|
|
2533
2080
|
expect(state.cellIds.getColumns().length).toBe(2);
|
|
@@ -2578,8 +2125,8 @@ describe("cell reducer", () => {
|
|
|
2578
2125
|
|
|
2579
2126
|
it("can compact columns", () => {
|
|
2580
2127
|
// Create initial state with 3 columns, including an empty one
|
|
2581
|
-
|
|
2582
|
-
|
|
2128
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
2129
|
+
seedCell({ cellId: cellId("1"), before: false });
|
|
2583
2130
|
actions.addColumnBreakpoint({ cellId: cellId("1") });
|
|
2584
2131
|
actions.addColumnBreakpoint({ cellId: cellId("2") });
|
|
2585
2132
|
actions.dropOverNewColumn({ cellId: cellId("2") });
|
|
@@ -2630,116 +2177,6 @@ describe("cell reducer", () => {
|
|
|
2630
2177
|
expect(state.cellIds.getColumns()[2].topLevelIds).toEqual([cellId("2")]);
|
|
2631
2178
|
});
|
|
2632
2179
|
|
|
2633
|
-
it("rebuildCellColumns regroups cells by config.column", () => {
|
|
2634
|
-
// Create four cells in a single column.
|
|
2635
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
2636
|
-
actions.createNewCell({ cellId: cellId("1"), before: false });
|
|
2637
|
-
actions.createNewCell({ cellId: cellId("2"), before: false });
|
|
2638
|
-
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2639
|
-
|
|
2640
|
-
// Explicitly set config.column on each cell. This ONLY updates metadata —
|
|
2641
|
-
// updateCellConfig does not touch the MultiColumn tree.
|
|
2642
|
-
actions.updateCellConfig({
|
|
2643
|
-
cellId: cellId("0"),
|
|
2644
|
-
config: { column: 0 },
|
|
2645
|
-
});
|
|
2646
|
-
actions.updateCellConfig({
|
|
2647
|
-
cellId: cellId("2"),
|
|
2648
|
-
config: { column: 1 },
|
|
2649
|
-
});
|
|
2650
|
-
|
|
2651
|
-
// Tree is still a single column at this point.
|
|
2652
|
-
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2653
|
-
|
|
2654
|
-
// Now rebuild the column tree from metadata.
|
|
2655
|
-
actions.rebuildCellColumns({
|
|
2656
|
-
cellIds: [cellId("0"), cellId("1"), cellId("2"), cellId("3")],
|
|
2657
|
-
});
|
|
2658
|
-
|
|
2659
|
-
expect(state.cellIds.getColumns().length).toBe(2);
|
|
2660
|
-
// Cell 1 inherits from 0 (col 0), cell 3 inherits from 2 (col 1).
|
|
2661
|
-
expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
|
|
2662
|
-
cellId("0"),
|
|
2663
|
-
cellId("1"),
|
|
2664
|
-
]);
|
|
2665
|
-
expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
|
|
2666
|
-
cellId("2"),
|
|
2667
|
-
cellId("3"),
|
|
2668
|
-
]);
|
|
2669
|
-
});
|
|
2670
|
-
|
|
2671
|
-
it("rebuildCellColumns with explicit column on every cell", () => {
|
|
2672
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
2673
|
-
actions.createNewCell({ cellId: cellId("1"), before: false });
|
|
2674
|
-
actions.createNewCell({ cellId: cellId("2"), before: false });
|
|
2675
|
-
|
|
2676
|
-
for (const [id, col] of [
|
|
2677
|
-
["0", 1],
|
|
2678
|
-
["1", 0],
|
|
2679
|
-
["2", 1],
|
|
2680
|
-
["3", 0],
|
|
2681
|
-
] as const) {
|
|
2682
|
-
actions.updateCellConfig({ cellId: cellId(id), config: { column: col } });
|
|
2683
|
-
}
|
|
2684
|
-
|
|
2685
|
-
actions.rebuildCellColumns({
|
|
2686
|
-
cellIds: [cellId("0"), cellId("1"), cellId("2"), cellId("3")],
|
|
2687
|
-
});
|
|
2688
|
-
|
|
2689
|
-
expect(state.cellIds.getColumns().length).toBe(2);
|
|
2690
|
-
expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
|
|
2691
|
-
cellId("1"),
|
|
2692
|
-
cellId("3"),
|
|
2693
|
-
]);
|
|
2694
|
-
expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
|
|
2695
|
-
cellId("0"),
|
|
2696
|
-
cellId("2"),
|
|
2697
|
-
]);
|
|
2698
|
-
});
|
|
2699
|
-
|
|
2700
|
-
it("rebuildCellColumns collapses to one column when all cells are col 0", () => {
|
|
2701
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
2702
|
-
actions.addColumnBreakpoint({ cellId: cellId("1") });
|
|
2703
|
-
expect(state.cellIds.getColumns().length).toBe(2);
|
|
2704
|
-
|
|
2705
|
-
// Wipe column metadata back to 0 for both cells.
|
|
2706
|
-
actions.updateCellConfig({ cellId: cellId("0"), config: { column: 0 } });
|
|
2707
|
-
actions.updateCellConfig({ cellId: cellId("1"), config: { column: 0 } });
|
|
2708
|
-
|
|
2709
|
-
actions.rebuildCellColumns({
|
|
2710
|
-
cellIds: [cellId("0"), cellId("1")],
|
|
2711
|
-
});
|
|
2712
|
-
|
|
2713
|
-
expect(state.cellIds.getColumns().length).toBe(1);
|
|
2714
|
-
expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([
|
|
2715
|
-
cellId("0"),
|
|
2716
|
-
cellId("1"),
|
|
2717
|
-
]);
|
|
2718
|
-
});
|
|
2719
|
-
|
|
2720
|
-
it("rebuildCellColumns follows the provided order, not current tree order", () => {
|
|
2721
|
-
// Start with a single column.
|
|
2722
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
2723
|
-
actions.createNewCell({ cellId: cellId("1"), before: false });
|
|
2724
|
-
actions.updateCellConfig({ cellId: cellId("0"), config: { column: 0 } });
|
|
2725
|
-
actions.updateCellConfig({ cellId: cellId("2"), config: { column: 1 } });
|
|
2726
|
-
|
|
2727
|
-
// Pass the reversed order. The rebuild should honor it.
|
|
2728
|
-
actions.rebuildCellColumns({
|
|
2729
|
-
cellIds: [cellId("2"), cellId("1"), cellId("0")],
|
|
2730
|
-
});
|
|
2731
|
-
|
|
2732
|
-
// cellIds iteration:
|
|
2733
|
-
// 2 → col=1, pushed to col1, prev=1
|
|
2734
|
-
// 1 → col=null, pushed to col[prev=1] = col1
|
|
2735
|
-
// 0 → col=0, pushed to col0
|
|
2736
|
-
expect(state.cellIds.getColumns()[0].topLevelIds).toEqual([cellId("0")]);
|
|
2737
|
-
expect(state.cellIds.getColumns()[1].topLevelIds).toEqual([
|
|
2738
|
-
cellId("2"),
|
|
2739
|
-
cellId("1"),
|
|
2740
|
-
]);
|
|
2741
|
-
});
|
|
2742
|
-
|
|
2743
2180
|
it("can clear output of a single cell", () => {
|
|
2744
2181
|
// Set up initial state with output
|
|
2745
2182
|
actions.handleCellMessage({
|
|
@@ -2828,7 +2265,7 @@ describe("cell reducer", () => {
|
|
|
2828
2265
|
|
|
2829
2266
|
it("can clear output of all cells", () => {
|
|
2830
2267
|
// Create multiple cells with output
|
|
2831
|
-
|
|
2268
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
2832
2269
|
const secondCellId = state.cellIds.atOrThrow(FIRST_COLUMN).atOrThrow(1);
|
|
2833
2270
|
|
|
2834
2271
|
// Add output to both cells
|
|
@@ -2875,121 +2312,9 @@ describe("cell reducer", () => {
|
|
|
2875
2312
|
expect(state.cellRuntime[secondCellId].consoleOutputs).toEqual([]);
|
|
2876
2313
|
});
|
|
2877
2314
|
|
|
2878
|
-
it("skips creating new cell if code exists and skipIfCodeExists is true", () => {
|
|
2879
|
-
// Add initial cell with code
|
|
2880
|
-
actions.updateCellCode({
|
|
2881
|
-
cellId: firstCellId,
|
|
2882
|
-
code: "import numpy as np",
|
|
2883
|
-
formattingChange: false,
|
|
2884
|
-
});
|
|
2885
|
-
|
|
2886
|
-
// Try to create new cell with same code and skipIfCodeExists
|
|
2887
|
-
actions.createNewCell({
|
|
2888
|
-
cellId: "__end__",
|
|
2889
|
-
code: "import numpy as np",
|
|
2890
|
-
before: false,
|
|
2891
|
-
skipIfCodeExists: true,
|
|
2892
|
-
});
|
|
2893
|
-
|
|
2894
|
-
// Should still only have one cell
|
|
2895
|
-
expect(state.cellIds.inOrderIds.length).toBe(1);
|
|
2896
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
2897
|
-
"
|
|
2898
|
-
[0] 'import numpy as np'
|
|
2899
|
-
"
|
|
2900
|
-
`);
|
|
2901
|
-
|
|
2902
|
-
// Verify we can still add cell with different code
|
|
2903
|
-
actions.createNewCell({
|
|
2904
|
-
cellId: "__end__",
|
|
2905
|
-
code: "import pandas as pd",
|
|
2906
|
-
before: false,
|
|
2907
|
-
skipIfCodeExists: true,
|
|
2908
|
-
});
|
|
2909
|
-
|
|
2910
|
-
expect(state.cellIds.inOrderIds.length).toBe(2);
|
|
2911
|
-
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
2912
|
-
"
|
|
2913
|
-
[0] 'import numpy as np'
|
|
2914
|
-
|
|
2915
|
-
[1] 'import pandas as pd'
|
|
2916
|
-
"
|
|
2917
|
-
`);
|
|
2918
|
-
});
|
|
2919
|
-
|
|
2920
|
-
it("can create and noop-update a setup cell", () => {
|
|
2921
|
-
// Create the setup cell
|
|
2922
|
-
actions.addSetupCellIfDoesntExist({ code: "# Setup code" });
|
|
2923
|
-
|
|
2924
|
-
// Check that setup cell was created
|
|
2925
|
-
expect(state.cellData[SETUP_CELL_ID].id).toBe(SETUP_CELL_ID);
|
|
2926
|
-
expect(state.cellData[SETUP_CELL_ID].name).toBe("setup");
|
|
2927
|
-
expect(state.cellData[SETUP_CELL_ID].code).toBe("# Setup code");
|
|
2928
|
-
expect(state.cellData[SETUP_CELL_ID].edited).toBe(true);
|
|
2929
|
-
expect(state.cellIds.inOrderIds).toContain(SETUP_CELL_ID);
|
|
2930
|
-
|
|
2931
|
-
// Update the setup cell
|
|
2932
|
-
actions.addSetupCellIfDoesntExist({ code: "# Updated setup code" });
|
|
2933
|
-
|
|
2934
|
-
// Check that the setup cell did not change, since it already exists
|
|
2935
|
-
expect(state.cellData[SETUP_CELL_ID].code).toBe("# Setup code");
|
|
2936
|
-
expect(state.cellData[SETUP_CELL_ID].edited).toBe(true);
|
|
2937
|
-
expect(state.cellIds.inOrderIds).toContain(SETUP_CELL_ID);
|
|
2938
|
-
});
|
|
2939
|
-
|
|
2940
|
-
it("can delete and undelete the setup cell", () => {
|
|
2941
|
-
// Create the setup cell
|
|
2942
|
-
actions.addSetupCellIfDoesntExist({ code: "# Setup code" });
|
|
2943
|
-
|
|
2944
|
-
// Check that setup cell was created
|
|
2945
|
-
expect(state.cellData[SETUP_CELL_ID].id).toBe(SETUP_CELL_ID);
|
|
2946
|
-
expect(state.cellData[SETUP_CELL_ID].name).toBe("setup");
|
|
2947
|
-
expect(state.cellData[SETUP_CELL_ID].code).toBe("# Setup code");
|
|
2948
|
-
expect(state.cellData[SETUP_CELL_ID].edited).toBe(true);
|
|
2949
|
-
expect(state.cellIds.inOrderIds).toContain(SETUP_CELL_ID);
|
|
2950
|
-
|
|
2951
|
-
// Delete the setup cell
|
|
2952
|
-
actions.deleteCell({ cellId: SETUP_CELL_ID });
|
|
2953
|
-
|
|
2954
|
-
// Check that setup cell was deleted
|
|
2955
|
-
expect(state.cellData[SETUP_CELL_ID]).toBeDefined(); // we keep old state
|
|
2956
|
-
expect(state.cellIds.inOrderIds).not.toContain(SETUP_CELL_ID);
|
|
2957
|
-
|
|
2958
|
-
// Undo delete the setup cell
|
|
2959
|
-
actions.undoDeleteCell();
|
|
2960
|
-
|
|
2961
|
-
// Check that setup cell was restored
|
|
2962
|
-
expect(state.cellData[SETUP_CELL_ID].id).toBe(SETUP_CELL_ID);
|
|
2963
|
-
expect(state.cellData[SETUP_CELL_ID].name).toBe("setup");
|
|
2964
|
-
expect(state.cellData[SETUP_CELL_ID].code).toBe("# Setup code");
|
|
2965
|
-
expect(state.cellData[SETUP_CELL_ID].edited).toBe(true);
|
|
2966
|
-
expect(state.cellIds.inOrderIds).toContain(SETUP_CELL_ID);
|
|
2967
|
-
|
|
2968
|
-
// Verify scrollKey is set to the restored setup cell
|
|
2969
|
-
expect(state.scrollKey).toBe(SETUP_CELL_ID);
|
|
2970
|
-
});
|
|
2971
|
-
|
|
2972
|
-
it("can delete and then create a new setup cell", () => {
|
|
2973
|
-
// Create the setup cell
|
|
2974
|
-
actions.addSetupCellIfDoesntExist({ code: "# Setup code" });
|
|
2975
|
-
|
|
2976
|
-
// Delete the setup cell
|
|
2977
|
-
actions.deleteCell({ cellId: SETUP_CELL_ID });
|
|
2978
|
-
|
|
2979
|
-
// Create a new setup cell
|
|
2980
|
-
actions.addSetupCellIfDoesntExist({ code: "# New code" });
|
|
2981
|
-
|
|
2982
|
-
// Check that the new setup cell was created
|
|
2983
|
-
expect(state.cellData[SETUP_CELL_ID].id).toBe(SETUP_CELL_ID);
|
|
2984
|
-
expect(state.cellData[SETUP_CELL_ID].name).toBe("setup");
|
|
2985
|
-
expect(state.cellData[SETUP_CELL_ID].code).toBe("# New code");
|
|
2986
|
-
expect(state.cellData[SETUP_CELL_ID].edited).toBe(true);
|
|
2987
|
-
expect(state.cellIds.inOrderIds).toContain(SETUP_CELL_ID);
|
|
2988
|
-
});
|
|
2989
|
-
|
|
2990
2315
|
it("can clear all outputs", () => {
|
|
2991
2316
|
// Add a cell and give it output
|
|
2992
|
-
|
|
2317
|
+
seedCell({
|
|
2993
2318
|
cellId: firstCellId,
|
|
2994
2319
|
before: false,
|
|
2995
2320
|
});
|
|
@@ -3017,202 +2342,14 @@ describe("cell reducer", () => {
|
|
|
3017
2342
|
expect(state.cellRuntime[cell2Id].output).toBeNull();
|
|
3018
2343
|
});
|
|
3019
2344
|
|
|
3020
|
-
describe("moveToNextCell", () => {
|
|
3021
|
-
let cell1Id: CellId;
|
|
3022
|
-
let cell2Id: CellId;
|
|
3023
|
-
let cell3Id: CellId;
|
|
3024
|
-
|
|
3025
|
-
beforeEach(() => {
|
|
3026
|
-
// Create a few cells to work with
|
|
3027
|
-
actions.createNewCell({ cellId: "__end__", before: false });
|
|
3028
|
-
actions.createNewCell({ cellId: "__end__", before: false });
|
|
3029
|
-
|
|
3030
|
-
cell1Id = state.cellIds.inOrderIds[0];
|
|
3031
|
-
cell2Id = state.cellIds.inOrderIds[1];
|
|
3032
|
-
cell3Id = state.cellIds.inOrderIds[2];
|
|
3033
|
-
});
|
|
3034
|
-
|
|
3035
|
-
it("creates new cell when moving after last cell with noCreate=false", () => {
|
|
3036
|
-
const initialCellCount = state.cellIds.inOrderIds.length;
|
|
3037
|
-
|
|
3038
|
-
actions.moveToNextCell({
|
|
3039
|
-
cellId: cell3Id,
|
|
3040
|
-
before: false,
|
|
3041
|
-
noCreate: false,
|
|
3042
|
-
});
|
|
3043
|
-
|
|
3044
|
-
expect(state.cellIds.inOrderIds.length).toBe(initialCellCount + 1);
|
|
3045
|
-
});
|
|
3046
|
-
|
|
3047
|
-
it("creates new cell when moving before first cell with noCreate=false", () => {
|
|
3048
|
-
const initialCellCount = state.cellIds.inOrderIds.length;
|
|
3049
|
-
|
|
3050
|
-
actions.moveToNextCell({
|
|
3051
|
-
cellId: cell1Id,
|
|
3052
|
-
before: true,
|
|
3053
|
-
noCreate: false,
|
|
3054
|
-
});
|
|
3055
|
-
|
|
3056
|
-
expect(state.cellIds.inOrderIds.length).toBe(initialCellCount + 1);
|
|
3057
|
-
});
|
|
3058
|
-
|
|
3059
|
-
it("does not create new cell when moving after last cell with noCreate=true", () => {
|
|
3060
|
-
const initialCellCount = state.cellIds.inOrderIds.length;
|
|
3061
|
-
const initialState = { ...state };
|
|
3062
|
-
|
|
3063
|
-
actions.moveToNextCell({
|
|
3064
|
-
cellId: cell3Id,
|
|
3065
|
-
before: false,
|
|
3066
|
-
noCreate: true,
|
|
3067
|
-
});
|
|
3068
|
-
|
|
3069
|
-
// Should not create a new cell
|
|
3070
|
-
expect(state.cellIds.inOrderIds.length).toBe(initialCellCount);
|
|
3071
|
-
// Should not crash or throw an error
|
|
3072
|
-
expect(state.cellIds.inOrderIds).toEqual(initialState.cellIds.inOrderIds);
|
|
3073
|
-
});
|
|
3074
|
-
|
|
3075
|
-
it("does not create new cell when moving before first cell with noCreate=true", () => {
|
|
3076
|
-
const initialCellCount = state.cellIds.inOrderIds.length;
|
|
3077
|
-
const initialState = { ...state };
|
|
3078
|
-
|
|
3079
|
-
actions.moveToNextCell({ cellId: cell1Id, before: true, noCreate: true });
|
|
3080
|
-
|
|
3081
|
-
// Should not create a new cell
|
|
3082
|
-
expect(state.cellIds.inOrderIds.length).toBe(initialCellCount);
|
|
3083
|
-
// Should not crash or throw an error
|
|
3084
|
-
expect(state.cellIds.inOrderIds).toEqual(initialState.cellIds.inOrderIds);
|
|
3085
|
-
});
|
|
3086
|
-
|
|
3087
|
-
it("focuses next cell when moving within bounds", () => {
|
|
3088
|
-
const focusSpy = vi.mocked(focusAndScrollCellIntoView);
|
|
3089
|
-
focusSpy.mockClear();
|
|
3090
|
-
|
|
3091
|
-
actions.moveToNextCell({
|
|
3092
|
-
cellId: cell1Id,
|
|
3093
|
-
before: false,
|
|
3094
|
-
noCreate: true,
|
|
3095
|
-
});
|
|
3096
|
-
|
|
3097
|
-
expect(focusSpy).toHaveBeenCalledWith({
|
|
3098
|
-
cellId: cell2Id,
|
|
3099
|
-
cell: state.cellHandles[cell2Id],
|
|
3100
|
-
isCodeHidden: false,
|
|
3101
|
-
codeFocus: "top",
|
|
3102
|
-
variableName: undefined,
|
|
3103
|
-
});
|
|
3104
|
-
});
|
|
3105
|
-
|
|
3106
|
-
it("focuses previous cell when moving backward within bounds", () => {
|
|
3107
|
-
const focusSpy = vi.mocked(focusAndScrollCellIntoView);
|
|
3108
|
-
focusSpy.mockClear();
|
|
3109
|
-
|
|
3110
|
-
actions.moveToNextCell({ cellId: cell2Id, before: true, noCreate: true });
|
|
3111
|
-
|
|
3112
|
-
expect(focusSpy).toHaveBeenCalledWith({
|
|
3113
|
-
cellId: cell1Id,
|
|
3114
|
-
cell: state.cellHandles[cell1Id],
|
|
3115
|
-
isCodeHidden: false,
|
|
3116
|
-
codeFocus: "bottom",
|
|
3117
|
-
variableName: undefined,
|
|
3118
|
-
});
|
|
3119
|
-
});
|
|
3120
|
-
|
|
3121
|
-
it("does not move focus from scratch cell", () => {
|
|
3122
|
-
const focusSpy = vi.mocked(focusAndScrollCellIntoView);
|
|
3123
|
-
focusSpy.mockClear();
|
|
3124
|
-
const initialState = { ...state };
|
|
3125
|
-
|
|
3126
|
-
actions.moveToNextCell({
|
|
3127
|
-
cellId: SCRATCH_CELL_ID,
|
|
3128
|
-
before: false,
|
|
3129
|
-
noCreate: false,
|
|
3130
|
-
});
|
|
3131
|
-
|
|
3132
|
-
expect(focusSpy).not.toHaveBeenCalled();
|
|
3133
|
-
expect(state.cellIds.inOrderIds).toEqual(initialState.cellIds.inOrderIds);
|
|
3134
|
-
});
|
|
3135
|
-
});
|
|
3136
|
-
|
|
3137
2345
|
describe("untouched cells functionality", () => {
|
|
3138
2346
|
it("starts with empty untouchedNewCells set", () => {
|
|
3139
2347
|
expect(state.untouchedNewCells).toEqual(new Set());
|
|
3140
2348
|
});
|
|
3141
2349
|
|
|
3142
|
-
it("can create a new cell with hideCode option", () => {
|
|
3143
|
-
const initialCellCount = state.cellIds.inOrderIds.length;
|
|
3144
|
-
|
|
3145
|
-
actions.createNewCell({
|
|
3146
|
-
cellId: "__end__",
|
|
3147
|
-
before: false,
|
|
3148
|
-
hideCode: true,
|
|
3149
|
-
});
|
|
3150
|
-
|
|
3151
|
-
expect(state.cellIds.inOrderIds.length).toBe(initialCellCount + 1);
|
|
3152
|
-
const newCellId =
|
|
3153
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3154
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3155
|
-
});
|
|
3156
|
-
|
|
3157
|
-
it("adds interactively-created hidden cell with boilerplate code to untouchedNewCells", () => {
|
|
3158
|
-
// Markdown cells are created with hideCode and non-empty default code
|
|
3159
|
-
// (e.g. `mo.md(r"""\n""")`). They are user-initiated, so their editor
|
|
3160
|
-
// should be shown until first blur.
|
|
3161
|
-
actions.createNewCell({
|
|
3162
|
-
cellId: "__end__",
|
|
3163
|
-
before: false,
|
|
3164
|
-
code: 'mo.md(r"""\n""")',
|
|
3165
|
-
hideCode: true,
|
|
3166
|
-
autoFocus: true,
|
|
3167
|
-
});
|
|
3168
|
-
|
|
3169
|
-
const newCellId =
|
|
3170
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3171
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3172
|
-
});
|
|
3173
|
-
|
|
3174
|
-
it("does not add programmatically-created hidden cell with code to untouchedNewCells", () => {
|
|
3175
|
-
// Cells created by the kernel (e.g. via code_mode) carry code and
|
|
3176
|
-
// autoFocus=false; their hide_code must take effect immediately.
|
|
3177
|
-
actions.createNewCell({
|
|
3178
|
-
cellId: "__end__",
|
|
3179
|
-
before: false,
|
|
3180
|
-
code: "x = 1",
|
|
3181
|
-
hideCode: true,
|
|
3182
|
-
autoFocus: false,
|
|
3183
|
-
});
|
|
3184
|
-
|
|
3185
|
-
const newCellId =
|
|
3186
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3187
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(false);
|
|
3188
|
-
});
|
|
3189
|
-
|
|
3190
|
-
it("does not add cell to untouchedNewCells when hideCode is false", () => {
|
|
3191
|
-
actions.createNewCell({
|
|
3192
|
-
cellId: "__end__",
|
|
3193
|
-
before: false,
|
|
3194
|
-
hideCode: false,
|
|
3195
|
-
});
|
|
3196
|
-
|
|
3197
|
-
const newCellId =
|
|
3198
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3199
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(false);
|
|
3200
|
-
});
|
|
3201
|
-
|
|
3202
|
-
it("does not add cell to untouchedNewCells when hideCode is undefined", () => {
|
|
3203
|
-
actions.createNewCell({
|
|
3204
|
-
cellId: "__end__",
|
|
3205
|
-
before: false,
|
|
3206
|
-
});
|
|
3207
|
-
|
|
3208
|
-
const newCellId =
|
|
3209
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3210
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(false);
|
|
3211
|
-
});
|
|
3212
|
-
|
|
3213
2350
|
it("can mark a cell as touched", () => {
|
|
3214
2351
|
// Create a cell with hideCode
|
|
3215
|
-
|
|
2352
|
+
seedCell({
|
|
3216
2353
|
cellId: "__end__",
|
|
3217
2354
|
before: false,
|
|
3218
2355
|
hideCode: true,
|
|
@@ -3230,7 +2367,7 @@ describe("cell reducer", () => {
|
|
|
3230
2367
|
|
|
3231
2368
|
it("markTouched is idempotent", () => {
|
|
3232
2369
|
// Create a cell with hideCode
|
|
3233
|
-
|
|
2370
|
+
seedCell({
|
|
3234
2371
|
cellId: "__end__",
|
|
3235
2372
|
before: false,
|
|
3236
2373
|
hideCode: true,
|
|
@@ -3260,17 +2397,17 @@ describe("cell reducer", () => {
|
|
|
3260
2397
|
|
|
3261
2398
|
it("can handle multiple untouched cells", () => {
|
|
3262
2399
|
// Create multiple cells with hideCode
|
|
3263
|
-
|
|
2400
|
+
seedCell({
|
|
3264
2401
|
cellId: "__end__",
|
|
3265
2402
|
before: false,
|
|
3266
2403
|
hideCode: true,
|
|
3267
2404
|
});
|
|
3268
|
-
|
|
2405
|
+
seedCell({
|
|
3269
2406
|
cellId: "__end__",
|
|
3270
2407
|
before: false,
|
|
3271
2408
|
hideCode: true,
|
|
3272
2409
|
});
|
|
3273
|
-
|
|
2410
|
+
seedCell({
|
|
3274
2411
|
cellId: "__end__",
|
|
3275
2412
|
before: false,
|
|
3276
2413
|
hideCode: false,
|
|
@@ -3295,12 +2432,12 @@ describe("cell reducer", () => {
|
|
|
3295
2432
|
|
|
3296
2433
|
it("preserves untouched state when cells are moved", () => {
|
|
3297
2434
|
// Create cells with hideCode
|
|
3298
|
-
|
|
2435
|
+
seedCell({
|
|
3299
2436
|
cellId: "__end__",
|
|
3300
2437
|
before: false,
|
|
3301
2438
|
hideCode: true,
|
|
3302
2439
|
});
|
|
3303
|
-
|
|
2440
|
+
seedCell({
|
|
3304
2441
|
cellId: "__end__",
|
|
3305
2442
|
before: false,
|
|
3306
2443
|
hideCode: true,
|
|
@@ -3324,58 +2461,9 @@ describe("cell reducer", () => {
|
|
|
3324
2461
|
expect(state.untouchedNewCells.has(cell2Id)).toBe(true);
|
|
3325
2462
|
});
|
|
3326
2463
|
|
|
3327
|
-
it("does not remove untouched state when cell is deleted", () => {
|
|
3328
|
-
// We could implement this, but it doesn't actually affect downstream behavior.
|
|
3329
|
-
// It is easier to leave it, so `undo` works as expected.
|
|
3330
|
-
|
|
3331
|
-
// Create a cell with hideCode
|
|
3332
|
-
actions.createNewCell({
|
|
3333
|
-
cellId: "__end__",
|
|
3334
|
-
before: false,
|
|
3335
|
-
hideCode: true,
|
|
3336
|
-
});
|
|
3337
|
-
|
|
3338
|
-
const newCellId =
|
|
3339
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3340
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3341
|
-
|
|
3342
|
-
// Delete the cell
|
|
3343
|
-
actions.deleteCell({ cellId: newCellId });
|
|
3344
|
-
|
|
3345
|
-
// Does not actually remove untouched state
|
|
3346
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3347
|
-
});
|
|
3348
|
-
|
|
3349
|
-
it("restores untouched state when cell deletion is undone", () => {
|
|
3350
|
-
// Create a cell with hideCode
|
|
3351
|
-
actions.createNewCell({
|
|
3352
|
-
cellId: "__end__",
|
|
3353
|
-
before: false,
|
|
3354
|
-
hideCode: true,
|
|
3355
|
-
});
|
|
3356
|
-
|
|
3357
|
-
const newCellId =
|
|
3358
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3359
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3360
|
-
|
|
3361
|
-
// Delete the cell
|
|
3362
|
-
actions.deleteCell({ cellId: newCellId });
|
|
3363
|
-
// Still exists in untouchedNewCells
|
|
3364
|
-
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
3365
|
-
|
|
3366
|
-
// Undo the deletion
|
|
3367
|
-
actions.undoDeleteCell();
|
|
3368
|
-
|
|
3369
|
-
// The cell should be restored but no longer untouched
|
|
3370
|
-
// (this is expected behavior - undoing doesn't restore untouched state)
|
|
3371
|
-
const restoredCellId =
|
|
3372
|
-
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3373
|
-
expect(state.untouchedNewCells.has(restoredCellId)).toBe(false);
|
|
3374
|
-
});
|
|
3375
|
-
|
|
3376
2464
|
it("untouched cell behavior with hide_code config", () => {
|
|
3377
2465
|
// Create a cell with hideCode and hide_code config
|
|
3378
|
-
|
|
2466
|
+
seedCell({
|
|
3379
2467
|
cellId: "__end__",
|
|
3380
2468
|
before: false,
|
|
3381
2469
|
hideCode: true,
|
|
@@ -3384,11 +2472,11 @@ describe("cell reducer", () => {
|
|
|
3384
2472
|
const newCellId =
|
|
3385
2473
|
state.cellIds.inOrderIds[state.cellIds.inOrderIds.length - 1];
|
|
3386
2474
|
|
|
3387
|
-
//
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
config: { hide_code: true },
|
|
3391
|
-
}
|
|
2475
|
+
// The document hides the cell's code
|
|
2476
|
+
state.cellData[newCellId] = {
|
|
2477
|
+
...state.cellData[newCellId],
|
|
2478
|
+
config: { ...state.cellData[newCellId].config, hide_code: true },
|
|
2479
|
+
};
|
|
3392
2480
|
|
|
3393
2481
|
// Cell should be untouched and have hide_code config
|
|
3394
2482
|
expect(state.untouchedNewCells.has(newCellId)).toBe(true);
|
|
@@ -3407,7 +2495,7 @@ describe("cell reducer", () => {
|
|
|
3407
2495
|
|
|
3408
2496
|
it("can mark an existing cell as untouched", () => {
|
|
3409
2497
|
// Create a cell without hideCode (not in untouchedNewCells)
|
|
3410
|
-
|
|
2498
|
+
seedCell({
|
|
3411
2499
|
cellId: "__end__",
|
|
3412
2500
|
before: false,
|
|
3413
2501
|
hideCode: false,
|
|
@@ -3425,7 +2513,7 @@ describe("cell reducer", () => {
|
|
|
3425
2513
|
|
|
3426
2514
|
it("markUntouched is idempotent", () => {
|
|
3427
2515
|
// Create a cell without hideCode
|
|
3428
|
-
|
|
2516
|
+
seedCell({
|
|
3429
2517
|
cellId: "__end__",
|
|
3430
2518
|
before: false,
|
|
3431
2519
|
hideCode: false,
|
|
@@ -3445,7 +2533,7 @@ describe("cell reducer", () => {
|
|
|
3445
2533
|
|
|
3446
2534
|
it("markUntouched does not affect already untouched cells", () => {
|
|
3447
2535
|
// Create a cell with hideCode (already in untouchedNewCells)
|
|
3448
|
-
|
|
2536
|
+
seedCell({
|
|
3449
2537
|
cellId: "__end__",
|
|
3450
2538
|
before: false,
|
|
3451
2539
|
hideCode: true,
|
|
@@ -3463,7 +2551,7 @@ describe("cell reducer", () => {
|
|
|
3463
2551
|
|
|
3464
2552
|
it("markTouched and markUntouched can toggle cell state", () => {
|
|
3465
2553
|
// Create a cell without hideCode
|
|
3466
|
-
|
|
2554
|
+
seedCell({
|
|
3467
2555
|
cellId: "__end__",
|
|
3468
2556
|
before: false,
|
|
3469
2557
|
hideCode: false,
|
|
@@ -3491,7 +2579,7 @@ describe("cell reducer", () => {
|
|
|
3491
2579
|
it("markUntouched works for markdown cell conversion scenario", () => {
|
|
3492
2580
|
// Simulates converting a Python cell to Markdown
|
|
3493
2581
|
// 1. Create a regular cell (no hideCode)
|
|
3494
|
-
|
|
2582
|
+
seedCell({
|
|
3495
2583
|
cellId: "__end__",
|
|
3496
2584
|
before: false,
|
|
3497
2585
|
hideCode: false,
|
|
@@ -3505,11 +2593,12 @@ describe("cell reducer", () => {
|
|
|
3505
2593
|
expect(state.untouchedNewCells.has(cellId)).toBe(false);
|
|
3506
2594
|
expect(exportedForTesting.isCellCodeHidden(state, cellId)).toBe(false);
|
|
3507
2595
|
|
|
3508
|
-
// 2. Convert to markdown:
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
2596
|
+
// 2. Convert to markdown: the document hides the code, and the cell
|
|
2597
|
+
// is marked untouched
|
|
2598
|
+
state.cellData[cellId] = {
|
|
2599
|
+
...state.cellData[cellId],
|
|
2600
|
+
config: { ...state.cellData[cellId].config, hide_code: true },
|
|
2601
|
+
};
|
|
3513
2602
|
actions.markUntouched({ cellId });
|
|
3514
2603
|
|
|
3515
2604
|
// Code should NOT be hidden because cell is untouched (user can edit)
|
|
@@ -3531,7 +2620,7 @@ describe("cell reducer", () => {
|
|
|
3531
2620
|
const { cellDataAtom, cellRuntimeAtom, cellHandleAtom } =
|
|
3532
2621
|
exportedForTesting;
|
|
3533
2622
|
|
|
3534
|
-
|
|
2623
|
+
seedCell({ cellId: firstCellId, before: false });
|
|
3535
2624
|
const newCellId = state.cellIds.inOrderIds[1];
|
|
3536
2625
|
|
|
3537
2626
|
const dataAtom1 = cellDataAtom(newCellId);
|
|
@@ -3547,31 +2636,6 @@ describe("cell reducer", () => {
|
|
|
3547
2636
|
expect(runtimeAtom2).toBe(runtimeAtom1);
|
|
3548
2637
|
expect(handleAtom2).toBe(handleAtom1);
|
|
3549
2638
|
});
|
|
3550
|
-
|
|
3551
|
-
it("cleans up atom family cache when cells are deleted", () => {
|
|
3552
|
-
const { cellDataAtom, cellRuntimeAtom, cellHandleAtom } =
|
|
3553
|
-
exportedForTesting;
|
|
3554
|
-
|
|
3555
|
-
actions.createNewCell({ cellId: firstCellId, before: false });
|
|
3556
|
-
const newCellId = state.cellIds.inOrderIds[1];
|
|
3557
|
-
|
|
3558
|
-
// Access to create cache entries
|
|
3559
|
-
const dataAtom1 = cellDataAtom(newCellId);
|
|
3560
|
-
const runtimeAtom1 = cellRuntimeAtom(newCellId);
|
|
3561
|
-
const handleAtom1 = cellHandleAtom(newCellId);
|
|
3562
|
-
|
|
3563
|
-
// Triggers purge
|
|
3564
|
-
actions.deleteCell({ cellId: newCellId });
|
|
3565
|
-
|
|
3566
|
-
// Access again (should be new instances after cleanup)
|
|
3567
|
-
const dataAtom2 = cellDataAtom(newCellId);
|
|
3568
|
-
const runtimeAtom2 = cellRuntimeAtom(newCellId);
|
|
3569
|
-
const handleAtom2 = cellHandleAtom(newCellId);
|
|
3570
|
-
|
|
3571
|
-
expect(dataAtom2).not.toBe(dataAtom1);
|
|
3572
|
-
expect(runtimeAtom2).not.toBe(runtimeAtom1);
|
|
3573
|
-
expect(handleAtom2).not.toBe(handleAtom1);
|
|
3574
|
-
});
|
|
3575
2639
|
});
|
|
3576
2640
|
});
|
|
3577
2641
|
|
|
@@ -3886,31 +2950,9 @@ describe("createTracebackInfoAtom", () => {
|
|
|
3886
2950
|
});
|
|
3887
2951
|
});
|
|
3888
2952
|
|
|
3889
|
-
describe("
|
|
2953
|
+
describe("kernel-ready", () => {
|
|
3890
2954
|
const CELL_A = cellId("A");
|
|
3891
2955
|
const CELL_B = cellId("B");
|
|
3892
|
-
const newCells: CellData[] = [
|
|
3893
|
-
{
|
|
3894
|
-
id: CELL_A,
|
|
3895
|
-
name: "a",
|
|
3896
|
-
code: "1",
|
|
3897
|
-
edited: false,
|
|
3898
|
-
lastCodeRun: null,
|
|
3899
|
-
lastExecutionTime: null,
|
|
3900
|
-
config: { hide_code: false, disabled: false, column: null },
|
|
3901
|
-
serializedEditorState: null,
|
|
3902
|
-
},
|
|
3903
|
-
{
|
|
3904
|
-
id: CELL_B,
|
|
3905
|
-
name: "b",
|
|
3906
|
-
code: "2",
|
|
3907
|
-
edited: false,
|
|
3908
|
-
lastCodeRun: null,
|
|
3909
|
-
lastExecutionTime: null,
|
|
3910
|
-
config: { hide_code: false, disabled: false, column: null },
|
|
3911
|
-
serializedEditorState: null,
|
|
3912
|
-
},
|
|
3913
|
-
];
|
|
3914
2956
|
|
|
3915
2957
|
const hydratedState = () =>
|
|
3916
2958
|
MockNotebook.notebookState({
|
|
@@ -3940,44 +2982,97 @@ describe("setCells snapshot preservation", () => {
|
|
|
3940
2982
|
},
|
|
3941
2983
|
});
|
|
3942
2984
|
|
|
3943
|
-
|
|
3944
|
-
const
|
|
3945
|
-
|
|
2985
|
+
it("setLastRun records what the kernel last ran", () => {
|
|
2986
|
+
const state = hydratedState();
|
|
2987
|
+
const next = exportedForTesting.reducer(state, {
|
|
2988
|
+
type: "setLastRun",
|
|
2989
|
+
payload: {
|
|
2990
|
+
lastCodeRun: { [CELL_A]: "0" },
|
|
2991
|
+
lastExecutionTime: { [CELL_A]: 5 },
|
|
2992
|
+
},
|
|
2993
|
+
});
|
|
2994
|
+
|
|
2995
|
+
expect(next.cellData[CELL_A]).toMatchObject({
|
|
2996
|
+
lastCodeRun: "0",
|
|
2997
|
+
lastExecutionTime: 5,
|
|
2998
|
+
edited: true,
|
|
2999
|
+
});
|
|
3000
|
+
expect(next.cellData[CELL_B]).toMatchObject({
|
|
3001
|
+
lastCodeRun: null,
|
|
3002
|
+
lastExecutionTime: null,
|
|
3003
|
+
edited: false,
|
|
3004
|
+
});
|
|
3005
|
+
expect(next.cellRuntime).toBe(state.cellRuntime);
|
|
3946
3006
|
});
|
|
3947
3007
|
|
|
3948
|
-
it("
|
|
3008
|
+
it("resetCellRuntimes starts every cell's runtime over", () => {
|
|
3949
3009
|
const next = exportedForTesting.reducer(hydratedState(), {
|
|
3950
|
-
type: "
|
|
3951
|
-
payload:
|
|
3010
|
+
type: "resetCellRuntimes",
|
|
3011
|
+
payload: undefined,
|
|
3952
3012
|
});
|
|
3953
3013
|
|
|
3954
|
-
expect(next.cellRuntime[CELL_A].output).
|
|
3955
|
-
|
|
3014
|
+
expect(next.cellRuntime[CELL_A].output).toBeNull();
|
|
3015
|
+
expect(next.cellRuntime[CELL_B].consoleOutputs).toEqual([]);
|
|
3016
|
+
});
|
|
3017
|
+
|
|
3018
|
+
it("resetCellRuntimes starts the scratch cell over too", () => {
|
|
3019
|
+
const state = MockNotebook.notebookState({
|
|
3020
|
+
cellData: { [CELL_A]: { id: CELL_A, code: "1" } },
|
|
3021
|
+
cellRuntime: {
|
|
3022
|
+
[SCRATCH_CELL_ID]: {
|
|
3023
|
+
output: {
|
|
3024
|
+
channel: "output",
|
|
3025
|
+
mimetype: "text/plain",
|
|
3026
|
+
data: "scratch",
|
|
3027
|
+
timestamp: 0,
|
|
3028
|
+
},
|
|
3029
|
+
},
|
|
3030
|
+
},
|
|
3031
|
+
});
|
|
3032
|
+
const next = exportedForTesting.reducer(state, {
|
|
3033
|
+
type: "resetCellRuntimes",
|
|
3034
|
+
payload: undefined,
|
|
3956
3035
|
});
|
|
3036
|
+
|
|
3037
|
+
expect(next.cellRuntime[SCRATCH_CELL_ID].output).toBeNull();
|
|
3957
3038
|
});
|
|
3958
3039
|
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3040
|
+
describe("resetCellRuntimes in WASM", () => {
|
|
3041
|
+
beforeEach(async () => {
|
|
3042
|
+
const { isWasm } = await import("@/core/wasm/utils");
|
|
3043
|
+
vi.mocked(isWasm).mockReturnValue(true);
|
|
3963
3044
|
});
|
|
3964
3045
|
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3046
|
+
afterEach(async () => {
|
|
3047
|
+
const { isWasm } = await import("@/core/wasm/utils");
|
|
3048
|
+
vi.mocked(isWasm).mockReturnValue(false);
|
|
3968
3049
|
});
|
|
3969
|
-
});
|
|
3970
3050
|
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3051
|
+
it("keeps hydrated outputs and console", () => {
|
|
3052
|
+
const next = exportedForTesting.reducer(hydratedState(), {
|
|
3053
|
+
type: "resetCellRuntimes",
|
|
3054
|
+
payload: undefined,
|
|
3055
|
+
});
|
|
3056
|
+
|
|
3057
|
+
expect(next.cellRuntime[CELL_A].output).toMatchObject({
|
|
3058
|
+
data: "hydrated-A",
|
|
3059
|
+
});
|
|
3060
|
+
expect(next.cellRuntime[CELL_B].consoleOutputs[0]).toMatchObject({
|
|
3061
|
+
data: "hydrated-B-stdout",
|
|
3062
|
+
});
|
|
3976
3063
|
});
|
|
3977
3064
|
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3065
|
+
it("starts cells with no prior runtime over", () => {
|
|
3066
|
+
const state = MockNotebook.notebookState({
|
|
3067
|
+
cellData: { [CELL_A]: { id: CELL_A, code: "1" } },
|
|
3068
|
+
});
|
|
3069
|
+
const next = exportedForTesting.reducer(state, {
|
|
3070
|
+
type: "resetCellRuntimes",
|
|
3071
|
+
payload: undefined,
|
|
3072
|
+
});
|
|
3073
|
+
|
|
3074
|
+
expect(next.cellRuntime[CELL_A].output).toBeNull();
|
|
3075
|
+
expect(next.cellRuntime[CELL_A].consoleOutputs).toEqual([]);
|
|
3076
|
+
});
|
|
3982
3077
|
});
|
|
3983
3078
|
});
|