@marimo-team/islands 0.25.3-dev173 → 0.25.3-dev176
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/{ErrorBoundary-wT3f3iJ1.js → ErrorBoundary-D66f-xAE.js} +1 -1
- package/dist/{any-language-editor-B92WMzoC.js → any-language-editor-BVFHDDQ3.js} +2 -2
- package/dist/{chat-ui-CuORr6fL.js → chat-ui-X-cWrL9u.js} +1222 -1222
- package/dist/{code-visibility-ZReaeMaF.js → code-visibility-CVVeTAwi.js} +2 -2
- package/dist/{common-DCevHg1m.js → common-DNlm9Cdj.js} +1074 -1078
- package/dist/{data-grid-overlay-editor-CTC-bJus.js → data-grid-overlay-editor-BArE3_zi.js} +1 -1
- 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/{error-entries-CmWMEsY_.js → error-entries-mpoD5t79.js} +4939 -4983
- 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-DwXkmewo.js → feedback-button-CyvqdxXN.js} +21 -21
- package/dist/{glide-data-editor-BlmcP-lw.js → glide-data-editor-BxvYRMC3.js} +3 -3
- package/dist/{globals-BdRitZ4p.js → globals-BJla9q8e.js} +1 -1
- package/dist/{html-to-image-bpiQh7ND.js → html-to-image-BoZthB4P.js} +454 -445
- package/dist/main.js +3587 -3587
- package/dist/{number-overlay-editor-DQG-hFHT.js → number-overlay-editor-BWg7xiRF.js} +1 -1
- package/dist/{process-output-BzloOI7F.js → process-output-DLS4Mqg_.js} +2 -2
- package/dist/{reveal-component-D3r3vSTK.js → reveal-component-feAltY24.js} +3 -3
- 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 +171 -813
- package/src/core/cells/__tests__/document.test.ts +5 -35
- 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 +38 -413
- package/src/core/cells/document.ts +7 -4
- 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 +19 -27
- package/src/core/islands/bridge.ts +0 -2
- package/src/core/kernel/handlers.ts +3 -3
- 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/session/useNotebookSession.tsx +6 -2
- package/src/core/wasm/bridge.ts +0 -16
- package/src/css/globals.css +56 -22
- package/src/stories/runtime-story.tsx +22 -15
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import { getRequestClient } from "../network/requests";
|
|
4
4
|
import { store } from "../state/jotai";
|
|
5
5
|
import { variablesAtom } from "../variables/state";
|
|
6
|
-
import {
|
|
6
|
+
import { notebookAtom } from "./cells";
|
|
7
|
+
import type { CreateCell, CreateCellOptions } from "./actions";
|
|
7
8
|
import { CellId } from "./ids";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -50,82 +51,85 @@ export function maybeAddMissingImport({
|
|
|
50
51
|
/**
|
|
51
52
|
* Adds a marimo import to the notebook if not already present.
|
|
52
53
|
* @param autoInstantiate Whether to automatically run the cell.
|
|
53
|
-
* @param
|
|
54
|
-
* @param fromCellId The cell to add the import to.
|
|
54
|
+
* @param createCell The command that creates a cell.
|
|
55
|
+
* @param fromCellId The cell to add the import next to.
|
|
55
56
|
* @param before Whether to add the import before or after the cell.
|
|
56
57
|
*
|
|
57
58
|
* Returns the ID of the new cell if added, otherwise null.
|
|
58
59
|
*/
|
|
59
60
|
export function maybeAddMarimoImport({
|
|
60
61
|
autoInstantiate,
|
|
61
|
-
|
|
62
|
+
createCell,
|
|
62
63
|
fromCellId,
|
|
63
64
|
before,
|
|
64
65
|
}: {
|
|
65
66
|
autoInstantiate: boolean;
|
|
66
|
-
|
|
67
|
+
createCell: CreateCell;
|
|
67
68
|
fromCellId?: CellId | null;
|
|
68
69
|
before?: boolean;
|
|
69
70
|
}): CellId | null {
|
|
70
|
-
|
|
71
|
-
let newCellId: CellId | null = null;
|
|
72
|
-
const added = maybeAddMissingImport({
|
|
71
|
+
return addImport({
|
|
73
72
|
moduleName: "marimo",
|
|
74
73
|
variableName: "mo",
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
cellId: fromCellId ?? "__end__",
|
|
79
|
-
before: before ?? false,
|
|
80
|
-
code: importStatement,
|
|
81
|
-
lastCodeRun: autoInstantiate ? importStatement : undefined,
|
|
82
|
-
newCellId: newCellId,
|
|
83
|
-
skipIfCodeExists: true,
|
|
84
|
-
autoFocus: false,
|
|
85
|
-
});
|
|
86
|
-
if (autoInstantiate) {
|
|
87
|
-
void client.sendRun({
|
|
88
|
-
cellIds: [newCellId],
|
|
89
|
-
codes: [importStatement],
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
},
|
|
74
|
+
autoInstantiate,
|
|
75
|
+
createCell,
|
|
76
|
+
placement: before ? { before: fromCellId } : { after: fromCellId },
|
|
93
77
|
});
|
|
94
|
-
return added ? newCellId : null;
|
|
95
78
|
}
|
|
96
79
|
|
|
97
80
|
export function maybeAddAltairImport({
|
|
98
81
|
autoInstantiate,
|
|
99
|
-
|
|
82
|
+
createCell,
|
|
100
83
|
fromCellId,
|
|
101
84
|
}: {
|
|
102
85
|
autoInstantiate: boolean;
|
|
103
|
-
|
|
86
|
+
createCell: CreateCell;
|
|
104
87
|
fromCellId?: CellId | null;
|
|
105
88
|
}): CellId | null {
|
|
106
|
-
|
|
107
|
-
let newCellId: CellId | null = null;
|
|
108
|
-
const added = maybeAddMissingImport({
|
|
89
|
+
return addImport({
|
|
109
90
|
moduleName: "altair",
|
|
110
91
|
variableName: "alt",
|
|
92
|
+
autoInstantiate,
|
|
93
|
+
createCell,
|
|
94
|
+
placement: { after: fromCellId },
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Create the import cell, and run it when the notebook runs on its own. */
|
|
99
|
+
function addImport({
|
|
100
|
+
moduleName,
|
|
101
|
+
variableName,
|
|
102
|
+
autoInstantiate,
|
|
103
|
+
createCell,
|
|
104
|
+
placement,
|
|
105
|
+
}: {
|
|
106
|
+
moduleName: string;
|
|
107
|
+
variableName: string;
|
|
108
|
+
autoInstantiate: boolean;
|
|
109
|
+
createCell: CreateCell;
|
|
110
|
+
placement: Pick<CreateCellOptions, "after" | "before">;
|
|
111
|
+
}): CellId | null {
|
|
112
|
+
let newCellId: CellId | null = null;
|
|
113
|
+
maybeAddMissingImport({
|
|
114
|
+
moduleName,
|
|
115
|
+
variableName,
|
|
111
116
|
onAddImport: (importStatement) => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
const id = CellId.create();
|
|
118
|
+
const created = createCell({
|
|
119
|
+
...placement,
|
|
120
|
+
id,
|
|
116
121
|
code: importStatement,
|
|
117
|
-
lastCodeRun: autoInstantiate ? importStatement : undefined,
|
|
118
|
-
newCellId: newCellId,
|
|
119
122
|
skipIfCodeExists: true,
|
|
120
|
-
|
|
123
|
+
focus: false,
|
|
121
124
|
});
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
newCellId = created === null ? null : id;
|
|
126
|
+
if (autoInstantiate && newCellId !== null) {
|
|
127
|
+
void getRequestClient().sendRun({
|
|
124
128
|
cellIds: [newCellId],
|
|
125
129
|
codes: [importStatement],
|
|
126
130
|
});
|
|
127
131
|
}
|
|
128
132
|
},
|
|
129
133
|
});
|
|
130
|
-
return
|
|
134
|
+
return newCellId;
|
|
131
135
|
}
|
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,7 +41,6 @@ import {
|
|
|
42
41
|
type CellData,
|
|
43
42
|
type CellRuntimeState,
|
|
44
43
|
createCell,
|
|
45
|
-
createCellConfig,
|
|
46
44
|
createCellRuntimeState,
|
|
47
45
|
isEdited,
|
|
48
46
|
} from "./types";
|
|
@@ -56,17 +54,21 @@ import {
|
|
|
56
54
|
notebookQueueOrRunningCount,
|
|
57
55
|
} from "./utils";
|
|
58
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
|
+
|
|
59
65
|
/**
|
|
60
|
-
* History entry for undoing
|
|
66
|
+
* History entry for undoing one deletion, of one or more cells.
|
|
61
67
|
*/
|
|
62
68
|
export interface UndoDeleteEntry {
|
|
63
69
|
type: "delete";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
column: CellColumnId;
|
|
67
|
-
index: CellIndex;
|
|
68
|
-
isSetupCell: boolean;
|
|
69
|
-
config: CellConfig;
|
|
70
|
+
/** In document order. Each cell is placed after the one before it. */
|
|
71
|
+
cells: DeletedCell[];
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
/**
|
|
@@ -162,40 +164,6 @@ export function initialNotebookState(): NotebookState {
|
|
|
162
164
|
});
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
/** The target cell ID to create a new cell relative to. Can be:
|
|
166
|
-
* - A CellId string for an existing cell
|
|
167
|
-
* - "__end__" to append at the end of the first column
|
|
168
|
-
* - {type: "__end__", columnId} to append at the end of a specific column
|
|
169
|
-
*/
|
|
170
|
-
export type CellPosition =
|
|
171
|
-
| CellId
|
|
172
|
-
| "__end__"
|
|
173
|
-
| { type: "__end__"; columnId: CellColumnId };
|
|
174
|
-
|
|
175
|
-
export interface CreateNewCellAction {
|
|
176
|
-
cellId: CellPosition;
|
|
177
|
-
/** Whether to insert before (true) or after (false) the target cell */
|
|
178
|
-
before: boolean;
|
|
179
|
-
/** Initial code content for the new cell */
|
|
180
|
-
code?: string;
|
|
181
|
-
/** Optional name for the new cell */
|
|
182
|
-
name?: string;
|
|
183
|
-
/** Optional cell configuration */
|
|
184
|
-
config?: CellConfig;
|
|
185
|
-
/** The last executed code for the new cell */
|
|
186
|
-
lastCodeRun?: string;
|
|
187
|
-
/** Timestamp of the last execution */
|
|
188
|
-
lastExecutionTime?: number;
|
|
189
|
-
/** Optional custom ID for the new cell. Auto-generated if not provided */
|
|
190
|
-
newCellId?: CellId;
|
|
191
|
-
/** Whether to focus the new cell after creation */
|
|
192
|
-
autoFocus?: boolean;
|
|
193
|
-
/** If true, skip creation if code already exists */
|
|
194
|
-
skipIfCodeExists?: boolean;
|
|
195
|
-
/** Hide the code in the new cell. This will be initially shown until the cell is blurred for the first time. */
|
|
196
|
-
hideCode?: boolean;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
167
|
/**
|
|
200
168
|
* Actions and reducer for the notebook state.
|
|
201
169
|
*/
|
|
@@ -206,85 +174,6 @@ const {
|
|
|
206
174
|
useActions,
|
|
207
175
|
valueAtom: notebookAtom,
|
|
208
176
|
} = createReducerAndAtoms(initialNotebookState, {
|
|
209
|
-
createNewCell: (state, action: CreateNewCellAction) => {
|
|
210
|
-
const {
|
|
211
|
-
cellId,
|
|
212
|
-
before,
|
|
213
|
-
code,
|
|
214
|
-
name,
|
|
215
|
-
config,
|
|
216
|
-
lastCodeRun = null,
|
|
217
|
-
lastExecutionTime = null,
|
|
218
|
-
autoFocus = true,
|
|
219
|
-
skipIfCodeExists = false,
|
|
220
|
-
hideCode = undefined,
|
|
221
|
-
} = action;
|
|
222
|
-
|
|
223
|
-
let columnId: CellColumnId;
|
|
224
|
-
let cellIndex: number;
|
|
225
|
-
|
|
226
|
-
// If skipIfCodeExists is true, check if the code already exists in the notebook
|
|
227
|
-
if (skipIfCodeExists) {
|
|
228
|
-
for (const cellId of state.cellIds.inOrderIds) {
|
|
229
|
-
if (state.cellData[cellId]?.code === code) {
|
|
230
|
-
return state;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (cellId === "__end__") {
|
|
236
|
-
const column = state.cellIds.atOrThrow(0);
|
|
237
|
-
columnId = column.id;
|
|
238
|
-
cellIndex = column.length;
|
|
239
|
-
} else if (typeof cellId === "string") {
|
|
240
|
-
const column = state.cellIds.findWithId(cellId);
|
|
241
|
-
columnId = column.id;
|
|
242
|
-
cellIndex = column.topLevelIds.indexOf(cellId);
|
|
243
|
-
} else if (cellId.type === "__end__") {
|
|
244
|
-
const column =
|
|
245
|
-
state.cellIds.get(cellId.columnId) || state.cellIds.atOrThrow(0);
|
|
246
|
-
columnId = column.id;
|
|
247
|
-
cellIndex = column.length;
|
|
248
|
-
} else {
|
|
249
|
-
throw new Error("Invalid cellId");
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const newCellId = action.newCellId || CellId.create();
|
|
253
|
-
const insertionIndex = before ? cellIndex : cellIndex + 1;
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
...state,
|
|
257
|
-
cellIds: state.cellIds.insertId(newCellId, columnId, insertionIndex),
|
|
258
|
-
cellData: {
|
|
259
|
-
...state.cellData,
|
|
260
|
-
[newCellId]: createCell({
|
|
261
|
-
id: newCellId,
|
|
262
|
-
code,
|
|
263
|
-
name,
|
|
264
|
-
lastCodeRun,
|
|
265
|
-
config: createCellConfig({
|
|
266
|
-
...config,
|
|
267
|
-
...(hideCode != null && { hide_code: hideCode }),
|
|
268
|
-
}),
|
|
269
|
-
lastExecutionTime,
|
|
270
|
-
edited: Boolean(code) && code !== lastCodeRun,
|
|
271
|
-
}),
|
|
272
|
-
},
|
|
273
|
-
cellRuntime: {
|
|
274
|
-
...state.cellRuntime,
|
|
275
|
-
[newCellId]: createCellRuntimeState(),
|
|
276
|
-
},
|
|
277
|
-
cellHandles: {
|
|
278
|
-
...state.cellHandles,
|
|
279
|
-
[newCellId]: createRef(),
|
|
280
|
-
},
|
|
281
|
-
scrollKey: autoFocus ? newCellId : null,
|
|
282
|
-
untouchedNewCells:
|
|
283
|
-
hideCode && autoFocus
|
|
284
|
-
? new Set([...state.untouchedNewCells, newCellId])
|
|
285
|
-
: state.untouchedNewCells,
|
|
286
|
-
};
|
|
287
|
-
},
|
|
288
177
|
moveCell: (
|
|
289
178
|
state,
|
|
290
179
|
action: {
|
|
@@ -679,128 +568,29 @@ const {
|
|
|
679
568
|
cellIds: state.cellIds.compact(),
|
|
680
569
|
};
|
|
681
570
|
},
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
// Expected for kernel-only cells or out-of-order transactions.
|
|
695
|
-
Logger.warn("Skipping delete for missing cellId", {
|
|
696
|
-
cellId,
|
|
697
|
-
error,
|
|
698
|
-
});
|
|
699
|
-
return state;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
const cellIndex = column.indexOfOrThrow(cellId);
|
|
703
|
-
const focusIndex = cellIndex === 0 ? 1 : cellIndex - 1;
|
|
704
|
-
let scrollKey: CellId | null = null;
|
|
705
|
-
if (column.length > 1) {
|
|
706
|
-
scrollKey = column.atOrThrow(focusIndex);
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
const editorView = state.cellHandles[cellId].current?.editorView;
|
|
710
|
-
const serializedEditorState = editorView?.state.toJSON({
|
|
711
|
-
history: historyField,
|
|
712
|
-
});
|
|
713
|
-
if (serializedEditorState) {
|
|
714
|
-
serializedEditorState.doc = state.cellData[cellId].code;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// release the granular atom(s) created for this cell
|
|
718
|
-
releaseCellAtoms(cellId);
|
|
719
|
-
const prevData = state.cellData[cellId];
|
|
720
|
-
return {
|
|
721
|
-
...state,
|
|
722
|
-
cellIds: state.cellIds.deleteById(cellId),
|
|
723
|
-
history: [
|
|
724
|
-
...state.history,
|
|
725
|
-
{
|
|
726
|
-
type: "delete",
|
|
727
|
-
name: prevData.name,
|
|
728
|
-
serializedEditorState: serializedEditorState,
|
|
729
|
-
column: column.id,
|
|
730
|
-
index: cellIndex,
|
|
731
|
-
isSetupCell: cellId === SETUP_CELL_ID,
|
|
732
|
-
config: prevData.config,
|
|
733
|
-
},
|
|
734
|
-
],
|
|
735
|
-
scrollKey: scrollKey,
|
|
736
|
-
};
|
|
737
|
-
},
|
|
738
|
-
undoDeleteCell: (state) => {
|
|
739
|
-
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
|
+
) {
|
|
740
583
|
return state;
|
|
741
584
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
if (
|
|
748
|
-
cellIds.length === 0 ||
|
|
749
|
-
placements.length !== cellIds.length ||
|
|
750
|
-
cellIds.some((id) => !state.cellData[id])
|
|
751
|
-
) {
|
|
752
|
-
return { ...state, history: state.history.slice(0, -1) };
|
|
753
|
-
}
|
|
754
|
-
const toRestore = cellIds.map((id, i) => ({
|
|
755
|
-
id,
|
|
756
|
-
columnId: placements[i].columnId,
|
|
757
|
-
index: placements[i].index,
|
|
758
|
-
}));
|
|
759
|
-
return {
|
|
760
|
-
...state,
|
|
761
|
-
cellIds: state.cellIds.placeCells(toRestore),
|
|
762
|
-
history: state.history.slice(0, -1),
|
|
763
|
-
scrollKey: cellIds[0] ?? null,
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
const {
|
|
768
|
-
name,
|
|
769
|
-
serializedEditorState = { doc: "" },
|
|
770
|
-
column,
|
|
771
|
-
index,
|
|
772
|
-
isSetupCell,
|
|
773
|
-
config,
|
|
774
|
-
} = last;
|
|
775
|
-
|
|
776
|
-
const cellId = isSetupCell ? SETUP_CELL_ID : CellId.create();
|
|
777
|
-
const undoCell = createCell({
|
|
778
|
-
id: cellId,
|
|
779
|
-
name,
|
|
780
|
-
code: serializedEditorState.doc,
|
|
781
|
-
edited: serializedEditorState.doc.trim().length > 0,
|
|
782
|
-
serializedEditorState,
|
|
783
|
-
config,
|
|
784
|
-
});
|
|
785
|
-
|
|
585
|
+
const toRestore = cellIds.map((id, i) => ({
|
|
586
|
+
id,
|
|
587
|
+
columnId: placements[i].columnId,
|
|
588
|
+
index: placements[i].index,
|
|
589
|
+
}));
|
|
786
590
|
return {
|
|
787
591
|
...state,
|
|
788
|
-
cellIds: state.cellIds.
|
|
789
|
-
|
|
790
|
-
...state.cellData,
|
|
791
|
-
[cellId]: undoCell,
|
|
792
|
-
},
|
|
793
|
-
cellRuntime: {
|
|
794
|
-
...state.cellRuntime,
|
|
795
|
-
[cellId]: createCellRuntimeState(),
|
|
796
|
-
},
|
|
797
|
-
cellHandles: {
|
|
798
|
-
...state.cellHandles,
|
|
799
|
-
[cellId]: createRef(),
|
|
800
|
-
},
|
|
801
|
-
history: state.history.slice(0, -1),
|
|
802
|
-
// Scroll to the newly created cell
|
|
803
|
-
scrollKey: cellId,
|
|
592
|
+
cellIds: state.cellIds.placeCells(toRestore),
|
|
593
|
+
scrollKey: cellIds[0] ?? null,
|
|
804
594
|
};
|
|
805
595
|
},
|
|
806
596
|
clearSerializedEditorState: (state, action: { cellId: CellId }) => {
|
|
@@ -853,35 +643,6 @@ const {
|
|
|
853
643
|
},
|
|
854
644
|
});
|
|
855
645
|
},
|
|
856
|
-
updateCellName: (state, action: { cellId: CellId; name: string }) => {
|
|
857
|
-
const { cellId, name } = action;
|
|
858
|
-
return updateCellData({
|
|
859
|
-
state,
|
|
860
|
-
cellId,
|
|
861
|
-
cellReducer: (cell) => {
|
|
862
|
-
return {
|
|
863
|
-
...cell,
|
|
864
|
-
name: name,
|
|
865
|
-
};
|
|
866
|
-
},
|
|
867
|
-
});
|
|
868
|
-
},
|
|
869
|
-
updateCellConfig: (
|
|
870
|
-
state,
|
|
871
|
-
action: { cellId: CellId; config: Partial<CellConfig> },
|
|
872
|
-
) => {
|
|
873
|
-
const { cellId, config } = action;
|
|
874
|
-
return updateCellData({
|
|
875
|
-
state,
|
|
876
|
-
cellId,
|
|
877
|
-
cellReducer: (cell) => {
|
|
878
|
-
return {
|
|
879
|
-
...cell,
|
|
880
|
-
config: createCellConfig({ ...cell.config, ...config }),
|
|
881
|
-
};
|
|
882
|
-
},
|
|
883
|
-
});
|
|
884
|
-
},
|
|
885
646
|
prepareForRun: (state, action: { cellId: CellId }) => {
|
|
886
647
|
const newState = updateCellRuntimeState({
|
|
887
648
|
state,
|
|
@@ -1020,97 +781,6 @@ const {
|
|
|
1020
781
|
}
|
|
1021
782
|
return { ...state, cellRuntime };
|
|
1022
783
|
},
|
|
1023
|
-
/**
|
|
1024
|
-
* Move focus to next cell
|
|
1025
|
-
*
|
|
1026
|
-
* Creates a new cell if the current cell is the last one in the array.
|
|
1027
|
-
*
|
|
1028
|
-
* If needed, scrolls newly created or focused cell into view.
|
|
1029
|
-
*
|
|
1030
|
-
* Replicates Shift+Enter functionality of Jupyter
|
|
1031
|
-
*/
|
|
1032
|
-
moveToNextCell: (
|
|
1033
|
-
state,
|
|
1034
|
-
action: { cellId: CellId; before: boolean; noCreate?: boolean },
|
|
1035
|
-
) => {
|
|
1036
|
-
const { cellId, before, noCreate = false } = action;
|
|
1037
|
-
|
|
1038
|
-
// Can't move focus of scratch cell
|
|
1039
|
-
if (cellId === SCRATCH_CELL_ID) {
|
|
1040
|
-
return state;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
const column = state.cellIds.findWithId(cellId);
|
|
1044
|
-
const index = column.indexOfOrThrow(cellId);
|
|
1045
|
-
const nextCellIndex = before ? index - 1 : index + 1;
|
|
1046
|
-
|
|
1047
|
-
const isPastLastCell = nextCellIndex === column.length;
|
|
1048
|
-
const isBeforeFirstCell = nextCellIndex === -1;
|
|
1049
|
-
|
|
1050
|
-
// Create a new cell at the end and set scrollKey to focus it
|
|
1051
|
-
if (isPastLastCell && !noCreate) {
|
|
1052
|
-
const newCellId = CellId.create();
|
|
1053
|
-
return {
|
|
1054
|
-
...state,
|
|
1055
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, nextCellIndex),
|
|
1056
|
-
cellData: {
|
|
1057
|
-
...state.cellData,
|
|
1058
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1059
|
-
},
|
|
1060
|
-
cellRuntime: {
|
|
1061
|
-
...state.cellRuntime,
|
|
1062
|
-
[newCellId]: createCellRuntimeState(),
|
|
1063
|
-
},
|
|
1064
|
-
cellHandles: {
|
|
1065
|
-
...state.cellHandles,
|
|
1066
|
-
[newCellId]: createRef(),
|
|
1067
|
-
},
|
|
1068
|
-
scrollKey: newCellId,
|
|
1069
|
-
};
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
if (isBeforeFirstCell && !noCreate) {
|
|
1073
|
-
const newCellId = CellId.create();
|
|
1074
|
-
return {
|
|
1075
|
-
...state,
|
|
1076
|
-
cellIds: state.cellIds.insertId(newCellId, column.id, 0),
|
|
1077
|
-
cellData: {
|
|
1078
|
-
...state.cellData,
|
|
1079
|
-
[newCellId]: createCell({ id: newCellId }),
|
|
1080
|
-
},
|
|
1081
|
-
cellRuntime: {
|
|
1082
|
-
...state.cellRuntime,
|
|
1083
|
-
[newCellId]: createCellRuntimeState(),
|
|
1084
|
-
},
|
|
1085
|
-
cellHandles: {
|
|
1086
|
-
...state.cellHandles,
|
|
1087
|
-
[newCellId]: createRef(),
|
|
1088
|
-
},
|
|
1089
|
-
scrollKey: newCellId,
|
|
1090
|
-
};
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
if ((isPastLastCell || isBeforeFirstCell) && noCreate) {
|
|
1094
|
-
// Trying to move past the last cell or before the first cell
|
|
1095
|
-
// with noCreate=true - do nothing
|
|
1096
|
-
return state;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
if (nextCellIndex >= 0 && nextCellIndex < column.length) {
|
|
1100
|
-
// Move to valid cell within bounds
|
|
1101
|
-
const nextCellId = column.atOrThrow(nextCellIndex);
|
|
1102
|
-
// Just focus, no state change
|
|
1103
|
-
focusAndScrollCellIntoView({
|
|
1104
|
-
cellId: nextCellId,
|
|
1105
|
-
cell: state.cellHandles[nextCellId],
|
|
1106
|
-
isCodeHidden: isCellCodeHidden(state, nextCellId),
|
|
1107
|
-
codeFocus: before ? "bottom" : "top",
|
|
1108
|
-
variableName: undefined,
|
|
1109
|
-
});
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
return state;
|
|
1113
|
-
},
|
|
1114
784
|
markTouched: (state, action: { cellId: CellId }) => {
|
|
1115
785
|
const { cellId } = action;
|
|
1116
786
|
|
|
@@ -1431,44 +1101,6 @@ const {
|
|
|
1431
1101
|
cellRuntime: newCellRuntime,
|
|
1432
1102
|
};
|
|
1433
1103
|
},
|
|
1434
|
-
addSetupCellIfDoesntExist: (state, action: { code?: string }) => {
|
|
1435
|
-
const { code } = action;
|
|
1436
|
-
|
|
1437
|
-
if (state.cellIds.setupCellExists()) {
|
|
1438
|
-
// Just focus on the existing setup cell
|
|
1439
|
-
return {
|
|
1440
|
-
...state,
|
|
1441
|
-
scrollKey: SETUP_CELL_ID,
|
|
1442
|
-
};
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
|
-
return {
|
|
1446
|
-
...state,
|
|
1447
|
-
cellIds: state.cellIds.insertId(
|
|
1448
|
-
SETUP_CELL_ID,
|
|
1449
|
-
state.cellIds.atOrThrow(0).id,
|
|
1450
|
-
0,
|
|
1451
|
-
),
|
|
1452
|
-
cellData: {
|
|
1453
|
-
...state.cellData,
|
|
1454
|
-
[SETUP_CELL_ID]: createCell({
|
|
1455
|
-
id: SETUP_CELL_ID,
|
|
1456
|
-
name: SETUP_CELL_ID,
|
|
1457
|
-
code,
|
|
1458
|
-
edited: Boolean(code),
|
|
1459
|
-
}),
|
|
1460
|
-
},
|
|
1461
|
-
cellRuntime: {
|
|
1462
|
-
...state.cellRuntime,
|
|
1463
|
-
[SETUP_CELL_ID]: createCellRuntimeState(),
|
|
1464
|
-
},
|
|
1465
|
-
cellHandles: {
|
|
1466
|
-
...state.cellHandles,
|
|
1467
|
-
[SETUP_CELL_ID]: createRef(),
|
|
1468
|
-
},
|
|
1469
|
-
scrollKey: SETUP_CELL_ID,
|
|
1470
|
-
};
|
|
1471
|
-
},
|
|
1472
1104
|
});
|
|
1473
1105
|
|
|
1474
1106
|
// We apply the middleware here (rather than inline in createReducerAndAtoms)
|
|
@@ -1876,20 +1508,13 @@ export function createTracebackInfoAtom(
|
|
|
1876
1508
|
});
|
|
1877
1509
|
}
|
|
1878
1510
|
|
|
1879
|
-
/**
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
*/
|
|
1883
|
-
export function useCellActions(
|
|
1884
|
-
options: { skipMiddleware?: boolean } = {},
|
|
1885
|
-
): CellActions {
|
|
1886
|
-
return useActions(options);
|
|
1511
|
+
/** The reducer's actions. Components use `useCellActions` from `./actions`. */
|
|
1512
|
+
export function useReducerActions(): ReducerCellActions {
|
|
1513
|
+
return useActions();
|
|
1887
1514
|
}
|
|
1888
1515
|
|
|
1889
|
-
/**
|
|
1890
|
-
|
|
1891
|
-
*/
|
|
1892
|
-
export type CellActions = ReturnType<typeof createActions>;
|
|
1516
|
+
/** The actions the reducer still handles. */
|
|
1517
|
+
export type ReducerCellActions = ReturnType<typeof createActions>;
|
|
1893
1518
|
|
|
1894
1519
|
/**
|
|
1895
1520
|
* This is exported for testing purposes only.
|