@marimo-team/islands 0.25.3-dev170 → 0.25.3-dev175
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-BbSXV-Xa.js → ConnectedDataExplorerComponent-Le_OBfmt.js} +9 -9
- package/dist/{ErrorBoundary-NE86qEWZ.js → ErrorBoundary-DNvcAIsP.js} +8 -8
- package/dist/{abnfDiagram-VCTEODGH-D7n07nXf.js → abnfDiagram-VCTEODGH-Tf1ghyQQ.js} +2 -2
- package/dist/{any-language-editor-3E24SnCV.js → any-language-editor-BVFHDDQ3.js} +4 -4
- package/dist/{architectureDiagram-5GKGNRK7-D6CjRib5.js → architectureDiagram-5GKGNRK7-xlnbTG0T.js} +1 -1
- package/dist/{chat-ui-CC7GekpG.js → chat-ui-X-cWrL9u.js} +1218 -1218
- package/dist/{check-SpOMoCLP.js → check-C9Mp9eCK.js} +1 -1
- package/dist/{chunk-IMKFNOWR-6dtPz7uS.js → chunk-IMKFNOWR-Cmd4a5jy.js} +1 -1
- package/dist/{chunk-SHT3W25Y-BwnFNKDA.js → chunk-SHT3W25Y-mSNp-WpO.js} +1 -1
- package/dist/{chunk-SVP7TREG-D2eV4vBJ.js → chunk-SVP7TREG-CWC49D8X.js} +1 -1
- package/dist/{chunk-TICWLB2K-BDs4-_-r.js → chunk-TICWLB2K-De9FINtG.js} +1 -1
- package/dist/{classDiagram-ZZMXUADV-DCJnf_8v.js → classDiagram-ZZMXUADV-DweTkYdp.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-BOmSzPBD.js → classDiagram-v2-VYDZK3BY-A6MR2TiE.js} +2 -2
- package/dist/{code-visibility-Bzvc6ajl.js → code-visibility-CH1lmM1h.js} +5 -5
- package/dist/{common-Ciw4zkh2.js → common-DIrS1UR9.js} +1081 -1085
- package/dist/{copy-icon-C1trdvVt.js → copy-icon-De584pZ4.js} +2 -2
- package/dist/{cynefinDiagram-5FMLGOSQ-Bln_Soky.js → cynefinDiagram-5FMLGOSQ-BSvo5le-.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-D-nf7WzW.js → dagre-GXQ25YYZ-tXRQslO6.js} +1 -1
- package/dist/{data-grid-overlay-editor-AQREmxI7.js → data-grid-overlay-editor-DFLZvFK0.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-PsgSMkY2.js → diagram-S7CK7UJ4-r3t5VtwI.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-DfwfUuSw.js → diagram-UQ7AKVKN-qgbC8YnT.js} +1 -1
- package/dist/{diagram-VX7I27RA-C9_e-oMc.js → diagram-VX7I27RA-CiHxEwtp.js} +1 -1
- package/dist/{diagram-Z3DM3KII-CWLa5tuY.js → diagram-Z3DM3KII-D95u15Ev.js} +1 -1
- package/dist/{dialog-DgeqyrEZ.js → dialog-DVRfQuhD.js} +24 -24
- package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
- package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
- package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
- package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
- package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
- package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
- package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
- package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
- package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
- package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
- package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
- package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
- package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
- package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
- package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
- package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
- package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
- package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
- package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
- package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
- package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
- package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
- package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
- package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
- package/dist/{dropdown-menu-B6ftyzOg.js → dropdown-menu-DCMbbQ35.js} +691 -691
- package/dist/{ebnfDiagram-PWID7BFC-B1QRM58v.js → ebnfDiagram-PWID7BFC-P7e4bryK.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-DJK_FqvW.js → erDiagram-RLTQ6QDP-CUHZcmRj.js} +1 -1
- package/dist/{error-banner-D40pmfQQ.js → error-banner-DxJ3s8YO.js} +57 -57
- package/dist/{error-entries-DgK3wUJR.js → error-entries-mpoD5t79.js} +4985 -5006
- package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
- package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
- package/dist/{feedback-button-8a6SETmT.js → feedback-button-DL0DJ-LB.js} +30 -30
- package/dist/{flowDiagram-HODETNUW-Uxc25XSJ.js → flowDiagram-HODETNUW-BGZ95AzI.js} +2 -2
- package/dist/{formats-DQCyPd5Z.js → formats-DI7HEVv7.js} +1 -1
- package/dist/{glide-data-editor-B70oke_v.js → glide-data-editor-n4wnx19S.js} +10 -10
- package/dist/{glide-utils-Dz_F4pAY.js → glide-utils-D98laidb.js} +2 -2
- package/dist/{globals-Cxd5hNlI.js → globals-NCsYyjpB.js} +3 -3
- package/dist/{html-to-image-D4yG5Ru0.js → html-to-image-BoZthB4P.js} +467 -458
- package/dist/{infoDiagram-27XIBGKW-DmjxqwL0.js → infoDiagram-27XIBGKW-BF0YX70D.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-NgCLHqQi.js → ishikawaDiagram-5VMMS53U-_itsAAn-.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-CZaG-iam.js → kanban-definition-UXKFOSKX-VNW2Beqh.js} +1 -1
- package/dist/{label-D9_-zSg-.js → label-Qvw1E97W.js} +1 -1
- package/dist/main.js +8257 -6606
- package/dist/{mermaid-CSvw7c71.js → mermaid-CZ6FrClS.js} +35 -35
- package/dist/{mindmap-definition-YA3MSWOX-DJYQBDH_.js → mindmap-definition-YA3MSWOX-DR4ripvd.js} +1 -1
- package/dist/{number-overlay-editor-ChK-SKUk.js → number-overlay-editor-rlvo4mo3.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-CHKO_dAe.js → pegDiagram-XKGWAZYB-CFr3XlGl.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-DVevbMAo.js → pieDiagram-E7YTZNPT-j91XYSLY.js} +1 -1
- package/dist/{process-output-DxvBAeL3.js → process-output-DLS4Mqg_.js} +4 -4
- package/dist/{railroadDiagram-O6MQD6OU-Detj1kcB.js → railroadDiagram-O6MQD6OU-Cd47ZV9E.js} +2 -2
- package/dist/{requirementDiagram-BXWQKSXE-BLFD0T_Z.js → requirementDiagram-BXWQKSXE-eJH6gLtX.js} +1 -1
- package/dist/{reveal-component-CXMXeDZD.js → reveal-component-BJfmRUzb.js} +9 -9
- package/dist/{select-CkF_GBxO.js → select-2KOiReNY.js} +324 -324
- package/dist/{sequenceDiagram-WJ2MYXX4-BZBgatQV.js → sequenceDiagram-WJ2MYXX4-DdfFEIrm.js} +1 -1
- package/dist/{spec-Mnkn3XEr.js → spec-h69nC3SI.js} +4 -4
- package/dist/{stateDiagram-D77RDMKH-4BZW9-6_.js → stateDiagram-D77RDMKH-DkjDvip8.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-C4sKC8Iq.js → stateDiagram-v2-MP3YSRHH-DBHACnOo.js} +2 -2
- package/dist/{swimlanes-42K2YHIH-SL5yeGe2.js → swimlanes-42K2YHIH-ogImlOmp.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-DqPmAYUv.js → swimlanesDiagram-VR7AAH4N-D6x-zsci.js} +2 -2
- package/dist/{timeline-definition-24CTP7MA-BfXUMWkq.js → timeline-definition-24CTP7MA-DQpLtsHD.js} +1 -1
- package/dist/{toDate-TMubKIVL.js → toDate-CDzoofJo.js} +2 -2
- package/dist/{toast-Btbve3Lm.js → toast-B5t9o6s_.js} +47 -47
- package/dist/{tooltip-CJ4Rqasp.js → tooltip-s4zZxwKe.js} +67 -67
- package/dist/{use-restore-focus-CmGwRNId.js → use-restore-focus-BgDTd2tc.js} +1 -1
- package/dist/{useAsyncData-DjMGFzFy.js → useAsyncData-Bn8SxUqM.js} +1 -1
- package/dist/{useDateFormatter-eCL_SdeG.js → useDateFormatter-D3Tkfzej.js} +2 -2
- package/dist/{useDeepCompareMemoize-BQR5TJot.js → useDeepCompareMemoize-CC2tnPCk.js} +1 -1
- package/dist/{useLifecycle-C_GvKWbQ.js → useLifecycle-BJlxHqWa.js} +2 -2
- package/dist/{useTheme-Bns2gJZ6.js → useTheme-DMfQYmlG.js} +85 -85
- package/dist/{vega-component-BsVptuhz.js → vega-component-CovWHi60.js} +7 -7
- package/dist/{vennDiagram-4TSXK5OY-CH65znGa.js → vennDiagram-4TSXK5OY-BD-SL_vq.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-z9pWKb2_.js → wardleyDiagram-VM6X3IG4-BDgJV4ah.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-MxyaWjjq.js → xychartDiagram-S5SC5T6Z-1hIHN6Rl.js} +1 -1
- package/package.json +1 -1
- package/src/__mocks__/document.tsx +54 -0
- package/src/__mocks__/notebook.ts +2 -1
- package/src/__mocks__/requests.ts +0 -2
- package/src/components/chat/chat-panel.tsx +3 -3
- package/src/components/datasources/__tests__/column-preview.test.tsx +6 -8
- package/src/components/datasources/column-preview.tsx +4 -8
- package/src/components/datasources/datasources.tsx +4 -3
- package/src/components/dependency-graph/minimap-content.tsx +2 -6
- package/src/components/dependency-graph/panels.tsx +2 -1
- package/src/components/editor/__tests__/Output.test.tsx +50 -32
- package/src/components/editor/__tests__/data-attributes.test.tsx +22 -11
- package/src/components/editor/__tests__/output-persistence.test.tsx +6 -1
- package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
- package/src/components/editor/actions/name-cell-input.tsx +4 -3
- package/src/components/editor/actions/useCellActionButton.tsx +20 -26
- package/src/components/editor/actions/useNotebookActions.tsx +13 -18
- package/src/components/editor/actions/useSetCodeVisibility.ts +10 -11
- package/src/components/editor/actions/useSetOutputsExpanded.ts +13 -18
- package/src/components/editor/cell/CreateCellButton.tsx +5 -9
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
- package/src/components/editor/cell/code/cell-editor.tsx +13 -20
- package/src/components/editor/cell/useAddCell.ts +4 -8
- package/src/components/editor/cell/useDeleteCell.tsx +10 -36
- package/src/components/editor/cell/useRunCells.ts +2 -5
- package/src/components/editor/cell/useSplitCell.tsx +2 -1
- package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
- package/src/components/editor/chrome/panels/snippets-panel.tsx +5 -11
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +3 -1
- package/src/components/editor/columns/sortable-column.tsx +1 -1
- package/src/components/editor/connections/components.tsx +4 -9
- package/src/components/editor/controls/Controls.tsx +1 -1
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +9 -3
- package/src/components/editor/documentation.css +34 -11
- package/src/components/editor/errors/auto-fix.tsx +4 -8
- package/src/components/editor/file-tree/file-explorer.tsx +3 -7
- package/src/components/editor/links/__tests__/cell-link.test.tsx +3 -1
- package/src/components/editor/links/cell-link.tsx +2 -1
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
- package/src/components/editor/navigation/__tests__/navigation.test.ts +73 -64
- package/src/components/editor/navigation/clipboard.ts +12 -11
- package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +11 -20
- package/src/components/editor/navigation/navigation.ts +20 -28
- package/src/components/editor/notebook-cell.tsx +7 -10
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
- package/src/components/editor/renderers/cell-array.tsx +10 -17
- package/src/components/markdown/markdown-renderer.tsx +4 -8
- package/src/components/pages/edit-page.tsx +32 -17
- package/src/components/scratchpad/scratchpad.test.tsx +3 -1
- package/src/components/scratchpad/scratchpad.tsx +4 -7
- package/src/components/slides/__tests__/minimap-actions.test.tsx +9 -25
- package/src/components/slides/minimap.tsx +7 -3
- package/src/components/slides/slide-cell-view.tsx +3 -3
- package/src/components/sort/SortableCellsProvider.tsx +2 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +18 -20
- package/src/core/ai/staged-cells.ts +8 -16
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +2 -2
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +2 -2
- package/src/core/ai/tools/base.ts +2 -2
- package/src/core/ai/tools/edit-notebook-tool.ts +13 -21
- package/src/core/cells/__tests__/actions.test.ts +474 -34
- package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
- package/src/core/cells/__tests__/cells.test.ts +251 -861
- package/src/core/cells/__tests__/document.test.ts +42 -38
- package/src/core/cells/__tests__/notebook-outline.test.ts +7 -1
- package/src/core/cells/__tests__/outputs.test.tsx +71 -53
- package/src/core/cells/actions.ts +391 -3
- package/src/core/cells/add-missing-import.ts +46 -42
- package/src/core/cells/cells.ts +73 -444
- package/src/core/cells/document.ts +38 -6
- package/src/core/cells/outputs.ts +12 -28
- package/src/core/codemirror/cells/extensions.ts +6 -6
- package/src/core/codemirror/cells/state.ts +1 -1
- package/src/core/codemirror/keymaps/vim.ts +2 -2
- package/src/core/edit-app.tsx +20 -25
- package/src/core/islands/__tests__/bootstrap.test.ts +56 -0
- package/src/core/islands/__tests__/bridge.test.ts +42 -0
- package/src/core/islands/bootstrap.ts +24 -1
- package/src/core/islands/bridge.ts +46 -5
- package/src/core/kernel/__tests__/handlers.test.ts +7 -153
- package/src/core/kernel/handlers.ts +18 -59
- package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
- package/src/core/network/requests-lazy.ts +0 -2
- package/src/core/network/requests-network.ts +0 -16
- package/src/core/network/requests-static.ts +0 -2
- package/src/core/network/requests-toasting.tsx +0 -2
- package/src/core/network/types.ts +0 -7
- package/src/core/notebook/document/__tests__/codemirror.test.ts +5 -0
- package/src/core/notebook/document/__tests__/draft.test.ts +41 -0
- package/src/core/notebook/document/__tests__/state.test.ts +21 -0
- package/src/core/notebook/document/draft.ts +35 -5
- package/src/core/notebook/document/index.ts +1 -0
- package/src/core/notebook/document/state.ts +6 -2
- package/src/core/run-app.tsx +1 -7
- package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +0 -6
- package/src/core/session/useNotebookSession.tsx +28 -35
- package/src/core/wasm/bridge.ts +0 -16
- package/src/css/globals.css +56 -22
- package/src/stories/runtime-story.tsx +22 -15
package/src/core/cells/cells.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import type * as Protocol from "@marimo-team/client/protocol";
|
|
4
4
|
import { type Atom, atom, useAtom, useAtomValue } from "jotai";
|
|
5
5
|
import { atomFamily, selectAtom, splitAtom } from "jotai/utils";
|
|
6
6
|
import { createRef, type ReducerWithoutAction } from "react";
|
|
7
7
|
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
8
|
-
import type { EditableDocument } from "@/core/notebook/document";
|
|
9
|
-
import type { CollapsibleTree } from "@/utils/id-tree";
|
|
8
|
+
import type { EditableDocument, Placement } from "@/core/notebook/document";
|
|
10
9
|
import {
|
|
11
10
|
type CellColumnId,
|
|
12
11
|
type CellIndex,
|
|
@@ -31,7 +30,7 @@ import { createDeepEqualAtom, store } from "../state/jotai";
|
|
|
31
30
|
import { isWasm } from "../wasm/utils";
|
|
32
31
|
import { prepareCellForExecution, transitionCell } from "./cell";
|
|
33
32
|
import { applyDocument, documentEditMiddleware } from "./document";
|
|
34
|
-
import { CellId, SCRATCH_CELL_ID
|
|
33
|
+
import { CellId, SCRATCH_CELL_ID } from "./ids";
|
|
35
34
|
import { type CellLog, getCellLogsForMessage } from "./logs";
|
|
36
35
|
import {
|
|
37
36
|
focusAndScrollCellIntoView,
|
|
@@ -42,8 +41,8 @@ import {
|
|
|
42
41
|
type CellData,
|
|
43
42
|
type CellRuntimeState,
|
|
44
43
|
createCell,
|
|
45
|
-
createCellConfig,
|
|
46
44
|
createCellRuntimeState,
|
|
45
|
+
isEdited,
|
|
47
46
|
} from "./types";
|
|
48
47
|
import {
|
|
49
48
|
canUndoDeletes,
|
|
@@ -55,17 +54,21 @@ import {
|
|
|
55
54
|
notebookQueueOrRunningCount,
|
|
56
55
|
} from "./utils";
|
|
57
56
|
|
|
57
|
+
/** A deleted cell as it was, with where it went in the document. */
|
|
58
|
+
export interface DeletedCell {
|
|
59
|
+
cell: Protocol.CellInput;
|
|
60
|
+
placement: Placement;
|
|
61
|
+
/** The editor's state at deletion, so undo brings its history back. */
|
|
62
|
+
serializedEditorState: SerializedEditorState | null;
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
/**
|
|
59
|
-
* History entry for undoing
|
|
66
|
+
* History entry for undoing one deletion, of one or more cells.
|
|
60
67
|
*/
|
|
61
68
|
export interface UndoDeleteEntry {
|
|
62
69
|
type: "delete";
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
column: CellColumnId;
|
|
66
|
-
index: CellIndex;
|
|
67
|
-
isSetupCell: boolean;
|
|
68
|
-
config: CellConfig;
|
|
70
|
+
/** In document order. Each cell is placed after the one before it. */
|
|
71
|
+
cells: DeletedCell[];
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
/**
|
|
@@ -161,40 +164,6 @@ export function initialNotebookState(): NotebookState {
|
|
|
161
164
|
});
|
|
162
165
|
}
|
|
163
166
|
|
|
164
|
-
/** The target cell ID to create a new cell relative to. Can be:
|
|
165
|
-
* - A CellId string for an existing cell
|
|
166
|
-
* - "__end__" to append at the end of the first column
|
|
167
|
-
* - {type: "__end__", columnId} to append at the end of a specific column
|
|
168
|
-
*/
|
|
169
|
-
export type CellPosition =
|
|
170
|
-
| CellId
|
|
171
|
-
| "__end__"
|
|
172
|
-
| { type: "__end__"; columnId: CellColumnId };
|
|
173
|
-
|
|
174
|
-
export interface CreateNewCellAction {
|
|
175
|
-
cellId: CellPosition;
|
|
176
|
-
/** Whether to insert before (true) or after (false) the target cell */
|
|
177
|
-
before: boolean;
|
|
178
|
-
/** Initial code content for the new cell */
|
|
179
|
-
code?: string;
|
|
180
|
-
/** Optional name for the new cell */
|
|
181
|
-
name?: string;
|
|
182
|
-
/** Optional cell configuration */
|
|
183
|
-
config?: CellConfig;
|
|
184
|
-
/** The last executed code for the new cell */
|
|
185
|
-
lastCodeRun?: string;
|
|
186
|
-
/** Timestamp of the last execution */
|
|
187
|
-
lastExecutionTime?: number;
|
|
188
|
-
/** Optional custom ID for the new cell. Auto-generated if not provided */
|
|
189
|
-
newCellId?: CellId;
|
|
190
|
-
/** Whether to focus the new cell after creation */
|
|
191
|
-
autoFocus?: boolean;
|
|
192
|
-
/** If true, skip creation if code already exists */
|
|
193
|
-
skipIfCodeExists?: boolean;
|
|
194
|
-
/** Hide the code in the new cell. This will be initially shown until the cell is blurred for the first time. */
|
|
195
|
-
hideCode?: boolean;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
167
|
/**
|
|
199
168
|
* Actions and reducer for the notebook state.
|
|
200
169
|
*/
|
|
@@ -205,85 +174,6 @@ const {
|
|
|
205
174
|
useActions,
|
|
206
175
|
valueAtom: notebookAtom,
|
|
207
176
|
} = createReducerAndAtoms(initialNotebookState, {
|
|
208
|
-
createNewCell: (state, action: CreateNewCellAction) => {
|
|
209
|
-
const {
|
|
210
|
-
cellId,
|
|
211
|
-
before,
|
|
212
|
-
code,
|
|
213
|
-
name,
|
|
214
|
-
config,
|
|
215
|
-
lastCodeRun = null,
|
|
216
|
-
lastExecutionTime = null,
|
|
217
|
-
autoFocus = true,
|
|
218
|
-
skipIfCodeExists = false,
|
|
219
|
-
hideCode = undefined,
|
|
220
|
-
} = action;
|
|
221
|
-
|
|
222
|
-
let columnId: CellColumnId;
|
|
223
|
-
let cellIndex: number;
|
|
224
|
-
|
|
225
|
-
// If skipIfCodeExists is true, check if the code already exists in the notebook
|
|
226
|
-
if (skipIfCodeExists) {
|
|
227
|
-
for (const cellId of state.cellIds.inOrderIds) {
|
|
228
|
-
if (state.cellData[cellId]?.code === code) {
|
|
229
|
-
return state;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (cellId === "__end__") {
|
|
235
|
-
const column = state.cellIds.atOrThrow(0);
|
|
236
|
-
columnId = column.id;
|
|
237
|
-
cellIndex = column.length;
|
|
238
|
-
} else if (typeof cellId === "string") {
|
|
239
|
-
const column = state.cellIds.findWithId(cellId);
|
|
240
|
-
columnId = column.id;
|
|
241
|
-
cellIndex = column.topLevelIds.indexOf(cellId);
|
|
242
|
-
} else if (cellId.type === "__end__") {
|
|
243
|
-
const column =
|
|
244
|
-
state.cellIds.get(cellId.columnId) || state.cellIds.atOrThrow(0);
|
|
245
|
-
columnId = column.id;
|
|
246
|
-
cellIndex = column.length;
|
|
247
|
-
} else {
|
|
248
|
-
throw new Error("Invalid cellId");
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const newCellId = action.newCellId || CellId.create();
|
|
252
|
-
const insertionIndex = before ? cellIndex : cellIndex + 1;
|
|
253
|
-
|
|
254
|
-
return {
|
|
255
|
-
...state,
|
|
256
|
-
cellIds: state.cellIds.insertId(newCellId, columnId, insertionIndex),
|
|
257
|
-
cellData: {
|
|
258
|
-
...state.cellData,
|
|
259
|
-
[newCellId]: createCell({
|
|
260
|
-
id: newCellId,
|
|
261
|
-
code,
|
|
262
|
-
name,
|
|
263
|
-
lastCodeRun,
|
|
264
|
-
config: createCellConfig({
|
|
265
|
-
...config,
|
|
266
|
-
...(hideCode != null && { hide_code: hideCode }),
|
|
267
|
-
}),
|
|
268
|
-
lastExecutionTime,
|
|
269
|
-
edited: Boolean(code) && code !== lastCodeRun,
|
|
270
|
-
}),
|
|
271
|
-
},
|
|
272
|
-
cellRuntime: {
|
|
273
|
-
...state.cellRuntime,
|
|
274
|
-
[newCellId]: createCellRuntimeState(),
|
|
275
|
-
},
|
|
276
|
-
cellHandles: {
|
|
277
|
-
...state.cellHandles,
|
|
278
|
-
[newCellId]: createRef(),
|
|
279
|
-
},
|
|
280
|
-
scrollKey: autoFocus ? newCellId : null,
|
|
281
|
-
untouchedNewCells:
|
|
282
|
-
hideCode && autoFocus
|
|
283
|
-
? new Set([...state.untouchedNewCells, newCellId])
|
|
284
|
-
: state.untouchedNewCells,
|
|
285
|
-
};
|
|
286
|
-
},
|
|
287
177
|
moveCell: (
|
|
288
178
|
state,
|
|
289
179
|
action: {
|
|
@@ -678,128 +568,29 @@ const {
|
|
|
678
568
|
cellIds: state.cellIds.compact(),
|
|
679
569
|
};
|
|
680
570
|
},
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
// Expected for kernel-only cells or out-of-order transactions.
|
|
694
|
-
Logger.warn("Skipping delete for missing cellId", {
|
|
695
|
-
cellId,
|
|
696
|
-
error,
|
|
697
|
-
});
|
|
698
|
-
return state;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
702
|
-
const focusIndex = cellIndex === 0 ? 1 : cellIndex - 1;
|
|
703
|
-
let scrollKey: CellId | null = null;
|
|
704
|
-
if (column.length > 1) {
|
|
705
|
-
scrollKey = column.atOrThrow(focusIndex);
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
const editorView = state.cellHandles[cellId].current?.editorView;
|
|
709
|
-
const serializedEditorState = editorView?.state.toJSON({
|
|
710
|
-
history: historyField,
|
|
711
|
-
});
|
|
712
|
-
if (serializedEditorState) {
|
|
713
|
-
serializedEditorState.doc = state.cellData[cellId].code;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
// release the granular atom(s) created for this cell
|
|
717
|
-
releaseCellAtoms(cellId);
|
|
718
|
-
const prevData = state.cellData[cellId];
|
|
719
|
-
return {
|
|
720
|
-
...state,
|
|
721
|
-
cellIds: state.cellIds.deleteById(cellId),
|
|
722
|
-
history: [
|
|
723
|
-
...state.history,
|
|
724
|
-
{
|
|
725
|
-
type: "delete",
|
|
726
|
-
name: prevData.name,
|
|
727
|
-
serializedEditorState: serializedEditorState,
|
|
728
|
-
column: column.id,
|
|
729
|
-
index: cellIndex,
|
|
730
|
-
isSetupCell: cellId === SETUP_CELL_ID,
|
|
731
|
-
config: prevData.config,
|
|
732
|
-
},
|
|
733
|
-
],
|
|
734
|
-
scrollKey: scrollKey,
|
|
735
|
-
};
|
|
736
|
-
},
|
|
737
|
-
undoDeleteCell: (state) => {
|
|
738
|
-
if (state.history.length === 0) {
|
|
571
|
+
/**
|
|
572
|
+
* Put moved cells back where they were.
|
|
573
|
+
*
|
|
574
|
+
* TODO(MO-8028): Move to `undoDeleteCellAtom` with the order family.
|
|
575
|
+
*/
|
|
576
|
+
undoMoveCells: (state, action: UndoMoveEntry) => {
|
|
577
|
+
const { cellIds, placements } = action;
|
|
578
|
+
if (
|
|
579
|
+
cellIds.length === 0 ||
|
|
580
|
+
placements.length !== cellIds.length ||
|
|
581
|
+
cellIds.some((id) => !state.cellData[id])
|
|
582
|
+
) {
|
|
739
583
|
return state;
|
|
740
584
|
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
if (
|
|
747
|
-
cellIds.length === 0 ||
|
|
748
|
-
placements.length !== cellIds.length ||
|
|
749
|
-
cellIds.some((id) => !state.cellData[id])
|
|
750
|
-
) {
|
|
751
|
-
return { ...state, history: state.history.slice(0, -1) };
|
|
752
|
-
}
|
|
753
|
-
const toRestore = cellIds.map((id, i) => ({
|
|
754
|
-
id,
|
|
755
|
-
columnId: placements[i].columnId,
|
|
756
|
-
index: placements[i].index,
|
|
757
|
-
}));
|
|
758
|
-
return {
|
|
759
|
-
...state,
|
|
760
|
-
cellIds: state.cellIds.placeCells(toRestore),
|
|
761
|
-
history: state.history.slice(0, -1),
|
|
762
|
-
scrollKey: cellIds[0] ?? null,
|
|
763
|
-
};
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
const {
|
|
767
|
-
name,
|
|
768
|
-
serializedEditorState = { doc: "" },
|
|
769
|
-
column,
|
|
770
|
-
index,
|
|
771
|
-
isSetupCell,
|
|
772
|
-
config,
|
|
773
|
-
} = last;
|
|
774
|
-
|
|
775
|
-
const cellId = isSetupCell ? SETUP_CELL_ID : CellId.create();
|
|
776
|
-
const undoCell = createCell({
|
|
777
|
-
id: cellId,
|
|
778
|
-
name,
|
|
779
|
-
code: serializedEditorState.doc,
|
|
780
|
-
edited: serializedEditorState.doc.trim().length > 0,
|
|
781
|
-
serializedEditorState,
|
|
782
|
-
config,
|
|
783
|
-
});
|
|
784
|
-
|
|
585
|
+
const toRestore = cellIds.map((id, i) => ({
|
|
586
|
+
id,
|
|
587
|
+
columnId: placements[i].columnId,
|
|
588
|
+
index: placements[i].index,
|
|
589
|
+
}));
|
|
785
590
|
return {
|
|
786
591
|
...state,
|
|
787
|
-
cellIds: state.cellIds.
|
|
788
|
-
|
|
789
|
-
...state.cellData,
|
|
790
|
-
[cellId]: undoCell,
|
|
791
|
-
},
|
|
792
|
-
cellRuntime: {
|
|
793
|
-
...state.cellRuntime,
|
|
794
|
-
[cellId]: createCellRuntimeState(),
|
|
795
|
-
},
|
|
796
|
-
cellHandles: {
|
|
797
|
-
...state.cellHandles,
|
|
798
|
-
[cellId]: createRef(),
|
|
799
|
-
},
|
|
800
|
-
history: state.history.slice(0, -1),
|
|
801
|
-
// Scroll to the newly created cell
|
|
802
|
-
scrollKey: cellId,
|
|
592
|
+
cellIds: state.cellIds.placeCells(toRestore),
|
|
593
|
+
scrollKey: cellIds[0] ?? null,
|
|
803
594
|
};
|
|
804
595
|
},
|
|
805
596
|
clearSerializedEditorState: (state, action: { cellId: CellId }) => {
|
|
@@ -852,35 +643,6 @@ const {
|
|
|
852
643
|
},
|
|
853
644
|
});
|
|
854
645
|
},
|
|
855
|
-
updateCellName: (state, action: { cellId: CellId; name: string }) => {
|
|
856
|
-
const { cellId, name } = action;
|
|
857
|
-
return updateCellData({
|
|
858
|
-
state,
|
|
859
|
-
cellId,
|
|
860
|
-
cellReducer: (cell) => {
|
|
861
|
-
return {
|
|
862
|
-
...cell,
|
|
863
|
-
name: name,
|
|
864
|
-
};
|
|
865
|
-
},
|
|
866
|
-
});
|
|
867
|
-
},
|
|
868
|
-
updateCellConfig: (
|
|
869
|
-
state,
|
|
870
|
-
action: { cellId: CellId; config: Partial<CellConfig> },
|
|
871
|
-
) => {
|
|
872
|
-
const { cellId, config } = action;
|
|
873
|
-
return updateCellData({
|
|
874
|
-
state,
|
|
875
|
-
cellId,
|
|
876
|
-
cellReducer: (cell) => {
|
|
877
|
-
return {
|
|
878
|
-
...cell,
|
|
879
|
-
config: createCellConfig({ ...cell.config, ...config }),
|
|
880
|
-
};
|
|
881
|
-
},
|
|
882
|
-
});
|
|
883
|
-
},
|
|
884
646
|
prepareForRun: (state, action: { cellId: CellId }) => {
|
|
885
647
|
const newState = updateCellRuntimeState({
|
|
886
648
|
state,
|
|
@@ -936,12 +698,7 @@ const {
|
|
|
936
698
|
cellLogs: [...state.cellLogs, ...action.logs],
|
|
937
699
|
};
|
|
938
700
|
},
|
|
939
|
-
/**
|
|
940
|
-
* Follow the host document's cells and order.
|
|
941
|
-
*
|
|
942
|
-
* Dispatched without middleware, since the document already has these
|
|
943
|
-
* changes.
|
|
944
|
-
*/
|
|
701
|
+
/** Follow the host document's cells and order. */
|
|
945
702
|
reconcileDocument: (state, document: EditableDocument) => {
|
|
946
703
|
const nextState = applyDocument(state, document);
|
|
947
704
|
for (const cellId of state.cellIds.inOrderIds) {
|
|
@@ -985,127 +742,44 @@ const {
|
|
|
985
742
|
},
|
|
986
743
|
});
|
|
987
744
|
},
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
// WASM has no server-side SessionView to replay outputs, so the
|
|
992
|
-
// snapshot hydrated by notebookStateFromSession is the only source.
|
|
993
|
-
const preserveSnapshot = isWasm();
|
|
994
|
-
const runtimeFor = (cellId: CellId): CellRuntimeState => {
|
|
995
|
-
if (!preserveSnapshot) {
|
|
996
|
-
return createCellRuntimeState();
|
|
997
|
-
}
|
|
998
|
-
const prev = state.cellRuntime[cellId];
|
|
999
|
-
const hasSnapshot =
|
|
1000
|
-
prev && (prev.output != null || prev.consoleOutputs.length > 0);
|
|
1001
|
-
return hasSnapshot ? prev : createCellRuntimeState();
|
|
1002
|
-
};
|
|
1003
|
-
const cellRuntime = Object.fromEntries(
|
|
1004
|
-
cells.map((cell) => [cell.id, runtimeFor(cell.id)]),
|
|
1005
|
-
);
|
|
1006
|
-
|
|
1007
|
-
return withScratchCell({
|
|
1008
|
-
...state,
|
|
1009
|
-
cellIds: MultiColumn.fromIdsAndColumns(
|
|
1010
|
-
cells.map((cell) => [cell.id, cell.config.column]),
|
|
1011
|
-
),
|
|
1012
|
-
cellData: cellData,
|
|
1013
|
-
cellRuntime: cellRuntime,
|
|
1014
|
-
cellHandles: Object.fromEntries(
|
|
1015
|
-
cells.map((cell) => [cell.id, createRef()]),
|
|
1016
|
-
),
|
|
1017
|
-
});
|
|
1018
|
-
},
|
|
1019
|
-
/**
|
|
1020
|
-
* Move focus to next cell
|
|
1021
|
-
*
|
|
1022
|
-
* Creates a new cell if the current cell is the last one in the array.
|
|
1023
|
-
*
|
|
1024
|
-
* If needed, scrolls newly created or focused cell into view.
|
|
1025
|
-
*
|
|
1026
|
-
* Replicates Shift+Enter functionality of Jupyter
|
|
1027
|
-
*/
|
|
1028
|
-
moveToNextCell: (
|
|
745
|
+
/** Record what the kernel last ran for each cell. */
|
|
746
|
+
setLastRun: (
|
|
1029
747
|
state,
|
|
1030
|
-
action: {
|
|
748
|
+
action: {
|
|
749
|
+
lastCodeRun: Record<CellId, string>;
|
|
750
|
+
lastExecutionTime: Record<CellId, number>;
|
|
751
|
+
},
|
|
1031
752
|
) => {
|
|
1032
|
-
const
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
const isPastLastCell = nextCellIndex === column.length;
|
|
1044
|
-
const isBeforeFirstCell = nextCellIndex === -1;
|
|
1045
|
-
|
|
1046
|
-
// Create a new cell at the end and set scrollKey to focus it
|
|
1047
|
-
if (isPastLastCell && !noCreate) {
|
|
1048
|
-
const newCellId = CellId.create();
|
|
1049
|
-
return {
|
|
1050
|
-
...state,
|
|
1051
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, nextCellIndex),
|
|
1052
|
-
cellData: {
|
|
1053
|
-
...state.cellData,
|
|
1054
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1055
|
-
},
|
|
1056
|
-
cellRuntime: {
|
|
1057
|
-
...state.cellRuntime,
|
|
1058
|
-
[newCellId]: createCellRuntimeState(),
|
|
1059
|
-
},
|
|
1060
|
-
cellHandles: {
|
|
1061
|
-
...state.cellHandles,
|
|
1062
|
-
[newCellId]: createRef(),
|
|
1063
|
-
},
|
|
1064
|
-
scrollKey: newCellId,
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
if (isBeforeFirstCell && !noCreate) {
|
|
1069
|
-
const newCellId = CellId.create();
|
|
1070
|
-
return {
|
|
1071
|
-
...state,
|
|
1072
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, 0),
|
|
1073
|
-
cellData: {
|
|
1074
|
-
...state.cellData,
|
|
1075
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1076
|
-
},
|
|
1077
|
-
cellRuntime: {
|
|
1078
|
-
...state.cellRuntime,
|
|
1079
|
-
[newCellId]: createCellRuntimeState(),
|
|
1080
|
-
},
|
|
1081
|
-
cellHandles: {
|
|
1082
|
-
...state.cellHandles,
|
|
1083
|
-
[newCellId]: createRef(),
|
|
1084
|
-
},
|
|
1085
|
-
scrollKey: newCellId,
|
|
753
|
+
const cellData = { ...state.cellData };
|
|
754
|
+
for (const cellId of state.cellIds.inOrderIds) {
|
|
755
|
+
const cell = state.cellData[cellId];
|
|
756
|
+
const lastCodeRun = action.lastCodeRun[cellId] ?? null;
|
|
757
|
+
cellData[cellId] = {
|
|
758
|
+
...cell,
|
|
759
|
+
lastCodeRun,
|
|
760
|
+
lastExecutionTime: action.lastExecutionTime[cellId] ?? null,
|
|
761
|
+
// A cell the kernel never ran is not stale on load.
|
|
762
|
+
edited: lastCodeRun !== null && isEdited(lastCodeRun, cell.code),
|
|
1086
763
|
};
|
|
1087
764
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
variableName: undefined,
|
|
1105
|
-
});
|
|
765
|
+
return { ...state, cellData };
|
|
766
|
+
},
|
|
767
|
+
/**
|
|
768
|
+
* Start each cell's runtime over for a new kernel. WASM keeps the outputs
|
|
769
|
+
* its mount-time snapshot gave it.
|
|
770
|
+
*/
|
|
771
|
+
resetCellRuntimes: (state) => {
|
|
772
|
+
const preserveSnapshot = isWasm();
|
|
773
|
+
const cellRuntime = { ...state.cellRuntime };
|
|
774
|
+
for (const cellId of [...state.cellIds.inOrderIds, SCRATCH_CELL_ID]) {
|
|
775
|
+
const previous = state.cellRuntime[cellId];
|
|
776
|
+
const hasSnapshot =
|
|
777
|
+
preserveSnapshot &&
|
|
778
|
+
previous !== undefined &&
|
|
779
|
+
(previous.output != null || previous.consoleOutputs.length > 0);
|
|
780
|
+
cellRuntime[cellId] = hasSnapshot ? previous : createCellRuntimeState();
|
|
1106
781
|
}
|
|
1107
|
-
|
|
1108
|
-
return state;
|
|
782
|
+
return { ...state, cellRuntime };
|
|
1109
783
|
},
|
|
1110
784
|
markTouched: (state, action: { cellId: CellId }) => {
|
|
1111
785
|
const { cellId } = action;
|
|
@@ -1427,44 +1101,6 @@ const {
|
|
|
1427
1101
|
cellRuntime: newCellRuntime,
|
|
1428
1102
|
};
|
|
1429
1103
|
},
|
|
1430
|
-
addSetupCellIfDoesntExist: (state, action: { code?: string }) => {
|
|
1431
|
-
const { code } = action;
|
|
1432
|
-
|
|
1433
|
-
if (state.cellIds.setupCellExists()) {
|
|
1434
|
-
// Just focus on the existing setup cell
|
|
1435
|
-
return {
|
|
1436
|
-
...state,
|
|
1437
|
-
scrollKey: SETUP_CELL_ID,
|
|
1438
|
-
};
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
return {
|
|
1442
|
-
...state,
|
|
1443
|
-
cellIds: state.cellIds.insertId(
|
|
1444
|
-
SETUP_CELL_ID,
|
|
1445
|
-
state.cellIds.atOrThrow(0).id,
|
|
1446
|
-
0,
|
|
1447
|
-
),
|
|
1448
|
-
cellData: {
|
|
1449
|
-
...state.cellData,
|
|
1450
|
-
[SETUP_CELL_ID]: createCell({
|
|
1451
|
-
id: SETUP_CELL_ID,
|
|
1452
|
-
name: SETUP_CELL_ID,
|
|
1453
|
-
code,
|
|
1454
|
-
edited: Boolean(code),
|
|
1455
|
-
}),
|
|
1456
|
-
},
|
|
1457
|
-
cellRuntime: {
|
|
1458
|
-
...state.cellRuntime,
|
|
1459
|
-
[SETUP_CELL_ID]: createCellRuntimeState(),
|
|
1460
|
-
},
|
|
1461
|
-
cellHandles: {
|
|
1462
|
-
...state.cellHandles,
|
|
1463
|
-
[SETUP_CELL_ID]: createRef(),
|
|
1464
|
-
},
|
|
1465
|
-
scrollKey: SETUP_CELL_ID,
|
|
1466
|
-
};
|
|
1467
|
-
},
|
|
1468
1104
|
});
|
|
1469
1105
|
|
|
1470
1106
|
// We apply the middleware here (rather than inline in createReducerAndAtoms)
|
|
@@ -1872,20 +1508,13 @@ export function createTracebackInfoAtom(
|
|
|
1872
1508
|
});
|
|
1873
1509
|
}
|
|
1874
1510
|
|
|
1875
|
-
/**
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
*/
|
|
1879
|
-
export function useCellActions(
|
|
1880
|
-
options: { skipMiddleware?: boolean } = {},
|
|
1881
|
-
): CellActions {
|
|
1882
|
-
return useActions(options);
|
|
1511
|
+
/** The reducer's actions. Components use `useCellActions` from `./actions`. */
|
|
1512
|
+
export function useReducerActions(): ReducerCellActions {
|
|
1513
|
+
return useActions();
|
|
1883
1514
|
}
|
|
1884
1515
|
|
|
1885
|
-
/**
|
|
1886
|
-
|
|
1887
|
-
*/
|
|
1888
|
-
export type CellActions = ReturnType<typeof createActions>;
|
|
1516
|
+
/** The actions the reducer still handles. */
|
|
1517
|
+
export type ReducerCellActions = ReturnType<typeof createActions>;
|
|
1889
1518
|
|
|
1890
1519
|
/**
|
|
1891
1520
|
* This is exported for testing purposes only.
|