@marimo-team/islands 0.25.3-dev219 → 0.25.3-dev222
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-yc4t1jAs.js → ErrorBoundary-Cg9q4kUW.js} +1 -1
- package/dist/{code-visibility-DYMqimfY.js → code-visibility-Dp-DkL1e.js} +1 -1
- package/dist/{common-kJmPJm8v.js → common-DHr2MXY3.js} +1 -1
- package/dist/{data-grid-overlay-editor-17lCy6kD.js → data-grid-overlay-editor-B-OJHxuO.js} +1 -1
- package/dist/{feedback-button-CpjwNdyn.js → feedback-button-DGAcA9xH.js} +2 -2
- package/dist/{glide-data-editor-B6g8_luK.js → glide-data-editor-09FJOvJw.js} +3 -3
- package/dist/{globals-Ct291CcQ.js → globals-2eTRp9qC.js} +1 -1
- package/dist/main.js +4247 -4238
- package/dist/{number-overlay-editor-BXuHpvAb.js → number-overlay-editor-XJ1jA8Jv.js} +1 -1
- package/dist/{reveal-component-DnGXnd7R.js → reveal-component-DxdLWQiq.js} +2 -2
- package/package.json +1 -1
- package/src/core/cells/__tests__/session.test.ts +4 -4
- package/src/core/cells/session.ts +1 -1
- package/src/core/meta/__tests__/code-visibility.test.tsx +1 -1
- package/src/core/notebook/document/__tests__/fixtures.ts +1 -1
- package/src/core/notebook/document/__tests__/test-host.ts +4 -4
- package/src/core/notebook/replica/__tests__/replica.test.ts +3 -0
- package/src/core/notebook/replica/__tests__/runtime.test.ts +78 -0
- package/src/core/notebook/replica/replica.ts +21 -3
- package/src/core/notebook/replica/resources/runtime.ts +14 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
|
|
2
2
|
import { t } from "./react-sHtZdjeP.js";
|
|
3
|
-
import { a as n } from "./glide-data-editor-
|
|
3
|
+
import { a as n } from "./glide-data-editor-09FJOvJw.js";
|
|
4
4
|
//#region ../node_modules/.pnpm/@glideapps+glide-data-grid@6.0.4-alpha24_lodash@4.17.21_marked@15.0.12_react-dom@19.3.0_27cffe7f1bc30287d59ac27db3240c5b/node_modules/@glideapps/glide-data-grid/dist/esm/internal/data-grid-overlay-editor/private/number-overlay-editor-style.js
|
|
5
5
|
var r = /* @__PURE__ */ e(t()), i = /*#__PURE__*/ n("div")({
|
|
6
6
|
name: "NumberOverlayEditorStyle",
|
|
@@ -3,7 +3,7 @@ import { c as t, g as n, h as r, m as i, t as a } from "./button-B6RjDKJx.js";
|
|
|
3
3
|
import { t as o } from "./react-sHtZdjeP.js";
|
|
4
4
|
import { t as s } from "./compiler-runtime-CldRdSsv.js";
|
|
5
5
|
import { m as c, t as l } from "./tooltip-C3UnvsRe.js";
|
|
6
|
-
import { $ as u, Q as d, Z as f, an as p, i as m, l as h, ln as g, n as _, on as v, r as y, t as b, u as x } from "./common-
|
|
6
|
+
import { $ as u, Q as d, Z as f, an as p, i as m, l as h, ln as g, n as _, on as v, r as y, t as b, u as x } from "./common-DHr2MXY3.js";
|
|
7
7
|
import { M as S } from "./select-BSxlITBo.js";
|
|
8
8
|
import { Y as ee } from "./dropdown-menu-CSNdPSnS.js";
|
|
9
9
|
import { Pt as C } from "./error-entries-CRPfxMqm.js";
|
|
@@ -11,7 +11,7 @@ import { t as w } from "./jsx-runtime-3BD1kT0s.js";
|
|
|
11
11
|
import { r as T } from "./use-restore-focus-BWO0z1lo.js";
|
|
12
12
|
import { D as E, t as D, x as O } from "./utils-DXkj82sK.js";
|
|
13
13
|
import { o as k } from "./static-state-BldGd99T.js";
|
|
14
|
-
import { a as A, n as te, t as ne } from "./code-visibility-
|
|
14
|
+
import { a as A, n as te, t as ne } from "./code-visibility-Dp-DkL1e.js";
|
|
15
15
|
/* empty css */
|
|
16
16
|
var j = c("sticky-note", [["path", {
|
|
17
17
|
d: "M21 9a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 15 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2z",
|
package/package.json
CHANGED
|
@@ -434,7 +434,7 @@ describe("readExport", () => {
|
|
|
434
434
|
expand_output: false,
|
|
435
435
|
},
|
|
436
436
|
etag: `embedded:${CELL_1}`,
|
|
437
|
-
|
|
437
|
+
code_fingerprint: `embedded:${CELL_1}:code`,
|
|
438
438
|
version: 1,
|
|
439
439
|
});
|
|
440
440
|
});
|
|
@@ -501,7 +501,7 @@ describe("readExport", () => {
|
|
|
501
501
|
expand_output: false,
|
|
502
502
|
},
|
|
503
503
|
etag: `embedded:${CELL_1}`,
|
|
504
|
-
|
|
504
|
+
code_fingerprint: `embedded:${CELL_1}:code`,
|
|
505
505
|
version: 1,
|
|
506
506
|
});
|
|
507
507
|
});
|
|
@@ -540,7 +540,7 @@ describe("readExport", () => {
|
|
|
540
540
|
expand_output: false,
|
|
541
541
|
},
|
|
542
542
|
etag: `embedded:${SETUP_CELL_ID}`,
|
|
543
|
-
|
|
543
|
+
code_fingerprint: `embedded:${SETUP_CELL_ID}:code`,
|
|
544
544
|
version: 1,
|
|
545
545
|
});
|
|
546
546
|
});
|
|
@@ -588,7 +588,7 @@ describe("readExport", () => {
|
|
|
588
588
|
expand_output: false,
|
|
589
589
|
},
|
|
590
590
|
etag: `embedded:${CELL_1}`,
|
|
591
|
-
|
|
591
|
+
code_fingerprint: `embedded:${CELL_1}:code`,
|
|
592
592
|
version: 1,
|
|
593
593
|
});
|
|
594
594
|
// Null result means no output.
|
|
@@ -179,7 +179,7 @@ function cellRecord(cellId: CellId, cell: NotebookCell): Protocol.Cell {
|
|
|
179
179
|
expand_output: cell.config?.expand_output ?? false,
|
|
180
180
|
},
|
|
181
181
|
etag: `${EMBEDDED}:${cellId}`,
|
|
182
|
-
|
|
182
|
+
code_fingerprint: cell.code_hash ?? `${EMBEDDED}:${cellId}:code`,
|
|
183
183
|
version: 1,
|
|
184
184
|
};
|
|
185
185
|
}
|
|
@@ -28,17 +28,17 @@ function record(
|
|
|
28
28
|
const cell = Protocol.CellInput.parse(input);
|
|
29
29
|
const config = Protocol.CellConfigInput.parse(cell.config ?? {});
|
|
30
30
|
const code = cell.code.replace(/\r\n?/g, "\n");
|
|
31
|
-
const
|
|
31
|
+
const codeFingerprint = hash(code);
|
|
32
32
|
return {
|
|
33
33
|
id: cell.id,
|
|
34
34
|
notebook_id: notebookId,
|
|
35
35
|
name: cell.name,
|
|
36
36
|
code,
|
|
37
37
|
config,
|
|
38
|
-
|
|
38
|
+
code_fingerprint: codeFingerprint,
|
|
39
39
|
etag: hash(
|
|
40
40
|
[
|
|
41
|
-
|
|
41
|
+
codeFingerprint,
|
|
42
42
|
cell.name,
|
|
43
43
|
...[
|
|
44
44
|
config.column,
|
|
@@ -203,7 +203,7 @@ export function createTestHost(initial: Document) {
|
|
|
203
203
|
? null
|
|
204
204
|
: {
|
|
205
205
|
etag: cell.etag,
|
|
206
|
-
|
|
206
|
+
code_fingerprint: cell.code_fingerprint,
|
|
207
207
|
version: cell.version,
|
|
208
208
|
};
|
|
209
209
|
}
|
|
@@ -223,12 +223,14 @@ describe("NotebookReplica lifetime", () => {
|
|
|
223
223
|
const snapshot = fixtureMessages("notebook-events.sse");
|
|
224
224
|
snapshot.slice(0, -3).forEach(attempt.receive);
|
|
225
225
|
expect(store.get(client.documentAtom)).toBeNull();
|
|
226
|
+
expect(store.get(client.runtimeAtom)).toBeNull();
|
|
226
227
|
snapshot.slice(-3).forEach(attempt.receive);
|
|
227
228
|
expect(store.get(client.documentAtom)?.revision.order).toEqual([
|
|
228
229
|
"c1",
|
|
229
230
|
"c3",
|
|
230
231
|
"k7f2",
|
|
231
232
|
]);
|
|
233
|
+
expect(store.get(client.runtimeAtom)?.id).toBe("r1");
|
|
232
234
|
attempt.drop();
|
|
233
235
|
await backoff();
|
|
234
236
|
expect(store.get(client.documentAtom)?.revision.order).toEqual([
|
|
@@ -236,6 +238,7 @@ describe("NotebookReplica lifetime", () => {
|
|
|
236
238
|
"c3",
|
|
237
239
|
"k7f2",
|
|
238
240
|
]);
|
|
241
|
+
expect(store.get(client.runtimeAtom)).toBeNull();
|
|
239
242
|
current.abort();
|
|
240
243
|
expect(store.get(client.documentAtom)).toBeNull();
|
|
241
244
|
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { runtime } from "../resources/runtime";
|
|
5
|
+
import { createNotebookReducer } from "@marimo-team/client";
|
|
6
|
+
import { fixtureEvents } from "./fixtures";
|
|
7
|
+
|
|
8
|
+
const reducer = createNotebookReducer({ runtime });
|
|
9
|
+
const snapshot = fixtureEvents("notebook-events.sse");
|
|
10
|
+
const confirmed = () => snapshot.reduce(reducer.reduce, reducer.initial);
|
|
11
|
+
const current = (state: ReturnType<typeof confirmed>) =>
|
|
12
|
+
state.resources.runtime;
|
|
13
|
+
const time = "2026-10-01T09:30:00Z";
|
|
14
|
+
|
|
15
|
+
describe("runtime resource", () => {
|
|
16
|
+
it("keeps the latest record and clears when that runtime is removed", () => {
|
|
17
|
+
const state = confirmed();
|
|
18
|
+
const running = current(state);
|
|
19
|
+
expect(running?.id).toBe("r1");
|
|
20
|
+
expect(running?.status).toBe("running");
|
|
21
|
+
|
|
22
|
+
const terminating = reducer.reduce(state, {
|
|
23
|
+
event: "runtime",
|
|
24
|
+
id: "98",
|
|
25
|
+
data: { runtime: { ...running!, status: "terminating" } },
|
|
26
|
+
});
|
|
27
|
+
expect(current(terminating)?.status).toBe("terminating");
|
|
28
|
+
expect(current(state)?.status).toBe("running");
|
|
29
|
+
|
|
30
|
+
const other = reducer.reduce(terminating, {
|
|
31
|
+
event: "runtime.removed",
|
|
32
|
+
id: "99",
|
|
33
|
+
data: { id: "r0", time },
|
|
34
|
+
});
|
|
35
|
+
expect(current(other)).toBe(current(terminating));
|
|
36
|
+
|
|
37
|
+
const removed = reducer.reduce(other, {
|
|
38
|
+
event: "runtime.removed",
|
|
39
|
+
id: "100",
|
|
40
|
+
data: { id: "r1", time },
|
|
41
|
+
});
|
|
42
|
+
expect(current(removed)).toBeNull();
|
|
43
|
+
const repeated = reducer.reduce(removed, {
|
|
44
|
+
event: "runtime.removed",
|
|
45
|
+
id: "101",
|
|
46
|
+
data: { id: "r1", time },
|
|
47
|
+
});
|
|
48
|
+
expect(repeated.resources).toBe(removed.resources);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("follows a restart to the replacement runtime", () => {
|
|
52
|
+
const state = confirmed();
|
|
53
|
+
const removed = reducer.reduce(state, {
|
|
54
|
+
event: "runtime.removed",
|
|
55
|
+
id: "98",
|
|
56
|
+
data: { id: "r1", time },
|
|
57
|
+
});
|
|
58
|
+
const replacement = {
|
|
59
|
+
...current(state)!,
|
|
60
|
+
id: "r2",
|
|
61
|
+
status: "starting" as const,
|
|
62
|
+
message: "Starting the kernel",
|
|
63
|
+
marimo_version: null,
|
|
64
|
+
started_at: "2026-10-01T09:31:00Z",
|
|
65
|
+
};
|
|
66
|
+
const starting = reducer.reduce(removed, {
|
|
67
|
+
event: "runtime",
|
|
68
|
+
id: "99",
|
|
69
|
+
data: { runtime: replacement },
|
|
70
|
+
});
|
|
71
|
+
expect(current(starting)).toEqual(replacement);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("clears on reset", () => {
|
|
75
|
+
const reset = reducer.reduce(confirmed(), { event: "reset", data: {} });
|
|
76
|
+
expect(current(reset)).toBeNull();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
NotebookEvents,
|
|
10
10
|
StreamStopped,
|
|
11
11
|
} from "@marimo-team/client";
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
Attachment,
|
|
14
|
+
NotebookOutput,
|
|
15
|
+
Runtime,
|
|
16
|
+
} from "@marimo-team/client/protocol";
|
|
13
17
|
import { type Atom, atom, type createStore } from "jotai/vanilla";
|
|
14
18
|
import { z } from "zod";
|
|
15
19
|
import type { NotebookBackend } from "./backend";
|
|
@@ -20,9 +24,17 @@ import {
|
|
|
20
24
|
} from "./connection";
|
|
21
25
|
import { attachments } from "./resources/attachments";
|
|
22
26
|
import { type Document, document } from "./resources/document";
|
|
27
|
+
import { runtime } from "./resources/runtime";
|
|
23
28
|
|
|
24
29
|
/** The kinds the editor reads, with marimo's own notifications. */
|
|
25
|
-
const TYPES = [
|
|
30
|
+
const TYPES = [
|
|
31
|
+
"notebook",
|
|
32
|
+
"cell",
|
|
33
|
+
"document",
|
|
34
|
+
"attachment",
|
|
35
|
+
"runtime",
|
|
36
|
+
"marimo",
|
|
37
|
+
] as const;
|
|
26
38
|
|
|
27
39
|
type EditorEvent = NotebookEvent<(typeof TYPES)[number]>;
|
|
28
40
|
|
|
@@ -52,6 +64,8 @@ export interface NotebookReplica {
|
|
|
52
64
|
readonly backendAtom: Atom<NotebookBackend | null>;
|
|
53
65
|
/** Live attachments, empty until the stream is ready or while disconnected. */
|
|
54
66
|
readonly attachmentsAtom: Atom<readonly Attachment[]>;
|
|
67
|
+
/** The notebook's runtime, null while it has none or the stream is not ready. */
|
|
68
|
+
readonly runtimeAtom: Atom<Runtime | null>;
|
|
55
69
|
/**
|
|
56
70
|
* Follow a backend, replacing any current connection.
|
|
57
71
|
*
|
|
@@ -110,7 +124,7 @@ export function createNotebookReplica(
|
|
|
110
124
|
state: ConnectionState.NOT_STARTED,
|
|
111
125
|
});
|
|
112
126
|
// One atom holds the whole stream, which resource atoms derive from.
|
|
113
|
-
const reducer = createNotebookReducer({ document, attachments });
|
|
127
|
+
const reducer = createNotebookReducer({ document, attachments, runtime });
|
|
114
128
|
const streamAtom = atom(reducer.initial);
|
|
115
129
|
// A resumed stream is live, but presence waits for this connection's ready.
|
|
116
130
|
const readyAtom = atom(false);
|
|
@@ -129,6 +143,9 @@ export function createNotebookReplica(
|
|
|
129
143
|
? get(streamAtom).resources.attachments
|
|
130
144
|
: attachments.initial,
|
|
131
145
|
);
|
|
146
|
+
const runtimeAtom = atom((get) =>
|
|
147
|
+
get(presentAtom) ? get(streamAtom).resources.runtime : null,
|
|
148
|
+
);
|
|
132
149
|
const backendAtom = atom<NotebookBackend | null>(null);
|
|
133
150
|
/** The connection this replica follows. Connecting again ends it. */
|
|
134
151
|
let current: { end(): void; reconnect(): Promise<void> } | undefined;
|
|
@@ -150,6 +167,7 @@ export function createNotebookReplica(
|
|
|
150
167
|
documentAtom,
|
|
151
168
|
backendAtom,
|
|
152
169
|
attachmentsAtom,
|
|
170
|
+
runtimeAtom,
|
|
153
171
|
connect,
|
|
154
172
|
reconnect: async () => current?.reconnect(),
|
|
155
173
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { Runtime } from "@marimo-team/client/protocol";
|
|
4
|
+
import type { NotebookResource } from "@marimo-team/client";
|
|
5
|
+
|
|
6
|
+
/** The notebook's runtime record while it has one. */
|
|
7
|
+
export const runtime: NotebookResource<Runtime | null, "runtime"> = {
|
|
8
|
+
initial: null,
|
|
9
|
+
on: {
|
|
10
|
+
runtime: (_state, { data }) => data.runtime,
|
|
11
|
+
"runtime.removed": (state, { data }) =>
|
|
12
|
+
state !== null && state.id === data.id ? null : state,
|
|
13
|
+
},
|
|
14
|
+
};
|