@marimo-team/islands 0.24.1-dev67 → 0.24.1-dev69
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/{chat-ui-BKe2HMeo.js → chat-ui-DM12Y9is.js} +1820 -1820
- package/dist/{common-8QNQrcue.js → common-BQcRCkCg.js} +6971 -6971
- package/dist/{html-to-image-BKk_y4-k.js → html-to-image-B7RQgQQy.js} +3849 -3849
- package/dist/main.js +469 -469
- package/dist/{process-output-BKvXi5lM.js → process-output-BCqcNNll.js} +5 -5
- package/dist/{reveal-component-B6O1FFou.js → reveal-component-DrW90oHy.js} +16 -16
- package/package.json +1 -1
- package/src/components/variables/__tests__/variables-table.test.tsx +110 -0
- package/src/components/variables/variables-table.tsx +2 -3
- package/src/core/cells/cells.ts +11 -0
- package/src/core/codemirror/go-to-definition/__tests__/utils.test.ts +48 -0
- package/src/core/codemirror/go-to-definition/utils.ts +2 -8
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as e, et as t, tt as n } from "./html-to-image-B7RQgQQy.js";
|
|
2
2
|
import { u as r } from "./dist-wdOJ5T7-.js";
|
|
3
3
|
import { b as i } from "./select-DQ9jU_B_.js";
|
|
4
4
|
import { n as a } from "./semaphore-89jsoHtS.js";
|
|
@@ -23,8 +23,8 @@ function c(e) {
|
|
|
23
23
|
for (let e = 0; e < a; e++) o[e] = i.charCodeAt(e);
|
|
24
24
|
return new Blob([o], { type: r });
|
|
25
25
|
}
|
|
26
|
-
function l({ contents:
|
|
27
|
-
return r ? c(t
|
|
26
|
+
function l({ contents: t, mimeType: n, isBase64: r }) {
|
|
27
|
+
return r ? c(e(t, n)) : new Blob([t], { type: n });
|
|
28
28
|
}
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/core/dom/events.ts
|
|
@@ -72,8 +72,8 @@ function v(e) {
|
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/components/editor/output/console/process-output.ts
|
|
75
|
-
function y(
|
|
76
|
-
return
|
|
75
|
+
function y(e) {
|
|
76
|
+
return e.mimetype.startsWith("application/vnd.marimo") || e.mimetype === "text/html" ? n(i.asString(e.data)) : t(i.asString(e.data));
|
|
77
77
|
}
|
|
78
78
|
//#endregion
|
|
79
79
|
export { d as a, h as c, s as d, o as f, m as i, c as l, _ as n, p as o, v as r, f as s, y as t, l as u };
|
|
@@ -2,9 +2,9 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
|
|
|
2
2
|
import { c as t, g as n, h as r, m as i, t as a } from "./button-DlqUC8W-.js";
|
|
3
3
|
import { t as o } from "./react-DMWcHin-.js";
|
|
4
4
|
import { t as s } from "./compiler-runtime-CAH9RLw2.js";
|
|
5
|
-
import {
|
|
5
|
+
import { it as c, wt as l } from "./html-to-image-B7RQgQQy.js";
|
|
6
6
|
import { u } from "./dist-wdOJ5T7-.js";
|
|
7
|
-
import { J as d, X as f, Y as p, in as m, l as h, n as g, rn as _, sn as v, t as y, u as b } from "./common-
|
|
7
|
+
import { J as d, X as f, Y as p, in as m, l as h, n as g, rn as _, sn as v, t as y, u as b } from "./common-BQcRCkCg.js";
|
|
8
8
|
import { R as x } from "./select-DQ9jU_B_.js";
|
|
9
9
|
import { X as S } from "./dropdown-menu-C8N-kZzD.js";
|
|
10
10
|
import { t as C } from "./jsx-runtime-CpoKNRgu.js";
|
|
@@ -6391,20 +6391,20 @@ var sa = (e) => {
|
|
|
6391
6391
|
let t = (0, A.c)(13), { cell: n } = e, r;
|
|
6392
6392
|
t[0] !== n.id || t[1] !== n.name ? (r = y(n.id, n.name), t[0] = n.id, t[1] = n.name, t[2] = r) : r = t[2];
|
|
6393
6393
|
let i = n.id, a = n.status, o = n.output, s;
|
|
6394
|
-
t[3] === n ? s = t[4] : (s =
|
|
6395
|
-
let
|
|
6396
|
-
t[5] !== n.id || t[6] !== n.output || t[7] !== n.status || t[8] !== s ? (
|
|
6394
|
+
t[3] === n ? s = t[4] : (s = c(n, !1), t[3] = n, t[4] = s);
|
|
6395
|
+
let l;
|
|
6396
|
+
t[5] !== n.id || t[6] !== n.output || t[7] !== n.status || t[8] !== s ? (l = /* @__PURE__ */ (0, q.jsx)(b, {
|
|
6397
6397
|
cellId: i,
|
|
6398
6398
|
status: a,
|
|
6399
6399
|
output: o,
|
|
6400
6400
|
stale: s
|
|
6401
|
-
}), t[5] = n.id, t[6] = n.output, t[7] = n.status, t[8] = s, t[9] =
|
|
6401
|
+
}), t[5] = n.id, t[6] = n.output, t[7] = n.status, t[8] = s, t[9] = l) : l = t[9];
|
|
6402
6402
|
let u;
|
|
6403
|
-
return t[10] !== r || t[11] !==
|
|
6403
|
+
return t[10] !== r || t[11] !== l ? (u = /* @__PURE__ */ (0, q.jsx)("div", {
|
|
6404
6404
|
className: "flex flex-col",
|
|
6405
6405
|
...r,
|
|
6406
|
-
children:
|
|
6407
|
-
}), t[10] = r, t[11] =
|
|
6406
|
+
children: l
|
|
6407
|
+
}), t[10] = r, t[11] = l, t[12] = u) : u = t[12], u;
|
|
6408
6408
|
}, ca = (e) => {
|
|
6409
6409
|
let t = (0, A.c)(24), { subslide: n, resolveShowCode: r, isEditable: i, slideConfigs: a, contentStyle: o } = e, s, c, l, u, d, f;
|
|
6410
6410
|
if (t[0] !== o || t[1] !== i || t[2] !== r || t[3] !== a || t[4] !== n) {
|
|
@@ -6453,7 +6453,7 @@ var ua = (e) => {
|
|
|
6453
6453
|
let o;
|
|
6454
6454
|
return t[3] === n ? o = t[4] : (o = /* @__PURE__ */ (0, q.jsx)(sa, { cell: n }), t[3] = n, t[4] = o), o;
|
|
6455
6455
|
}, da = (e) => {
|
|
6456
|
-
let n = (0, A.c)(147), { slideCells: o, layout: s, setLayout:
|
|
6456
|
+
let n = (0, A.c)(147), { slideCells: o, layout: s, setLayout: c, noOutputIds: u, activeIndex: y, onSlideChange: b, mode: x, configWidth: S, isEditable: C } = e, O = C !== void 0 && C, j = (0, k.useRef)(null), M = (0, k.useRef)(null), { width: te, height: N } = ea(j), P = w() != null, ne = E(l), re;
|
|
6457
6457
|
n[0] === ne ? re = n[1] : (re = ne ? [] : [Ji], n[0] = ne, n[1] = re);
|
|
6458
6458
|
let ie = re, [ae, F] = (0, k.useState)(fa), oe = g(o), se;
|
|
6459
6459
|
n[2] === oe ? se = n[3] : (se = !ee() && oe, n[2] = oe, n[3] = se);
|
|
@@ -6720,17 +6720,17 @@ var ua = (e) => {
|
|
|
6720
6720
|
disabled: P
|
|
6721
6721
|
}), n[129] = P, n[130] = ot);
|
|
6722
6722
|
let st = L?.id, ct;
|
|
6723
|
-
n[131] !== s || n[132] !==
|
|
6723
|
+
n[131] !== s || n[132] !== c || n[133] !== st ? (ct = /* @__PURE__ */ (0, q.jsx)(d, {
|
|
6724
6724
|
defaultSize: 10,
|
|
6725
6725
|
minSize: 4,
|
|
6726
6726
|
collapsible: !0,
|
|
6727
6727
|
collapsedSize: 4,
|
|
6728
6728
|
children: /* @__PURE__ */ (0, q.jsx)(fr, {
|
|
6729
6729
|
layout: s,
|
|
6730
|
-
setLayout:
|
|
6730
|
+
setLayout: c,
|
|
6731
6731
|
cellId: st
|
|
6732
6732
|
})
|
|
6733
|
-
}), n[131] = s, n[132] =
|
|
6733
|
+
}), n[131] = s, n[132] = c, n[133] = st, n[134] = ct) : ct = n[134];
|
|
6734
6734
|
let lt;
|
|
6735
6735
|
n[135] !== K || n[136] !== ot || n[137] !== ct ? (lt = /* @__PURE__ */ (0, q.jsxs)(p, {
|
|
6736
6736
|
direction: "vertical",
|
|
@@ -6743,12 +6743,12 @@ var ua = (e) => {
|
|
|
6743
6743
|
]
|
|
6744
6744
|
}), n[135] = K, n[136] = ot, n[137] = ct, n[138] = lt) : lt = n[138];
|
|
6745
6745
|
let ut;
|
|
6746
|
-
n[139] !== L || n[140] !== S || n[141] !== s || n[142] !==
|
|
6746
|
+
n[139] !== L || n[140] !== S || n[141] !== s || n[142] !== c ? (ut = /* @__PURE__ */ (0, q.jsx)(h, {
|
|
6747
6747
|
configWidth: S,
|
|
6748
6748
|
layout: s,
|
|
6749
|
-
setLayout:
|
|
6749
|
+
setLayout: c,
|
|
6750
6750
|
activeConfigCell: L
|
|
6751
|
-
}), n[139] = L, n[140] = S, n[141] = s, n[142] =
|
|
6751
|
+
}), n[139] = L, n[140] = S, n[141] = s, n[142] = c, n[143] = ut) : ut = n[143];
|
|
6752
6752
|
let dt;
|
|
6753
6753
|
return n[144] !== lt || n[145] !== ut ? (dt = /* @__PURE__ */ (0, q.jsxs)("div", {
|
|
6754
6754
|
className: "flex-1 min-w-0 flex flex-row gap-3",
|
package/package.json
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { python } from "@codemirror/lang-python";
|
|
4
|
+
import { EditorState } from "@codemirror/state";
|
|
5
|
+
import { EditorView } from "@codemirror/view";
|
|
6
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
7
|
+
import { Provider } from "jotai";
|
|
8
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
9
|
+
import { MockNotebook } from "@/__mocks__/notebook";
|
|
10
|
+
import { cellId, variableName } from "@/__tests__/branded";
|
|
11
|
+
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
12
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
13
|
+
import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
|
|
14
|
+
import { HTMLCellId } from "@/core/cells/ids";
|
|
15
|
+
import { editorMountScheduler } from "@/core/codemirror/editor-mount-scheduler";
|
|
16
|
+
import { store } from "@/core/state/jotai";
|
|
17
|
+
import type { Variables } from "@/core/variables/types";
|
|
18
|
+
import { VariableTable } from "../variables-table";
|
|
19
|
+
|
|
20
|
+
async function tick(): Promise<void> {
|
|
21
|
+
await new Promise((resolve) => requestAnimationFrame(resolve));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const views: EditorView[] = [];
|
|
25
|
+
const elements: HTMLElement[] = [];
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
for (const view of views.splice(0)) {
|
|
29
|
+
view.destroy();
|
|
30
|
+
}
|
|
31
|
+
for (const element of elements.splice(0)) {
|
|
32
|
+
element.remove();
|
|
33
|
+
}
|
|
34
|
+
store.set(notebookAtom, initialNotebookState());
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("VariableTable cell links", () => {
|
|
38
|
+
test("declared-by click builds the queued editor and highlights the variable", async () => {
|
|
39
|
+
const usageCell = cellId("usage");
|
|
40
|
+
const definingCell = cellId("defining");
|
|
41
|
+
const definingCode = "y = 1\nx = 42";
|
|
42
|
+
|
|
43
|
+
const definingView = new EditorView({
|
|
44
|
+
state: EditorState.create({
|
|
45
|
+
doc: definingCode,
|
|
46
|
+
extensions: [python()],
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
views.push(definingView);
|
|
50
|
+
|
|
51
|
+
const notebook = MockNotebook.notebookState({
|
|
52
|
+
cellData: {
|
|
53
|
+
[usageCell]: { name: "usage_cell" },
|
|
54
|
+
[definingCell]: { name: "defining_cell" },
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
// The defining cell's editor build still waits in the mount queue, the
|
|
58
|
+
// state right after a large notebook opens.
|
|
59
|
+
const handle: { current: CellHandle | null } = { current: null };
|
|
60
|
+
notebook.cellHandles[definingCell] = handle;
|
|
61
|
+
editorMountScheduler.request(definingCell, () => {
|
|
62
|
+
handle.current = {
|
|
63
|
+
editorView: definingView,
|
|
64
|
+
editorViewOrNull: definingView,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
store.set(notebookAtom, notebook);
|
|
68
|
+
|
|
69
|
+
// The link's click handler requires the target cell's element on the page.
|
|
70
|
+
const cellElement = document.createElement("div");
|
|
71
|
+
cellElement.id = HTMLCellId.create(definingCell);
|
|
72
|
+
document.body.append(cellElement);
|
|
73
|
+
elements.push(cellElement);
|
|
74
|
+
|
|
75
|
+
const variables: Variables = {
|
|
76
|
+
[variableName("x")]: {
|
|
77
|
+
dataType: "int",
|
|
78
|
+
declaredBy: [definingCell],
|
|
79
|
+
name: variableName("x"),
|
|
80
|
+
usedBy: [usageCell],
|
|
81
|
+
value: "42",
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
render(
|
|
86
|
+
<Provider store={store}>
|
|
87
|
+
<TooltipProvider>
|
|
88
|
+
<VariableTable
|
|
89
|
+
cellIds={[usageCell, definingCell]}
|
|
90
|
+
variables={variables}
|
|
91
|
+
/>
|
|
92
|
+
</TooltipProvider>
|
|
93
|
+
</Provider>,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
expect(handle.current).toBeNull();
|
|
97
|
+
|
|
98
|
+
fireEvent.click(screen.getByText("defining_cell"));
|
|
99
|
+
// First frame: the link's click callback runs and builds the queued
|
|
100
|
+
// editor synchronously.
|
|
101
|
+
await tick();
|
|
102
|
+
expect(handle.current?.editorView).toBe(definingView);
|
|
103
|
+
expect(cellElement.classList.contains("focus-outline")).toBe(true);
|
|
104
|
+
// Second frame: the jump dispatches the selection.
|
|
105
|
+
await tick();
|
|
106
|
+
expect(definingView.state.selection.main.head).toBe(
|
|
107
|
+
definingCode.indexOf("x = 42"),
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -15,7 +15,7 @@ import { SquareEqualIcon, WorkflowIcon } from "lucide-react";
|
|
|
15
15
|
import React, { memo, useMemo } from "react";
|
|
16
16
|
import { useLocale } from "react-aria";
|
|
17
17
|
import { CellLink } from "@/components/editor/links/cell-link";
|
|
18
|
-
import {
|
|
18
|
+
import { ensureCellEditorView, useCellNames } from "@/core/cells/cells";
|
|
19
19
|
import type { CellId } from "@/core/cells/ids";
|
|
20
20
|
import { isInternalCellName } from "@/core/cells/names";
|
|
21
21
|
import { goToVariableDefinition } from "@/core/codemirror/go-to-definition/commands";
|
|
@@ -135,9 +135,8 @@ const COLUMNS = [
|
|
|
135
135
|
cell: ({ getValue }) => {
|
|
136
136
|
const [declaredBy, usedBy, name] = getValue();
|
|
137
137
|
|
|
138
|
-
// Highlight the variable in the cell editor
|
|
139
138
|
const highlightInCell = (cellId: CellId) => {
|
|
140
|
-
const editorView =
|
|
139
|
+
const editorView = ensureCellEditorView(cellId);
|
|
141
140
|
if (editorView) {
|
|
142
141
|
goToVariableDefinition(editorView, name);
|
|
143
142
|
}
|
package/src/core/cells/cells.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { Objects } from "@/utils/objects";
|
|
|
19
19
|
import { extractAllTracebackInfo, type TracebackInfo } from "@/utils/traceback";
|
|
20
20
|
import { createReducerAndAtoms } from "../../utils/createReducer";
|
|
21
21
|
import { foldAllBulk, unfoldAllBulk } from "../codemirror/editing/commands";
|
|
22
|
+
import { editorMountScheduler } from "../codemirror/editor-mount-scheduler";
|
|
22
23
|
import {
|
|
23
24
|
splitEditor,
|
|
24
25
|
updateEditorCodeFromPython,
|
|
@@ -1919,6 +1920,16 @@ export const getCellEditorView = (cellId: CellId) => {
|
|
|
1919
1920
|
return cellHandles[cellId].current?.editorView;
|
|
1920
1921
|
};
|
|
1921
1922
|
|
|
1923
|
+
/**
|
|
1924
|
+
* Get the cell's editor view. When the view's build is still queued in the
|
|
1925
|
+
* progressive-mount scheduler, build it synchronously first. This lets user
|
|
1926
|
+
* actions target a cell whose editor is not mounted yet.
|
|
1927
|
+
*/
|
|
1928
|
+
export const ensureCellEditorView = (cellId: CellId) => {
|
|
1929
|
+
editorMountScheduler.promote(cellId);
|
|
1930
|
+
return getCellEditorView(cellId);
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1922
1933
|
export function flattenTopLevelNotebookCells(
|
|
1923
1934
|
state: NotebookState,
|
|
1924
1935
|
): (CellData & CellRuntimeState)[] {
|
|
@@ -5,7 +5,9 @@ import { EditorState } from "@codemirror/state";
|
|
|
5
5
|
import { EditorView, keymap } from "@codemirror/view";
|
|
6
6
|
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
7
7
|
import { cellId, variableName } from "@/__tests__/branded";
|
|
8
|
+
import type { CellHandle } from "@/components/editor/notebook-cell";
|
|
8
9
|
import { initialNotebookState, notebookAtom } from "@/core/cells/cells";
|
|
10
|
+
import { editorMountScheduler } from "@/core/codemirror/editor-mount-scheduler";
|
|
9
11
|
import { store } from "@/core/state/jotai";
|
|
10
12
|
import { variablesAtom } from "@/core/variables/state";
|
|
11
13
|
import {
|
|
@@ -184,6 +186,52 @@ print(mymodule)`;
|
|
|
184
186
|
moduleCode.indexOf("mymodule"),
|
|
185
187
|
);
|
|
186
188
|
});
|
|
189
|
+
|
|
190
|
+
test("builds the defining cell's queued editor before jumping", async () => {
|
|
191
|
+
const definingCell = cellId("queued-defining-cell");
|
|
192
|
+
const usageCell = cellId("usage-cell");
|
|
193
|
+
const definingCode = "a = 10";
|
|
194
|
+
const usageCode = "print(a)";
|
|
195
|
+
|
|
196
|
+
const definingView = createEditor(definingCode, definingCode.length);
|
|
197
|
+
const usageView = createEditor(usageCode, usageCode.indexOf("a"));
|
|
198
|
+
views.push(definingView, usageView);
|
|
199
|
+
|
|
200
|
+
// The defining cell's editor build still waits in the mount queue, the
|
|
201
|
+
// state right after a large notebook opens.
|
|
202
|
+
const handle: { current: CellHandle | null } = { current: null };
|
|
203
|
+
editorMountScheduler.request(definingCell, () => {
|
|
204
|
+
handle.current = {
|
|
205
|
+
editorView: definingView,
|
|
206
|
+
editorViewOrNull: definingView,
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const notebook = initialNotebookState();
|
|
211
|
+
notebook.cellHandles[definingCell] = handle;
|
|
212
|
+
notebook.cellHandles[usageCell] = {
|
|
213
|
+
current: { editorView: usageView, editorViewOrNull: usageView },
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
store.set(notebookAtom, notebook);
|
|
217
|
+
store.set(variablesAtom, {
|
|
218
|
+
[variableName("a")]: {
|
|
219
|
+
dataType: "int",
|
|
220
|
+
declaredBy: [definingCell],
|
|
221
|
+
name: variableName("a"),
|
|
222
|
+
usedBy: [usageCell],
|
|
223
|
+
value: "10",
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const result = goToDefinitionAtCursorPosition(usageView);
|
|
228
|
+
|
|
229
|
+
expect(result).toBe(true);
|
|
230
|
+
// The jump built the queued editor synchronously.
|
|
231
|
+
expect(handle.current?.editorView).toBe(definingView);
|
|
232
|
+
await tick();
|
|
233
|
+
expect(definingView.state.selection.main.head).toBe(0);
|
|
234
|
+
});
|
|
187
235
|
});
|
|
188
236
|
|
|
189
237
|
describe("goToDefinitionWithLspFallback", () => {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "@codemirror/view";
|
|
11
11
|
import type { CellId } from "@/core/cells/ids";
|
|
12
12
|
import { hotkeysAtom, platformAtom } from "../../config/config";
|
|
13
|
-
import {
|
|
13
|
+
import { ensureCellEditorView } from "../../cells/cells";
|
|
14
14
|
import { store } from "../../state/jotai";
|
|
15
15
|
import { variablesAtom } from "../../variables/state";
|
|
16
16
|
import type { VariableName, Variables } from "../../variables/types";
|
|
@@ -181,12 +181,6 @@ function getEditorForVariable(
|
|
|
181
181
|
return null;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
/**
|
|
185
|
-
* Go to the given line number in the editor view.
|
|
186
|
-
* @param view The editor view to go to.
|
|
187
|
-
* @param line The line number to go to.
|
|
188
|
-
*/
|
|
189
184
|
function getEditorForCell(cellId: CellId): EditorView | null {
|
|
190
|
-
|
|
191
|
-
return notebookState.cellHandles[cellId].current?.editorView ?? null;
|
|
185
|
+
return ensureCellEditorView(cellId) ?? null;
|
|
192
186
|
}
|