@marimo-team/islands 0.25.3-dev197 → 0.25.3-dev198
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-BRuwLOIx.js → ConnectedDataExplorerComponent-BsWiIPFk.js} +4 -4
- package/dist/{ErrorBoundary-jQVF8yMb.js → ErrorBoundary-D1Z3KAf_.js} +2 -2
- package/dist/{abnfDiagram-VCTEODGH-LlJTOOU_.js → abnfDiagram-VCTEODGH-I2x4Yu25.js} +2 -2
- package/dist/{architectureDiagram-5GKGNRK7-9PQtGLLZ.js → architectureDiagram-5GKGNRK7-1bSQMKzK.js} +1 -1
- package/dist/{arrays-DA6KkLfq.js → arrays-DoQ-AILx.js} +7 -21
- package/dist/{capabilities-CvWU-ey_.js → capabilities-C2QUNRXi.js} +1 -1
- package/dist/{chat-ui-Bl2euMBD.js → chat-ui-BAyHM_GD.js} +524 -524
- package/dist/{chunk-IMKFNOWR-DcXv-BD5.js → chunk-IMKFNOWR-fsCGAJ9G.js} +1 -1
- package/dist/{chunk-SHT3W25Y-VwnELN23.js → chunk-SHT3W25Y-D2STW4hj.js} +1 -1
- package/dist/{chunk-SVP7TREG-DgQpI5Zi.js → chunk-SVP7TREG-CiY7cQG-.js} +1 -1
- package/dist/{chunk-TICWLB2K-CTg6VTJT.js → chunk-TICWLB2K-C_t5RBp9.js} +1 -1
- package/dist/{classDiagram-ZZMXUADV-UzmcFrnW.js → classDiagram-ZZMXUADV-B2JvZAP4.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-DhjiI6IQ.js → classDiagram-v2-VYDZK3BY-L8VsZG5A.js} +2 -2
- package/dist/{code-visibility-CjZo_SV8.js → code-visibility-CInEQd1e.js} +19 -19
- package/dist/{common-CFLvScF3.js → common-W5HfVJPN.js} +4362 -4362
- package/dist/{cynefinDiagram-5FMLGOSQ-O4ShIbJX.js → cynefinDiagram-5FMLGOSQ-DdllC264.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-dtHhhcPu.js → dagre-GXQ25YYZ-BaWHw4_f.js} +1 -1
- package/dist/{data-grid-overlay-editor-CzW3mY6m.js → data-grid-overlay-editor-BQCaV0fI.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-ppPYVZ6W.js → diagram-S7CK7UJ4-pFt-tUDe.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-CMZDf--k.js → diagram-UQ7AKVKN-DqGJiBp4.js} +1 -1
- package/dist/{diagram-VX7I27RA-CFvJdx-C.js → diagram-VX7I27RA-Dr-yzMjf.js} +1 -1
- package/dist/{diagram-Z3DM3KII-Dt6_uFbv.js → diagram-Z3DM3KII-8xzJzv-w.js} +1 -1
- package/dist/{dropdown-menu-CeaOsjWZ.js → dropdown-menu-NlnsmNA6.js} +2 -2
- package/dist/{ebnfDiagram-PWID7BFC-DpRFrKK-.js → ebnfDiagram-PWID7BFC-Br04Wy-E.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-CqAU4b0u.js → erDiagram-RLTQ6QDP-D5-XVgvv.js} +1 -1
- package/dist/{error-entries-CYGwr5-O.js → error-entries-BacCWMWj.js} +4678 -5028
- package/dist/{feedback-button-GR_8U4Vo.js → feedback-button-DLXUcQ7l.js} +113 -113
- package/dist/{flowDiagram-HODETNUW-i8-Gw8HO.js → flowDiagram-HODETNUW-CVl2kREF.js} +2 -2
- package/dist/{formats-BtoHHy42.js → formats-BCYthwyc.js} +1 -1
- package/dist/{glide-data-editor-Dfdxc22H.js → glide-data-editor-D5YaHPKx.js} +5 -5
- package/dist/{globals-CxjzBEbP.js → globals-DjX1uxzy.js} +2 -2
- package/dist/{html-to-image-Cy5UDpQJ.js → html-to-image-DAmgSo5P.js} +624 -573
- package/dist/{infoDiagram-27XIBGKW-DpfOKdLL.js → infoDiagram-27XIBGKW-BJ4vNcZE.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-Dg7mrMG7.js → ishikawaDiagram-5VMMS53U-B_Jy1Dsm.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-QB6e3Jrj.js → kanban-definition-UXKFOSKX-C6MkS9vw.js} +1 -1
- package/dist/main.js +1117 -1117
- package/dist/{mermaid-CeWG4Egr.js → mermaid-Bh918qrq.js} +34 -34
- package/dist/{mindmap-definition-YA3MSWOX-BTz3uTGe.js → mindmap-definition-YA3MSWOX-BP3ZTuir.js} +1 -1
- package/dist/{number-overlay-editor-CwHYeI4e.js → number-overlay-editor-3C_K6w_0.js} +1 -1
- package/dist/{once-DWGO2mQ2.js → once-NnpX_HnX.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-3ZIEa3mB.js → pegDiagram-XKGWAZYB-nNGOQtnt.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-BJAlk046.js → pieDiagram-E7YTZNPT-CpRz5BZz.js} +1 -1
- package/dist/{process-output-q9MTAIMX.js → process-output-DweUmAmV.js} +3 -3
- package/dist/{railroadDiagram-O6MQD6OU-Dn3bsSRa.js → railroadDiagram-O6MQD6OU-BqOEN4I0.js} +2 -2
- package/dist/{requirementDiagram-BXWQKSXE-wcOmQQCL.js → requirementDiagram-BXWQKSXE-CEfg6vu9.js} +1 -1
- package/dist/{reveal-component-C5bOqXlB.js → reveal-component-JjJRTT9d.js} +17 -17
- package/dist/{sequenceDiagram-WJ2MYXX4-DSh_qxoF.js → sequenceDiagram-WJ2MYXX4-IOmpQcOi.js} +1 -1
- package/dist/{spec-C7Fos-If.js → spec-Dkp64vVQ.js} +1 -1
- package/dist/{stateDiagram-D77RDMKH-DH_H8NMH.js → stateDiagram-D77RDMKH-tgU-EY9_.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-D_JM7MEK.js → stateDiagram-v2-MP3YSRHH-BofhG6q1.js} +2 -2
- package/dist/{swimlanes-42K2YHIH-CfoTJO-9.js → swimlanes-42K2YHIH-DW4vWDBd.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-Z_QhvK0G.js → swimlanesDiagram-VR7AAH4N-BJcrqUJr.js} +2 -2
- package/dist/{swiper-component-D2geL1Ku.js → swiper-component-BVfnhbnt.js} +1 -1
- package/dist/{timeline-definition-24CTP7MA-BFtdScaL.js → timeline-definition-24CTP7MA-D_QU3NGs.js} +1 -1
- package/dist/{toDate-CQAFSwos.js → toDate-BNDEXbfV.js} +30 -30
- package/dist/{useAsyncData-BeyZyjso.js → useAsyncData-ASDni9vH.js} +1 -1
- package/dist/{useDeepCompareMemoize-DOQgae0W.js → useDeepCompareMemoize-B1Ogyf53.js} +1 -1
- package/dist/{useIframeCapabilities-DNvaj9wM.js → useIframeCapabilities-6a_yDNXp.js} +1 -1
- package/dist/{useLifecycle-n2lnCFS8.js → useLifecycle-Bfpa2m7k.js} +1 -1
- package/dist/{useTheme-CY777LXN.js → useTheme-5TwyOh3B.js} +66 -66
- package/dist/{vega-component-0nQzA-I8.js → vega-component-BHS9UOtC.js} +19 -19
- package/dist/{vennDiagram-4TSXK5OY-BXY8IGCA.js → vennDiagram-4TSXK5OY-YFYsNIAh.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-D0tFe6eC.js → wardleyDiagram-VM6X3IG4-i_n8mAWC.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-Dx8wFM-y.js → xychartDiagram-S5SC5T6Z-BYGN95wW.js} +1 -1
- package/package.json +1 -1
- package/src/__mocks__/document.tsx +13 -4
- package/src/__mocks__/notebook.ts +1 -2
- package/src/components/datasources/datasources.tsx +1 -1
- package/src/components/dependency-graph/custom-node.tsx +1 -1
- package/src/components/dependency-graph/minimap-content.tsx +12 -14
- package/src/components/editor/actions/useSetCodeVisibility.ts +1 -1
- package/src/components/editor/actions/useSetOutputsExpanded.ts +1 -1
- package/src/components/editor/alerts/stdin-blocking-alert.tsx +1 -1
- package/src/components/editor/cell/code/cell-editor.tsx +1 -1
- package/src/components/editor/cell/useSplitCell.tsx +8 -5
- package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/session-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/variable-panel.tsx +1 -5
- package/src/components/editor/chrome/wrapper/minimap-state.ts +1 -1
- 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 +1 -1
- package/src/components/editor/links/__tests__/cell-link.test.tsx +1 -1
- package/src/components/editor/links/cell-link-list.tsx +1 -1
- package/src/components/editor/links/cell-link.tsx +1 -1
- package/src/components/editor/navigation/__tests__/navigation.test.ts +20 -6
- package/src/components/editor/navigation/__tests__/selection.test.ts +1 -2
- package/src/components/editor/navigation/clipboard.ts +5 -3
- package/src/components/editor/renderers/cell-array.tsx +7 -12
- 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/useFocusFirstEditor.ts +1 -1
- package/src/components/editor/stdin-blocking-alert.tsx +1 -1
- package/src/components/slides/__tests__/minimap-actions.test.tsx +13 -4
- package/src/components/slides/__tests__/minimap.test.ts +38 -19
- package/src/components/slides/minimap.tsx +11 -10
- package/src/components/sort/SortableCellsProvider.tsx +2 -21
- package/src/components/tracing/tracing.tsx +1 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +1 -1
- package/src/core/ai/context/providers/__tests__/cell-output.test.ts +8 -12
- package/src/core/ai/context/providers/cell-output.ts +2 -2
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +34 -66
- package/src/core/ai/tools/edit-notebook-tool.ts +12 -10
- package/src/core/cells/__tests__/actions.test.ts +64 -25
- package/src/core/cells/__tests__/arrange.test.ts +156 -4
- package/src/core/cells/__tests__/cells.test.ts +12 -290
- package/src/core/cells/__tests__/document.test.ts +2 -46
- package/src/core/cells/__tests__/harness.ts +28 -4
- package/src/core/cells/__tests__/layout.test.ts +42 -54
- package/src/core/cells/__tests__/session.test.ts +0 -2
- package/src/core/cells/__tests__/utils.test.ts +9 -107
- package/src/core/cells/actions.ts +112 -26
- package/src/core/cells/add-missing-import.ts +1 -1
- package/src/core/cells/arrange.ts +206 -13
- package/src/core/cells/cells.ts +28 -256
- package/src/core/cells/document.ts +18 -122
- package/src/core/cells/layout.ts +79 -10
- package/src/core/cells/pending-delete-service.ts +1 -1
- package/src/core/cells/utils.ts +4 -4
- package/src/core/codemirror/copilot/__tests__/getCodes.test.ts +6 -7
- package/src/core/codemirror/copilot/getCodes.ts +2 -2
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +1 -2
- package/src/core/codemirror/lsp/utils.ts +1 -1
- package/src/core/documentation/doc-lookup.ts +1 -1
- package/src/core/edit-app.tsx +2 -5
- package/src/core/errors/error-entries.ts +1 -1
- package/src/core/islands/__tests__/bootstrap.test.ts +2 -6
- package/src/core/islands/components/web-components.tsx +1 -1
- package/src/core/notebook/document/__tests__/codemirror.test.ts +8 -0
- package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +1 -1
- package/src/stories/cell.stories.tsx +1 -2
- package/src/stories/layout/vertical/one-column.stories.tsx +1 -2
- package/src/stories/runtime-story.tsx +2 -3
- package/src/utils/__tests__/id-tree.test.ts +0 -617
- package/src/utils/id-tree.tsx +0 -609
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { useDeleteCellCallback } from "@/components/editor/cell/useDeleteCell";
|
|
4
4
|
import { outputIsStale } from "@/core/cells/cell";
|
|
5
|
-
import { useCellIds } from "@/core/cells/cells";
|
|
6
5
|
import { useCellActions } from "@/core/cells/actions";
|
|
7
6
|
import type { CellId } from "@/core/cells/ids";
|
|
8
|
-
import type
|
|
7
|
+
import { type CellColumnId, type Layout, useLayout } from "@/core/cells/layout";
|
|
9
8
|
import { useEffect, useRef, useState } from "react";
|
|
10
9
|
import type { ICellRendererProps } from "../editor/renderers/types";
|
|
11
10
|
import type {
|
|
@@ -50,7 +49,6 @@ import { SLIDE_TYPE_OPTIONS_BY_VALUE } from "./slide-form";
|
|
|
50
49
|
|
|
51
50
|
type Props = ICellRendererProps<SlidesLayout>;
|
|
52
51
|
type SlideCell = Props["cells"][number];
|
|
53
|
-
type CellIdsState = ReturnType<typeof useCellIds>;
|
|
54
52
|
type DropPosition = "before" | "after";
|
|
55
53
|
|
|
56
54
|
interface ProjectedDropTarget {
|
|
@@ -229,7 +227,7 @@ export const SlidesMinimap = ({
|
|
|
229
227
|
slideTypes,
|
|
230
228
|
onSlideClick,
|
|
231
229
|
}: SlidesMinimapProps) => {
|
|
232
|
-
const
|
|
230
|
+
const layout = useLayout();
|
|
233
231
|
const { moveCellToIndex, createCell } = useCellActions();
|
|
234
232
|
const deleteCell = useDeleteCellCallback();
|
|
235
233
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
@@ -297,7 +295,7 @@ export const SlidesMinimap = ({
|
|
|
297
295
|
try {
|
|
298
296
|
if (activeId && dropTarget) {
|
|
299
297
|
const resolvedTarget = resolveDropTarget({
|
|
300
|
-
|
|
298
|
+
layout,
|
|
301
299
|
activeId,
|
|
302
300
|
target: dropTarget,
|
|
303
301
|
});
|
|
@@ -751,24 +749,27 @@ function projectDropTarget(
|
|
|
751
749
|
}
|
|
752
750
|
|
|
753
751
|
function resolveDropTarget({
|
|
754
|
-
|
|
752
|
+
layout,
|
|
755
753
|
activeId,
|
|
756
754
|
target,
|
|
757
755
|
}: {
|
|
758
|
-
|
|
756
|
+
layout: Layout;
|
|
759
757
|
activeId: CellId;
|
|
760
758
|
target: ProjectedDropTarget;
|
|
761
759
|
}): ResolvedDropTarget | null {
|
|
762
760
|
if (activeId === target.overId) {
|
|
763
761
|
return null;
|
|
764
762
|
}
|
|
765
|
-
if (
|
|
763
|
+
if (layout.columns.length !== 1) {
|
|
766
764
|
Logger.warn("Multi-column mode is not supported");
|
|
767
765
|
return null;
|
|
768
766
|
}
|
|
769
767
|
|
|
770
|
-
const column =
|
|
771
|
-
const overIndex = column.
|
|
768
|
+
const [column] = layout.columns;
|
|
769
|
+
const overIndex = column.ids.indexOf(target.overId);
|
|
770
|
+
if (overIndex === -1) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
772
773
|
|
|
773
774
|
return {
|
|
774
775
|
cellId: activeId,
|
|
@@ -22,10 +22,8 @@ import React, { useCallback, useMemo, useState } from "react";
|
|
|
22
22
|
import type { CellId } from "@/core/cells/ids";
|
|
23
23
|
import { useAppConfig } from "@/core/config/config";
|
|
24
24
|
import { Arrays } from "@/utils/arrays";
|
|
25
|
-
import type { CellColumnId, MultiColumn } from "@/utils/id-tree";
|
|
26
25
|
import { invariant } from "@/utils/invariant";
|
|
27
|
-
import {
|
|
28
|
-
import { findColumn, layoutAtom } from "../../core/cells/layout";
|
|
26
|
+
import { findColumn, isColumnId, layoutAtom } from "../../core/cells/layout";
|
|
29
27
|
import { store } from "../../core/state/jotai";
|
|
30
28
|
import { useCellActions } from "../../core/cells/actions";
|
|
31
29
|
import { useEvent } from "../../hooks/useEvent";
|
|
@@ -50,9 +48,6 @@ const SortableCellsProviderInternal = ({
|
|
|
50
48
|
useCellActions();
|
|
51
49
|
|
|
52
50
|
const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
|
|
53
|
-
const [clonedItems, setClonedItems] = useState<MultiColumn<CellId> | null>(
|
|
54
|
-
null,
|
|
55
|
-
);
|
|
56
51
|
|
|
57
52
|
const config = useAppConfig();
|
|
58
53
|
const modifiers = useMemo(() => {
|
|
@@ -76,20 +71,10 @@ const SortableCellsProviderInternal = ({
|
|
|
76
71
|
|
|
77
72
|
const handleDragStart = useEvent((event: DragStartEvent) => {
|
|
78
73
|
setActiveId(event.active.id);
|
|
79
|
-
const notebook = getNotebook();
|
|
80
|
-
setClonedItems(notebook.cellIds);
|
|
81
74
|
});
|
|
82
75
|
|
|
83
76
|
const handleDragCancel = useEvent(() => {
|
|
84
|
-
// TODO: restore cloned items
|
|
85
|
-
if (clonedItems) {
|
|
86
|
-
// Reset items to their original state in case items have been
|
|
87
|
-
// Dragged across containers
|
|
88
|
-
// setItems(clonedItems);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
77
|
setActiveId(null);
|
|
92
|
-
setClonedItems(null);
|
|
93
78
|
});
|
|
94
79
|
|
|
95
80
|
/**
|
|
@@ -236,9 +221,5 @@ const SortableCellsProviderInternal = ({
|
|
|
236
221
|
export const SortableCellsProvider = React.memo(SortableCellsProviderInternal);
|
|
237
222
|
|
|
238
223
|
function isCellId(id: UniqueIdentifier): id is CellId {
|
|
239
|
-
return typeof id === "string" && !id
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function isColumnId(id: UniqueIdentifier): id is CellColumnId {
|
|
243
|
-
return typeof id === "string" && id.startsWith("tree_");
|
|
224
|
+
return typeof id === "string" && !isColumnId(id);
|
|
244
225
|
}
|
|
@@ -209,7 +209,7 @@ const TraceBlockBody: React.FC<{
|
|
|
209
209
|
const elapsedTime = cellRun.elapsedTime ?? 0;
|
|
210
210
|
return {
|
|
211
211
|
cell: cellRun.cellId,
|
|
212
|
-
cellNum: cellIds.
|
|
212
|
+
cellNum: cellIds.indexOf(cellRun.cellId),
|
|
213
213
|
startTimestamp: formatChartTime(cellRun.startTime),
|
|
214
214
|
endTimestamp: formatChartTime(cellRun.startTime + elapsedTime),
|
|
215
215
|
elapsedTime: formatElapsedTime(elapsedTime * 1000),
|
|
@@ -43,7 +43,7 @@ vi.mock("../../cells/actions", () => ({
|
|
|
43
43
|
vi.mock("../../cells/cells", async () => {
|
|
44
44
|
const { atom } = await import("jotai");
|
|
45
45
|
return {
|
|
46
|
-
notebookAtom: atom({ cellData: {}, cellIds:
|
|
46
|
+
notebookAtom: atom({ cellData: {}, cellIds: [] }),
|
|
47
47
|
cellHandleAtom: vi.fn(() => ({
|
|
48
48
|
read: vi.fn(() => mockCellHandle),
|
|
49
49
|
})),
|
|
@@ -34,9 +34,7 @@ describe("CellOutputContextProvider", () => {
|
|
|
34
34
|
beforeEach(() => {
|
|
35
35
|
// Create a basic mock notebook state
|
|
36
36
|
mockNotebook = {
|
|
37
|
-
cellIds:
|
|
38
|
-
inOrderIds: ["cell1", "cell2", "cell3"],
|
|
39
|
-
},
|
|
37
|
+
cellIds: ["cell1", "cell2", "cell3"],
|
|
40
38
|
cellData: {
|
|
41
39
|
cell1: {
|
|
42
40
|
id: "cell1",
|
|
@@ -207,7 +205,7 @@ describe("Cell output utility functions", () => {
|
|
|
207
205
|
|
|
208
206
|
beforeEach(() => {
|
|
209
207
|
const mockNotebook = {
|
|
210
|
-
cellIds:
|
|
208
|
+
cellIds: [],
|
|
211
209
|
cellData: {},
|
|
212
210
|
cellRuntime: {},
|
|
213
211
|
} as unknown as NotebookState;
|
|
@@ -226,7 +224,7 @@ describe("Cell output utility functions", () => {
|
|
|
226
224
|
|
|
227
225
|
for (const testCase of testCases) {
|
|
228
226
|
mockStore = createMockStore({
|
|
229
|
-
cellIds:
|
|
227
|
+
cellIds: ["test"],
|
|
230
228
|
cellData: {
|
|
231
229
|
test: { id: "test", name: "", code: "" },
|
|
232
230
|
},
|
|
@@ -261,7 +259,7 @@ describe("Cell output utility functions", () => {
|
|
|
261
259
|
|
|
262
260
|
for (const testCase of testCases) {
|
|
263
261
|
mockStore = createMockStore({
|
|
264
|
-
cellIds:
|
|
262
|
+
cellIds: ["test"],
|
|
265
263
|
cellData: {
|
|
266
264
|
test: { id: "test", name: "", code: "" },
|
|
267
265
|
},
|
|
@@ -295,7 +293,7 @@ describe("Cell output utility functions", () => {
|
|
|
295
293
|
|
|
296
294
|
for (const testCase of testCases) {
|
|
297
295
|
mockStore = createMockStore({
|
|
298
|
-
cellIds:
|
|
296
|
+
cellIds: ["test"],
|
|
299
297
|
cellData: {
|
|
300
298
|
test: { id: "test", name: "", code: "" },
|
|
301
299
|
},
|
|
@@ -338,7 +336,7 @@ describe("Cell output utility functions", () => {
|
|
|
338
336
|
} as unknown as Document;
|
|
339
337
|
|
|
340
338
|
const mockNotebook = {
|
|
341
|
-
cellIds:
|
|
339
|
+
cellIds: [],
|
|
342
340
|
cellData: {},
|
|
343
341
|
cellRuntime: {},
|
|
344
342
|
} as unknown as NotebookState;
|
|
@@ -369,7 +367,7 @@ describe("Cell output utility functions", () => {
|
|
|
369
367
|
).mockReturnValue(mockDiv);
|
|
370
368
|
|
|
371
369
|
mockStore = createMockStore({
|
|
372
|
-
cellIds:
|
|
370
|
+
cellIds: ["test"],
|
|
373
371
|
cellData: {
|
|
374
372
|
test: { id: "test", name: "", code: "" },
|
|
375
373
|
},
|
|
@@ -395,9 +393,7 @@ describe("Cell output utility functions", () => {
|
|
|
395
393
|
|
|
396
394
|
beforeEach(() => {
|
|
397
395
|
mockNotebook = {
|
|
398
|
-
cellIds:
|
|
399
|
-
inOrderIds: ["cell1", "cell2"],
|
|
400
|
-
},
|
|
396
|
+
cellIds: ["cell1", "cell2"],
|
|
401
397
|
cellData: {
|
|
402
398
|
cell1: {
|
|
403
399
|
id: "cell1",
|
|
@@ -93,7 +93,7 @@ export class CellOutputContextProvider extends AIContextProvider<CellOutputConte
|
|
|
93
93
|
const notebook = this.store.get(notebookAtom);
|
|
94
94
|
const items: CellOutputContextItem[] = [];
|
|
95
95
|
|
|
96
|
-
for (const cellId of notebook.cellIds
|
|
96
|
+
for (const cellId of notebook.cellIds) {
|
|
97
97
|
const cellContextData = getCellContextData(cellId, notebook);
|
|
98
98
|
const cellOutput = cellContextData.cellOutput;
|
|
99
99
|
|
|
@@ -358,7 +358,7 @@ export function getCellContextData(
|
|
|
358
358
|
const cellRuntime = notebook.cellRuntime[cellId];
|
|
359
359
|
|
|
360
360
|
const cellData = notebook.cellData[cellId];
|
|
361
|
-
const cellIndex = notebook.cellIds.
|
|
361
|
+
const cellIndex = notebook.cellIds.indexOf(cellId);
|
|
362
362
|
const cellName = displayCellName(cellData.name, cellIndex);
|
|
363
363
|
|
|
364
364
|
let consoleOutputs: BaseOutput[] | undefined;
|
|
@@ -4,12 +4,18 @@ import { EditorState } from "@codemirror/state";
|
|
|
4
4
|
import { EditorView } from "@codemirror/view";
|
|
5
5
|
import { getDefaultStore } from "jotai";
|
|
6
6
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { mockDocumentModel } from "@/__mocks__/document";
|
|
7
8
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
8
9
|
import { cellId } from "@/__tests__/branded";
|
|
9
10
|
import { notebookAtom } from "@/core/cells/cells";
|
|
10
11
|
import type { CellId } from "@/core/cells/ids";
|
|
11
12
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
12
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
cell,
|
|
15
|
+
CONFIG,
|
|
16
|
+
document as documentOf,
|
|
17
|
+
withCells,
|
|
18
|
+
} from "@/core/notebook/document/__tests__/fixtures";
|
|
13
19
|
import { cellConfigExtension } from "../../../codemirror/config/extension";
|
|
14
20
|
import { adaptiveLanguageConfiguration } from "../../../codemirror/language/extension";
|
|
15
21
|
import { stagedAICellsAtom } from "../../staged-cells";
|
|
@@ -61,7 +67,6 @@ describe("EditNotebookTool", () => {
|
|
|
61
67
|
let tool: EditNotebookTool;
|
|
62
68
|
let cellId1: CellId;
|
|
63
69
|
let cellId2: CellId;
|
|
64
|
-
let cellId3: CellId;
|
|
65
70
|
let toolContext: {
|
|
66
71
|
addStagedCell: ReturnType<typeof vi.fn>;
|
|
67
72
|
createCell: ReturnType<typeof vi.fn>;
|
|
@@ -86,7 +91,6 @@ describe("EditNotebookTool", () => {
|
|
|
86
91
|
|
|
87
92
|
cellId1 = cellId("cell-1");
|
|
88
93
|
cellId2 = cellId("cell-2");
|
|
89
|
-
cellId3 = cellId("cell-3");
|
|
90
94
|
|
|
91
95
|
// Reset mocks
|
|
92
96
|
vi.clearAllMocks();
|
|
@@ -443,27 +447,37 @@ describe("EditNotebookTool", () => {
|
|
|
443
447
|
[cellId2]: { code: "x = 2" },
|
|
444
448
|
},
|
|
445
449
|
});
|
|
446
|
-
// Create multi-column layout
|
|
447
|
-
notebook.cellIds = MultiColumn.from([[cellId1], [cellId2]]);
|
|
448
450
|
store.set(notebookAtom, notebook);
|
|
449
|
-
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
{
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
451
|
+
// The layout reads columns from the document's cells.
|
|
452
|
+
const { stop } = mockDocumentModel(
|
|
453
|
+
store,
|
|
454
|
+
withCells(documentOf(), {
|
|
455
|
+
c1: null,
|
|
456
|
+
c2: null,
|
|
457
|
+
[cellId1]: cell(cellId1, "x = 1"),
|
|
458
|
+
[cellId2]: cell(cellId2, "x = 2", {
|
|
459
|
+
config: { ...CONFIG, column: 1 },
|
|
460
|
+
}),
|
|
461
|
+
}),
|
|
460
462
|
);
|
|
461
463
|
|
|
462
|
-
|
|
464
|
+
try {
|
|
465
|
+
const result = await tool.handler(
|
|
466
|
+
{
|
|
467
|
+
edit: {
|
|
468
|
+
type: "add_cell",
|
|
469
|
+
position: { type: "column_end", columnIndex: 1 },
|
|
470
|
+
code: "y = 2",
|
|
471
|
+
},
|
|
472
|
+
},
|
|
473
|
+
toolContext as never,
|
|
474
|
+
);
|
|
463
475
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
476
|
+
expect(result.status).toBe("success");
|
|
477
|
+
expect(store.get(stagedAICellsAtom).size).toBe(1);
|
|
478
|
+
} finally {
|
|
479
|
+
stop();
|
|
480
|
+
}
|
|
467
481
|
});
|
|
468
482
|
|
|
469
483
|
it("should throw error when cell ID doesn't exist for position", async () => {
|
|
@@ -698,52 +712,6 @@ describe("EditNotebookTool", () => {
|
|
|
698
712
|
});
|
|
699
713
|
});
|
|
700
714
|
|
|
701
|
-
describe("validation", () => {
|
|
702
|
-
it("should validate cell exists in multi-column notebook", async () => {
|
|
703
|
-
const notebook = MockNotebook.notebookState({
|
|
704
|
-
cellData: {
|
|
705
|
-
[cellId1]: { code: "x = 1" },
|
|
706
|
-
[cellId2]: { code: "x = 2" },
|
|
707
|
-
[cellId3]: { code: "x = 3" },
|
|
708
|
-
},
|
|
709
|
-
});
|
|
710
|
-
// Create multi-column layout
|
|
711
|
-
notebook.cellIds = MultiColumn.from([[cellId1, cellId2], [cellId3]]);
|
|
712
|
-
store.set(notebookAtom, notebook);
|
|
713
|
-
|
|
714
|
-
// Should not throw for cells in different columns
|
|
715
|
-
const editorView = createMockEditorView("x = 1");
|
|
716
|
-
notebook.cellHandles[cellId1] = { current: { editorView } } as never;
|
|
717
|
-
notebook.cellHandles[cellId3] = { current: { editorView } } as never;
|
|
718
|
-
|
|
719
|
-
await expect(
|
|
720
|
-
tool.handler(
|
|
721
|
-
{
|
|
722
|
-
edit: {
|
|
723
|
-
type: "update_cell",
|
|
724
|
-
position: { cellId: cellId1 },
|
|
725
|
-
code: "y = 1",
|
|
726
|
-
},
|
|
727
|
-
},
|
|
728
|
-
toolContext as never,
|
|
729
|
-
),
|
|
730
|
-
).resolves.toBeDefined();
|
|
731
|
-
|
|
732
|
-
await expect(
|
|
733
|
-
tool.handler(
|
|
734
|
-
{
|
|
735
|
-
edit: {
|
|
736
|
-
type: "update_cell",
|
|
737
|
-
position: { cellId: cellId3 },
|
|
738
|
-
code: "y = 3",
|
|
739
|
-
},
|
|
740
|
-
},
|
|
741
|
-
toolContext as never,
|
|
742
|
-
),
|
|
743
|
-
).resolves.toBeDefined();
|
|
744
|
-
});
|
|
745
|
-
});
|
|
746
|
-
|
|
747
715
|
describe("return value", () => {
|
|
748
716
|
it("should return success status with next steps", async () => {
|
|
749
717
|
const notebook = MockNotebook.notebookState({
|
|
@@ -7,7 +7,11 @@ import { type NotebookState, notebookAtom } from "@/core/cells/cells";
|
|
|
7
7
|
import type { CreateCellOptions } from "@/core/cells/actions";
|
|
8
8
|
import { CellId } from "@/core/cells/ids";
|
|
9
9
|
import { prepareCellCodeUpdate } from "@/core/codemirror/language/cell-code";
|
|
10
|
-
import
|
|
10
|
+
import {
|
|
11
|
+
type CellColumnId,
|
|
12
|
+
type Layout,
|
|
13
|
+
layoutAtom,
|
|
14
|
+
} from "@/core/cells/layout";
|
|
11
15
|
import { stagedAICellsAtom } from "../staged-cells";
|
|
12
16
|
import {
|
|
13
17
|
type AiTool,
|
|
@@ -201,7 +205,10 @@ export class EditNotebookTool implements AiTool<
|
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
placement = {
|
|
204
|
-
endOf: this.getColumnId(
|
|
208
|
+
endOf: this.getColumnId(
|
|
209
|
+
position.columnIndex,
|
|
210
|
+
store.get(layoutAtom),
|
|
211
|
+
),
|
|
205
212
|
};
|
|
206
213
|
break;
|
|
207
214
|
|
|
@@ -259,8 +266,7 @@ export class EditNotebookTool implements AiTool<
|
|
|
259
266
|
};
|
|
260
267
|
|
|
261
268
|
private validateCellIdExists(cellId: CellId, notebook: NotebookState) {
|
|
262
|
-
|
|
263
|
-
if (!cellIds.getColumns().some((column) => column.idSet.has(cellId))) {
|
|
269
|
+
if (!notebook.cellIds.includes(cellId)) {
|
|
264
270
|
throw new ToolExecutionError("Cell not found", {
|
|
265
271
|
code: "CELL_NOT_FOUND",
|
|
266
272
|
isRetryable: false,
|
|
@@ -269,12 +275,8 @@ export class EditNotebookTool implements AiTool<
|
|
|
269
275
|
}
|
|
270
276
|
}
|
|
271
277
|
|
|
272
|
-
private getColumnId(
|
|
273
|
-
|
|
274
|
-
notebook: NotebookState,
|
|
275
|
-
): CellColumnId {
|
|
276
|
-
const cellIds = notebook.cellIds;
|
|
277
|
-
const columns = cellIds.getColumns();
|
|
278
|
+
private getColumnId(columnIndex: number, layout: Layout): CellColumnId {
|
|
279
|
+
const { columns } = layout;
|
|
278
280
|
|
|
279
281
|
if (columnIndex < 0 || columnIndex >= columns.length) {
|
|
280
282
|
throw new ToolExecutionError("Column index is out of range", {
|
|
@@ -5,7 +5,6 @@ import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
5
5
|
import { cellId } from "@/__tests__/branded";
|
|
6
6
|
import { createStore } from "jotai";
|
|
7
7
|
import { cell, CONFIG } from "@/core/notebook/document/__tests__/fixtures";
|
|
8
|
-
import type { CellIndex } from "@/utils/id-tree";
|
|
9
8
|
import {
|
|
10
9
|
addSetupCellAtom,
|
|
11
10
|
collapseAllCellsAtom,
|
|
@@ -17,9 +16,11 @@ import {
|
|
|
17
16
|
focusCellAtom,
|
|
18
17
|
moveToNextCellAtom,
|
|
19
18
|
showCellIfHiddenAtom,
|
|
19
|
+
splitCellAtom,
|
|
20
20
|
undoDeleteCellAtom,
|
|
21
|
+
undoSplitCellAtom,
|
|
21
22
|
} from "../actions";
|
|
22
|
-
import { moveCellsRelativeToAtom } from "../arrange";
|
|
23
|
+
import { moveCellAtom, moveCellsRelativeToAtom } from "../arrange";
|
|
23
24
|
import {
|
|
24
25
|
cellDataAtom,
|
|
25
26
|
cellHandleAtom,
|
|
@@ -95,7 +96,7 @@ describe("createCellAtom", () => {
|
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
it("names the column of a cell placed first in a later column", () => {
|
|
98
|
-
const { store,
|
|
99
|
+
const { store, cellIn } = setup({
|
|
99
100
|
c2: cell("c2", "y = 2", { config: { ...CONFIG, column: 1 } }),
|
|
100
101
|
});
|
|
101
102
|
|
|
@@ -103,12 +104,14 @@ describe("createCellAtom", () => {
|
|
|
103
104
|
|
|
104
105
|
expect(cellIn(id as string)?.config.column).toBe(1);
|
|
105
106
|
expect(cellIn(c2)?.config.column).toBeNull();
|
|
106
|
-
expect(
|
|
107
|
-
|
|
107
|
+
expect(store.get(layoutAtom).columns.map((c) => c.ids)).toEqual([
|
|
108
|
+
[c1],
|
|
109
|
+
[id, c2],
|
|
110
|
+
]);
|
|
108
111
|
});
|
|
109
112
|
|
|
110
113
|
it("places a cell in the column of its anchor, whatever config it carries", () => {
|
|
111
|
-
const { store, order,
|
|
114
|
+
const { store, order, cellIn } = setup({
|
|
112
115
|
c2: cell("c2", "y = 2", { config: { ...CONFIG, column: 1 } }),
|
|
113
116
|
});
|
|
114
117
|
|
|
@@ -124,21 +127,23 @@ describe("createCellAtom", () => {
|
|
|
124
127
|
hide_code: true,
|
|
125
128
|
column: null,
|
|
126
129
|
});
|
|
127
|
-
expect(
|
|
130
|
+
expect(store.get(layoutAtom).columns[1].ids).toEqual([c2, id]);
|
|
128
131
|
});
|
|
129
132
|
|
|
130
|
-
it("
|
|
131
|
-
const { store,
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
it("fills an emptied column, which keeps its id", () => {
|
|
134
|
+
const { store, columns, columnIds, cellIn } = setup({
|
|
135
|
+
c3: cell("c3", "z = 3", { config: { ...CONFIG, column: 1 } }),
|
|
136
|
+
});
|
|
137
|
+
const [first, second] = columnIds();
|
|
138
|
+
// Moving its only cell out leaves the column on the page, to add to.
|
|
139
|
+
store.set(moveCellAtom, { cellId: c3, direction: "left" });
|
|
140
|
+
expect(columns()).toEqual([[c3, c1, c2], []]);
|
|
137
141
|
|
|
138
|
-
const id = store.set(createCellAtom, { endOf:
|
|
142
|
+
const id = store.set(createCellAtom, { endOf: second });
|
|
139
143
|
|
|
140
144
|
expect(cellIn(id as string)?.config.column).toBe(1);
|
|
141
|
-
expect(
|
|
145
|
+
expect(columns()).toEqual([[c3, c1, c2], [id]]);
|
|
146
|
+
expect(columnIds()).toEqual([first, second]);
|
|
142
147
|
});
|
|
143
148
|
|
|
144
149
|
it("creates nothing when a cell already has the code", () => {
|
|
@@ -161,6 +166,40 @@ describe("createCellAtom", () => {
|
|
|
161
166
|
});
|
|
162
167
|
});
|
|
163
168
|
|
|
169
|
+
describe("splitCellAtom", () => {
|
|
170
|
+
it("splits a cell at the cursor and undoes it", () => {
|
|
171
|
+
const { store, order, notebook, cellIn, mountEditor } = setup({
|
|
172
|
+
c1: cell("c1", "line1\nline2"),
|
|
173
|
+
});
|
|
174
|
+
const view = mountEditor(c1);
|
|
175
|
+
view.dispatch({ selection: { anchor: 5 } });
|
|
176
|
+
|
|
177
|
+
const id = store.set(splitCellAtom, { cellId: c1 }) as CellId;
|
|
178
|
+
|
|
179
|
+
expect(order()).toEqual([c1, id, c2]);
|
|
180
|
+
expect(cellIn(c1)?.code).toBe("line1");
|
|
181
|
+
expect(cellIn(id)?.code).toBe("line2");
|
|
182
|
+
expect(view.state.doc.toString()).toBe("line1");
|
|
183
|
+
expect(notebook().scrollKey).toBe(id);
|
|
184
|
+
|
|
185
|
+
store.set(undoSplitCellAtom, {
|
|
186
|
+
cellId: c1,
|
|
187
|
+
newCellId: id,
|
|
188
|
+
snapshot: "line1\nline2",
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
expect(order()).toEqual([c1, c2]);
|
|
192
|
+
expect(cellIn(c1)?.code).toBe("line1\nline2");
|
|
193
|
+
expect(view.state.doc.toString()).toBe("line1\nline2");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("does nothing for a cell without an editor", () => {
|
|
197
|
+
const { store, order } = setup();
|
|
198
|
+
expect(store.set(splitCellAtom, { cellId: c1 })).toBeNull();
|
|
199
|
+
expect(order()).toEqual([c1, c2]);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
|
|
164
203
|
describe("moveToNextCellAtom", () => {
|
|
165
204
|
it("focuses the neighbouring cell within the column", () => {
|
|
166
205
|
const { store, order } = setup();
|
|
@@ -218,14 +257,14 @@ describe("addSetupCellAtom", () => {
|
|
|
218
257
|
});
|
|
219
258
|
|
|
220
259
|
it("places the setup cell in an empty first column", () => {
|
|
221
|
-
const { store, notebook, cellIn } = setup({
|
|
260
|
+
const { store, columns, notebook, cellIn } = setup({
|
|
222
261
|
c1: cell(c1, "x = 1", { config: { ...CONFIG, column: 1 } }),
|
|
223
262
|
});
|
|
224
|
-
expect(
|
|
263
|
+
expect(columns()[0]).toEqual([]);
|
|
225
264
|
|
|
226
265
|
store.set(addSetupCellAtom, { code: "import marimo as mo" });
|
|
227
266
|
|
|
228
|
-
expect(
|
|
267
|
+
expect(columns()[0]).toEqual([SETUP_CELL_ID]);
|
|
229
268
|
expect(cellIn(SETUP_CELL_ID)?.config.column).toBe(0);
|
|
230
269
|
expect(notebook().scrollKey).toBe(SETUP_CELL_ID);
|
|
231
270
|
});
|
|
@@ -297,16 +336,16 @@ describe("deleteCellsAtom", () => {
|
|
|
297
336
|
});
|
|
298
337
|
|
|
299
338
|
it("names the column of a cell that followed a deleted column start", () => {
|
|
300
|
-
const { store,
|
|
339
|
+
const { store, cellIn } = setup({
|
|
301
340
|
c2: cell("c2", "y = 2", { config: { ...CONFIG, column: 1 } }),
|
|
302
341
|
c3: cell("c3", "z = 3"),
|
|
303
342
|
});
|
|
304
|
-
expect(
|
|
343
|
+
expect(store.get(layoutAtom).columns[1].ids).toEqual([c2, c3]);
|
|
305
344
|
|
|
306
345
|
store.set(deleteCellsAtom, { cellIds: [c2] });
|
|
307
346
|
|
|
308
347
|
expect(cellIn(c3)?.config.column).toBe(1);
|
|
309
|
-
expect(
|
|
348
|
+
expect(store.get(layoutAtom).columns[1].ids).toEqual([c3]);
|
|
310
349
|
});
|
|
311
350
|
|
|
312
351
|
it("forgets a deleted cell's editor-only state and its atoms", () => {
|
|
@@ -386,14 +425,14 @@ describe("undoDeleteCellAtom", () => {
|
|
|
386
425
|
const { store, order, notebook } = setup({
|
|
387
426
|
c3: cell("c3", "z = 3"),
|
|
388
427
|
});
|
|
389
|
-
const column =
|
|
428
|
+
const column = store.get(layoutAtom).columns[0];
|
|
390
429
|
store.set(moveCellsRelativeToAtom, {
|
|
391
430
|
cellIds: [c1, c2],
|
|
392
431
|
targetCellId: c3,
|
|
393
432
|
position: "after",
|
|
394
433
|
previousPlacements: [
|
|
395
|
-
{ columnId: column.id, index: 0
|
|
396
|
-
{ columnId: column.id, index: 1
|
|
434
|
+
{ columnId: column.id, index: 0 },
|
|
435
|
+
{ columnId: column.id, index: 1 },
|
|
397
436
|
],
|
|
398
437
|
});
|
|
399
438
|
expect(order()).toEqual([c3, c1, c2]);
|