@marimo-team/islands 0.25.3-dev312 → 0.25.3-dev316

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.
Files changed (53) hide show
  1. package/dist/{ErrorBoundary-CCrWQ8Zi.js → ErrorBoundary-C3G05Nb1.js} +1 -1
  2. package/dist/{chat-ui-DkuxGEDp.js → chat-ui-DASKYW38.js} +13 -13
  3. package/dist/{code-visibility-DLBADpvq.js → code-visibility-B3_gXvem.js} +31 -32
  4. package/dist/{common-Cc-bvilP.js → common-Vd6TgXHQ.js} +5074 -5074
  5. package/dist/{config-BVYA1P0C.js → config-CL7mwGLX.js} +87 -129
  6. package/dist/{data-grid-overlay-editor-CAEih52I.js → data-grid-overlay-editor-DLEPVcX1.js} +1 -1
  7. package/dist/{error-entries-istW7Xbs.js → error-entries-kb4H6PAT.js} +533 -508
  8. package/dist/feedback-button-gqE30Uez.js +370 -0
  9. package/dist/{formats-CMa7L3E8.js → formats-qhBmYb0l.js} +1 -1
  10. package/dist/{glide-data-editor-hsf5AOwE.js → glide-data-editor-BmtEcZoo.js} +3 -3
  11. package/dist/{globals-Blgj9EWO.js → globals-BIt_qRYC.js} +1 -1
  12. package/dist/{html-to-image-pPbR2cDx.js → html-to-image-DR8VPB7E.js} +4018 -4021
  13. package/dist/main.js +606 -607
  14. package/dist/{number-overlay-editor-BgNsDtQP.js → number-overlay-editor-Bbxt9i1c.js} +1 -1
  15. package/dist/{process-output-BySO1nIs.js → process-output-BDMtqL6K.js} +2 -2
  16. package/dist/{reveal-component-MUD9gGln.js → reveal-component-DXFsIk5S.js} +4 -4
  17. package/dist/static-state-Dtocd9UO.js +68 -0
  18. package/dist/{vega-component-Bly2lDhz.js → vega-component-CeN8zClP.js} +9 -9
  19. package/package.json +1 -1
  20. package/src/__tests__/mount.test.ts +17 -58
  21. package/src/components/editor/actions/useRestartKernel.tsx +0 -5
  22. package/src/components/editor/cell/__tests__/useRunCells.test.tsx +0 -3
  23. package/src/components/editor/cell/useRunCells.ts +2 -2
  24. package/src/components/editor/chrome/wrapper/footer-items/backend-status.tsx +2 -16
  25. package/src/components/editor/renderers/cell-array.tsx +0 -3
  26. package/src/core/edit-app.tsx +2 -7
  27. package/src/core/executions/__tests__/run.test.ts +0 -3
  28. package/src/core/executions/index.ts +1 -1
  29. package/src/core/executions/run.ts +1 -14
  30. package/src/core/islands/bootstrap.ts +0 -1
  31. package/src/core/network/__tests__/requests-network.test.ts +0 -16
  32. package/src/core/network/connection.ts +0 -5
  33. package/src/core/network/requests-toasting.tsx +1 -49
  34. package/src/core/network/resolve.ts +1 -5
  35. package/src/core/notebook/replica/__tests__/replica.test.ts +3 -3
  36. package/src/core/notebook/replica/connection.ts +1 -5
  37. package/src/core/runtime/__tests__/createWsUrl.test.ts +4 -16
  38. package/src/core/runtime/__tests__/runtime.test.ts +58 -168
  39. package/src/core/runtime/adapter.ts +1 -8
  40. package/src/core/runtime/config.ts +4 -59
  41. package/src/core/runtime/runtime.ts +1 -31
  42. package/src/core/runtime/types.ts +0 -5
  43. package/src/core/session/__tests__/useNotebookReplica.hook.test.tsx +5 -5
  44. package/src/core/session/__tests__/useNotebookSession.hook.test.tsx +125 -29
  45. package/src/core/session/connection-utils.ts +2 -14
  46. package/src/core/session/useNotebookSession.tsx +19 -12
  47. package/src/mount.tsx +3 -9
  48. package/src/utils/errors.ts +0 -7
  49. package/dist/feedback-button-BJvIOw-c.js +0 -371
  50. package/dist/toDate-5qPtZ6HL.js +0 -94
  51. package/src/components/editor/alerts/connecting-alert.tsx +0 -27
  52. package/src/core/network/__tests__/requests-lazy.test.ts +0 -322
  53. package/src/core/network/requests-lazy.ts +0 -222
@@ -1,6 +1,6 @@
1
1
  import { a as e } from "./rolldown-runtime-BPCzCO3I.js";
2
2
  import { t } from "./react-CHbZqgBF.js";
3
- import { a as n } from "./glide-data-editor-hsf5AOwE.js";
3
+ import { a as n } from "./glide-data-editor-BmtEcZoo.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",
@@ -1,6 +1,6 @@
1
- import { T as e } from "./html-to-image-pPbR2cDx.js";
1
+ import { T as e } from "./html-to-image-DR8VPB7E.js";
2
2
  import { h as t } from "./tooltip-BekOCQ3v.js";
3
- import { X as n, Y as r } from "./error-entries-istW7Xbs.js";
3
+ import { $ as n, Q as r } from "./error-entries-kb4H6PAT.js";
4
4
  import { r as i } from "./assertNever-efcK_v3t.js";
5
5
  import { n as a } from "./semaphore-8KhQouXt.js";
6
6
  var o = t("file", [["path", {
@@ -3,15 +3,15 @@ import { g as t, h as n, i as r, m as i, t as a } from "./button-BuSV-mLI.js";
3
3
  import { t as o } from "./react-CHbZqgBF.js";
4
4
  import { t as s } from "./compiler-runtime-DNezxW8I.js";
5
5
  import { h as c, t as l } from "./tooltip-BekOCQ3v.js";
6
- import { $ as u, Q as d, _n as f, an as p, bn as m, et as h, gn as g, i as _, l as v, n as y, on as b, r as x, t as S, u as C } from "./common-Cc-bvilP.js";
6
+ import { $ as u, Q as d, _n as f, an as p, bn as m, et as h, gn as g, i as _, l as v, n as y, on as b, r as x, t as S, u as C } from "./common-Vd6TgXHQ.js";
7
7
  import { M as w } from "./select-XmXyen3r.js";
8
8
  import { Y as T } from "./dropdown-menu-CAejOChE.js";
9
- import { At as E } from "./error-entries-istW7Xbs.js";
9
+ import { Nt as E } from "./error-entries-kb4H6PAT.js";
10
10
  import { t as D } from "./jsx-runtime-6ZiU38At.js";
11
11
  import { Ft as O, Rt as k, d as A, r as ee } from "./use-restore-focus-DyrKLdSB.js";
12
12
  import { t as j } from "./useEvent-xDnF2X04.js";
13
- import { p as te } from "./toDate-5qPtZ6HL.js";
14
- import { n as ne, t as re } from "./code-visibility-DLBADpvq.js";
13
+ import { o as te } from "./static-state-Dtocd9UO.js";
14
+ import { n as ne, t as re } from "./code-visibility-B3_gXvem.js";
15
15
  /* empty css */
16
16
  var M = 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",
@@ -0,0 +1,68 @@
1
+ import { t as e } from "./compiler-runtime-DNezxW8I.js";
2
+ import { Ft as t, Rt as n, d as r, m as i, yt as a } from "./use-restore-focus-DyrKLdSB.js";
3
+ import { t as o } from "./invariant-DLmrl-hA.js";
4
+ //#region src/core/wasm/utils.ts
5
+ function s() {
6
+ return typeof document < "u" && document.querySelector("marimo-wasm") !== null;
7
+ }
8
+ var c = 6048e5, l = 864e5, u = Symbol.for("constructDateFrom");
9
+ //#endregion
10
+ //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constructFrom.js
11
+ function d(e, t) {
12
+ return typeof e == "function" ? e(t) : e && typeof e == "object" && u in e ? e[u](t) : e instanceof Date ? new e.constructor(t) : new Date(t);
13
+ }
14
+ //#endregion
15
+ //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/toDate.js
16
+ function f(e, t) {
17
+ return d(t || e, e);
18
+ }
19
+ //#endregion
20
+ //#region src/utils/assertExists.ts
21
+ var p = e();
22
+ function m(e, t) {
23
+ if (e == null) throw Error(t || `Expected value but got ${e}`);
24
+ }
25
+ //#endregion
26
+ //#region src/core/mode.ts
27
+ function h() {
28
+ let e = a.get(_);
29
+ return m(e, "internal-error: initial mode not found"), o(e !== "present", "internal-error: initial mode cannot be 'present'"), e;
30
+ }
31
+ var g = n({
32
+ mode: r() ? "read" : "not-set",
33
+ cellAnchor: null
34
+ }), _ = n(void 0);
35
+ function v() {
36
+ let e = a.get(_);
37
+ return e !== "home" && e !== "gallery";
38
+ }
39
+ var y = n(!1);
40
+ function b() {
41
+ let e = (0, p.c)(1), { mode: n } = t(g), r = t(y), a;
42
+ return e[0] === Symbol.for("react.memo_cache_sentinel") ? (a = new URLSearchParams(window.location.search).get(i.kiosk), e[0] = a) : a = e[0], n !== "read" && !r && a !== "true";
43
+ }
44
+ //#endregion
45
+ //#region src/core/static/static-state.ts
46
+ function x(e) {
47
+ if (typeof e != "object" || !e || Array.isArray(e)) return !1;
48
+ for (let t of Object.values(e)) if (typeof t != "string") return !1;
49
+ return !0;
50
+ }
51
+ function S(e) {
52
+ if (typeof e != "object" || !e || Array.isArray(e)) return !1;
53
+ let t = e;
54
+ return !(!x(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
55
+ }
56
+ function C() {
57
+ let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
58
+ return S(e) ? e : void 0;
59
+ }
60
+ function w() {
61
+ return C() !== void 0;
62
+ }
63
+ function T() {
64
+ let e = C();
65
+ return o(e !== void 0, "Not a static notebook"), e.files;
66
+ }
67
+ //#endregion
68
+ export { v as a, g as c, d, l as f, _ as i, m as l, s as m, w as n, y as o, c as p, h as r, b as s, T as t, f as u };
@@ -3,14 +3,14 @@ import { g as t, h as n, m as r, s as i } from "./button-BuSV-mLI.js";
3
3
  import { t as a } from "./react-CHbZqgBF.js";
4
4
  import { t as o } from "./compiler-runtime-DNezxW8I.js";
5
5
  import { t as s } from "./tooltip-BekOCQ3v.js";
6
- import { t as c, u as l } from "./config-BVYA1P0C.js";
6
+ import { l as c, t as l } from "./config-CL7mwGLX.js";
7
7
  import { t as u } from "./jsx-runtime-6ZiU38At.js";
8
8
  import { u as d } from "./use-restore-focus-DyrKLdSB.js";
9
9
  import { n as f } from "./error-banner-DkQNU4bn.js";
10
10
  import { t as p } from "./debounce-DrhhziJv.js";
11
11
  import { t as ee } from "./objects-DCmMvZtn.js";
12
12
  import { t as te } from "./useEvent-xDnF2X04.js";
13
- import { a as ne, i as re, n as ie, t as m } from "./formats-CMa7L3E8.js";
13
+ import { a as ne, i as re, n as ie, t as m } from "./formats-qhBmYb0l.js";
14
14
  import { a as h, t as g } from "./arrays-DoQ-AILx.js";
15
15
  import { t as ae } from "./useAsyncData-DMBliR6D.js";
16
16
  import { t as _ } from "./semaphore-8KhQouXt.js";
@@ -22,7 +22,7 @@ import { t as de } from "./use-vega-container-remeasure-DFBTESqc.js";
22
22
  //#region src/plugins/impl/vega/fix-relative-url.ts
23
23
  var fe = /* @__PURE__ */ e(a(), 1), pe = o();
24
24
  function me(e) {
25
- return e.data && "url" in e.data && (e.data.url = c(e.data.url).href), e;
25
+ return e.data && "url" in e.data && (e.data.url = l(e.data.url).href), e;
26
26
  }
27
27
  //#endregion
28
28
  //#region src/plugins/impl/vega/types.ts
@@ -487,7 +487,7 @@ async function W(e) {
487
487
  }), !e.data || !("url" in e.data)) return e;
488
488
  let i;
489
489
  try {
490
- i = c(e.data.url);
490
+ i = l(e.data.url);
491
491
  } catch {
492
492
  return e;
493
493
  }
@@ -525,7 +525,7 @@ var K = (e) => {
525
525
  embedOptions: s
526
526
  }), t[5] = i, t[6] = s, t[7] = a, t[8] = u, t[9] = r, t[10] = n, t[11] = p) : p = t[11], p;
527
527
  }, q = (e) => {
528
- let a = (0, pe.c)(50), { value: o, setValue: c, chartSelection: u, fieldSelection: f, spec: ne, embedOptions: m } = e, { theme: h } = d(), g = (0, fe.useRef)(null), ae = (0, fe.useRef)(void 0), [_, se] = (0, fe.useState)(), v;
528
+ let a = (0, pe.c)(50), { value: o, setValue: l, chartSelection: u, fieldSelection: f, spec: ne, embedOptions: m } = e, { theme: h } = d(), g = (0, fe.useRef)(null), ae = (0, fe.useRef)(void 0), [_, se] = (0, fe.useState)(), v;
529
529
  bb0: {
530
530
  if (m && "actions" in m) {
531
531
  v = m.actions;
@@ -545,12 +545,12 @@ var K = (e) => {
545
545
  let C = x, w;
546
546
  a[5] === C ? w = a[6] : (w = E(C), a[5] = C, a[6] = w);
547
547
  let T = w, D;
548
- a[7] !== c || a[8] !== o ? (D = (e) => {
549
- c({
548
+ a[7] !== l || a[8] !== o ? (D = (e) => {
549
+ l({
550
550
  ...o,
551
551
  ...e
552
552
  });
553
- }, a[7] = c, a[8] = o, a[9] = D) : D = a[9];
553
+ }, a[7] = l, a[8] = o, a[9] = D) : D = a[9];
554
554
  let O = te(D), k;
555
555
  a[10] === O ? k = a[11] : (k = p((e, n) => {
556
556
  t.debug("[Vega signal]", e, n);
@@ -587,7 +587,7 @@ var K = (e) => {
587
587
  className: "text-xs flex flex-col",
588
588
  children: e.map(ve)
589
589
  }),
590
- children: /* @__PURE__ */ (0, G.jsx)(l, { className: "absolute bottom-1 right-0 m-2 h-4 w-4 cursor-help text-muted-foreground hover:text-foreground" })
590
+ children: /* @__PURE__ */ (0, G.jsx)(c, { className: "absolute bottom-1 right-0 m-2 h-4 w-4 cursor-help text-muted-foreground hover:text-foreground" })
591
591
  });
592
592
  }, a[20] = T, a[21] = R);
593
593
  let z = R, B = h === "dark" ? "dark" : void 0, V;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev312",
3
+ "version": "0.25.3-dev316",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -4,10 +4,10 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import { getSerializedLayout } from "@/core/layout/layout";
5
5
  import { initialLayoutState, layoutStateAtom } from "@/core/layout/state";
6
6
  import { kioskModeAtom } from "@/core/mode";
7
- import { connectionAtom } from "@/core/network/connection";
7
+ import { runtimeConfigAtom } from "@/core/runtime/config";
8
+ import { RuntimeManager } from "@/core/runtime/runtime";
8
9
  import { store } from "@/core/state/jotai";
9
10
  import { isStaticNotebook } from "@/core/static/static-state";
10
- import { ConnectionState } from "@/core/session/types";
11
11
  import { pairConfigAtom } from "@/core/config/pair";
12
12
  import { PAIR_CONFIG } from "./fixtures/pair-config";
13
13
  import { mount, visibleForTesting } from "../mount";
@@ -58,8 +58,7 @@ describe("mount", () => {
58
58
  vi.mocked(isStaticNotebook).mockReturnValue(false);
59
59
  store.set(layoutStateAtom, initialLayoutState());
60
60
  store.set(kioskModeAtom, false);
61
- // Reset connection atom to initial state
62
- store.set(connectionAtom, { state: ConnectionState.NOT_STARTED });
61
+ vi.spyOn(RuntimeManager.prototype, "init").mockResolvedValue(undefined);
63
62
  });
64
63
 
65
64
  afterEach(() => {
@@ -100,63 +99,23 @@ describe("mount", () => {
100
99
  expect(store.get(pairConfigAtom)).toBeUndefined();
101
100
  });
102
101
 
103
- describe("connection state initialization", () => {
104
- it("should set connection to CONNECTING when runtimeConfig has lazy=false", () => {
105
- mount(
106
- {
107
- ...baseOptions,
108
- runtimeConfig: [{ url: "http://localhost:8080", lazy: false }],
109
- },
110
- mockElement,
111
- );
112
-
113
- const connection = store.get(connectionAtom);
114
- expect(connection.state).toBe(ConnectionState.CONNECTING);
115
- });
116
-
117
- it("should keep connection as NOT_STARTED when runtimeConfig has lazy=true", () => {
118
- mount(
119
- {
120
- ...baseOptions,
121
- runtimeConfig: [{ url: "http://localhost:8080", lazy: true }],
122
- },
123
- mockElement,
124
- );
125
-
126
- const connection = store.get(connectionAtom);
127
- expect(connection.state).toBe(ConnectionState.NOT_STARTED);
128
- });
129
-
130
- it("should keep connection as NOT_STARTED when no runtimeConfig is provided", () => {
131
- mount(
132
- {
133
- ...baseOptions,
134
- runtimeConfig: [],
135
- },
136
- mockElement,
137
- );
138
-
139
- const connection = store.get(connectionAtom);
140
- expect(connection.state).toBe(ConnectionState.NOT_STARTED);
141
- });
142
-
143
- it("should keep connection as NOT_STARTED for static notebooks even with lazy=false", () => {
144
- vi.mocked(isStaticNotebook).mockReturnValue(true);
102
+ it("starts looking for the page's runtime", () => {
103
+ mountRead();
145
104
 
146
- // Reset mount state to allow another mount
147
- visibleForTesting.reset();
105
+ expect(RuntimeManager.prototype.init).toHaveBeenCalledOnce();
106
+ });
148
107
 
149
- mount(
150
- {
151
- ...baseOptions,
152
- runtimeConfig: [{ url: "http://localhost:8080", lazy: false }],
153
- },
154
- mockElement,
155
- );
108
+ it("accepts a runtime config that still carries `lazy`", () => {
109
+ const error = mount(
110
+ {
111
+ ...baseOptions,
112
+ runtimeConfig: [{ url: "http://localhost:8080", lazy: true }],
113
+ },
114
+ mockElement,
115
+ );
156
116
 
157
- const connection = store.get(connectionAtom);
158
- expect(connection.state).toBe(ConnectionState.NOT_STARTED);
159
- });
117
+ expect(error).toBeUndefined();
118
+ expect(store.get(runtimeConfigAtom).url).toBe("http://localhost:8080");
160
119
  });
161
120
 
162
121
  it("hydrates the layout embedded in the mount config", () => {
@@ -1,16 +1,12 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { useSetAtom } from "jotai";
4
3
  import { useImperativeModal } from "@/components/modal/ImperativeModal";
5
4
  import { AlertDialogDestructiveAction } from "@/components/ui/alert-dialog";
6
- import { connectionAtom } from "@/core/network/connection";
7
5
  import { useRequestClient } from "@/core/network/requests";
8
- import { ConnectionState } from "@/core/session/types";
9
6
  import { reloadSafe } from "@/utils/reload-safe";
10
7
 
11
8
  export function useRestartKernel() {
12
9
  const { openConfirm } = useImperativeModal();
13
- const setConnection = useSetAtom(connectionAtom);
14
10
  const { sendRestart } = useRequestClient();
15
11
 
16
12
  return () => {
@@ -22,7 +18,6 @@ export function useRestartKernel() {
22
18
  confirmAction: (
23
19
  <AlertDialogDestructiveAction
24
20
  onClick={async () => {
25
- setConnection({ state: ConnectionState.CLOSING });
26
21
  await sendRestart();
27
22
  reloadSafe();
28
23
  }}
@@ -27,9 +27,6 @@ const toast = vi.fn();
27
27
  vi.mock("@/components/ui/use-toast", () => ({
28
28
  toast: (...args: unknown[]) => toast(...args),
29
29
  }));
30
- vi.mock("@/core/runtime/config", () => ({
31
- startRuntimeIfLazy: async () => undefined,
32
- }));
33
30
 
34
31
  const C1 = cellId("c1");
35
32
  const C2 = cellId("c2");
@@ -13,7 +13,7 @@ import {
13
13
  cellFreshnessAtom,
14
14
  runCells,
15
15
  syncEdits,
16
- waitForRuntime,
16
+ waitForRuntimeRunning,
17
17
  } from "@/core/executions";
18
18
  import { getCurrentLanguageAdapter } from "@/core/codemirror/language/commands";
19
19
  import { activeDocumentModelAtom } from "@/core/session/active-notebook";
@@ -36,7 +36,7 @@ export function useRunStaleCells() {
36
36
  return;
37
37
  }
38
38
  try {
39
- await waitForRuntime(store);
39
+ await waitForRuntimeRunning(store);
40
40
  } catch (error) {
41
41
  if (store.get(activeDocumentModelAtom) !== model) {
42
42
  return;
@@ -6,11 +6,10 @@ import type React from "react";
6
6
  import { Spinner } from "@/components/icons/spinner";
7
7
  import { Tooltip } from "@/components/ui/tooltip";
8
8
  import { connectionAtom } from "@/core/network/connection";
9
- import { useConnectToRuntime, useRuntimeManager } from "@/core/runtime/config";
9
+ import { useRuntimeManager } from "@/core/runtime/config";
10
10
  import { store } from "@/core/state/jotai";
11
11
  import { isWasm } from "@/core/wasm/utils";
12
12
  import {
13
- isAppClosing,
14
13
  isAppConnected,
15
14
  isAppConnecting,
16
15
  isAppNotStarted,
@@ -36,7 +35,6 @@ export function getConnectionStatus(): ConnectionStatus {
36
35
  export const BackendConnectionStatus: React.FC = () => {
37
36
  const connection = useAtomValue(connectionAtom).state;
38
37
  const runtime = useRuntimeManager();
39
- const connectToRuntime = useConnectToRuntime();
40
38
  const setConnectionStatus = useSetAtom(connectionStatusAtom);
41
39
 
42
40
  const { isFetching, error, data, refetch } = useAsyncData(async () => {
@@ -103,10 +101,6 @@ export const BackendConnectionStatus: React.FC = () => {
103
101
  return <Spinner size="small" />;
104
102
  }
105
103
 
106
- if (isAppClosing(connection)) {
107
- return <Spinner className="text-destructive" size="small" />;
108
- }
109
-
110
104
  if (isAppConnected(connection)) {
111
105
  if (data?.isHealthy) {
112
106
  return <CheckCircle2Icon className="w-4 h-4 text-(--green-9)" />;
@@ -123,14 +117,6 @@ export const BackendConnectionStatus: React.FC = () => {
123
117
  return <PowerOffIcon className="w-4 h-4 text-red-500" />;
124
118
  };
125
119
 
126
- const handleClick = () => {
127
- if (isAppNotStarted(connection)) {
128
- void connectToRuntime();
129
- } else {
130
- refetch();
131
- }
132
- };
133
-
134
120
  return (
135
121
  <Tooltip
136
122
  content={
@@ -147,7 +133,7 @@ export const BackendConnectionStatus: React.FC = () => {
147
133
  >
148
134
  <button
149
135
  type="button"
150
- onClick={handleClick}
136
+ onClick={refetch}
151
137
  className="p-1 hover:bg-accent rounded flex items-center gap-1.5 text-xs text-muted-foreground"
152
138
  data-testid="backend-status"
153
139
  >
@@ -29,7 +29,6 @@ import type { AppConfig, UserConfig } from "../../../core/config/config-schema";
29
29
  import type { AppMode } from "../../../core/mode";
30
30
  import { useHotkey } from "../../../hooks/useHotkey";
31
31
  import { type Theme, useTheme } from "../../../theme/useTheme";
32
- import { NotStartedConnectionAlert } from "../alerts/connecting-alert";
33
32
  import { FloatingOutline } from "../chrome/panels/outline/floating-outline";
34
33
  import { useChromeActions } from "../chrome/state";
35
34
  import { Column } from "../columns/cell-column";
@@ -124,8 +123,6 @@ const CellArrayInternal: React.FC<CellArrayProps> = ({
124
123
  <StartupLogsAlert />
125
124
  <StdinBlockingAlert />
126
125
  <NotebookBanner width={appConfig.width} />
127
- {/* Only show if not cells, otherwise running a single cell will start the connection */}
128
- {cellIds.length === 0 && <NotStartedConnectionAlert />}
129
126
  <div
130
127
  className={cn(
131
128
  appConfig.width === "columns" &&
@@ -7,7 +7,6 @@ const TooltipProvider = Tooltip.Provider;
7
7
 
8
8
  import { useAtomValue } from "jotai";
9
9
  import { lazy, useEffect } from "react";
10
- import { NotStartedConnectionAlert } from "@/components/editor/alerts/connecting-alert";
11
10
  import { Controls } from "@/components/editor/controls/Controls";
12
11
  import { SandboxController } from "@/components/editor/chrome/panels/sandbox-controller";
13
12
  import { ConnectionNotice } from "@/components/editor/alerts/connection-notice";
@@ -196,12 +195,8 @@ export const EditApp: React.FC<EditAppProps> = ({
196
195
  canOpenPackages={!hideControls}
197
196
  />
198
197
 
199
- {/* Don't render until we have a single cell. NotStartedConnectionAlert
200
- still covers the "no remote runtime started" prompt. */}
201
- <ProgressiveBoundary
202
- requires={hasCellsAtom}
203
- fallback={<NotStartedConnectionAlert />}
204
- >
198
+ {/* Don't render until we have a single cell. */}
199
+ <ProgressiveBoundary requires={hasCellsAtom}>
205
200
  <CellsRenderer appConfig={appConfig} mode={viewState.mode}>
206
201
  {editableCellsArray}
207
202
  </CellsRenderer>
@@ -30,9 +30,6 @@ const toast = vi.fn();
30
30
  vi.mock("@/components/ui/use-toast", () => ({
31
31
  toast: (...args: unknown[]) => toast(...args),
32
32
  }));
33
- vi.mock("@/core/runtime/config", () => ({
34
- startRuntimeIfLazy: async () => undefined,
35
- }));
36
33
 
37
34
  const C1 = cellId("c1");
38
35
  const C2 = cellId("c2");
@@ -22,7 +22,7 @@ export {
22
22
  } from "./atoms";
23
23
  export type { CellFreshness, CellFreshnessLookup } from "./freshness";
24
24
  export { replyInput } from "./input";
25
- export { runCells, syncEdits, waitForRuntime } from "./run";
25
+ export { runCells, syncEdits } from "./run";
26
26
  export {
27
27
  useCellExecution,
28
28
  useCellFreshness,
@@ -6,7 +6,6 @@ import type * as Protocol from "@marimo-team/client/protocol";
6
6
  import type { createStore } from "jotai";
7
7
  import type { DocumentModel } from "@/core/notebook/document";
8
8
  import { toast } from "@/components/ui/use-toast";
9
- import { startRuntimeIfLazy } from "@/core/runtime/config";
10
9
  import { activeDocumentModelAtom } from "@/core/session/active-notebook";
11
10
  import { prettyError } from "@/utils/errors";
12
11
  import { Logger } from "@/utils/Logger";
@@ -20,18 +19,6 @@ import {
20
19
 
21
20
  type Store = ReturnType<typeof createStore>;
22
21
 
23
- /**
24
- * Start a lazy runtime and wait until the host reports it running.
25
- *
26
- * The host refuses a run while its runtime is not running, so a request
27
- * made during startup waits here instead of failing. It rejects once the
28
- * runtime cannot come up, so the request is not left waiting.
29
- */
30
- export async function waitForRuntime(store: Store): Promise<void> {
31
- await startRuntimeIfLazy();
32
- await waitForRuntimeRunning(store);
33
- }
34
-
35
22
  /**
36
23
  * Get this browser's edits to the host before a command that names cells.
37
24
  *
@@ -69,7 +56,7 @@ export async function runCells(
69
56
  // notebook, has been seen.
70
57
  let request = requestRun(store, cellIds);
71
58
  try {
72
- await waitForRuntime(store);
59
+ await waitForRuntimeRunning(store);
73
60
  request ??= requestRun(store, cellIds);
74
61
  if (request === null) {
75
62
  throw new Error("No notebook is shown");
@@ -203,7 +203,6 @@ function handleNotification(
203
203
  case "startup-logs":
204
204
  case "startup-progress":
205
205
  case "interrupted":
206
- case "reconnected":
207
206
  case "cache-cleared":
208
207
  case "cache-info":
209
208
  case "kernel-startup-error":
@@ -4,16 +4,12 @@
4
4
 
5
5
  import { beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import * as apiModule from "../api";
7
- import { visibleForTesting } from "../requests-lazy";
8
7
  import { createNetworkRequests } from "../requests-network";
9
8
 
10
- const { ACTIONS } = visibleForTesting;
11
-
12
9
  // Mock dependencies
13
10
  vi.mock("../../runtime/config", () => ({
14
11
  getRuntimeManager: vi.fn(() => ({
15
12
  sessionHeaders: vi.fn(() => ({ "X-Test-Header": "test" })),
16
- isLazy: true,
17
13
  })),
18
14
  }));
19
15
 
@@ -64,18 +60,6 @@ describe("createNetworkRequests", () => {
64
60
  );
65
61
  });
66
62
 
67
- it("all request methods have an action defined", () => {
68
- const requests = createNetworkRequests();
69
- const methodNames = Object.keys(requests);
70
-
71
- for (const methodName of methodNames) {
72
- expect(
73
- ACTIONS[methodName as keyof typeof ACTIONS],
74
- `Method ${methodName} has no action defined`,
75
- ).toBeDefined();
76
- }
77
- });
78
-
79
63
  describe("special behavior", () => {
80
64
  it("exportAsHTML should set assetUrl in dev/test mode", async () => {
81
65
  const originalEnv = process.env.NODE_ENV;
@@ -75,8 +75,3 @@ export const isClosedAtom = atom((get) => {
75
75
  const connection = get(connectionAtom);
76
76
  return connection.state === ConnectionState.CLOSED;
77
77
  });
78
-
79
- export const isNotStartedAtom = atom((get) => {
80
- const connection = get(connectionAtom);
81
- return connection.state === ConnectionState.NOT_STARTED;
82
- });
@@ -1,15 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  /* oxlint-disable typescript/no-explicit-any */
3
3
 
4
- import { useAtomValue } from "jotai";
5
- import { Spinner } from "@/components/icons/spinner";
6
- import { Button } from "@/components/ui/button";
7
4
  import { toast } from "@/components/ui/use-toast";
8
- import { HTTPError, NoKernelConnectedError, prettyError } from "@/utils/errors";
5
+ import { HTTPError, prettyError } from "@/utils/errors";
9
6
  import { Logger } from "@/utils/Logger";
10
- import { useConnectToRuntime } from "../runtime/config";
11
- import { store } from "../state/jotai";
12
- import { isConnectingAtom } from "./connection";
13
7
  import type { EditRequests, RequestKey, RunRequests } from "./types";
14
8
 
15
9
  export function createErrorToastingRequests(
@@ -95,26 +89,6 @@ export function createErrorToastingRequests(
95
89
  try {
96
90
  return await handler(...args);
97
91
  } catch (error) {
98
- // Special handling for NoKernelConnectedError error
99
- if (error instanceof NoKernelConnectedError) {
100
- // If we are connecting to a kernel, don't show the toast
101
- const isConnecting = store.get(isConnectingAtom);
102
- if (isConnecting) {
103
- return;
104
- }
105
-
106
- const toastId = toast({
107
- title: "Kernel Not Connected",
108
- description:
109
- "You need to connect to a kernel to perform this action.",
110
- variant: "default",
111
- action: <ConnectButton onConnect={() => toastId.dismiss()} />,
112
- });
113
- Logger.error(`Failed to handle request: ${key}`, error);
114
- // Rethrow the error so that the caller can handle it
115
- throw error;
116
- }
117
-
118
92
  // A capability 403: the connection is read-only for this action. The
119
93
  // live capability notification already moved the UI to viewer state,
120
94
  // so don't alarm the user with an error toast.
@@ -141,25 +115,3 @@ export function createErrorToastingRequests(
141
115
 
142
116
  return handlers;
143
117
  }
144
-
145
- export const ConnectButton: React.FC<{ onConnect: () => void }> = ({
146
- onConnect,
147
- }) => {
148
- const connectToRuntime = useConnectToRuntime();
149
- const isConnecting = useAtomValue(isConnectingAtom);
150
- return (
151
- <Button
152
- size="xs"
153
- onClick={() => {
154
- connectToRuntime();
155
- setTimeout(() => {
156
- onConnect();
157
- }, 800);
158
- }}
159
- disabled={isConnecting}
160
- >
161
- {isConnecting && <Spinner size="small" className="mr-1" />}
162
- Connect
163
- </Button>
164
- );
165
- };
@@ -1,10 +1,8 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { withPackageInvalidation } from "../packages/package-data";
3
- import { getRuntimeManager } from "../runtime/config";
4
3
  import { isStaticNotebook } from "../static/static-state";
5
4
  import { PyodideBridge } from "../wasm/bridge";
6
5
  import { isWasm } from "../wasm/utils";
7
- import { createLazyRequests } from "./requests-lazy";
8
6
  import { createNetworkRequests } from "./requests-network";
9
7
  import { createStaticRequests } from "./requests-static";
10
8
  import { createErrorToastingRequests } from "./requests-toasting";
@@ -17,9 +15,7 @@ export function resolveRequestClient(): EditRequests & RunRequests {
17
15
  } else if (isStaticNotebook()) {
18
16
  base = createStaticRequests();
19
17
  } else {
20
- base = createLazyRequests(createNetworkRequests(), () =>
21
- getRuntimeManager(),
22
- );
18
+ base = createNetworkRequests();
23
19
  }
24
20
  return withPackageInvalidation(createErrorToastingRequests(base));
25
21
  }