@marimo-team/islands 0.25.3-dev218 → 0.25.3-dev221

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.
@@ -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-CuChRm49.js";
3
+ import { a as n } from "./glide-data-editor-Dnne6LfS.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-CZPoYa5d.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-CbUT6FYs.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-DI0kifrD.js";
14
+ import { a as A, n as te, t as ne } from "./code-visibility-CYzEUXNB.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev218",
3
+ "version": "0.25.3-dev221",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -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 { Attachment, NotebookOutput } from "@marimo-team/client/protocol";
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 = ["notebook", "cell", "document", "attachment", "marimo"] as const;
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
+ };