@marimo-team/islands 0.25.3-dev27 → 0.25.3-dev270
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-DfG3PRaJ.js → ConnectedDataExplorerComponent-eLHPh6uu.js} +120 -116
- package/dist/{ErrorBoundary-DKAio_E4.js → ErrorBoundary-BDom11jj.js} +66 -71
- package/dist/_baseSet-BfI5FjBM.js +328 -0
- package/dist/{abnfDiagram-VCTEODGH-B3w-XWX8.js → abnfDiagram-VCTEODGH-hqd0IBtX.js} +2 -2
- package/dist/any-language-editor-DnG26QXh.js +75 -0
- package/dist/{architectureDiagram-5GKGNRK7-C18U9A6k.js → architectureDiagram-5GKGNRK7-BzLAFcc0.js} +1 -1
- package/dist/{arrays-CN1djC4k.js → arrays-DoQ-AILx.js} +15 -27
- package/dist/assertNever-DIU3JJbt.js +507 -0
- package/dist/assets/__vite-browser-external-BKBpimif.js +1 -0
- package/dist/assets/worker-CgoMtD-_.js +113 -0
- package/dist/{blockDiagram-I7D4REHJ-Cg25UrxT.js → blockDiagram-I7D4REHJ-Dkhe6_PP.js} +1 -1
- package/dist/{button-CvjkwdSk.js → button-0-RqY1DW.js} +229 -218
- package/dist/{capabilities-CQ5IjhzL.js → capabilities-B6yy_CBN.js} +2 -2
- package/dist/{chat-ui-DDJuqS87.js → chat-ui-BWIkve2R.js} +2071 -1780
- package/dist/{check-BMKBBrdc.js → check-gUSZbRsl.js} +1 -1
- package/dist/{chunk-IMKFNOWR-CrS5bzqW.js → chunk-IMKFNOWR-DOeVvuyE.js} +1 -1
- package/dist/{chunk-SHT3W25Y-StpvPvUG.js → chunk-SHT3W25Y-DZoFI8wR.js} +1 -1
- package/dist/{chunk-SVP7TREG-CBXjbYZC.js → chunk-SVP7TREG-CWu86PSW.js} +1 -1
- package/dist/{chunk-TICWLB2K-Dp6bIb-q.js → chunk-TICWLB2K-BrM0GoP3.js} +1 -1
- package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
- package/dist/{classDiagram-ZZMXUADV-BFYuxV5g.js → classDiagram-ZZMXUADV-DYi4V2bB.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-D_tjXVMl.js → classDiagram-v2-VYDZK3BY-tN7FIk-m.js} +2 -2
- package/dist/{code-visibility-CFvLbCZJ.js → code-visibility-BWNUti7D.js} +43 -50
- package/dist/{common-1HUDUr7W.js → common-bFQY94fl.js} +10277 -9719
- package/dist/config-BsPruWMR.js +636 -0
- package/dist/{copy-icon-BgUO8jsi.js → copy-icon-C2I8sw4h.js} +3 -3
- package/dist/createReducer-DdtT_7ji.js +67 -0
- package/dist/{cynefinDiagram-5FMLGOSQ-DSgYrHB2.js → cynefinDiagram-5FMLGOSQ-D5nCnDc-.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-GYlruCBf.js → dagre-GXQ25YYZ-BHkd7f_i.js} +3 -3
- package/dist/{dagre-BGSfXNEb.js → dagre-mqiMAsFY.js} +531 -680
- package/dist/{data-grid-overlay-editor-ZxoN8gVB.js → data-grid-overlay-editor-CVQ68_by.js} +5 -5
- package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
- package/dist/{debounce-C3jyATpc.js → debounce-DrhhziJv.js} +2 -2
- package/dist/{diagram-S7CK7UJ4-DRu5LX5_.js → diagram-S7CK7UJ4-D1ALppT2.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-DD7uiejP.js → diagram-UQ7AKVKN-DLv0b83L.js} +1 -1
- package/dist/{diagram-VX7I27RA-ByH9KAJJ.js → diagram-VX7I27RA-7XJ7J6qg.js} +1 -1
- package/dist/{diagram-Z3DM3KII-BsQHPRke.js → diagram-Z3DM3KII-7M7zbHp_.js} +1 -1
- package/dist/{dialog-Cc479ZEH.js → dialog-DzCj1qQv.js} +26 -26
- package/dist/{dist-Bvs24R_E.js → dist-11T5wq3_.js} +31 -30
- package/dist/{dist-F8Ep36rk.js → dist-17ugwGZc.js} +59 -58
- package/dist/{dist-BMQf5zIS.js → dist-7cRjf--y.js} +123 -122
- package/dist/{dist-diIx5qJW.js → dist-B8pkfkzc.js} +31 -30
- package/dist/{dist-CN_BeG2I.js → dist-B9UoM_wq.js} +58 -57
- package/dist/{dist-CLdpGQVr.js → dist-BGuMTs1i.js} +118 -117
- package/dist/{dist-BK4Oj99o.js → dist-BHW11fni.js} +18 -17
- package/dist/dist-BLY4m1Wi.js +850 -0
- package/dist/{dist-PXYI_yuP.js → dist-BNlcVoxs.js} +24 -23
- package/dist/{dist-D6d86eNJ.js → dist-BQYe5Bju.js} +47 -46
- package/dist/{dist-CkTTIdBe.js → dist-BX1mn8na.js} +337 -337
- package/dist/{dist-DiDibOYr.js → dist-Bh0PTKUW.js} +151 -150
- package/dist/{dist-CSJ0MDRw.js → dist-CKaXK92p.js} +56 -55
- package/dist/{dist-C8fAKSH1.js → dist-CLhwfhpJ.js} +53 -52
- package/dist/{dist-DoE4XJBC.js → dist-CYeqK4Xw.js} +9801 -10649
- package/dist/{dist-BLfKmR-l.js → dist-Cxlp3WH6.js} +16 -15
- package/dist/{dist-D-wwqlzJ.js → dist-DSJPGj42.js} +158 -157
- package/dist/{dist-BorMD-uX.js → dist-DU9ICsWZ.js} +75 -74
- package/dist/{dist-DBtSl3sf.js → dist-DWv0ALBi.js} +47 -46
- package/dist/{dist-OR1OnN-y.js → dist-DiBpWEsB.js} +31 -30
- package/dist/{dist-CrSP_H1M.js → dist-DiLFTlnl.js} +242 -242
- package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
- package/dist/{dist-CN8zI-XC.js → dist-X9CsotJl.js} +239 -239
- package/dist/{dist-CSbh1PNP.js → dist-cVDV5IuI.js} +23 -22
- package/dist/{dist-BuaRHxOc.js → dist-fRfaOoq8.js} +44 -43
- package/dist/{dist-Cg7gzw-a.js → dist-gTTI-9Px.js} +78 -77
- package/dist/dropdown-menu-CdXE15an.js +6089 -0
- package/dist/{ebnfDiagram-PWID7BFC-CQRK5_eT.js → ebnfDiagram-PWID7BFC-DHH1qlmV.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-BKtWrDVh.js → erDiagram-RLTQ6QDP-fI_0dGef.js} +1 -1
- package/dist/{error-banner-CFPHFw4h.js → error-banner-DPc9eIw5.js} +87 -86
- package/dist/error-entries-CxN-Nq3V.js +2573 -0
- package/dist/{esm-AMFssoNp.js → esm-BDqqT86j.js} +329 -329
- package/dist/{esm-D2gTsXEV.js → esm-BgKjMvWw.js} +530 -529
- package/dist/feedback-button-D9dvgMiT.js +374 -0
- package/dist/{flowDiagram-HODETNUW-1IN-ih2E.js → flowDiagram-HODETNUW-Brg9MA6i.js} +2 -2
- package/dist/{formats-Buu00Z2q.js → formats-DbSvAPY-.js} +6 -6
- package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
- package/dist/{glide-data-editor-BBgCAPbk.js → glide-data-editor-DRBPJNtK.js} +6676 -2890
- package/dist/{glide-utils-DM9zBO4W.js → glide-utils-BSw3SSHF.js} +84 -45
- package/dist/{globals-DhH_o2tF.js → globals-CDnhWJOj.js} +3 -3
- package/dist/{graphlib-BmY_CCV9.js → graphlib-nlwT3Wvy.js} +177 -220
- package/dist/hasIn-C20JsQ2m.js +28 -0
- package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
- package/dist/{error-entries-Cz3yNs7w.js → html-to-image-Bc2AvXHG.js} +26695 -26850
- package/dist/{infoDiagram-27XIBGKW-CkB-zr4p.js → infoDiagram-27XIBGKW-E9e403YT.js} +1 -1
- package/dist/isArrayLikeObject-B-HXCsex.js +626 -0
- package/dist/isEmpty-CdX7MTE1.js +14 -0
- package/dist/{ishikawaDiagram-5VMMS53U-wlyLjBmM.js → ishikawaDiagram-5VMMS53U-C-RlYDRo.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-C2usY0i-.js → kanban-definition-UXKFOSKX-CLFl_uqK.js} +1 -1
- package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
- package/dist/{loader-BQOfjTIJ.js → loader-BVEtQ4F3.js} +12 -12
- package/dist/main.js +10420 -8311
- package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
- package/dist/{mermaid-BA-Z6wGL.js → mermaid-rd09e1JL.js} +54 -54
- package/dist/{mindmap-definition-YA3MSWOX-nKOWS8RR.js → mindmap-definition-YA3MSWOX-BQ8TWtyB.js} +1 -1
- package/dist/{now-jM8-M7IR.js → now-BKZCLE5P.js} +12 -13
- package/dist/{number-overlay-editor-CvLhxHLb.js → number-overlay-editor-CkcPsvT7.js} +3 -3
- package/dist/{objects-CzUgoMIF.js → objects-DCmMvZtn.js} +1 -3
- package/dist/{once-BtE-wKRL.js → once-NnpX_HnX.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-Dac9EIKD.js → pegDiagram-XKGWAZYB-CN8UHFPi.js} +2 -2
- package/dist/pencil-DcT8AE0h.js +10 -0
- package/dist/pick-tCszMUbm.js +35 -0
- package/dist/{pieDiagram-E7YTZNPT-B7S-DsW_.js → pieDiagram-E7YTZNPT-DGuJ0EBd.js} +1 -1
- package/dist/precisionRound-DhAzeRcm.js +49 -0
- package/dist/{process-output-B-KBO95p.js → process-output-qecD7Dk8.js} +4 -4
- package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
- package/dist/{railroadDiagram-O6MQD6OU-Cfa5Q-hr.js → railroadDiagram-O6MQD6OU-BPDA8wy8.js} +2 -2
- package/dist/{react-vega-BED0DjiB.js → react-vega-C4T9Rb_w.js} +12284 -12270
- package/dist/{requirementDiagram-BXWQKSXE-d8zXCJIk.js → requirementDiagram-BXWQKSXE-ChzLGbGW.js} +1 -1
- package/dist/{reveal-component-C9BavSsS.js → reveal-component-DMHnoLjA.js} +1131 -1108
- package/dist/schemas-CdscWNy_.js +4747 -0
- package/dist/select-OxgozOC8.js +1200 -0
- package/dist/{sequenceDiagram-WJ2MYXX4-b6pei3lJ.js → sequenceDiagram-WJ2MYXX4-DFX-bE6O.js} +1 -1
- package/dist/{spec-BJzgmvVa.js → spec-oJn0RhpQ.js} +41 -11
- package/dist/{stateDiagram-D77RDMKH-Be-xSpaZ.js → stateDiagram-D77RDMKH-BR7cI3wK.js} +4 -4
- package/dist/{stateDiagram-v2-MP3YSRHH-5Y-FxesJ.js → stateDiagram-v2-MP3YSRHH-oGqB5UDI.js} +2 -2
- package/dist/static-state-CuV6Pc3a.js +72 -0
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-nRRl4NU0.js → swimlanes-42K2YHIH-DwSZl1yC.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-BS79510V.js → swimlanesDiagram-VR7AAH4N-BHlcd-Ri.js} +2 -2
- package/dist/{swiper-component-DKntyn8p.js → swiper-component-Dvj-goaD.js} +2 -2
- package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
- package/dist/{timeline-definition-24CTP7MA-Cfzf8WPf.js → timeline-definition-24CTP7MA-DMmP-G2O.js} +1 -1
- package/dist/toast-DbBHmxmB.js +491 -0
- package/dist/{tooltip-CtBZ5q8p.js → tooltip-BfcDQd2j.js} +329 -305
- package/dist/use-restore-focus-CmflVLWJ.js +1672 -0
- package/dist/{useAsyncData-BD534XmW.js → useAsyncData-BYIAoMqn.js} +15 -14
- package/dist/{useDateFormatter-DkajGwwd.js → useDateFormatter-ButWkdcK.js} +2 -2
- package/dist/{useDeepCompareMemoize-C72_RNsu.js → useDeepCompareMemoize-Bz0c5GN6.js} +1 -1
- package/dist/{useIframeCapabilities-DBETvvPl.js → useIframeCapabilities-BIolGsF1.js} +1 -1
- package/dist/useLifecycle-JjxCC7Vu.js +112 -0
- package/dist/useTheme-DPLobSFs.js +339 -0
- package/dist/utils-EBklsC5R.js +813 -0
- package/dist/{vega-component-nB1kV6sb.js → vega-component-rxIxAAh9.js} +171 -170
- 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-CeY6Z1xZ.js → vennDiagram-4TSXK5OY-Db8GtH1G.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-Cxs9NtVi.js → wardleyDiagram-VM6X3IG4-DmIiC3FU.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-DNWbvPK7.js → xychartDiagram-S5SC5T6Z-DS9OPrNq.js} +2 -2
- package/package.json +17 -20
- package/src/__mocks__/document.tsx +63 -0
- package/src/__mocks__/executions.ts +195 -0
- package/src/__mocks__/notebook.ts +3 -5
- package/src/__mocks__/partial.ts +26 -0
- package/src/__mocks__/requests.ts +1 -4
- package/src/__tests__/CellStatus.test.tsx +19 -20
- package/src/__tests__/fixtures/pair-config.ts +1 -1
- package/src/__tests__/main.test.tsx +24 -1
- 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/__tests__/state.test.tsx +50 -0
- package/src/components/app-config/ai-config.tsx +156 -150
- package/src/components/app-config/app-config-button.tsx +6 -5
- package/src/components/app-config/app-config-form.tsx +5 -9
- package/src/components/app-config/common.tsx +7 -9
- package/src/components/app-config/data-form.tsx +112 -113
- package/src/components/app-config/mcp-config.tsx +30 -53
- package/src/components/app-config/user-config-form.css +91 -0
- package/src/components/app-config/user-config-form.tsx +266 -349
- package/src/components/chat/__tests__/capabilities-popover.test.tsx +0 -1
- package/src/components/chat/__tests__/chat-display.test.tsx +196 -0
- package/src/components/chat/__tests__/chat-markdown.test.tsx +43 -0
- package/src/components/chat/__tests__/chat-utils.test.ts +93 -1
- 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/__tests__/turn-timing.test.ts +84 -0
- package/src/components/chat/__tests__/use-assistant-turn.test.ts +95 -0
- package/src/components/chat/__tests__/user-message.test.tsx +27 -0
- package/src/components/chat/acp/__tests__/agent-panel-initialization.test.tsx +1 -1
- package/src/components/chat/acp/__tests__/agent-panel.test.tsx +22 -17
- 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/agent-panel.tsx +6 -3
- package/src/components/chat/acp/blocks.tsx +13 -12
- package/src/components/chat/acp/common.tsx +4 -5
- package/src/components/chat/acp/model-selector.tsx +1 -1
- package/src/components/chat/acp/session-tabs.tsx +8 -3
- package/src/components/chat/agent-activity.tsx +132 -0
- package/src/components/chat/capabilities-popover.tsx +2 -11
- package/src/components/chat/chat-components.tsx +9 -4
- package/src/components/chat/chat-display.tsx +131 -57
- package/src/components/chat/chat-history-popover.tsx +6 -1
- package/src/components/chat/chat-markdown.tsx +15 -0
- package/src/components/chat/chat-panel.tsx +216 -294
- package/src/components/chat/chat-typography.css +108 -0
- package/src/components/chat/chat-utils.ts +24 -35
- package/src/components/chat/notebook-access-selector.stories.tsx +22 -0
- package/src/components/chat/notebook-access-selector.tsx +100 -0
- package/src/components/chat/tool-call/__tests__/tool-labels.test.ts +76 -0
- package/src/components/chat/tool-call/__tests__/tool-step.test.tsx +57 -0
- package/src/components/chat/tool-call/shared.ts +6 -0
- package/src/components/chat/tool-call/tool-call-view.tsx +22 -76
- package/src/components/chat/tool-call/tool-labels.ts +172 -0
- package/src/components/chat/tool-call/tool-result.tsx +1 -1
- package/src/components/chat/tool-call/tool-step.tsx +145 -0
- package/src/components/chat/turn-timing.ts +73 -0
- package/src/components/chat/use-assistant-turn.ts +65 -0
- package/src/components/chat/use-chat-generation.ts +20 -0
- package/src/components/chat/user-message.tsx +145 -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-formatting/types.ts +1 -2
- 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 +56 -43
- package/src/components/datasources/utils.ts +32 -23
- package/src/components/debugger/debugger-code.tsx +5 -0
- package/src/components/dependency-graph/custom-node.tsx +1 -1
- 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 +15 -20
- 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 -21
- package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
- package/src/components/editor/__tests__/output-persistence.test.tsx +8 -4
- 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-commands.test.ts +21 -40
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +41 -14
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +6 -24
- package/src/components/editor/actions/__tests__/useCellActionButton.test.tsx +131 -0
- package/src/components/editor/actions/name-cell-input.tsx +4 -3
- package/src/components/editor/actions/pair-with-agent-commands.ts +10 -7
- package/src/components/editor/actions/pair-with-agent-modal.tsx +29 -30
- package/src/components/editor/actions/pair-with-agent.tsx +16 -39
- package/src/components/editor/actions/useCellActionButton.tsx +47 -35
- package/src/components/editor/actions/useConfigActions.tsx +3 -4
- package/src/components/editor/actions/useNotebookActions.tsx +25 -29
- package/src/components/editor/actions/useRestartKernel.tsx +1 -1
- package/src/components/editor/actions/useSetCodeVisibility.ts +11 -12
- package/src/components/editor/actions/useSetOutputsExpanded.ts +14 -19
- package/src/components/editor/ai/ai-completion-editor.tsx +2 -1
- package/src/components/editor/ai/completion-handlers.tsx +0 -37
- package/src/components/editor/ai/prompt-input.tsx +189 -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/alerts/stdin-blocking-alert.tsx +4 -2
- 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/CellStatus.tsx +23 -19
- 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 +18 -8
- package/src/components/editor/cell/StagedAICell.tsx +52 -137
- package/src/components/editor/cell/StopButton.tsx +2 -2
- package/src/components/editor/cell/__tests__/useRunCells.test.ts +45 -0
- 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/cell-context-menu.tsx +4 -1
- package/src/components/editor/cell/code/__tests__/language-toggle.test.tsx +54 -0
- package/src/components/editor/cell/code/cell-editor.tsx +65 -169
- package/src/components/editor/cell/code/language-toggle.tsx +8 -7
- package/src/components/editor/cell/collapse.tsx +15 -4
- 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 +20 -8
- package/src/components/editor/cell/useShouldShowInterrupt.ts +2 -12
- package/src/components/editor/cell/useSplitCell.tsx +10 -6
- package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +1 -1
- package/src/components/editor/chrome/components/feedback-button.tsx +2 -8
- 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/dependency-graph-panel.tsx +1 -1
- 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/panel-header.tsx +13 -0
- package/src/components/editor/chrome/panels/secrets-panel.tsx +1 -0
- package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/snippets-panel.tsx +10 -12
- package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
- package/src/components/editor/chrome/types.ts +1 -1
- package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +7 -9
- 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 +265 -37
- package/src/components/editor/chrome/wrapper/__tests__/useAskAiAboutCell.test.tsx +58 -0
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +91 -74
- 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 -2
- package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +143 -72
- package/src/components/editor/chrome/wrapper/pending-ai-changes-badge.tsx +25 -0
- package/src/components/editor/chrome/wrapper/sidebar.tsx +8 -4
- package/src/components/editor/chrome/wrapper/storage.ts +1 -1
- package/src/components/editor/chrome/wrapper/useAskAiAboutCell.ts +36 -0
- package/src/components/editor/columns/__tests__/cell-column.test.tsx +1 -1
- package/src/components/editor/columns/cell-column.tsx +1 -1
- package/src/components/editor/columns/sortable-column.tsx +2 -2
- package/src/components/editor/connections/components.tsx +5 -10
- package/src/components/editor/controls/Controls.tsx +4 -4
- 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 +25 -20
- 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__/filename-form.test.tsx +1 -4
- 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/filename-form.tsx +1 -1
- package/src/components/editor/header/status.tsx +44 -22
- package/src/components/editor/links/__tests__/cell-link.test.tsx +148 -0
- package/src/components/editor/links/cell-link-list.tsx +1 -1
- package/src/components/editor/links/cell-link.tsx +21 -11
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
- package/src/components/editor/navigation/__tests__/navigation.test.ts +108 -85
- package/src/components/editor/navigation/__tests__/selection.test.ts +43 -21
- package/src/components/editor/navigation/clipboard.ts +17 -14
- package/src/components/editor/navigation/focus-utils.ts +23 -4
- package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +17 -33
- package/src/components/editor/navigation/navigation.ts +74 -72
- package/src/components/editor/navigation/selection.ts +30 -29
- package/src/components/editor/notebook-banner.tsx +1 -0
- package/src/components/editor/notebook-cell.tsx +114 -126
- 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/VideoOutput.tsx +6 -0
- package/src/components/editor/output/__tests__/VideoOutput.test.tsx +131 -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/__tests__/add-cell-buttons.test.tsx +18 -0
- package/src/components/editor/renderers/cell-array.tsx +32 -100
- package/src/components/editor/renderers/grid-layout/__tests__/grid-layout.test.tsx +75 -0
- package/src/components/editor/renderers/grid-layout/grid-layout.tsx +34 -22
- package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -2
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +1 -1
- package/src/components/editor/renderers/vertical-layout/__tests__/useFocusFirstEditor.test.ts +4 -4
- package/src/components/editor/renderers/vertical-layout/sidebar/toggle.tsx +7 -1
- package/src/components/editor/renderers/vertical-layout/useFocusFirstEditor.ts +1 -1
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +13 -34
- package/src/components/editor/stdin-blocking-alert.tsx +4 -2
- 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 +39 -28
- package/src/components/mcp/mcp-status-indicator.tsx +18 -14
- package/src/components/pages/__tests__/home-page.test.tsx +116 -0
- package/src/components/pages/edit-page.tsx +19 -17
- package/src/components/pages/home-page.tsx +164 -91
- package/src/components/scratchpad/scratchpad.test.tsx +89 -0
- package/src/components/scratchpad/scratchpad.tsx +47 -33
- package/src/components/scratchpad/state.ts +7 -0
- package/src/components/slides/__tests__/minimap-actions.test.tsx +22 -29
- package/src/components/slides/__tests__/minimap.test.ts +38 -19
- package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +37 -0
- package/src/components/slides/minimap.tsx +21 -14
- package/src/components/slides/reveal-component.tsx +72 -36
- package/src/components/slides/reveal-slides.css +5 -4
- package/src/components/slides/slide-cell-view.tsx +32 -29
- package/src/components/slides/slide-form.tsx +1 -0
- package/src/components/slides/slide-scroll-hint.tsx +3 -1
- package/src/components/slides/slide.tsx +3 -4
- package/src/components/sort/SortableCellsProvider.tsx +8 -25
- package/src/components/tracing/tracing-keyboard.test.tsx +85 -0
- package/src/components/tracing/tracing.tsx +46 -42
- package/src/components/ui/__tests__/draggable-popover.test.tsx +24 -0
- package/src/components/ui/__tests__/fullscreen.test.tsx +44 -2
- 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/fullscreen.tsx +25 -1
- package/src/components/ui/range-slider.tsx +22 -9
- package/src/components/ui/toast.tsx +1 -1
- package/src/core/MarimoApp.tsx +3 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +89 -608
- package/src/core/ai/context/context.ts +2 -0
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
- package/src/core/ai/context/providers/__tests__/cell.test.ts +49 -0
- package/src/core/ai/context/providers/cell-output.ts +2 -2
- package/src/core/ai/context/providers/cell.ts +54 -0
- package/src/core/ai/context/providers/datasource.ts +6 -2
- package/src/core/ai/staged-cells.ts +56 -323
- package/src/core/ai/state.ts +3 -0
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +40 -88
- 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 +86 -80
- 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 -426
- package/src/core/cells/__tests__/actions.test.ts +624 -35
- package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
- package/src/core/cells/__tests__/arrange.test.ts +432 -0
- package/src/core/cells/__tests__/cell.test.ts +85 -151
- package/src/core/cells/__tests__/cells.test.ts +269 -2667
- package/src/core/cells/__tests__/collapseConsoleOutputs.test.ts +54 -0
- package/src/core/cells/__tests__/document.test.ts +164 -0
- package/src/core/cells/__tests__/editor.test.ts +57 -0
- package/src/core/cells/__tests__/flush-document.test.ts +40 -0
- package/src/core/cells/__tests__/harness.ts +106 -0
- package/src/core/cells/__tests__/layout.test.ts +177 -0
- package/src/core/cells/__tests__/notebook-outline.test.ts +122 -0
- package/src/core/cells/__tests__/outputs.test.tsx +71 -53
- package/src/core/cells/__tests__/pending-delete-service.test.tsx +11 -20
- package/src/core/cells/__tests__/session.test.ts +445 -211
- package/src/core/cells/__tests__/utils.test.ts +76 -347
- package/src/core/cells/actions.ts +678 -6
- package/src/core/cells/add-missing-import.ts +47 -43
- package/src/core/cells/arrange.ts +529 -0
- package/src/core/cells/cell.ts +45 -136
- package/src/core/cells/cells.ts +133 -1385
- package/src/core/cells/columns.ts +38 -0
- package/src/core/cells/document.ts +178 -0
- package/src/core/cells/edit.ts +30 -0
- package/src/core/cells/editor.ts +82 -0
- package/src/core/cells/focus.ts +27 -6
- package/src/core/cells/layout.ts +221 -0
- package/src/core/cells/outputs.ts +12 -28
- package/src/core/cells/pending-delete-service.ts +8 -14
- package/src/core/cells/scrollCellIntoView.ts +6 -0
- package/src/core/cells/session.ts +76 -53
- package/src/core/cells/types.ts +34 -41
- package/src/core/cells/utils.ts +46 -75
- package/src/core/codemirror/__tests__/format.test.ts +0 -34
- package/src/core/codemirror/__tests__/setup.test.ts +61 -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 +2 -6
- package/src/core/codemirror/cells/extensions.ts +30 -28
- package/src/core/codemirror/cells/state.ts +2 -6
- package/src/core/codemirror/cm.ts +5 -1
- package/src/core/codemirror/config/types.ts +1 -1
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
- package/src/core/codemirror/copilot/getCodes.ts +2 -2
- package/src/core/codemirror/format.ts +6 -23
- 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 +19 -13
- 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/__tests__/notebook-lsp.test.ts +1 -2
- package/src/core/codemirror/lsp/notebook-lsp.ts +6 -5
- package/src/core/codemirror/lsp/utils.ts +1 -1
- package/src/core/codemirror/misc/__tests__/paste.test.ts +3 -1
- package/src/core/codemirror/misc/paste.ts +1 -1
- package/src/core/codemirror/placeholder/__tests__/extensions.test.ts +75 -0
- package/src/core/codemirror/placeholder/extensions.ts +80 -19
- package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
- package/src/core/codemirror/readonly/extension.ts +2 -2
- package/src/core/codemirror/utils.ts +1 -0
- package/src/core/config/__tests__/app-config.test.ts +64 -0
- package/src/core/config/__tests__/config-schema.test.ts +56 -6
- package/src/core/config/config-schema.ts +17 -4
- package/src/core/config/config.ts +65 -20
- package/src/core/config/feature-flag.tsx +0 -2
- 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/documentation/doc-lookup.ts +1 -1
- package/src/core/edit-app.tsx +22 -28
- package/src/core/errors/error-entries.ts +4 -1
- package/src/core/executions/__tests__/atoms.test.ts +99 -0
- package/src/core/executions/__tests__/select.test.ts +268 -0
- package/src/core/executions/atoms.ts +206 -0
- package/src/core/executions/hooks.ts +31 -0
- package/src/core/executions/index.ts +31 -0
- package/src/core/executions/select.ts +175 -0
- package/src/core/export/__tests__/hooks.test.ts +0 -5
- 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/hotkeys/hotkeys.ts +2 -1
- package/src/core/islands/__tests__/bootstrap.test.ts +69 -17
- package/src/core/islands/__tests__/bridge.test.ts +85 -27
- package/src/core/islands/bootstrap.ts +50 -54
- package/src/core/islands/bridge.ts +84 -25
- package/src/core/islands/components/__tests__/IslandControls.test.tsx +7 -5
- package/src/core/islands/components/output-wrapper.tsx +5 -5
- package/src/core/islands/components/web-components.tsx +1 -1
- 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 +17 -79
- package/src/core/kernel/state.ts +0 -15
- package/src/core/lifecycle/render-policy.ts +12 -26
- package/src/core/meta/__tests__/code-visibility.test.tsx +78 -70
- package/src/core/meta/code-visibility.ts +18 -9
- package/src/core/network/__tests__/connection.test.ts +1 -1
- package/src/core/network/__tests__/requests-lazy.test.ts +6 -8
- package/src/core/network/connection-notice.ts +1 -1
- package/src/core/network/connection.ts +1 -1
- package/src/core/network/requests-lazy.ts +5 -8
- package/src/core/network/requests-network.ts +5 -31
- package/src/core/network/requests-static.ts +1 -4
- package/src/core/network/requests-toasting.tsx +1 -4
- package/src/core/network/types.ts +6 -14
- package/src/core/network/useConnectionNotice.ts +8 -2
- package/src/core/notebook/__tests__/operations.test.ts +51 -0
- package/src/core/notebook/attachments.ts +38 -0
- package/src/core/notebook/document/__tests__/codemirror.test.ts +759 -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__/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 +102 -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 +369 -0
- package/src/core/notebook/index.ts +19 -0
- package/src/core/notebook/operations.ts +30 -0
- package/src/core/notebook/replica/AGENTS.md +11 -0
- package/src/core/{host → notebook/replica}/__tests__/attachments.test.ts +9 -10
- package/src/core/{host → notebook/replica}/__tests__/document.test.ts +18 -16
- package/src/core/notebook/replica/__tests__/executions.test.ts +200 -0
- package/src/core/notebook/replica/__tests__/fixtures.ts +79 -0
- package/src/core/notebook/replica/__tests__/replica.test.ts +559 -0
- package/src/core/notebook/replica/__tests__/results.test.ts +193 -0
- package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -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 +20 -0
- package/src/core/notebook/replica/replica.ts +336 -0
- package/src/core/{host → notebook/replica}/resources/attachments.ts +6 -3
- package/src/core/{host → notebook/replica}/resources/document.ts +3 -3
- package/src/core/notebook/replica/resources/executions.ts +157 -0
- package/src/core/notebook/replica/resources/results.ts +48 -0
- package/src/core/notebook/replica/resources/runtime.ts +14 -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 +49 -51
- package/src/core/runtime/__tests__/adapter.test.ts +4 -4
- package/src/core/runtime/__tests__/createWsUrl.test.ts +77 -7
- package/src/core/runtime/__tests__/runtime.test.ts +32 -74
- package/src/core/runtime/adapter.ts +5 -5
- package/src/core/runtime/config.ts +2 -2
- package/src/core/runtime/runtime.ts +33 -46
- package/src/core/runtime/types.ts +0 -2
- package/src/core/saving/__tests__/document.test.tsx +123 -0
- package/src/core/saving/__tests__/state.test.ts +111 -0
- package/src/core/saving/__tests__/useAutoSave.test.tsx +67 -0
- package/src/core/saving/document.ts +33 -0
- package/src/core/saving/filename.ts +1 -1
- package/src/core/saving/save-component.tsx +39 -60
- package/src/core/saving/state.ts +38 -39
- package/src/core/saving/useAutoSave.ts +17 -53
- package/src/core/session/__tests__/backend.test.ts +236 -0
- package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +186 -0
- package/src/core/{websocket → session}/__tests__/useNotebookSession.hook.test.tsx +247 -262
- package/src/core/session/active-notebook.ts +28 -0
- package/src/core/session/backend.ts +123 -0
- package/src/core/session/embedded.ts +7 -0
- package/src/core/{websocket → session}/types.ts +2 -2
- package/src/core/session/useNotebookReplica.ts +74 -0
- package/src/core/{websocket → session}/useNotebookSession.tsx +85 -67
- 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 +306 -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 +166 -0
- package/src/core/transports/wasm.ts +97 -0
- package/src/core/vscode/__tests__/vscode-bindings.test.ts +125 -0
- package/src/core/vscode/vscode-bindings.ts +14 -2
- package/src/core/wasm/__tests__/bridge.test.ts +210 -64
- package/src/core/wasm/__tests__/worker.test.ts +188 -0
- package/src/core/wasm/bridge.ts +120 -73
- 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 +30 -18
- package/src/core/wasm/worker/worker.ts +118 -72
- package/src/css/app/Cell.css +7 -36
- package/src/css/app/codemirror.css +1 -1
- package/src/css/common.css +1 -1
- 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 +20 -15
- package/src/plugins/__tests__/plugin-object-schemas.test.ts +104 -0
- package/src/plugins/core/RenderHTML.tsx +3 -5
- package/src/plugins/core/__test__/RenderHTML-copy.test.tsx +60 -0
- package/src/plugins/core/registerReactComponent.tsx +5 -14
- package/src/plugins/impl/CodeEditorPlugin.tsx +1 -1
- package/src/plugins/impl/DataEditorPlugin.tsx +34 -9
- 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__/DataEditorPlugin.test.ts +93 -4
- 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 +17 -15
- package/src/plugins/impl/code/any-language-editor.tsx +2 -2
- package/src/plugins/impl/common/error-banner.tsx +5 -3
- package/src/plugins/impl/data-editor/__tests__/column-types.test.ts +37 -0
- package/src/plugins/impl/data-editor/__tests__/editor-state.test.ts +52 -1
- package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +113 -1
- package/src/plugins/impl/data-editor/__tests__/glide-utils.test.ts +116 -0
- package/src/plugins/impl/data-editor/column-types.ts +52 -0
- package/src/plugins/impl/data-editor/editor-state.ts +18 -2
- package/src/plugins/impl/data-editor/glide-data-editor.tsx +73 -12
- package/src/plugins/impl/data-editor/glide-utils.ts +33 -10
- package/src/plugins/impl/data-editor/types.ts +7 -0
- 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 +44 -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/DownloadPlugin.tsx +7 -11
- package/src/plugins/layout/RoutesPlugin.tsx +1 -1
- package/src/plugins/layout/__test__/DownloadPlugin.test.tsx +205 -0
- package/src/stories/__tests__/editor-story.test.tsx +33 -0
- package/src/stories/button.stories.tsx +1 -0
- package/src/stories/cell-status.stories.tsx +17 -10
- package/src/stories/cell.stories.tsx +2 -36
- 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 +28 -32
- package/src/stories/runtime-story.tsx +23 -17
- 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} +127 -1
- package/src/utils/__tests__/download.test.tsx +183 -23
- 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 +115 -79
- package/src/utils/download.ts +67 -6
- package/src/utils/maps.ts +0 -3
- package/src/utils/numbers.ts +79 -18
- package/src/utils/objects.ts +4 -9
- package/src/utils/time.ts +10 -0
- package/src/utils/tracer.ts +9 -5
- package/src/utils/zod-utils.ts +1 -3
- package/dist/_baseMerge-BiGRwuqv.js +0 -165
- package/dist/any-language-editor-D4q-IFcM.js +0 -76
- package/dist/assets/__vite-browser-external-BXYkiFsk.js +0 -1
- package/dist/assets/worker-HPY9fbhz.js +0 -114
- package/dist/dropdown-menu-DHP9P4VE.js +0 -4678
- package/dist/feedback-button-B2JRVQRd.js +0 -379
- package/dist/hasIn-o2Us0uVx.js +0 -132
- package/dist/html-to-image-DWTzN7q3.js +0 -3251
- package/dist/isArrayLikeObject-BZl-15ir.js +0 -450
- package/dist/isEmpty-BSZ1LaUo.js +0 -35
- package/dist/isSymbol-kQcfYbNX.js +0 -8
- package/dist/label-DoysmLMW.js +0 -281
- package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
- package/dist/pick-CJeoxYOS.js +0 -51
- package/dist/precisionRound-DMIVQrt2.js +0 -97
- package/dist/select-DemoKT4G.js +0 -1344
- package/dist/toDate-CJWU9dyl.js +0 -1185
- package/dist/toast-PkdZraM8.js +0 -1830
- package/dist/use-restore-focus-CKjfFjLM.js +0 -6369
- package/dist/useLifecycle-BGWzTwHK.js +0 -169
- package/dist/useTheme-BhQvec43.js +0 -904
- package/src/components/chat/reasoning-accordion.tsx +0 -61
- package/src/components/chat/tool-call/tool-error-card.tsx +0 -81
- package/src/components/chat/tool-call/tool-history-row.tsx +0 -174
- package/src/components/editor/ai/__tests__/staged-cell-submission.test.ts +0 -106
- package/src/components/editor/ai/add-cell-with-ai.tsx +0 -506
- package/src/components/editor/ai/staged-cell-submission.ts +0 -46
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +0 -64
- package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +0 -50
- package/src/components/editor/chrome/wrapper/footer-items/rtc-status.tsx +0 -65
- package/src/components/editor/navigation/__tests__/state.test.ts +0 -81
- package/src/components/editor/navigation/state.ts +0 -65
- package/src/components/icons/loading-ellipsis.tsx +0 -46
- 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 -18
- 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/codemirror/rtc/extension.ts +0 -453
- package/src/core/codemirror/rtc/loro/__tests__/sync.test.ts +0 -52
- package/src/core/codemirror/rtc/loro/awareness.ts +0 -531
- package/src/core/codemirror/rtc/loro/colors.ts +0 -38
- package/src/core/codemirror/rtc/loro/sync.ts +0 -168
- package/src/core/host/AGENTS.md +0 -11
- package/src/core/host/__tests__/events.test.ts +0 -46
- package/src/core/host/__tests__/fixtures.ts +0 -39
- package/src/core/host/__tests__/notebook-client.test.ts +0 -433
- package/src/core/host/__tests__/protocol.test.ts +0 -214
- package/src/core/host/__tests__/stream.test.ts +0 -209
- package/src/core/host/connection.ts +0 -81
- package/src/core/host/events.ts +0 -61
- package/src/core/host/notebook-client.ts +0 -290
- package/src/core/host/protocol.ts +0 -1945
- package/src/core/host/resources/resource.ts +0 -47
- package/src/core/host/stream.ts +0 -211
- package/src/core/rtc/state.ts +0 -34
- 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 -170
- package/src/core/websocket/state.ts +0 -7
- 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 -88
- package/src/utils/__tests__/id-tree.test.ts +0 -2145
- package/src/utils/id-tree.tsx +0 -1134
- /package/src/{core/attachments/toast.ts → components/editor/agent-toast.ts} +0 -0
- /package/src/core/{websocket → session}/connection-utils.ts +0 -0
package/src/core/cells/cells.ts
CHANGED
|
@@ -1,74 +1,68 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import { dequal as isEqual } from "dequal";
|
|
3
|
+
import type * as Protocol from "@marimo-team/client/protocol";
|
|
5
4
|
import { type Atom, atom, useAtom, useAtomValue } from "jotai";
|
|
6
5
|
import { atomFamily, selectAtom, splitAtom } from "jotai/utils";
|
|
7
6
|
import { createRef, type ReducerWithoutAction } from "react";
|
|
8
7
|
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
9
|
-
import type {
|
|
8
|
+
import type { EditableDocument, Placement } from "@/core/notebook/document";
|
|
10
9
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "@/
|
|
10
|
+
cellExecutionInputsAtom,
|
|
11
|
+
cellExecutionView,
|
|
12
|
+
withdrawCells,
|
|
13
|
+
} from "@/core/executions";
|
|
14
|
+
import type { CellColumnId } from "./layout";
|
|
15
15
|
import { invariant } from "@/utils/invariant";
|
|
16
16
|
import { Logger } from "@/utils/Logger";
|
|
17
|
-
import { clamp } from "@/utils/math";
|
|
18
17
|
import { Objects } from "@/utils/objects";
|
|
19
18
|
import { extractAllTracebackInfo, type TracebackInfo } from "@/utils/traceback";
|
|
20
19
|
import { createReducerAndAtoms } from "../../utils/createReducer";
|
|
21
20
|
import { foldAllBulk, unfoldAllBulk } from "../codemirror/editing/commands";
|
|
22
21
|
import { editorMountScheduler } from "../codemirror/editor-mount-scheduler";
|
|
23
|
-
import {
|
|
24
|
-
splitEditor,
|
|
25
|
-
updateEditorCodeFromPython,
|
|
26
|
-
} from "../codemirror/language/utils";
|
|
27
22
|
import type { SerializedEditorState } from "../codemirror/types";
|
|
28
|
-
import {
|
|
23
|
+
import { mergeOutlines } from "../dom/outline";
|
|
29
24
|
import type { CellMessage } from "../kernel/messages";
|
|
30
25
|
import { isErrorMime } from "../mime";
|
|
31
26
|
import type { CellConfig } from "../network/types";
|
|
32
|
-
import { canUseRtc, isRtcEnabled } from "../rtc/state";
|
|
33
27
|
import { createDeepEqualAtom, store } from "../state/jotai";
|
|
34
28
|
import { isWasm } from "../wasm/utils";
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
29
|
+
import { transitionCell } from "./cell";
|
|
30
|
+
import { applyDocument } from "./document";
|
|
31
|
+
import { isCodeHidden, shownHiddenCodeAtom } from "./editor";
|
|
32
|
+
import { type CellId, SCRATCH_CELL_ID } from "./ids";
|
|
38
33
|
import { type CellLog, getCellLogsForMessage } from "./logs";
|
|
39
|
-
import {
|
|
40
|
-
|
|
41
|
-
scrollToBottom,
|
|
42
|
-
scrollToTop,
|
|
43
|
-
} from "./scrollCellIntoView";
|
|
34
|
+
import type { Outline } from "./outline";
|
|
35
|
+
import { focusAndScrollCellIntoView } from "./scrollCellIntoView";
|
|
44
36
|
import {
|
|
45
37
|
type CellData,
|
|
46
38
|
type CellRuntimeState,
|
|
47
39
|
createCell,
|
|
48
|
-
createCellConfig,
|
|
49
40
|
createCellRuntimeState,
|
|
41
|
+
isEdited,
|
|
50
42
|
} from "./types";
|
|
51
43
|
import {
|
|
52
44
|
canUndoDeletes,
|
|
53
45
|
disabledCellIds,
|
|
54
46
|
enabledCellIds,
|
|
55
47
|
getUndoLabel,
|
|
56
|
-
notebookIsRunning,
|
|
57
48
|
notebookNeedsRun,
|
|
58
|
-
notebookQueueOrRunningCount,
|
|
59
49
|
} from "./utils";
|
|
60
50
|
|
|
51
|
+
/** A deleted cell as it was, with where it went in the document. */
|
|
52
|
+
export interface DeletedCell {
|
|
53
|
+
cell: Protocol.CellInput;
|
|
54
|
+
placement: Placement;
|
|
55
|
+
/** The editor's state at deletion, so undo brings its history back. */
|
|
56
|
+
serializedEditorState: SerializedEditorState | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
61
59
|
/**
|
|
62
|
-
* History entry for undoing
|
|
60
|
+
* History entry for undoing one deletion, of one or more cells.
|
|
63
61
|
*/
|
|
64
62
|
export interface UndoDeleteEntry {
|
|
65
63
|
type: "delete";
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
column: CellColumnId;
|
|
69
|
-
index: CellIndex;
|
|
70
|
-
isSetupCell: boolean;
|
|
71
|
-
config: CellConfig;
|
|
64
|
+
/** In document order. Each cell is placed after the one before it. */
|
|
65
|
+
cells: DeletedCell[];
|
|
72
66
|
}
|
|
73
67
|
|
|
74
68
|
/**
|
|
@@ -77,7 +71,7 @@ export interface UndoDeleteEntry {
|
|
|
77
71
|
export interface UndoMoveEntry {
|
|
78
72
|
type: "move";
|
|
79
73
|
cellIds: CellId[];
|
|
80
|
-
placements: Array<{ columnId: CellColumnId; index:
|
|
74
|
+
placements: Array<{ columnId: CellColumnId; index: number }>;
|
|
81
75
|
}
|
|
82
76
|
|
|
83
77
|
export type HistoryEntry = UndoDeleteEntry | UndoMoveEntry;
|
|
@@ -89,7 +83,8 @@ export interface NotebookState {
|
|
|
89
83
|
/**
|
|
90
84
|
* Order of cells on the page.
|
|
91
85
|
*/
|
|
92
|
-
|
|
86
|
+
/** The cells in document order. */
|
|
87
|
+
cellIds: CellId[];
|
|
93
88
|
/**
|
|
94
89
|
* Map of cells to their view state
|
|
95
90
|
*/
|
|
@@ -116,12 +111,6 @@ export interface NotebookState {
|
|
|
116
111
|
* Logs of all cell messages
|
|
117
112
|
*/
|
|
118
113
|
cellLogs: CellLog[];
|
|
119
|
-
/**
|
|
120
|
-
* Set of cells that have been created that are initialized with `hide_code`.
|
|
121
|
-
*
|
|
122
|
-
* These start temporarily open until their first blur event.
|
|
123
|
-
*/
|
|
124
|
-
untouchedNewCells: Set<CellId>;
|
|
125
114
|
}
|
|
126
115
|
|
|
127
116
|
function withScratchCell(notebookState: NotebookState): NotebookState {
|
|
@@ -153,733 +142,49 @@ function withScratchCell(notebookState: NotebookState): NotebookState {
|
|
|
153
142
|
*/
|
|
154
143
|
export function initialNotebookState(): NotebookState {
|
|
155
144
|
return withScratchCell({
|
|
156
|
-
cellIds:
|
|
145
|
+
cellIds: [],
|
|
157
146
|
cellData: {},
|
|
158
147
|
cellRuntime: {},
|
|
159
148
|
cellHandles: {},
|
|
160
149
|
history: [],
|
|
161
150
|
scrollKey: null,
|
|
162
151
|
cellLogs: [],
|
|
163
|
-
untouchedNewCells: new Set<CellId>(),
|
|
164
152
|
});
|
|
165
153
|
}
|
|
166
154
|
|
|
167
|
-
/** The target cell ID to create a new cell relative to. Can be:
|
|
168
|
-
* - A CellId string for an existing cell
|
|
169
|
-
* - "__end__" to append at the end of the first column
|
|
170
|
-
* - {type: "__end__", columnId} to append at the end of a specific column
|
|
171
|
-
*/
|
|
172
|
-
export type CellPosition =
|
|
173
|
-
| CellId
|
|
174
|
-
| "__end__"
|
|
175
|
-
| { type: "__end__"; columnId: CellColumnId };
|
|
176
|
-
|
|
177
|
-
export interface CreateNewCellAction {
|
|
178
|
-
cellId: CellPosition;
|
|
179
|
-
/** Whether to insert before (true) or after (false) the target cell */
|
|
180
|
-
before: boolean;
|
|
181
|
-
/** Initial code content for the new cell */
|
|
182
|
-
code?: string;
|
|
183
|
-
/** Optional name for the new cell */
|
|
184
|
-
name?: string;
|
|
185
|
-
/** Optional cell configuration */
|
|
186
|
-
config?: CellConfig;
|
|
187
|
-
/** The last executed code for the new cell */
|
|
188
|
-
lastCodeRun?: string;
|
|
189
|
-
/** Timestamp of the last execution */
|
|
190
|
-
lastExecutionTime?: number;
|
|
191
|
-
/** Optional custom ID for the new cell. Auto-generated if not provided */
|
|
192
|
-
newCellId?: CellId;
|
|
193
|
-
/** Whether to focus the new cell after creation */
|
|
194
|
-
autoFocus?: boolean;
|
|
195
|
-
/** If true, skip creation if code already exists */
|
|
196
|
-
skipIfCodeExists?: boolean;
|
|
197
|
-
/** Hide the code in the new cell. This will be initially shown until the cell is blurred for the first time. */
|
|
198
|
-
hideCode?: boolean;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
155
|
/**
|
|
202
156
|
* Actions and reducer for the notebook state.
|
|
203
157
|
*/
|
|
204
158
|
const {
|
|
205
159
|
reducer,
|
|
206
|
-
addMiddleware,
|
|
207
160
|
createActions,
|
|
208
161
|
useActions,
|
|
209
162
|
valueAtom: notebookAtom,
|
|
210
163
|
} = createReducerAndAtoms(initialNotebookState, {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
config,
|
|
218
|
-
lastCodeRun = null,
|
|
219
|
-
lastExecutionTime = null,
|
|
220
|
-
autoFocus = true,
|
|
221
|
-
skipIfCodeExists = false,
|
|
222
|
-
hideCode = undefined,
|
|
223
|
-
} = action;
|
|
224
|
-
|
|
225
|
-
let columnId: CellColumnId;
|
|
226
|
-
let cellIndex: number;
|
|
227
|
-
|
|
228
|
-
// If skipIfCodeExists is true, check if the code already exists in the notebook
|
|
229
|
-
if (skipIfCodeExists) {
|
|
230
|
-
for (const cellId of state.cellIds.inOrderIds) {
|
|
231
|
-
if (state.cellData[cellId]?.code === code) {
|
|
232
|
-
return state;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (cellId === "__end__") {
|
|
238
|
-
const column = state.cellIds.atOrThrow(0);
|
|
239
|
-
columnId = column.id;
|
|
240
|
-
cellIndex = column.length;
|
|
241
|
-
} else if (typeof cellId === "string") {
|
|
242
|
-
const column = state.cellIds.findWithId(cellId);
|
|
243
|
-
columnId = column.id;
|
|
244
|
-
cellIndex = column.topLevelIds.indexOf(cellId);
|
|
245
|
-
} else if (cellId.type === "__end__") {
|
|
246
|
-
const column =
|
|
247
|
-
state.cellIds.get(cellId.columnId) || state.cellIds.atOrThrow(0);
|
|
248
|
-
columnId = column.id;
|
|
249
|
-
cellIndex = column.length;
|
|
250
|
-
} else {
|
|
251
|
-
throw new Error("Invalid cellId");
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const newCellId = action.newCellId || CellId.create();
|
|
255
|
-
const insertionIndex = before ? cellIndex : cellIndex + 1;
|
|
256
|
-
|
|
257
|
-
return {
|
|
258
|
-
...state,
|
|
259
|
-
cellIds: state.cellIds.insertId(newCellId, columnId, insertionIndex),
|
|
260
|
-
cellData: {
|
|
261
|
-
...state.cellData,
|
|
262
|
-
[newCellId]: createCell({
|
|
263
|
-
id: newCellId,
|
|
264
|
-
code,
|
|
265
|
-
name,
|
|
266
|
-
lastCodeRun,
|
|
267
|
-
config: createCellConfig({
|
|
268
|
-
...config,
|
|
269
|
-
...(hideCode != null && { hide_code: hideCode }),
|
|
270
|
-
}),
|
|
271
|
-
lastExecutionTime,
|
|
272
|
-
edited: Boolean(code) && code !== lastCodeRun,
|
|
273
|
-
}),
|
|
274
|
-
},
|
|
275
|
-
cellRuntime: {
|
|
276
|
-
...state.cellRuntime,
|
|
277
|
-
[newCellId]: createCellRuntimeState(),
|
|
278
|
-
},
|
|
279
|
-
cellHandles: {
|
|
280
|
-
...state.cellHandles,
|
|
281
|
-
[newCellId]: createRef(),
|
|
282
|
-
},
|
|
283
|
-
scrollKey: autoFocus ? newCellId : null,
|
|
284
|
-
untouchedNewCells:
|
|
285
|
-
hideCode && autoFocus
|
|
286
|
-
? new Set([...state.untouchedNewCells, newCellId])
|
|
287
|
-
: state.untouchedNewCells,
|
|
288
|
-
};
|
|
289
|
-
},
|
|
290
|
-
moveCell: (
|
|
291
|
-
state,
|
|
292
|
-
action: {
|
|
293
|
-
cellId: CellId;
|
|
294
|
-
before?: boolean;
|
|
295
|
-
direction?: "left" | "right";
|
|
296
|
-
},
|
|
297
|
-
) => {
|
|
298
|
-
const { cellId, before, direction } = action;
|
|
299
|
-
|
|
300
|
-
if (before !== undefined && direction !== undefined) {
|
|
301
|
-
Logger.warn(
|
|
302
|
-
"Both before and direction specified for moveCell. Ignoring one.",
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
// Handle left/right movement
|
|
307
|
-
if (direction) {
|
|
308
|
-
const fromColumn = state.cellIds.findWithId(cellId);
|
|
309
|
-
const fromColumnIndex = state.cellIds.indexOf(fromColumn);
|
|
310
|
-
const toColumnIndex =
|
|
311
|
-
direction === "left" ? fromColumnIndex - 1 : fromColumnIndex + 1;
|
|
312
|
-
const toColumn = state.cellIds.at(toColumnIndex);
|
|
313
|
-
|
|
314
|
-
// If no column to move to, return unchanged state
|
|
315
|
-
if (!toColumn) {
|
|
316
|
-
return state;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return {
|
|
320
|
-
...state,
|
|
321
|
-
cellIds: state.cellIds.moveAcrossColumns(
|
|
322
|
-
fromColumn.id,
|
|
323
|
-
cellId,
|
|
324
|
-
toColumn.id,
|
|
325
|
-
undefined,
|
|
326
|
-
),
|
|
327
|
-
scrollKey: cellId,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// Handle up/down movement
|
|
332
|
-
const column = state.cellIds.findWithId(cellId);
|
|
333
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
334
|
-
|
|
335
|
-
if (before && cellIndex === 0) {
|
|
336
|
-
return {
|
|
337
|
-
...state,
|
|
338
|
-
cellIds: state.cellIds.moveWithinColumn(column.id, cellIndex, 0),
|
|
339
|
-
scrollKey: cellId,
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
if (!before && cellIndex === column.length - 1) {
|
|
343
|
-
return {
|
|
344
|
-
...state,
|
|
345
|
-
cellIds: state.cellIds.moveWithinColumn(
|
|
346
|
-
column.id,
|
|
347
|
-
cellIndex,
|
|
348
|
-
column.length - 1,
|
|
349
|
-
),
|
|
350
|
-
scrollKey: cellId,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
return before
|
|
355
|
-
? {
|
|
356
|
-
...state,
|
|
357
|
-
cellIds: state.cellIds.moveWithinColumn(
|
|
358
|
-
column.id,
|
|
359
|
-
cellIndex,
|
|
360
|
-
cellIndex - 1,
|
|
361
|
-
),
|
|
362
|
-
scrollKey: cellId,
|
|
363
|
-
}
|
|
364
|
-
: {
|
|
365
|
-
...state,
|
|
366
|
-
cellIds: state.cellIds.moveWithinColumn(
|
|
367
|
-
column.id,
|
|
368
|
-
cellIndex,
|
|
369
|
-
cellIndex + 1,
|
|
370
|
-
),
|
|
371
|
-
scrollKey: cellId,
|
|
372
|
-
};
|
|
373
|
-
},
|
|
374
|
-
moveCellToIndex: (
|
|
375
|
-
state,
|
|
376
|
-
action: {
|
|
377
|
-
cellId: CellId;
|
|
378
|
-
columnId: CellColumnId;
|
|
379
|
-
index: number;
|
|
380
|
-
},
|
|
381
|
-
) => {
|
|
382
|
-
const { cellId, columnId, index } = action;
|
|
383
|
-
const fromColumn = state.cellIds.findWithId(cellId);
|
|
384
|
-
const fromIndex = fromColumn.indexOfOrThrow(cellId);
|
|
385
|
-
|
|
386
|
-
const destinationColumn = state.cellIds.get(columnId);
|
|
387
|
-
if (!destinationColumn) {
|
|
388
|
-
return state;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
const clampedIndex = Math.max(0, Math.min(index, destinationColumn.length));
|
|
392
|
-
const adjustedIndex =
|
|
393
|
-
fromColumn.id === columnId && fromIndex < clampedIndex
|
|
394
|
-
? clampedIndex - 1
|
|
395
|
-
: clampedIndex;
|
|
396
|
-
|
|
397
|
-
if (fromColumn.id === columnId && fromIndex === adjustedIndex) {
|
|
398
|
-
return state;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const withoutCell = state.cellIds.deleteById(cellId);
|
|
402
|
-
const updatedColumn = withoutCell.get(columnId);
|
|
403
|
-
if (!updatedColumn) {
|
|
404
|
-
return state;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return {
|
|
408
|
-
...state,
|
|
409
|
-
cellIds: withoutCell.insertId(
|
|
410
|
-
cellId,
|
|
411
|
-
columnId,
|
|
412
|
-
Math.max(0, Math.min(adjustedIndex, updatedColumn.length)),
|
|
413
|
-
),
|
|
414
|
-
scrollKey: null,
|
|
415
|
-
};
|
|
416
|
-
},
|
|
417
|
-
dropCellOverCell: (state, action: { cellId: CellId; overCellId: CellId }) => {
|
|
418
|
-
const { cellId, overCellId } = action;
|
|
419
|
-
|
|
420
|
-
const fromColumn = state.cellIds.findWithId(cellId);
|
|
421
|
-
const toColumn = state.cellIds.findWithId(overCellId);
|
|
422
|
-
|
|
423
|
-
const fromIndex = fromColumn.indexOfOrThrow(cellId);
|
|
424
|
-
const toIndex = toColumn.indexOfOrThrow(overCellId);
|
|
425
|
-
|
|
426
|
-
if (fromColumn.id === toColumn.id) {
|
|
427
|
-
if (fromIndex === toIndex) {
|
|
428
|
-
return state;
|
|
429
|
-
}
|
|
430
|
-
return {
|
|
431
|
-
...state,
|
|
432
|
-
cellIds: state.cellIds.moveWithinColumn(
|
|
433
|
-
fromColumn.id,
|
|
434
|
-
fromIndex,
|
|
435
|
-
toIndex,
|
|
436
|
-
),
|
|
437
|
-
scrollKey: null,
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
return {
|
|
442
|
-
...state,
|
|
443
|
-
cellIds: state.cellIds.moveAcrossColumns(
|
|
444
|
-
fromColumn.id,
|
|
445
|
-
cellId,
|
|
446
|
-
toColumn.id,
|
|
447
|
-
overCellId,
|
|
448
|
-
),
|
|
449
|
-
scrollKey: null,
|
|
450
|
-
};
|
|
451
|
-
},
|
|
452
|
-
moveCellsRelativeTo: (
|
|
453
|
-
state,
|
|
454
|
-
action: {
|
|
455
|
-
cellIds: CellId[];
|
|
456
|
-
targetCellId: CellId;
|
|
457
|
-
position: "before" | "after";
|
|
458
|
-
previousPlacements?: Array<{ columnId: CellColumnId; index: CellIndex }>;
|
|
459
|
-
},
|
|
460
|
-
) => {
|
|
461
|
-
const { cellIds, targetCellId, position, previousPlacements } = action;
|
|
462
|
-
if (cellIds.length === 0) {
|
|
463
|
-
return state;
|
|
464
|
-
}
|
|
465
|
-
const newCellIds = state.cellIds.moveCellsRelativeTo(
|
|
466
|
-
cellIds,
|
|
467
|
-
targetCellId,
|
|
468
|
-
position,
|
|
469
|
-
);
|
|
470
|
-
// Only record undo when caller provided full before-state
|
|
471
|
-
const canUndoMove =
|
|
472
|
-
previousPlacements && previousPlacements.length === cellIds.length;
|
|
473
|
-
const history = canUndoMove
|
|
474
|
-
? [
|
|
475
|
-
...state.history,
|
|
476
|
-
{ type: "move" as const, cellIds, placements: previousPlacements },
|
|
477
|
-
]
|
|
478
|
-
: state.history;
|
|
479
|
-
return {
|
|
480
|
-
...state,
|
|
481
|
-
cellIds: newCellIds,
|
|
482
|
-
history,
|
|
483
|
-
scrollKey: null,
|
|
484
|
-
};
|
|
485
|
-
},
|
|
486
|
-
dropCellOverColumn: (
|
|
487
|
-
state,
|
|
488
|
-
action: { cellId: CellId; columnId: CellColumnId },
|
|
489
|
-
) => {
|
|
490
|
-
const { cellId, columnId } = action;
|
|
491
|
-
const fromColumn = state.cellIds.findWithId(cellId);
|
|
492
|
-
|
|
493
|
-
return {
|
|
494
|
-
...state,
|
|
495
|
-
cellIds: state.cellIds.moveAcrossColumns(
|
|
496
|
-
fromColumn.id,
|
|
497
|
-
cellId,
|
|
498
|
-
columnId,
|
|
499
|
-
undefined,
|
|
500
|
-
),
|
|
501
|
-
};
|
|
502
|
-
},
|
|
503
|
-
dropOverNewColumn: (state, action: { cellId: CellId }) => {
|
|
504
|
-
const { cellId } = action;
|
|
505
|
-
return {
|
|
506
|
-
...state,
|
|
507
|
-
cellIds: state.cellIds.moveToNewColumn(cellId),
|
|
508
|
-
};
|
|
509
|
-
},
|
|
510
|
-
moveColumn: (
|
|
511
|
-
state,
|
|
512
|
-
action: {
|
|
513
|
-
column: CellColumnId;
|
|
514
|
-
overColumn: CellColumnId | "_left_" | "_right_";
|
|
515
|
-
},
|
|
516
|
-
) => {
|
|
517
|
-
if (action.column === action.overColumn) {
|
|
518
|
-
return state;
|
|
519
|
-
}
|
|
520
|
-
return {
|
|
521
|
-
...state,
|
|
522
|
-
cellIds: state.cellIds.moveColumn(action.column, action.overColumn),
|
|
523
|
-
};
|
|
524
|
-
},
|
|
525
|
-
focusCell: (
|
|
526
|
-
state,
|
|
527
|
-
action: { cellId: CellId; where: "before" | "after" | "exact" },
|
|
528
|
-
) => {
|
|
529
|
-
const column = state.cellIds.findWithId(action.cellId);
|
|
530
|
-
if (column.length === 0) {
|
|
531
|
-
return state;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
const { cellId, where } = action;
|
|
535
|
-
const index = column.indexOfOrThrow(cellId);
|
|
536
|
-
|
|
537
|
-
let focusIndex: number;
|
|
538
|
-
if (where === "before") {
|
|
539
|
-
focusIndex = clamp(index - 1, 0, column.length - 1);
|
|
540
|
-
} else if (where === "after") {
|
|
541
|
-
focusIndex = clamp(index + 1, 0, column.length - 1);
|
|
542
|
-
} else {
|
|
543
|
-
focusIndex = index;
|
|
544
|
-
}
|
|
545
|
-
const focusCellId = column.atOrThrow(focusIndex);
|
|
546
|
-
// can scroll immediately, without setting scrollKey in state, because
|
|
547
|
-
// CellArray won't need to re-render
|
|
548
|
-
focusAndScrollCellIntoView({
|
|
549
|
-
cellId: focusCellId,
|
|
550
|
-
cell: state.cellHandles[focusCellId],
|
|
551
|
-
isCodeHidden: isCellCodeHidden(state, focusCellId),
|
|
552
|
-
codeFocus: where === "after" ? "top" : "bottom",
|
|
553
|
-
variableName: undefined,
|
|
554
|
-
});
|
|
555
|
-
return state;
|
|
556
|
-
},
|
|
557
|
-
focusTopCell: (state) => {
|
|
558
|
-
// TODO: focus the existing column, not the first column
|
|
559
|
-
const column = state.cellIds.getColumns().at(0);
|
|
560
|
-
if (column === undefined || column.length === 0) {
|
|
561
|
-
return state;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const cellId = column.first();
|
|
565
|
-
focusAndScrollCellIntoView({
|
|
566
|
-
cellId: cellId,
|
|
567
|
-
cell: state.cellHandles[cellId],
|
|
568
|
-
isCodeHidden: isCellCodeHidden(state, cellId),
|
|
569
|
-
codeFocus: undefined,
|
|
570
|
-
variableName: undefined,
|
|
571
|
-
});
|
|
572
|
-
scrollToTop();
|
|
573
|
-
return state;
|
|
574
|
-
},
|
|
575
|
-
focusBottomCell: (state) => {
|
|
576
|
-
// TODO: focus the existing column, not the last column
|
|
577
|
-
const column = state.cellIds.getColumns().at(-1);
|
|
578
|
-
if (column === undefined || column.length === 0) {
|
|
579
|
-
return state;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
const cellId = column.last();
|
|
583
|
-
focusAndScrollCellIntoView({
|
|
584
|
-
cellId: cellId,
|
|
585
|
-
cell: state.cellHandles[cellId],
|
|
586
|
-
isCodeHidden: isCellCodeHidden(state, cellId),
|
|
587
|
-
codeFocus: undefined,
|
|
588
|
-
variableName: undefined,
|
|
589
|
-
});
|
|
590
|
-
scrollToBottom();
|
|
591
|
-
return state;
|
|
592
|
-
},
|
|
593
|
-
sendToTop: (state, action: { cellId: CellId; scroll?: boolean }) => {
|
|
594
|
-
const column = state.cellIds.findWithId(action.cellId);
|
|
595
|
-
if (column.length === 0) {
|
|
596
|
-
return state;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
const { cellId, scroll = true } = action;
|
|
600
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
601
|
-
if (cellIndex === 0) {
|
|
602
|
-
return state;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
return {
|
|
606
|
-
...state,
|
|
607
|
-
cellIds: state.cellIds.moveWithinColumn(column.id, cellIndex, 0),
|
|
608
|
-
scrollKey: scroll ? cellId : null,
|
|
609
|
-
};
|
|
610
|
-
},
|
|
611
|
-
sendToBottom: (state, action: { cellId: CellId; scroll?: boolean }) => {
|
|
612
|
-
const column = state.cellIds.findWithId(action.cellId);
|
|
613
|
-
if (column.length === 0) {
|
|
614
|
-
return state;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
const { cellId, scroll = true } = action;
|
|
618
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
619
|
-
const newIndex = column.length - 1;
|
|
620
|
-
|
|
621
|
-
if (cellIndex === newIndex) {
|
|
622
|
-
return state;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
return {
|
|
626
|
-
...state,
|
|
627
|
-
cellIds: state.cellIds.moveWithinColumn(column.id, cellIndex, newIndex),
|
|
628
|
-
scrollKey: scroll ? cellId : null,
|
|
629
|
-
};
|
|
630
|
-
},
|
|
631
|
-
addColumn: (state, action: { columnId: CellColumnId }) => {
|
|
632
|
-
// Add column and new cell
|
|
633
|
-
const newCellId = CellId.create();
|
|
634
|
-
return {
|
|
635
|
-
...state,
|
|
636
|
-
cellIds: state.cellIds.addColumn(action.columnId, [newCellId]),
|
|
637
|
-
cellData: {
|
|
638
|
-
...state.cellData,
|
|
639
|
-
[newCellId]: createCell({
|
|
640
|
-
id: newCellId,
|
|
641
|
-
}),
|
|
642
|
-
},
|
|
643
|
-
cellRuntime: {
|
|
644
|
-
...state.cellRuntime,
|
|
645
|
-
[newCellId]: createCellRuntimeState(),
|
|
646
|
-
},
|
|
647
|
-
cellHandles: {
|
|
648
|
-
...state.cellHandles,
|
|
649
|
-
[newCellId]: createRef(),
|
|
650
|
-
},
|
|
651
|
-
scrollKey: newCellId,
|
|
652
|
-
};
|
|
653
|
-
},
|
|
654
|
-
addColumnBreakpoint: (state, action: { cellId: CellId }) => {
|
|
655
|
-
const { cellId } = action;
|
|
656
|
-
if (state.cellIds.getColumns()[0].inOrderIds[0] === cellId) {
|
|
657
|
-
return state;
|
|
658
|
-
}
|
|
659
|
-
return {
|
|
660
|
-
...state,
|
|
661
|
-
cellIds: state.cellIds.insertBreakpoint(cellId),
|
|
662
|
-
};
|
|
663
|
-
},
|
|
664
|
-
deleteColumn: (state, action: { columnId: CellColumnId }) => {
|
|
665
|
-
// Move all cells in the column to the previous column
|
|
666
|
-
const { columnId } = action;
|
|
667
|
-
return {
|
|
668
|
-
...state,
|
|
669
|
-
cellIds: state.cellIds.delete(columnId),
|
|
670
|
-
};
|
|
671
|
-
},
|
|
672
|
-
mergeAllColumns: (state) => {
|
|
673
|
-
return {
|
|
674
|
-
...state,
|
|
675
|
-
cellIds: state.cellIds.mergeAllColumns(),
|
|
676
|
-
};
|
|
677
|
-
},
|
|
678
|
-
compactColumns: (state) => {
|
|
679
|
-
return {
|
|
680
|
-
...state,
|
|
681
|
-
cellIds: state.cellIds.compact(),
|
|
682
|
-
};
|
|
683
|
-
},
|
|
684
|
-
deleteCell: (state, action: { cellId: CellId }) => {
|
|
685
|
-
const cellId = action.cellId;
|
|
686
|
-
|
|
687
|
-
// Can't delete the last cell, across all columns
|
|
688
|
-
if (state.cellIds.hasOnlyOneId()) {
|
|
689
|
-
return state;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
let column: CollapsibleTree<CellId>;
|
|
693
|
-
try {
|
|
694
|
-
column = state.cellIds.findWithId(cellId);
|
|
695
|
-
} catch (error) {
|
|
696
|
-
// Expected for kernel-only cells or out-of-order transactions.
|
|
697
|
-
Logger.warn("Skipping delete for missing cellId", {
|
|
698
|
-
cellId,
|
|
699
|
-
error,
|
|
700
|
-
});
|
|
701
|
-
return state;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
705
|
-
const focusIndex = cellIndex === 0 ? 1 : cellIndex - 1;
|
|
706
|
-
let scrollKey: CellId | null = null;
|
|
707
|
-
if (column.length > 1) {
|
|
708
|
-
scrollKey = column.atOrThrow(focusIndex);
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
const editorView = state.cellHandles[cellId].current?.editorView;
|
|
712
|
-
const serializedEditorState = editorView?.state.toJSON({
|
|
713
|
-
history: historyField,
|
|
714
|
-
});
|
|
715
|
-
if (serializedEditorState) {
|
|
716
|
-
serializedEditorState.doc = state.cellData[cellId].code;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// release the granular atom(s) created for this cell
|
|
720
|
-
releaseCellAtoms(cellId);
|
|
721
|
-
const prevData = state.cellData[cellId];
|
|
722
|
-
return {
|
|
723
|
-
...state,
|
|
724
|
-
cellIds: state.cellIds.deleteById(cellId),
|
|
725
|
-
history: [
|
|
726
|
-
...state.history,
|
|
727
|
-
{
|
|
728
|
-
type: "delete",
|
|
729
|
-
name: prevData.name,
|
|
730
|
-
serializedEditorState: serializedEditorState,
|
|
731
|
-
column: column.id,
|
|
732
|
-
index: cellIndex,
|
|
733
|
-
isSetupCell: cellId === SETUP_CELL_ID,
|
|
734
|
-
config: prevData.config,
|
|
735
|
-
},
|
|
736
|
-
],
|
|
737
|
-
scrollKey: scrollKey,
|
|
738
|
-
};
|
|
739
|
-
},
|
|
740
|
-
undoDeleteCell: (state) => {
|
|
741
|
-
if (state.history.length === 0) {
|
|
742
|
-
return state;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
const last = state.history[state.history.length - 1];
|
|
746
|
-
|
|
747
|
-
if (last.type === "move") {
|
|
748
|
-
const { cellIds, placements } = last;
|
|
749
|
-
if (
|
|
750
|
-
cellIds.length === 0 ||
|
|
751
|
-
placements.length !== cellIds.length ||
|
|
752
|
-
cellIds.some((id) => !state.cellData[id])
|
|
753
|
-
) {
|
|
754
|
-
return { ...state, history: state.history.slice(0, -1) };
|
|
755
|
-
}
|
|
756
|
-
const toRestore = cellIds.map((id, i) => ({
|
|
757
|
-
id,
|
|
758
|
-
columnId: placements[i].columnId,
|
|
759
|
-
index: placements[i].index,
|
|
760
|
-
}));
|
|
761
|
-
return {
|
|
762
|
-
...state,
|
|
763
|
-
cellIds: state.cellIds.placeCells(toRestore),
|
|
764
|
-
history: state.history.slice(0, -1),
|
|
765
|
-
scrollKey: cellIds[0] ?? null,
|
|
766
|
-
};
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
const {
|
|
770
|
-
name,
|
|
771
|
-
serializedEditorState = { doc: "" },
|
|
772
|
-
column,
|
|
773
|
-
index,
|
|
774
|
-
isSetupCell,
|
|
775
|
-
config,
|
|
776
|
-
} = last;
|
|
777
|
-
|
|
778
|
-
const cellId = isSetupCell ? SETUP_CELL_ID : CellId.create();
|
|
779
|
-
const undoCell = createCell({
|
|
780
|
-
id: cellId,
|
|
781
|
-
name,
|
|
782
|
-
code: serializedEditorState.doc,
|
|
783
|
-
edited: serializedEditorState.doc.trim().length > 0,
|
|
784
|
-
serializedEditorState,
|
|
785
|
-
config,
|
|
786
|
-
});
|
|
787
|
-
|
|
788
|
-
return {
|
|
789
|
-
...state,
|
|
790
|
-
cellIds: state.cellIds.insertId(cellId, column, index),
|
|
791
|
-
cellData: {
|
|
792
|
-
...state.cellData,
|
|
793
|
-
[cellId]: undoCell,
|
|
794
|
-
},
|
|
795
|
-
cellRuntime: {
|
|
796
|
-
...state.cellRuntime,
|
|
797
|
-
[cellId]: createCellRuntimeState(),
|
|
798
|
-
},
|
|
799
|
-
cellHandles: {
|
|
800
|
-
...state.cellHandles,
|
|
801
|
-
[cellId]: createRef(),
|
|
802
|
-
},
|
|
803
|
-
history: state.history.slice(0, -1),
|
|
804
|
-
// Scroll to the newly created cell
|
|
805
|
-
scrollKey: cellId,
|
|
806
|
-
};
|
|
807
|
-
},
|
|
808
|
-
clearSerializedEditorState: (state, action: { cellId: CellId }) => {
|
|
809
|
-
const { cellId } = action;
|
|
810
|
-
return updateCellData({
|
|
811
|
-
state,
|
|
812
|
-
cellId,
|
|
813
|
-
cellReducer: (cell) => {
|
|
814
|
-
return {
|
|
815
|
-
...cell,
|
|
816
|
-
serializedEditorState: null,
|
|
817
|
-
};
|
|
818
|
-
},
|
|
819
|
-
});
|
|
820
|
-
},
|
|
821
|
-
updateCellCode: (
|
|
164
|
+
/**
|
|
165
|
+
* Keep a cell as run, or as edited, as it was before formatting rewrote
|
|
166
|
+
* its code from `before` to `after`. The code itself arrives through the
|
|
167
|
+
* document.
|
|
168
|
+
*/
|
|
169
|
+
codeFormatted: (
|
|
822
170
|
state,
|
|
823
|
-
action: {
|
|
824
|
-
cellId: CellId;
|
|
825
|
-
code: string;
|
|
826
|
-
/**
|
|
827
|
-
* Whether or not the update is a formatting change,
|
|
828
|
-
* if so, the 'edited' state will be handled differently.
|
|
829
|
-
*/
|
|
830
|
-
formattingChange: boolean;
|
|
831
|
-
},
|
|
171
|
+
action: { cellId: CellId; before: string; after: string },
|
|
832
172
|
) => {
|
|
833
|
-
const { cellId,
|
|
173
|
+
const { cellId, before, after } = action;
|
|
834
174
|
if (!state.cellData[cellId]) {
|
|
835
175
|
return state;
|
|
836
176
|
}
|
|
837
|
-
|
|
838
|
-
return updateCellData({
|
|
839
|
-
state,
|
|
840
|
-
cellId,
|
|
841
|
-
cellReducer: (cell) => {
|
|
842
|
-
// Formatting-only change means we can re-use the last code run
|
|
843
|
-
// if it was not previously edited. And we don't change the edited state.
|
|
844
|
-
return formattingChange
|
|
845
|
-
? {
|
|
846
|
-
...cell,
|
|
847
|
-
code: code,
|
|
848
|
-
lastCodeRun: cell.edited ? cell.lastCodeRun : code,
|
|
849
|
-
}
|
|
850
|
-
: {
|
|
851
|
-
...cell,
|
|
852
|
-
code: code,
|
|
853
|
-
edited: code.trim() !== cell.lastCodeRun,
|
|
854
|
-
};
|
|
855
|
-
},
|
|
856
|
-
});
|
|
857
|
-
},
|
|
858
|
-
updateCellName: (state, action: { cellId: CellId; name: string }) => {
|
|
859
|
-
const { cellId, name } = action;
|
|
860
177
|
return updateCellData({
|
|
861
178
|
state,
|
|
862
179
|
cellId,
|
|
863
180
|
cellReducer: (cell) => {
|
|
181
|
+
const lastCodeRun = isEdited(cell.lastCodeRun, before)
|
|
182
|
+
? cell.lastCodeRun
|
|
183
|
+
: after;
|
|
864
184
|
return {
|
|
865
185
|
...cell,
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
},
|
|
869
|
-
});
|
|
870
|
-
},
|
|
871
|
-
updateCellConfig: (
|
|
872
|
-
state,
|
|
873
|
-
action: { cellId: CellId; config: Partial<CellConfig> },
|
|
874
|
-
) => {
|
|
875
|
-
const { cellId, config } = action;
|
|
876
|
-
return updateCellData({
|
|
877
|
-
state,
|
|
878
|
-
cellId,
|
|
879
|
-
cellReducer: (cell) => {
|
|
880
|
-
return {
|
|
881
|
-
...cell,
|
|
882
|
-
config: createCellConfig({ ...cell.config, ...config }),
|
|
186
|
+
lastCodeRun,
|
|
187
|
+
edited: isEdited(lastCodeRun, cell.code),
|
|
883
188
|
};
|
|
884
189
|
},
|
|
885
190
|
});
|
|
@@ -888,9 +193,7 @@ const {
|
|
|
888
193
|
const newState = updateCellRuntimeState({
|
|
889
194
|
state,
|
|
890
195
|
cellId: action.cellId,
|
|
891
|
-
cellReducer: (cell) => {
|
|
892
|
-
return prepareCellForExecution(cell);
|
|
893
|
-
},
|
|
196
|
+
cellReducer: (cell) => ({ ...cell, debuggerActive: false }),
|
|
894
197
|
});
|
|
895
198
|
return updateCellData({
|
|
896
199
|
state: newState,
|
|
@@ -939,158 +242,14 @@ const {
|
|
|
939
242
|
cellLogs: [...state.cellLogs, ...action.logs],
|
|
940
243
|
};
|
|
941
244
|
},
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
// Create new cell data and runtime states for the new cell IDs
|
|
949
|
-
const nextCellData = { ...state.cellData };
|
|
950
|
-
const nextCellRuntime = { ...state.cellRuntime };
|
|
951
|
-
const nextCellHandles = { ...state.cellHandles };
|
|
952
|
-
|
|
953
|
-
for (const cellId of action.cellIds) {
|
|
954
|
-
if (!(cellId in state.cellData)) {
|
|
955
|
-
nextCellData[cellId] = createCell({ id: cellId });
|
|
956
|
-
}
|
|
957
|
-
if (!(cellId in state.cellRuntime)) {
|
|
958
|
-
nextCellRuntime[cellId] = createCellRuntimeState();
|
|
959
|
-
}
|
|
960
|
-
if (!(cellId in state.cellHandles)) {
|
|
961
|
-
nextCellHandles[cellId] = createRef();
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
|
|
965
|
-
return {
|
|
966
|
-
...state,
|
|
967
|
-
cellIds: MultiColumn.fromWithPreviousShape(action.cellIds, state.cellIds),
|
|
968
|
-
cellData: nextCellData,
|
|
969
|
-
cellRuntime: nextCellRuntime,
|
|
970
|
-
cellHandles: nextCellHandles,
|
|
971
|
-
};
|
|
972
|
-
},
|
|
973
|
-
/**
|
|
974
|
-
* Rebuild the MultiColumn tree using each cell's `config.column` value.
|
|
975
|
-
*
|
|
976
|
-
* Used after a transaction whose `set-config` changes updated cells'
|
|
977
|
-
* column metadata without physically moving them in the tree. Cells with
|
|
978
|
-
* `config.column == null` inherit the column of the previous cell in the
|
|
979
|
-
* given order (see `MultiColumn.fromIdsAndColumns`), which lets the server
|
|
980
|
-
* send column changes only at column boundaries.
|
|
981
|
-
*/
|
|
982
|
-
rebuildCellColumns: (state, action: { cellIds: CellId[] }) => {
|
|
983
|
-
const newCellIds = MultiColumn.fromIdsAndColumns(
|
|
984
|
-
action.cellIds.map((id) => [
|
|
985
|
-
id,
|
|
986
|
-
state.cellData[id]?.config.column ?? null,
|
|
987
|
-
]),
|
|
988
|
-
);
|
|
989
|
-
return { ...state, cellIds: newCellIds };
|
|
990
|
-
},
|
|
991
|
-
setCellCodes: (
|
|
992
|
-
state,
|
|
993
|
-
action: {
|
|
994
|
-
codes: string[];
|
|
995
|
-
ids: CellId[];
|
|
996
|
-
codeIsStale: boolean;
|
|
997
|
-
names?: string[];
|
|
998
|
-
configs?: CellConfig[];
|
|
999
|
-
},
|
|
1000
|
-
) => {
|
|
1001
|
-
invariant(
|
|
1002
|
-
action.codes.length === action.ids.length,
|
|
1003
|
-
"Expected codes and ids to have the same length",
|
|
1004
|
-
);
|
|
1005
|
-
|
|
1006
|
-
let nextState = { ...state };
|
|
1007
|
-
|
|
1008
|
-
const cellReducer = ({
|
|
1009
|
-
cell,
|
|
1010
|
-
code,
|
|
1011
|
-
cellId,
|
|
1012
|
-
name,
|
|
1013
|
-
config,
|
|
1014
|
-
}: {
|
|
1015
|
-
cell: CellData | undefined;
|
|
1016
|
-
code: string;
|
|
1017
|
-
cellId: CellId;
|
|
1018
|
-
name?: string;
|
|
1019
|
-
config?: CellConfig;
|
|
1020
|
-
}) => {
|
|
1021
|
-
if (!cell) {
|
|
1022
|
-
return createCell({
|
|
1023
|
-
id: cellId,
|
|
1024
|
-
code,
|
|
1025
|
-
name: name,
|
|
1026
|
-
config: config,
|
|
1027
|
-
lastCodeRun: action.codeIsStale ? null : code,
|
|
1028
|
-
edited: action.codeIsStale && code.trim().length > 0,
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
// If code is stale, we don't promote it to lastCodeRun
|
|
1033
|
-
const lastCodeRun = action.codeIsStale ? cell.lastCodeRun : code;
|
|
1034
|
-
|
|
1035
|
-
// Mark as edited if the code has changed
|
|
1036
|
-
const edited = lastCodeRun
|
|
1037
|
-
? lastCodeRun.trim() !== code.trim()
|
|
1038
|
-
: Boolean(code);
|
|
1039
|
-
|
|
1040
|
-
// No change
|
|
1041
|
-
if (cell.code.trim() === code.trim()) {
|
|
1042
|
-
return {
|
|
1043
|
-
...cell,
|
|
1044
|
-
code: code,
|
|
1045
|
-
edited,
|
|
1046
|
-
lastCodeRun,
|
|
1047
|
-
...(name !== undefined && { name }),
|
|
1048
|
-
...(config !== undefined && { config }),
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
// Update codemirror if mounted. RTC-backed cells sync via Loro; others
|
|
1053
|
-
// (e.g. scratchpad) still need an explicit editor update.
|
|
1054
|
-
if (!isRtcEnabled() || !canUseRtc(cellId)) {
|
|
1055
|
-
const cellHandle = nextState.cellHandles[cellId].current;
|
|
1056
|
-
if (cellHandle?.editorViewOrNull) {
|
|
1057
|
-
updateEditorCodeFromPython(cellHandle.editorViewOrNull, code);
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
return {
|
|
1062
|
-
...cell,
|
|
1063
|
-
code: code,
|
|
1064
|
-
edited,
|
|
1065
|
-
lastCodeRun,
|
|
1066
|
-
...(name !== undefined && { name }),
|
|
1067
|
-
...(config !== undefined && { config }),
|
|
1068
|
-
};
|
|
1069
|
-
};
|
|
1070
|
-
|
|
1071
|
-
for (let i = 0; i < action.ids.length; i++) {
|
|
1072
|
-
const cellId = action.ids[i];
|
|
1073
|
-
const code = action.codes[i];
|
|
1074
|
-
if (cellId === undefined || code === undefined) {
|
|
1075
|
-
continue;
|
|
245
|
+
/** Follow the host document's cells and order. */
|
|
246
|
+
reconcileDocument: (state, document: EditableDocument) => {
|
|
247
|
+
const nextState = applyDocument(state, document);
|
|
248
|
+
for (const cellId of state.cellIds) {
|
|
249
|
+
if (!(cellId in nextState.cellData)) {
|
|
250
|
+
releaseCellAtoms(cellId);
|
|
1076
251
|
}
|
|
1077
|
-
const name = action.names?.[i];
|
|
1078
|
-
const config = action.configs?.[i];
|
|
1079
|
-
nextState = {
|
|
1080
|
-
...nextState,
|
|
1081
|
-
cellData: {
|
|
1082
|
-
...nextState.cellData,
|
|
1083
|
-
[cellId]: cellReducer({
|
|
1084
|
-
cell: nextState.cellData[cellId],
|
|
1085
|
-
code,
|
|
1086
|
-
cellId,
|
|
1087
|
-
name,
|
|
1088
|
-
config,
|
|
1089
|
-
}),
|
|
1090
|
-
},
|
|
1091
|
-
};
|
|
1092
252
|
}
|
|
1093
|
-
|
|
1094
253
|
return nextState;
|
|
1095
254
|
},
|
|
1096
255
|
setStdinResponse: (
|
|
@@ -1114,6 +273,7 @@ const {
|
|
|
1114
273
|
mimetype: stdinOutput.mimetype,
|
|
1115
274
|
data: stdinOutput.data,
|
|
1116
275
|
timestamp: stdinOutput.timestamp,
|
|
276
|
+
id: stdinOutput.id,
|
|
1117
277
|
// An empty response resolves the prompt without retaining the secret.
|
|
1118
278
|
response: stdinOutput.mimetype === "text/password" ? "" : response,
|
|
1119
279
|
};
|
|
@@ -1126,155 +286,37 @@ const {
|
|
|
1126
286
|
},
|
|
1127
287
|
});
|
|
1128
288
|
},
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
const hasSnapshot =
|
|
1141
|
-
prev && (prev.output != null || prev.consoleOutputs.length > 0);
|
|
1142
|
-
return hasSnapshot ? prev : createCellRuntimeState();
|
|
1143
|
-
};
|
|
1144
|
-
const cellRuntime = Object.fromEntries(
|
|
1145
|
-
cells.map((cell) => [cell.id, runtimeFor(cell.id)]),
|
|
1146
|
-
);
|
|
1147
|
-
|
|
1148
|
-
return withScratchCell({
|
|
1149
|
-
...state,
|
|
1150
|
-
cellIds: MultiColumn.fromIdsAndColumns(
|
|
1151
|
-
cells.map((cell) => [cell.id, cell.config.column]),
|
|
1152
|
-
),
|
|
1153
|
-
cellData: cellData,
|
|
1154
|
-
cellRuntime: cellRuntime,
|
|
1155
|
-
cellHandles: Object.fromEntries(
|
|
1156
|
-
cells.map((cell) => [cell.id, createRef()]),
|
|
1157
|
-
),
|
|
1158
|
-
});
|
|
1159
|
-
},
|
|
1160
|
-
/**
|
|
1161
|
-
* Move focus to next cell
|
|
1162
|
-
*
|
|
1163
|
-
* Creates a new cell if the current cell is the last one in the array.
|
|
1164
|
-
*
|
|
1165
|
-
* If needed, scrolls newly created or focused cell into view.
|
|
1166
|
-
*
|
|
1167
|
-
* Replicates Shift+Enter functionality of Jupyter
|
|
1168
|
-
*/
|
|
1169
|
-
moveToNextCell: (
|
|
1170
|
-
state,
|
|
1171
|
-
action: { cellId: CellId; before: boolean; noCreate?: boolean },
|
|
1172
|
-
) => {
|
|
1173
|
-
const { cellId, before, noCreate = false } = action;
|
|
1174
|
-
|
|
1175
|
-
// Can't move focus of scratch cell
|
|
1176
|
-
if (cellId === SCRATCH_CELL_ID) {
|
|
1177
|
-
return state;
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
const column = state.cellIds.findWithId(cellId);
|
|
1181
|
-
const index = column.indexOfOrThrow(cellId);
|
|
1182
|
-
const nextCellIndex = before ? index - 1 : index + 1;
|
|
1183
|
-
|
|
1184
|
-
const isPastLastCell = nextCellIndex === column.length;
|
|
1185
|
-
const isBeforeFirstCell = nextCellIndex === -1;
|
|
1186
|
-
|
|
1187
|
-
// Create a new cell at the end and set scrollKey to focus it
|
|
1188
|
-
if (isPastLastCell && !noCreate) {
|
|
1189
|
-
const newCellId = CellId.create();
|
|
1190
|
-
return {
|
|
1191
|
-
...state,
|
|
1192
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, nextCellIndex),
|
|
1193
|
-
cellData: {
|
|
1194
|
-
...state.cellData,
|
|
1195
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1196
|
-
},
|
|
1197
|
-
cellRuntime: {
|
|
1198
|
-
...state.cellRuntime,
|
|
1199
|
-
[newCellId]: createCellRuntimeState(),
|
|
1200
|
-
},
|
|
1201
|
-
cellHandles: {
|
|
1202
|
-
...state.cellHandles,
|
|
1203
|
-
[newCellId]: createRef(),
|
|
1204
|
-
},
|
|
1205
|
-
scrollKey: newCellId,
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
if (isBeforeFirstCell && !noCreate) {
|
|
1210
|
-
const newCellId = CellId.create();
|
|
1211
|
-
return {
|
|
1212
|
-
...state,
|
|
1213
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, 0),
|
|
1214
|
-
cellData: {
|
|
1215
|
-
...state.cellData,
|
|
1216
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1217
|
-
},
|
|
1218
|
-
cellRuntime: {
|
|
1219
|
-
...state.cellRuntime,
|
|
1220
|
-
[newCellId]: createCellRuntimeState(),
|
|
1221
|
-
},
|
|
1222
|
-
cellHandles: {
|
|
1223
|
-
...state.cellHandles,
|
|
1224
|
-
[newCellId]: createRef(),
|
|
1225
|
-
},
|
|
1226
|
-
scrollKey: newCellId,
|
|
1227
|
-
};
|
|
1228
|
-
}
|
|
1229
|
-
|
|
1230
|
-
if ((isPastLastCell || isBeforeFirstCell) && noCreate) {
|
|
1231
|
-
// Trying to move past the last cell or before the first cell
|
|
1232
|
-
// with noCreate=true - do nothing
|
|
1233
|
-
return state;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
if (nextCellIndex >= 0 && nextCellIndex < column.length) {
|
|
1237
|
-
// Move to valid cell within bounds
|
|
1238
|
-
const nextCellId = column.atOrThrow(nextCellIndex);
|
|
1239
|
-
// Just focus, no state change
|
|
1240
|
-
focusAndScrollCellIntoView({
|
|
1241
|
-
cellId: nextCellId,
|
|
1242
|
-
cell: state.cellHandles[nextCellId],
|
|
1243
|
-
isCodeHidden: isCellCodeHidden(state, nextCellId),
|
|
1244
|
-
codeFocus: before ? "bottom" : "top",
|
|
1245
|
-
variableName: undefined,
|
|
1246
|
-
});
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
return state;
|
|
1250
|
-
},
|
|
1251
|
-
markTouched: (state, action: { cellId: CellId }) => {
|
|
1252
|
-
const { cellId } = action;
|
|
1253
|
-
|
|
1254
|
-
if (state.untouchedNewCells.has(cellId)) {
|
|
1255
|
-
const nextUntouchedNewCells = new Set(state.untouchedNewCells);
|
|
1256
|
-
nextUntouchedNewCells.delete(cellId);
|
|
1257
|
-
return {
|
|
1258
|
-
...state,
|
|
1259
|
-
untouchedNewCells: nextUntouchedNewCells,
|
|
289
|
+
/** Record what the kernel last ran for each cell. */
|
|
290
|
+
setLastRun: (state, action: { lastCodeRun: Record<CellId, string> }) => {
|
|
291
|
+
const cellData = { ...state.cellData };
|
|
292
|
+
for (const cellId of state.cellIds) {
|
|
293
|
+
const cell = state.cellData[cellId];
|
|
294
|
+
const lastCodeRun = action.lastCodeRun[cellId] ?? null;
|
|
295
|
+
cellData[cellId] = {
|
|
296
|
+
...cell,
|
|
297
|
+
lastCodeRun,
|
|
298
|
+
// A cell the kernel never ran is not stale on load.
|
|
299
|
+
edited: lastCodeRun !== null && isEdited(lastCodeRun, cell.code),
|
|
1260
300
|
};
|
|
1261
301
|
}
|
|
1262
|
-
|
|
1263
|
-
return state;
|
|
302
|
+
return { ...state, cellData };
|
|
1264
303
|
},
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Start each cell's runtime over for a new kernel. WASM keeps the outputs
|
|
306
|
+
* its mount-time snapshot gave it.
|
|
307
|
+
*/
|
|
308
|
+
resetCellRuntimes: (state) => {
|
|
309
|
+
const preserveSnapshot = isWasm();
|
|
310
|
+
const cellRuntime = { ...state.cellRuntime };
|
|
311
|
+
for (const cellId of [...state.cellIds, SCRATCH_CELL_ID]) {
|
|
312
|
+
const previous = state.cellRuntime[cellId];
|
|
313
|
+
const hasSnapshot =
|
|
314
|
+
preserveSnapshot &&
|
|
315
|
+
previous !== undefined &&
|
|
316
|
+
(previous.output != null || previous.consoleOutputs.length > 0);
|
|
317
|
+
cellRuntime[cellId] = hasSnapshot ? previous : createCellRuntimeState();
|
|
1275
318
|
}
|
|
1276
|
-
|
|
1277
|
-
return state;
|
|
319
|
+
return { ...state, cellRuntime };
|
|
1278
320
|
},
|
|
1279
321
|
scrollToTarget: (state) => {
|
|
1280
322
|
// Scroll to the specified cell and clear the scroll key.
|
|
@@ -1283,16 +325,15 @@ const {
|
|
|
1283
325
|
return state;
|
|
1284
326
|
}
|
|
1285
327
|
|
|
1286
|
-
const
|
|
1287
|
-
const index = column.indexOfOrThrow(scrollKey);
|
|
1288
|
-
|
|
1289
|
-
const cellId =
|
|
1290
|
-
index === column.length - 1 ? column.last() : column.atOrThrow(index);
|
|
1291
|
-
|
|
328
|
+
const cellId = scrollKey;
|
|
1292
329
|
focusAndScrollCellIntoView({
|
|
1293
330
|
cellId: cellId,
|
|
1294
331
|
cell: state.cellHandles[cellId],
|
|
1295
|
-
isCodeHidden:
|
|
332
|
+
isCodeHidden: isCodeHidden(
|
|
333
|
+
state.cellData[cellId]?.config.hide_code,
|
|
334
|
+
store.get(shownHiddenCodeAtom),
|
|
335
|
+
cellId,
|
|
336
|
+
),
|
|
1296
337
|
codeFocus: undefined,
|
|
1297
338
|
variableName: undefined,
|
|
1298
339
|
});
|
|
@@ -1322,201 +363,6 @@ const {
|
|
|
1322
363
|
cellLogs: [],
|
|
1323
364
|
};
|
|
1324
365
|
},
|
|
1325
|
-
collapseCell: (state, action: { cellId: CellId }) => {
|
|
1326
|
-
const { cellId } = action;
|
|
1327
|
-
const column = state.cellIds.findWithId(cellId);
|
|
1328
|
-
|
|
1329
|
-
// Get all the top-level outlines
|
|
1330
|
-
const outlines = column.topLevelIds.map((id) => {
|
|
1331
|
-
const cell = state.cellRuntime[id];
|
|
1332
|
-
return cell.outline;
|
|
1333
|
-
});
|
|
1334
|
-
|
|
1335
|
-
// Find the start/end of the collapsed range
|
|
1336
|
-
const startIndex = column.indexOfOrThrow(cellId);
|
|
1337
|
-
const range = findCollapseRange(startIndex, outlines);
|
|
1338
|
-
if (!range) {
|
|
1339
|
-
return state;
|
|
1340
|
-
}
|
|
1341
|
-
const endCellId = column.atOrThrow(range[1]);
|
|
1342
|
-
|
|
1343
|
-
return {
|
|
1344
|
-
...state,
|
|
1345
|
-
// Collapse the range
|
|
1346
|
-
cellIds: state.cellIds.transformWithCellId(cellId, (column) =>
|
|
1347
|
-
column.collapse(cellId, endCellId),
|
|
1348
|
-
),
|
|
1349
|
-
scrollKey: cellId,
|
|
1350
|
-
};
|
|
1351
|
-
},
|
|
1352
|
-
expandCell: (state, action: { cellId: CellId }) => {
|
|
1353
|
-
const { cellId } = action;
|
|
1354
|
-
return {
|
|
1355
|
-
...state,
|
|
1356
|
-
cellIds: state.cellIds.transformWithCellId(cellId, (column) =>
|
|
1357
|
-
column.expand(cellId),
|
|
1358
|
-
),
|
|
1359
|
-
scrollKey: cellId,
|
|
1360
|
-
};
|
|
1361
|
-
},
|
|
1362
|
-
collapseAllCells: (state) => {
|
|
1363
|
-
return {
|
|
1364
|
-
...state,
|
|
1365
|
-
cellIds: state.cellIds.transformAll((column) => {
|
|
1366
|
-
// Get all the top-level outlines
|
|
1367
|
-
const outlines = column.topLevelIds.map((id) => {
|
|
1368
|
-
const cell = state.cellRuntime[id];
|
|
1369
|
-
return cell.outline;
|
|
1370
|
-
});
|
|
1371
|
-
|
|
1372
|
-
// Find the start/end of the collapsed ranges
|
|
1373
|
-
const nodes = [...column.nodes];
|
|
1374
|
-
const visibleEndByOriginalEnd = new Map<CellIndex, CellIndex>();
|
|
1375
|
-
const reversedCollapseRanges = [];
|
|
1376
|
-
|
|
1377
|
-
// Iterate in reverse order (bottom-up) to process children first
|
|
1378
|
-
let i = nodes.length - 1;
|
|
1379
|
-
while (i >= 0) {
|
|
1380
|
-
const range = findCollapseRange(i, outlines);
|
|
1381
|
-
if (range) {
|
|
1382
|
-
const startIndex = i;
|
|
1383
|
-
const originalEnd = range[1];
|
|
1384
|
-
const endIndex =
|
|
1385
|
-
visibleEndByOriginalEnd.get(originalEnd) ?? originalEnd;
|
|
1386
|
-
|
|
1387
|
-
// After this section collapses, its heading represents this
|
|
1388
|
-
// endpoint for any enclosing section that shares it.
|
|
1389
|
-
visibleEndByOriginalEnd.set(originalEnd, startIndex);
|
|
1390
|
-
|
|
1391
|
-
// Add the range to the list of ranges
|
|
1392
|
-
const cellId = column.atOrThrow(startIndex);
|
|
1393
|
-
const until = column.atOrThrow(endIndex);
|
|
1394
|
-
reversedCollapseRanges.push({ id: cellId, until });
|
|
1395
|
-
} else {
|
|
1396
|
-
reversedCollapseRanges.push(null);
|
|
1397
|
-
}
|
|
1398
|
-
i--;
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
const collapseRanges = reversedCollapseRanges.toReversed();
|
|
1402
|
-
return column.collapseAll(collapseRanges);
|
|
1403
|
-
}),
|
|
1404
|
-
};
|
|
1405
|
-
},
|
|
1406
|
-
expandAllCells: (state) => {
|
|
1407
|
-
return {
|
|
1408
|
-
...state,
|
|
1409
|
-
cellIds: state.cellIds.transformAll((column) => column.expandAll()),
|
|
1410
|
-
};
|
|
1411
|
-
},
|
|
1412
|
-
showCellIfHidden: (state, action: { cellId: CellId }) => {
|
|
1413
|
-
const { cellId } = action;
|
|
1414
|
-
const column = state.cellIds.findWithId(cellId);
|
|
1415
|
-
const prev = column;
|
|
1416
|
-
const result = column.findAndExpandDeep(cellId);
|
|
1417
|
-
|
|
1418
|
-
if (result.equals(prev)) {
|
|
1419
|
-
return state;
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
return {
|
|
1423
|
-
...state,
|
|
1424
|
-
cellIds: state.cellIds.transformWithCellId(cellId, () => result),
|
|
1425
|
-
};
|
|
1426
|
-
},
|
|
1427
|
-
splitCell: (state, action: { cellId: CellId }) => {
|
|
1428
|
-
const { cellId } = action;
|
|
1429
|
-
const column = state.cellIds.findWithId(cellId);
|
|
1430
|
-
const index = column.indexOfOrThrow(cellId);
|
|
1431
|
-
const cell = state.cellData[cellId];
|
|
1432
|
-
const cellHandle = state.cellHandles[cellId].current;
|
|
1433
|
-
|
|
1434
|
-
if (cellHandle?.editorView == null) {
|
|
1435
|
-
return state;
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
const { beforeCursorCode, afterCursorCode } = splitEditor(
|
|
1439
|
-
cellHandle.editorView,
|
|
1440
|
-
);
|
|
1441
|
-
|
|
1442
|
-
updateEditorCodeFromPython(cellHandle.editorView, beforeCursorCode);
|
|
1443
|
-
|
|
1444
|
-
const newCellId = CellId.create();
|
|
1445
|
-
|
|
1446
|
-
return {
|
|
1447
|
-
...state,
|
|
1448
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, index + 1),
|
|
1449
|
-
cellData: {
|
|
1450
|
-
...state.cellData,
|
|
1451
|
-
[cellId]: {
|
|
1452
|
-
...cell,
|
|
1453
|
-
code: beforeCursorCode,
|
|
1454
|
-
edited:
|
|
1455
|
-
Boolean(beforeCursorCode) &&
|
|
1456
|
-
beforeCursorCode.trim() !== cell.lastCodeRun?.trim(),
|
|
1457
|
-
},
|
|
1458
|
-
[newCellId]: createCell({
|
|
1459
|
-
id: newCellId,
|
|
1460
|
-
code: afterCursorCode,
|
|
1461
|
-
edited: Boolean(afterCursorCode),
|
|
1462
|
-
}),
|
|
1463
|
-
},
|
|
1464
|
-
cellRuntime: {
|
|
1465
|
-
...state.cellRuntime,
|
|
1466
|
-
[cellId]: {
|
|
1467
|
-
...state.cellRuntime[cellId],
|
|
1468
|
-
output: null,
|
|
1469
|
-
consoleOutputs: [],
|
|
1470
|
-
},
|
|
1471
|
-
[newCellId]: createCellRuntimeState(),
|
|
1472
|
-
},
|
|
1473
|
-
cellHandles: {
|
|
1474
|
-
...state.cellHandles,
|
|
1475
|
-
[newCellId]: createRef(),
|
|
1476
|
-
},
|
|
1477
|
-
scrollKey: newCellId,
|
|
1478
|
-
};
|
|
1479
|
-
},
|
|
1480
|
-
undoSplitCell: (state, action: { cellId: CellId; snapshot: string }) => {
|
|
1481
|
-
const { cellId, snapshot } = action;
|
|
1482
|
-
|
|
1483
|
-
const cell = state.cellData[cellId];
|
|
1484
|
-
const cellHandle = state.cellHandles[cellId].current;
|
|
1485
|
-
|
|
1486
|
-
if (cellHandle?.editorView == null) {
|
|
1487
|
-
return state;
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
updateEditorCodeFromPython(cellHandle.editorView, snapshot);
|
|
1491
|
-
|
|
1492
|
-
return {
|
|
1493
|
-
...state,
|
|
1494
|
-
cellIds: state.cellIds.transformWithCellId(cellId, (column) => {
|
|
1495
|
-
const newCellIndex = column.indexOfOrThrow(cellId) + 1;
|
|
1496
|
-
return column.deleteAtIndex(newCellIndex);
|
|
1497
|
-
}),
|
|
1498
|
-
cellData: {
|
|
1499
|
-
...state.cellData,
|
|
1500
|
-
[cellId]: {
|
|
1501
|
-
...cell,
|
|
1502
|
-
code: snapshot,
|
|
1503
|
-
edited:
|
|
1504
|
-
Boolean(snapshot) && snapshot?.trim() !== cell.lastCodeRun?.trim(),
|
|
1505
|
-
},
|
|
1506
|
-
},
|
|
1507
|
-
cellRuntime: {
|
|
1508
|
-
...state.cellRuntime,
|
|
1509
|
-
[cellId]: {
|
|
1510
|
-
...state.cellRuntime[cellId],
|
|
1511
|
-
output: null,
|
|
1512
|
-
consoleOutputs: [],
|
|
1513
|
-
},
|
|
1514
|
-
},
|
|
1515
|
-
cellHandles: {
|
|
1516
|
-
...state.cellHandles,
|
|
1517
|
-
},
|
|
1518
|
-
};
|
|
1519
|
-
},
|
|
1520
366
|
clearCellOutput: (state, action: { cellId: CellId }) => {
|
|
1521
367
|
const { cellId } = action;
|
|
1522
368
|
return updateCellRuntimeState({
|
|
@@ -1545,7 +391,7 @@ const {
|
|
|
1545
391
|
},
|
|
1546
392
|
clearAllCellOutputs: (state) => {
|
|
1547
393
|
const newCellRuntime = { ...state.cellRuntime };
|
|
1548
|
-
for (const cellId of state.cellIds
|
|
394
|
+
for (const cellId of state.cellIds) {
|
|
1549
395
|
newCellRuntime[cellId] = {
|
|
1550
396
|
...newCellRuntime[cellId],
|
|
1551
397
|
output: null,
|
|
@@ -1557,58 +403,8 @@ const {
|
|
|
1557
403
|
cellRuntime: newCellRuntime,
|
|
1558
404
|
};
|
|
1559
405
|
},
|
|
1560
|
-
addSetupCellIfDoesntExist: (state, action: { code?: string }) => {
|
|
1561
|
-
const { code } = action;
|
|
1562
|
-
|
|
1563
|
-
if (state.cellIds.setupCellExists()) {
|
|
1564
|
-
// Just focus on the existing setup cell
|
|
1565
|
-
return {
|
|
1566
|
-
...state,
|
|
1567
|
-
scrollKey: SETUP_CELL_ID,
|
|
1568
|
-
};
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
return {
|
|
1572
|
-
...state,
|
|
1573
|
-
cellIds: state.cellIds.insertId(
|
|
1574
|
-
SETUP_CELL_ID,
|
|
1575
|
-
state.cellIds.atOrThrow(0).id,
|
|
1576
|
-
0,
|
|
1577
|
-
),
|
|
1578
|
-
cellData: {
|
|
1579
|
-
...state.cellData,
|
|
1580
|
-
[SETUP_CELL_ID]: createCell({
|
|
1581
|
-
id: SETUP_CELL_ID,
|
|
1582
|
-
name: SETUP_CELL_ID,
|
|
1583
|
-
code,
|
|
1584
|
-
edited: Boolean(code),
|
|
1585
|
-
}),
|
|
1586
|
-
},
|
|
1587
|
-
cellRuntime: {
|
|
1588
|
-
...state.cellRuntime,
|
|
1589
|
-
[SETUP_CELL_ID]: createCellRuntimeState(),
|
|
1590
|
-
},
|
|
1591
|
-
cellHandles: {
|
|
1592
|
-
...state.cellHandles,
|
|
1593
|
-
[SETUP_CELL_ID]: createRef(),
|
|
1594
|
-
},
|
|
1595
|
-
scrollKey: SETUP_CELL_ID,
|
|
1596
|
-
};
|
|
1597
|
-
},
|
|
1598
406
|
});
|
|
1599
407
|
|
|
1600
|
-
// We apply the middleware here (rather than inline in createReducerAndAtoms)
|
|
1601
|
-
// so that the document transaction middleware can import CellActions and
|
|
1602
|
-
// strictly type the dispatched actions without creating a circular dependency.
|
|
1603
|
-
addMiddleware(documentTransactionMiddleware);
|
|
1604
|
-
|
|
1605
|
-
function isCellCodeHidden(state: NotebookState, cellId: CellId): boolean {
|
|
1606
|
-
return (
|
|
1607
|
-
Boolean(state.cellData[cellId].config.hide_code) &&
|
|
1608
|
-
!state.untouchedNewCells.has(cellId)
|
|
1609
|
-
);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
408
|
// Helper function to update a cell in the array
|
|
1613
409
|
function updateCellRuntimeState({
|
|
1614
410
|
state,
|
|
@@ -1656,43 +452,12 @@ function updateCellData({
|
|
|
1656
452
|
};
|
|
1657
453
|
}
|
|
1658
454
|
|
|
455
|
+
/** Each cell's config in order. The document's `column` configs are canonical. */
|
|
1659
456
|
export function getCellConfigs(state: NotebookState): CellConfig[] {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
// Handle the case where there's only one column
|
|
1666
|
-
// We don't want to set the column config
|
|
1667
|
-
const hasMultipleColumns = state.cellIds.getColumns().length > 1;
|
|
1668
|
-
if (!hasMultipleColumns) {
|
|
1669
|
-
return state.cellIds.getColumns().flatMap((column) => {
|
|
1670
|
-
return column.inOrderIds.map((cellId) => {
|
|
1671
|
-
return {
|
|
1672
|
-
...cells[cellId].config,
|
|
1673
|
-
...defaultCellConfig,
|
|
1674
|
-
};
|
|
1675
|
-
});
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
return state.cellIds.getColumns().flatMap((column, columnIndex) => {
|
|
1680
|
-
return column.inOrderIds.map((cellId, cellIndex) => {
|
|
1681
|
-
const config: Partial<CellConfig> = { ...defaultCellConfig };
|
|
1682
|
-
|
|
1683
|
-
// Only set the column index for the first cell in the column
|
|
1684
|
-
if (cellIndex === 0) {
|
|
1685
|
-
config.column = columnIndex;
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
|
-
const newConfig = {
|
|
1689
|
-
...cells[cellId].config,
|
|
1690
|
-
...config,
|
|
1691
|
-
};
|
|
1692
|
-
|
|
1693
|
-
return newConfig;
|
|
1694
|
-
});
|
|
1695
|
-
});
|
|
457
|
+
return state.cellIds.map((cellId) => ({
|
|
458
|
+
...state.cellData[cellId].config,
|
|
459
|
+
column: state.cellData[cellId].config.column ?? null,
|
|
460
|
+
}));
|
|
1696
461
|
}
|
|
1697
462
|
|
|
1698
463
|
export {
|
|
@@ -1712,9 +477,7 @@ export const addLogs = imperativeActions.addLogs;
|
|
|
1712
477
|
|
|
1713
478
|
export const cellIdsAtom = atom((get) => get(notebookAtom).cellIds);
|
|
1714
479
|
|
|
1715
|
-
export const hasOnlyOneCellAtom = atom((get) =>
|
|
1716
|
-
get(cellIdsAtom).hasOnlyOneId(),
|
|
1717
|
-
);
|
|
480
|
+
export const hasOnlyOneCellAtom = atom((get) => get(cellIdsAtom).length === 1);
|
|
1718
481
|
|
|
1719
482
|
export const hasDisabledCellsAtom = atom(
|
|
1720
483
|
(get) => disabledCellIds(get(notebookAtom)).length > 0,
|
|
@@ -1728,11 +491,13 @@ export const canUndoDeletesAtom = atom((get) =>
|
|
|
1728
491
|
|
|
1729
492
|
export const undoLabelAtom = atom((get) => getUndoLabel(get(notebookAtom)));
|
|
1730
493
|
|
|
1731
|
-
export const needsRunAtom = atom((get) =>
|
|
494
|
+
export const needsRunAtom = atom((get) =>
|
|
495
|
+
notebookNeedsRun(get(notebookAtom), get(cellExecutionInputsAtom)),
|
|
496
|
+
);
|
|
1732
497
|
|
|
1733
498
|
export const cellErrorsAtom = atom((get) => {
|
|
1734
499
|
const { cellIds, cellRuntime, cellData } = get(notebookAtom);
|
|
1735
|
-
const errors = cellIds
|
|
500
|
+
const errors = cellIds
|
|
1736
501
|
.map((cellId) => {
|
|
1737
502
|
const cell = cellRuntime[cellId];
|
|
1738
503
|
const { name } = cellData[cellId];
|
|
@@ -1760,11 +525,28 @@ export const cellErrorsAtom = atom((get) => {
|
|
|
1760
525
|
return errors;
|
|
1761
526
|
});
|
|
1762
527
|
|
|
528
|
+
/**
|
|
529
|
+
* The outline of each cell whose output has a heading. Compared by value, so
|
|
530
|
+
* readers are left alone by the runtime messages that change no heading.
|
|
531
|
+
*/
|
|
532
|
+
export const cellOutlinesAtom = createDeepEqualAtom(
|
|
533
|
+
atom((get) => {
|
|
534
|
+
const outlines: Partial<Record<CellId, Outline>> = {};
|
|
535
|
+
for (const [id, runtime] of Objects.entries(
|
|
536
|
+
get(notebookAtom).cellRuntime,
|
|
537
|
+
)) {
|
|
538
|
+
if (runtime.outline !== null && runtime.outline.items.length > 0) {
|
|
539
|
+
outlines[id] = runtime.outline;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return outlines;
|
|
543
|
+
}),
|
|
544
|
+
);
|
|
545
|
+
|
|
1763
546
|
export const notebookOutline = atom((get) => {
|
|
1764
|
-
const
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1767
|
-
);
|
|
547
|
+
const cellIds = get(cellIdsAtom);
|
|
548
|
+
const cellRuntime = get(cellsRuntimeAtom);
|
|
549
|
+
const outlines = cellIds.map((cellId) => cellRuntime[cellId].outline);
|
|
1768
550
|
return mergeOutlines(outlines);
|
|
1769
551
|
});
|
|
1770
552
|
|
|
@@ -1774,7 +556,7 @@ export const cellIdToNamesMap = createDeepEqualAtom(
|
|
|
1774
556
|
atom((get) => {
|
|
1775
557
|
const { cellIds, cellData } = get(notebookAtom);
|
|
1776
558
|
const names: Record<CellId, string | undefined> = Objects.fromEntries(
|
|
1777
|
-
cellIds.
|
|
559
|
+
cellIds.map((cellId) => [cellId, cellData[cellId]?.name]),
|
|
1778
560
|
);
|
|
1779
561
|
return names;
|
|
1780
562
|
}),
|
|
@@ -1831,41 +613,19 @@ export const getCells = () => store.get(notebookAtom).cellIds;
|
|
|
1831
613
|
*/
|
|
1832
614
|
export const getCellNames = () => {
|
|
1833
615
|
const { cellIds, cellData } = store.get(notebookAtom);
|
|
1834
|
-
return cellIds.
|
|
616
|
+
return cellIds.map((id) => cellData[id]?.name).filter(Boolean);
|
|
1835
617
|
};
|
|
1836
618
|
|
|
1837
619
|
const cellDataAtoms = splitAtom(
|
|
1838
620
|
selectAtom(notebookAtom, (cells) =>
|
|
1839
|
-
cells.cellIds.
|
|
621
|
+
cells.cellIds.map((id) => cells.cellData[id]),
|
|
1840
622
|
),
|
|
1841
623
|
);
|
|
1842
624
|
export const useCellDataAtoms = () => useAtom(cellDataAtoms);
|
|
1843
625
|
|
|
1844
626
|
export const cellsRuntimeAtom = atom((get) => get(notebookAtom).cellRuntime);
|
|
1845
627
|
|
|
1846
|
-
export const
|
|
1847
|
-
notebookIsRunning(get(notebookAtom)),
|
|
1848
|
-
);
|
|
1849
|
-
export const onlyScratchpadIsRunningAtom = atom((get) => {
|
|
1850
|
-
const { cellRuntime } = get(notebookAtom);
|
|
1851
|
-
return Object.entries(cellRuntime).every(
|
|
1852
|
-
([id, rt]) => rt.status !== "running" || id === SCRATCH_CELL_ID,
|
|
1853
|
-
);
|
|
1854
|
-
});
|
|
1855
|
-
export const notebookQueuedOrRunningCountAtom = atom((get) =>
|
|
1856
|
-
notebookQueueOrRunningCount(get(notebookAtom)),
|
|
1857
|
-
);
|
|
1858
|
-
|
|
1859
|
-
export const numColumnsAtom = atom(
|
|
1860
|
-
(get) => get(notebookAtom).cellIds.colLength,
|
|
1861
|
-
);
|
|
1862
|
-
export const hasCellsAtom = atom(
|
|
1863
|
-
(get) => get(notebookAtom).cellIds.idLength > 0,
|
|
1864
|
-
);
|
|
1865
|
-
export const columnIdsAtom = atom((get) =>
|
|
1866
|
-
get(notebookAtom).cellIds.getColumnIds(),
|
|
1867
|
-
);
|
|
1868
|
-
|
|
628
|
+
export const hasCellsAtom = atom((get) => get(notebookAtom).cellIds.length > 0);
|
|
1869
629
|
export const cellDataAtom = atomFamily((cellId: CellId) =>
|
|
1870
630
|
atom((get) => get(notebookAtom).cellData[cellId]),
|
|
1871
631
|
);
|
|
@@ -1889,6 +649,7 @@ export function releaseCellAtoms(cellId: CellId) {
|
|
|
1889
649
|
cellDataAtom.remove(cellId);
|
|
1890
650
|
cellRuntimeAtom.remove(cellId);
|
|
1891
651
|
cellHandleAtom.remove(cellId);
|
|
652
|
+
withdrawCells(store, [cellId]);
|
|
1892
653
|
}
|
|
1893
654
|
|
|
1894
655
|
/** Subscribes to reactive updates of the cell's data. */
|
|
@@ -1906,7 +667,7 @@ export const useCellHandle = (cellId: CellId) =>
|
|
|
1906
667
|
*/
|
|
1907
668
|
export const getAllEditorViews = () => {
|
|
1908
669
|
const { cellIds, cellHandles } = store.get(notebookAtom);
|
|
1909
|
-
return cellIds
|
|
670
|
+
return cellIds
|
|
1910
671
|
.map((cellId) => cellHandles[cellId]?.current?.editorViewOrNull)
|
|
1911
672
|
.filter(Boolean);
|
|
1912
673
|
};
|
|
@@ -1930,16 +691,10 @@ export function flattenTopLevelNotebookCells(
|
|
|
1930
691
|
state: NotebookState,
|
|
1931
692
|
): (CellData & CellRuntimeState)[] {
|
|
1932
693
|
const { cellIds, cellData, cellRuntime } = state;
|
|
1933
|
-
return cellIds.
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
})),
|
|
1938
|
-
);
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
|
-
export function createUntouchedCellAtom(cellId: CellId): Atom<boolean> {
|
|
1942
|
-
return atom((get) => get(notebookAtom).untouchedNewCells.has(cellId));
|
|
694
|
+
return cellIds.map((cellId) => ({
|
|
695
|
+
...cellData[cellId],
|
|
696
|
+
...cellRuntime[cellId],
|
|
697
|
+
}));
|
|
1943
698
|
}
|
|
1944
699
|
|
|
1945
700
|
export function createTracebackInfoAtom(
|
|
@@ -1955,7 +710,8 @@ export function createTracebackInfoAtom(
|
|
|
1955
710
|
return undefined;
|
|
1956
711
|
}
|
|
1957
712
|
|
|
1958
|
-
|
|
713
|
+
const { status } = cellExecutionView(get(cellExecutionInputsAtom), cellId);
|
|
714
|
+
if (status === "queued" || status === "running") {
|
|
1959
715
|
return undefined;
|
|
1960
716
|
}
|
|
1961
717
|
|
|
@@ -2001,20 +757,13 @@ export function createTracebackInfoAtom(
|
|
|
2001
757
|
});
|
|
2002
758
|
}
|
|
2003
759
|
|
|
2004
|
-
/**
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
*/
|
|
2008
|
-
export function useCellActions(
|
|
2009
|
-
options: { skipMiddleware?: boolean } = {},
|
|
2010
|
-
): CellActions {
|
|
2011
|
-
return useActions(options);
|
|
760
|
+
/** The reducer's actions. Components use `useCellActions` from `./actions`. */
|
|
761
|
+
export function useReducerActions(): ReducerCellActions {
|
|
762
|
+
return useActions();
|
|
2012
763
|
}
|
|
2013
764
|
|
|
2014
|
-
/**
|
|
2015
|
-
|
|
2016
|
-
*/
|
|
2017
|
-
export type CellActions = ReturnType<typeof createActions>;
|
|
765
|
+
/** The actions the reducer still handles. */
|
|
766
|
+
export type ReducerCellActions = ReturnType<typeof createActions>;
|
|
2018
767
|
|
|
2019
768
|
/**
|
|
2020
769
|
* This is exported for testing purposes only.
|
|
@@ -2023,7 +772,6 @@ export const exportedForTesting = {
|
|
|
2023
772
|
reducer,
|
|
2024
773
|
createActions,
|
|
2025
774
|
initialNotebookState,
|
|
2026
|
-
isCellCodeHidden,
|
|
2027
775
|
// Export atom families for testing cleanup
|
|
2028
776
|
cellDataAtom,
|
|
2029
777
|
cellRuntimeAtom,
|