@marimo-team/islands 0.25.3-dev290 → 0.25.3-dev291

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 (23) hide show
  1. package/dist/{ErrorBoundary-DwcFY0Nf.js → ErrorBoundary-Df7sOY5r.js} +1 -1
  2. package/dist/{chat-ui-ByGe2rP1.js → chat-ui-CoAmcc-W.js} +3 -3
  3. package/dist/{code-visibility-DSS4dPIe.js → code-visibility-DO6O_8h-.js} +2 -2
  4. package/dist/{common-CHNDbyF2.js → common-Coz-wkOd.js} +2312 -2285
  5. package/dist/{data-grid-overlay-editor-8fOxyvQO.js → data-grid-overlay-editor-LbsctrY7.js} +1 -1
  6. package/dist/{error-entries-9U4BFHjf.js → error-entries-CQl9aZz1.js} +539 -530
  7. package/dist/{feedback-button-C7Wzdmjf.js → feedback-button-DQXS8piQ.js} +3 -3
  8. package/dist/{glide-data-editor-BA2VyhpI.js → glide-data-editor-CiTOpufo.js} +3 -3
  9. package/dist/{globals-DLzuY2gk.js → globals-Bmz_qpY8.js} +1 -1
  10. package/dist/{html-to-image-BYh_MorV.js → html-to-image-DbxMq9QA.js} +1 -1
  11. package/dist/main.js +10 -10
  12. package/dist/{number-overlay-editor-BpuvB3ho.js → number-overlay-editor-CXO_e1Yo.js} +1 -1
  13. package/dist/{process-output-bS3MGJ3f.js → process-output-BHsfwmw9.js} +2 -2
  14. package/dist/{reveal-component-BKBSU4IA.js → reveal-component-CLRZbwl1.js} +3 -3
  15. package/package.json +1 -1
  16. package/src/components/editor/output/MarimoErrorOutput.tsx +39 -3
  17. package/src/core/dom/outline.ts +4 -1
  18. package/src/core/executions/__tests__/hooks.test.tsx +46 -1
  19. package/src/core/executions/__tests__/output.test.ts +266 -0
  20. package/src/core/executions/atoms.ts +35 -0
  21. package/src/core/executions/hooks.ts +44 -5
  22. package/src/core/executions/index.ts +16 -1
  23. package/src/core/executions/output.ts +242 -0
@@ -3,14 +3,14 @@ import { h as t, t as n } from "./button-DZuNnIZO.js";
3
3
  import { t as r } from "./react-sHtZdjeP.js";
4
4
  import { t as i } from "./compiler-runtime-CldRdSsv.js";
5
5
  import { t as a } from "./copy-icon-CtllOdmg.js";
6
- import { D as o, E as s, F as c, Gt as l, L as u, i as d, j as f, n as p, q as m } from "./error-entries-9U4BFHjf.js";
7
- import { n as h, t as ee } from "./globals-DLzuY2gk.js";
6
+ import { D as o, E as s, F as c, Gt as l, L as u, i as d, j as f, n as p, q as m } from "./error-entries-CQl9aZz1.js";
7
+ import { n as h, t as ee } from "./globals-Bmz_qpY8.js";
8
8
  import { r as g } from "./assertNever-B-YzWzbL.js";
9
9
  import { t as _ } from "./jsx-runtime-3BD1kT0s.js";
10
10
  import { Ft as te, p as v, yt as ne } from "./use-restore-focus-CosX7-gx.js";
11
11
  import { a as re, i as ie, n as ae, r as oe } from "./dialog-CaYm5imE.js";
12
12
  import { t as se } from "./useAsyncData-Ci4AvJff.js";
13
- import { t as ce } from "./code-visibility-DSS4dPIe.js";
13
+ import { t as ce } from "./code-visibility-DO6O_8h-.js";
14
14
  //#region src/components/ui/skeleton.tsx
15
15
  var y = /* @__PURE__ */ e(r(), 1), b = i(), x = _(), S = (e) => {
16
16
  let n = (0, b.c)(8), r, i;
@@ -14,7 +14,7 @@ import { t as P } from "./jsx-runtime-3BD1kT0s.js";
14
14
  import { u as oe } from "./use-restore-focus-CosX7-gx.js";
15
15
  import { t as F } from "./useEvent-BRH-aCqi.js";
16
16
  import { n as I, t as se } from "./objectWithoutPropertiesLoose-BRDcTsfB.js";
17
- import { t as ce } from "./ErrorBoundary-DwcFY0Nf.js";
17
+ import { t as ce } from "./ErrorBoundary-Df7sOY5r.js";
18
18
  import { A as le, C as ue, D as de, E as fe, F as pe, I as me, L as he, M as ge, N as _e, O as L, P as ve, R as ye, S as be, T as xe, _ as Se, a as R, b as Ce, c as z, d as we, f as B, g as V, h as Te, i as Ee, j as H, k as U, l as De, m as Oe, n as ke, o as Ae, p as je, r as W, s as Me, t as Ne, u as Pe, v as Fe, w as Ie, x as Le, y as Re, z as ze } from "./data-grid-types-0PJ-9N5n.js";
19
19
  //#region ../node_modules/.pnpm/@emotion+memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js
20
20
  function Be(e) {
@@ -7068,7 +7068,7 @@ function us(e, t, n, r, i) {
7068
7068
  }
7069
7069
  //#endregion
7070
7070
  //#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/data-editor/data-editor.js
7071
- var ds = /* @__PURE__ */ e(wr(), 1), fs = /* @__PURE__ */ e(Or(), 1), ps = G.lazy(async () => await import("./data-grid-overlay-editor-8fOxyvQO.js")), ms = 0;
7071
+ var ds = /* @__PURE__ */ e(wr(), 1), fs = /* @__PURE__ */ e(Or(), 1), ps = G.lazy(async () => await import("./data-grid-overlay-editor-LbsctrY7.js")), ms = 0;
7072
7072
  function hs(e) {
7073
7073
  return (0, ds.default)((0, fs.default)((0, fs.default)(e).filter((e) => e.span !== void 0).map((e) => (0, io.default)((e.span?.[0] ?? 0) + 1, (e.span?.[1] ?? 0) + 1))));
7074
7074
  }
@@ -9299,7 +9299,7 @@ function Js(e, t, n, r, i) {
9299
9299
  }
9300
9300
  //#endregion
9301
9301
  //#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/cells/number-cell.js
9302
- var Ys = G.lazy(async () => await import("./number-overlay-editor-BpuvB3ho.js")), Xs = {
9302
+ var Ys = G.lazy(async () => await import("./number-overlay-editor-CXO_e1Yo.js")), Xs = {
9303
9303
  getAccessibilityString: (e) => e.data?.toString() ?? "",
9304
9304
  kind: W.Number,
9305
9305
  needsHover: (e) => e.hoverEffect === !0,
@@ -1,6 +1,6 @@
1
1
  import { h as e } from "./tooltip-DMMiOn2f.js";
2
2
  import { yt as t } from "./use-restore-focus-CosX7-gx.js";
3
- import { r as n } from "./code-visibility-DSS4dPIe.js";
3
+ import { r as n } from "./code-visibility-DO6O_8h-.js";
4
4
  var r = e("triangle-alert", [
5
5
  ["path", {
6
6
  d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",
@@ -9,7 +9,7 @@ import { a as ne, i as re, o as D, r as O, s as k, t as ie } from "./useLifecycl
9
9
  import { a as ae, c as oe, i as se, n as ce, o as le, r as ue, s as de, t as fe } from "./select-DsoP1qe8.js";
10
10
  import { Y as pe, mt as me, q as he } from "./dropdown-menu-Bb0bFOIk.js";
11
11
  import { c as ge, l as _e, n as ve } from "./config-C8MFHQ2E.js";
12
- import { C as A, E as j, Et as ye, G as be, I as xe, It as Se, K as M, L as N, Nt as Ce, O as we, Ot as Te, P as Ee, R as De, Rt as Oe, S as ke, T as Ae, Ut as je, _ as Me, _t as Ne, a as Pe, at as Fe, bt as Ie, dt as Le, f as Re, ft as ze, gt as Be, h as Ve, ht as He, it as Ue, k as We, mt as Ge, o as Ke, p as qe, pt as Je, rt as Ye, s as Xe, v as Ze, vt as Qe, wt as $e, x as et, xt as tt, yt as nt, zt as rt } from "./error-entries-9U4BFHjf.js";
12
+ import { C as A, E as j, Et as ye, G as be, I as xe, It as Se, K as M, L as N, Nt as Ce, O as we, Ot as Te, P as Ee, R as De, Rt as Oe, S as ke, T as Ae, Ut as je, _ as Me, _t as Ne, a as Pe, at as Fe, bt as Ie, dt as Le, f as Re, ft as ze, gt as Be, h as Ve, ht as He, it as Ue, k as We, mt as Ge, o as Ke, p as qe, pt as Je, rt as Ye, s as Xe, v as Ze, vt as Qe, wt as $e, x as et, xt as tt, yt as nt, zt as rt } from "./error-entries-CQl9aZz1.js";
13
13
  import { n as it } from "./assertNever-B-YzWzbL.js";
14
14
  import { t as at } from "./react-dom-DUmH0GXv.js";
15
15
  import { t as ot } from "./jsx-runtime-3BD1kT0s.js";
package/dist/main.js CHANGED
@@ -3,20 +3,20 @@ import { _ as a, a as o, d as s, g as c, h as l, i as u, l as d, m as f, n as p,
3
3
  import { t as y } from "./react-sHtZdjeP.js";
4
4
  import { t as b } from "./compiler-runtime-CldRdSsv.js";
5
5
  import { i as x, n as S, r as C, t as w } from "./copy-icon-CtllOdmg.js";
6
- import { B as T, Bt as E, Dt as D, E as O, F as k, Ft as A, Ht as j, I as M, It as N, L as P, Lt as F, M as I, O as L, Ot as R, P as z, Pt as B, R as ee, Rt as te, St as ne, Ut as re, X as ie, Z as ae, _ as oe, _t as se, a as ce, at as le, b as ue, bt as de, c as fe, ct as pe, dt as me, i as he, it as ge, j as _e, jt as ve, lt as ye, mt as be, n as xe, o as Se, ot as Ce, q as we, rt as Te, ut as Ee, vt as De, yt as Oe, z as ke, zt as Ae } from "./html-to-image-BYh_MorV.js";
6
+ import { B as T, Bt as E, Dt as D, E as O, F as k, Ft as A, Ht as j, I as M, It as N, L as P, Lt as F, M as I, O as L, Ot as R, P as z, Pt as B, R as ee, Rt as te, St as ne, Ut as re, X as ie, Z as ae, _ as oe, _t as se, a as ce, at as le, b as ue, bt as de, c as fe, ct as pe, dt as me, i as he, it as ge, j as _e, jt as ve, lt as ye, mt as be, n as xe, o as Se, ot as Ce, q as we, rt as Te, ut as Ee, vt as De, yt as Oe, z as ke, zt as Ae } from "./html-to-image-DbxMq9QA.js";
7
7
  import { a as je, f as Me, h as Ne, i as Pe, m as Fe, n as Ie, o as Le, r as Re, t as ze } from "./tooltip-DMMiOn2f.js";
8
8
  import { D as Be, E as Ve, O as He, S as Ue, T as We, _ as Ge, a as Ke, c as qe, d as Je, f as Ye, g as Xe, h as Ze, i as Qe, l as $e, m as et, n as tt, o as nt, p as rt, r as it, s as at, t as ot, u as st, v as ct, w as lt, x as ut, y as dt } from "./spec-BZMDxAu7.js";
9
- import { $t as ft, A as pt, At as mt, B as ht, Bt as gt, C as _t, Cn as vt, Ct as yt, D as bt, Dt as xt, E as St, En as Ct, Et as wt, F as Tt, Ft as Et, G as Dt, Gt as Ot, H as kt, Ht as At, I as jt, It as Mt, J as Nt, Jt as Pt, K as Ft, Kt as It, L as Lt, Lt as Rt, M as zt, Mt as Bt, N as Vt, Nt as Ht, O as Ut, Ot as Wt, P as Gt, Pt as Kt, Qt as qt, R as Jt, Rt as Yt, S as Xt, Sn as Zt, T as Qt, Tn as $t, Tt as en, U as tn, Ut as nn, V as rn, Vt as an, W as on, Wt as sn, X as cn, Xt as ln, Y as un, Yt as dn, Z as fn, Zt as pn, _ as mn, _t as hn, an as gn, at as _n, b as vn, bn as yn, bt as bn, c as xn, cn as Sn, ct as Cn, d as wn, dn as Tn, dt as En, en as Dn, f as On, fn as kn, ft as An, g as jn, gn as Mn, gt as Nn, h as Pn, hn as Fn, ht as In, in as Ln, it as Rn, j as zn, jt as Bn, k as Vn, kt as Hn, ln as Un, lt as Wn, m as Gn, mn as Kn, mt as qn, nn as Jn, nt as Yn, on as Xn, ot as Zn, p as Qn, pn as $n, pt as er, q as tr, qt as nr, r as rr, rn as ir, rt as ar, sn as or, st as sr, t as cr, tn as lr, tt as ur, u as dr, un as fr, ut as pr, v as mr, vn as hr, vt as gr, w as _r, wn as vr, wt as yr, x as br, xn as xr, y as Sr, yn as Cr, yt as wr, z as Tr, zt as Er } from "./common-CHNDbyF2.js";
9
+ import { $t as ft, A as pt, At as mt, B as ht, Bt as gt, C as _t, Cn as vt, Ct as yt, D as bt, Dt as xt, E as St, En as Ct, Et as wt, F as Tt, Ft as Et, G as Dt, Gt as Ot, H as kt, Ht as At, I as jt, It as Mt, J as Nt, Jt as Pt, K as Ft, Kt as It, L as Lt, Lt as Rt, M as zt, Mt as Bt, N as Vt, Nt as Ht, O as Ut, Ot as Wt, P as Gt, Pt as Kt, Qt as qt, R as Jt, Rt as Yt, S as Xt, Sn as Zt, T as Qt, Tn as $t, Tt as en, U as tn, Ut as nn, V as rn, Vt as an, W as on, Wt as sn, X as cn, Xt as ln, Y as un, Yt as dn, Z as fn, Zt as pn, _ as mn, _t as hn, an as gn, at as _n, b as vn, bn as yn, bt as bn, c as xn, cn as Sn, ct as Cn, d as wn, dn as Tn, dt as En, en as Dn, f as On, fn as kn, ft as An, g as jn, gn as Mn, gt as Nn, h as Pn, hn as Fn, ht as In, in as Ln, it as Rn, j as zn, jt as Bn, k as Vn, kt as Hn, ln as Un, lt as Wn, m as Gn, mn as Kn, mt as qn, nn as Jn, nt as Yn, on as Xn, ot as Zn, p as Qn, pn as $n, pt as er, q as tr, qt as nr, r as rr, rn as ir, rt as ar, sn as or, st as sr, t as cr, tn as lr, tt as ur, u as dr, un as fr, ut as pr, v as mr, vn as hr, vt as gr, w as _r, wn as vr, wt as yr, x as br, xn as xr, y as Sr, yn as Cr, yt as wr, z as Tr, zt as Er } from "./common-Coz-wkOd.js";
10
10
  import { a as Dr, n as Or, s as kr, t as Ar } from "./useLifecycle-SniivYmC.js";
11
11
  import { t as jr } from "./check-XFzZeH-y.js";
12
12
  import { A as Mr, C as Nr, D as Pr, M as Fr, O as Ir, a as Lr, c as Rr, d as zr, i as Br, k as Vr, l as Hr, n as Ur, o as Wr, r as Gr, s as Kr, t as qr, w as Jr, x as Yr } from "./select-DsoP1qe8.js";
13
13
  import { B as Xr, C as Zr, J as Qr, Mt as $r, Q as ei, S as ti, Sn as ni, W as ri, X as ii, Y as ai, Z as oi, _ as si, _t as ci, a as li, bn as ui, c as di, f as fi, g as pi, h as mi, i as hi, kt as gi, m as _i, n as vi, nt as yi, p as bi, pt as xi, r as Si, s as Ci, t as wi, v as Ti, w as Ei, xn as Di, y as Oi, z as ki } from "./dropdown-menu-Bb0bFOIk.js";
14
14
  import { c as Ai, i as ji, l as Mi, o as Ni, s as Pi, t as Fi } from "./config-C8MFHQ2E.js";
15
- import { A as Ii, At as Li, B as Ri, Ct as zi, E as Bi, Et as Vi, Ft as Hi, H as Ui, Ht as Wi, J as Gi, K as Ki, Lt as qi, Mt as Ji, P as Yi, Pt as Xi, Q as Zi, St as Qi, Ut as $i, V as ea, Vt as ta, X as na, Y as ra, Z as ia, _ as aa, c as oa, d as sa, dt as ca, g as la, h as ua, j as da, jt as fa, kt as pa, lt as ma, m as ha, ot as ga, p as _a, q as va, s as ya, st as ba, ut as xa, z as Sa, zt as Ca } from "./error-entries-9U4BFHjf.js";
16
- import { a as wa, c as Ta, d as Ea, f as Da, i as Oa, l as ka, n as Aa, o as ja, r as Ma, s as Na, t as Pa } from "./process-output-bS3MGJ3f.js";
15
+ import { A as Ii, At as Li, B as Ri, Ct as zi, E as Bi, Et as Vi, Ft as Hi, H as Ui, Ht as Wi, J as Gi, K as Ki, Lt as qi, Mt as Ji, P as Yi, Pt as Xi, Q as Zi, St as Qi, Ut as $i, V as ea, Vt as ta, X as na, Y as ra, Z as ia, _ as aa, c as oa, d as sa, dt as ca, g as la, h as ua, j as da, jt as fa, kt as pa, lt as ma, m as ha, ot as ga, p as _a, q as va, s as ya, st as ba, ut as xa, z as Sa, zt as Ca } from "./error-entries-CQl9aZz1.js";
16
+ import { a as wa, c as Ta, d as Ea, f as Da, i as Oa, l as ka, n as Aa, o as ja, r as Ma, s as Na, t as Pa } from "./process-output-BHsfwmw9.js";
17
17
  import { t as Fa } from "./pencil-DYUlSKxZ.js";
18
18
  import { a as Ia, c as La, d as Ra, f as za, i as Ba, l as Va, r as Ha } from "./glide-utils-BSQr4d90.js";
19
- import { n as Ua, t as Wa } from "./globals-DLzuY2gk.js";
19
+ import { n as Ua, t as Wa } from "./globals-Bmz_qpY8.js";
20
20
  import { a as Ga, i as Ka, n as qa, r as Ja, s as Ya, t as Xa } from "./assertNever-B-YzWzbL.js";
21
21
  import { t as Za } from "./react-dom-DUmH0GXv.js";
22
22
  import { t as Qa } from "./jsx-runtime-3BD1kT0s.js";
@@ -40,10 +40,10 @@ import { n as qs, t as Js } from "./esm-BDqqT86j.js";
40
40
  import { p as Ys } from "./dist-B8pkfkzc.js";
41
41
  import { t as Xs } from "./useAsyncData-Ci4AvJff.js";
42
42
  import { t as Zs } from "./semaphore-89jsoHtS.js";
43
- import { t as Qs } from "./ErrorBoundary-DwcFY0Nf.js";
43
+ import { t as Qs } from "./ErrorBoundary-Df7sOY5r.js";
44
44
  import { D as $s, O as ec } from "./vega-loader.browser-B9Pz0EGP.js";
45
45
  import { a as tc, n as nc } from "./loader-DZvtzQoD.js";
46
- import { a as rc, c as ic, i as ac, l as oc, o as sc, s as cc, t as lc } from "./code-visibility-DSS4dPIe.js";
46
+ import { a as rc, c as ic, i as ac, l as oc, o as sc, s as cc, t as lc } from "./code-visibility-DO6O_8h-.js";
47
47
  import { t as uc } from "./useDeepCompareMemoize-NaaWoFlX.js";
48
48
  import { t as dc } from "./esm-BgKjMvWw.js";
49
49
  //#region ../node_modules/.pnpm/iconify-icon@2.3.0/node_modules/iconify-icon/dist/iconify-icon.mjs
@@ -11929,7 +11929,7 @@ var xE = (e) => {
11929
11929
  output: t
11930
11930
  };
11931
11931
  } };
11932
- } }, DE = J.lazy(() => import("./chat-ui-ByGe2rP1.js").then((e) => ({ default: e.Chatbot }))), OE = H(K({
11932
+ } }, DE = J.lazy(() => import("./chat-ui-CoAmcc-W.js").then((e) => ({ default: e.Chatbot }))), OE = H(K({
11933
11933
  id: W(),
11934
11934
  role: V([
11935
11935
  "system",
@@ -12398,7 +12398,7 @@ function ED(e, t) {
12398
12398
  }
12399
12399
  //#endregion
12400
12400
  //#region src/plugins/impl/DataEditorPlugin.tsx
12401
- var DD = J.lazy(() => import("./glide-data-editor-BA2VyhpI.js").then((e) => e.t)), OD = cE("marimo-data-editor", { cssStyles: [jE, ME] }).withData(K({
12401
+ var DD = J.lazy(() => import("./glide-data-editor-CiTOpufo.js").then((e) => e.t)), OD = cE("marimo-data-editor", { cssStyles: [jE, ME] }).withData(K({
12402
12402
  initialValue: K({ edits: H(K({
12403
12403
  rowIdx: U(),
12404
12404
  columnId: W(),
@@ -32188,7 +32188,7 @@ function DH(e) {
32188
32188
  }
32189
32189
  //#endregion
32190
32190
  //#region src/components/editor/renderers/slides-layout/slides-layout.tsx
32191
- var OH = J.lazy(() => import("./reveal-component-BKBSU4IA.js")), kH = (e) => {
32191
+ var OH = J.lazy(() => import("./reveal-component-CLRZbwl1.js")), kH = (e) => {
32192
32192
  let t = (0, X.c)(33), { layout: n, setLayout: r, cells: i, mode: a } = e, o = lo(Fs), s = a === "read" || o, c = lo(Qi) > 1, [l, u] = (0, J.useState)(null), d;
32193
32193
  t[0] !== i || t[1] !== n ? (d = TR(i, n), t[0] = i, t[1] = n, t[2] = d) : d = t[2];
32194
32194
  let { slideCells: f, skippedIds: p, noOutputIds: m, slideTypes: h, startCellIndex: g } = d, _;
@@ -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-BA2VyhpI.js";
3
+ import { a as n } from "./glide-data-editor-CiTOpufo.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-BYh_MorV.js";
1
+ import { T as e } from "./html-to-image-DbxMq9QA.js";
2
2
  import { h as t } from "./tooltip-DMMiOn2f.js";
3
- import { et as n, tt as r } from "./error-entries-9U4BFHjf.js";
3
+ import { et as n, tt as r } from "./error-entries-CQl9aZz1.js";
4
4
  import { r as i } from "./assertNever-B-YzWzbL.js";
5
5
  import { n as a } from "./semaphore-89jsoHtS.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-DZuNnIZO.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 { h as c, t as l } from "./tooltip-DMMiOn2f.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-CHNDbyF2.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-Coz-wkOd.js";
7
7
  import { M as w } from "./select-DsoP1qe8.js";
8
8
  import { Y as T } from "./dropdown-menu-Bb0bFOIk.js";
9
- import { Ft as E } from "./error-entries-9U4BFHjf.js";
9
+ import { Ft as E } from "./error-entries-CQl9aZz1.js";
10
10
  import { t as D } from "./jsx-runtime-3BD1kT0s.js";
11
11
  import { Ft as O, Rt as k, d as A, r as ee } from "./use-restore-focus-CosX7-gx.js";
12
12
  import { t as j } from "./useEvent-BRH-aCqi.js";
13
13
  import { o as te } from "./static-state-D-Q-Ajaa.js";
14
- import { n as ne, t as re } from "./code-visibility-DSS4dPIe.js";
14
+ import { n as ne, t as re } from "./code-visibility-DO6O_8h-.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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev290",
3
+ "version": "0.25.3-dev291",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -28,6 +28,7 @@ import { viewStateAtom } from "@/core/mode";
28
28
  import { renderHTML } from "@/plugins/core/RenderHTML";
29
29
  import { splitMangledLocals } from "@/utils/local-variables";
30
30
  import type { MarimoError } from "../../../core/kernel/messages";
31
+ import type { CellError, HostDiagnostic } from "@/core/executions";
31
32
  import { cn } from "../../../utils/cn";
32
33
  import { Alert, AlertTitle } from "../../ui/alert";
33
34
  import { openPackageManager } from "../chrome/panels/packages-utils";
@@ -95,7 +96,7 @@ const Tip = (props: {
95
96
 
96
97
  interface Props {
97
98
  cellId: CellId | undefined;
98
- errors: MarimoError[];
99
+ errors: readonly CellError[];
99
100
  code?: string;
100
101
  className?: string;
101
102
  }
@@ -217,6 +218,13 @@ export const MarimoErrorOutput = ({
217
218
  (e): e is Extract<MarimoError, { type: "sql-error" }> =>
218
219
  e.type === "sql-error",
219
220
  );
221
+ const diagnostics = errors.filter(
222
+ (e): e is HostDiagnostic => e.type === "diagnostic",
223
+ );
224
+ // The report describes kernel errors; a host diagnostic is already prose.
225
+ const kernelErrors = errors.filter(
226
+ (e): e is MarimoError => e.type !== "diagnostic",
227
+ );
220
228
  const openScratchpad = () => {
221
229
  chromeActions.openApplication("scratchpad");
222
230
  };
@@ -278,6 +286,32 @@ export const MarimoErrorOutput = ({
278
286
  );
279
287
  }
280
288
 
289
+ if (diagnostics.length > 0) {
290
+ messages.push(
291
+ <div key="diagnostics">
292
+ {diagnostics.map((diagnostic) => (
293
+ <div key={`${diagnostic.kind}:${diagnostic.msg}`}>
294
+ <p className="text-muted-foreground font-medium">
295
+ {diagnostic.msg}
296
+ </p>
297
+ {diagnostic.related.length > 0 && (
298
+ <ul className="list-disc">
299
+ {diagnostic.related.map((cell) => (
300
+ <li
301
+ className={liStyle}
302
+ key={`${cell.cell_id}:${cell.message}`}
303
+ >
304
+ <CellLinkError cellId={cell.cell_id} /> {cell.message}
305
+ </li>
306
+ ))}
307
+ </ul>
308
+ )}
309
+ </div>
310
+ ))}
311
+ </div>,
312
+ );
313
+ }
314
+
281
315
  if (setupErrors.length > 0) {
282
316
  messages.push(
283
317
  <div key="setup-refs">
@@ -740,9 +774,11 @@ export const MarimoErrorOutput = ({
740
774
  >
741
775
  {title}
742
776
  <div className="flex flex-col gap-4">{renderMessages()}</div>
743
- {cellId && errors.length > 0 && (
777
+ {cellId && kernelErrors.length > 0 && (
744
778
  <SendErrorReportButton
745
- getContent={() => buildErrorReport(cellId, { code, errors })}
779
+ getContent={() =>
780
+ buildErrorReport(cellId, { code, errors: kernelErrors })
781
+ }
746
782
  />
747
783
  )}
748
784
  </Alert>
@@ -4,6 +4,7 @@ import { sanitizeHtml } from "@/plugins/core/sanitize-html";
4
4
  import { invariant } from "@/utils/invariant";
5
5
  import { Logger } from "@/utils/Logger";
6
6
  import type { Outline, OutlineItem } from "../cells/outline";
7
+ import type { CellOutput } from "@/core/executions/output";
7
8
  import type { OutputMessage } from "../kernel/messages";
8
9
 
9
10
  // Tags that we don't want to include in the outline
@@ -101,7 +102,9 @@ export function mergeOutlines(outlines: (Outline | null)[]): Outline {
101
102
  };
102
103
  }
103
104
 
104
- export function parseOutline(output: OutputMessage | null): Outline | null {
105
+ export function parseOutline(
106
+ output: OutputMessage | CellOutput | null,
107
+ ): Outline | null {
105
108
  if (output == null) {
106
109
  return null;
107
110
  }
@@ -11,7 +11,8 @@ import {
11
11
  document as documentOf,
12
12
  withCells,
13
13
  } from "@/core/notebook/document/__tests__/fixtures";
14
- import { useCellFreshness } from "../hooks";
14
+ import { clearCellOutputs } from "../atoms";
15
+ import { useCellFreshness, useCellOutput } from "../hooks";
15
16
 
16
17
  const C1 = cellId("c1");
17
18
  const C2 = cellId("c2");
@@ -104,3 +105,47 @@ describe("useCellFreshness", () => {
104
105
  expect(renders).toBe(before.renders);
105
106
  });
106
107
  });
108
+
109
+ describe("useCellOutput", () => {
110
+ const shown = (id: string) =>
111
+ MockExecutions.completed(id, {
112
+ code_fingerprint: `${id}-hash`,
113
+ outcome: {
114
+ kind: "value",
115
+ display: { mimetype: "text/plain", data: `${id} value` },
116
+ },
117
+ });
118
+
119
+ it("reads the result's value and hides it once cleared, until a newer result", () => {
120
+ const { store, replica, wrapper } = setup([shown(C1)]);
121
+ const { result } = renderHook(() => useCellOutput(C1), { wrapper });
122
+ expect(result.current?.data).toBe("c1 value");
123
+
124
+ act(() => {
125
+ clearCellOutputs(store, [C1]);
126
+ });
127
+ expect(result.current).toBeNull();
128
+
129
+ act(() => {
130
+ const next = MockExecutions.inputs([shown(C1)]);
131
+ store.set(replica.executionsAtom, next.executions);
132
+ store.set(replica.resultsAtom, next.results);
133
+ });
134
+ expect(result.current?.data).toBe("c1 value");
135
+ });
136
+
137
+ it("forgets what was cleared when the replica follows another notebook", () => {
138
+ const { store, replica, wrapper } = setup([shown(C1)]);
139
+ const { result } = renderHook(() => useCellOutput(C1), { wrapper });
140
+ act(() => {
141
+ clearCellOutputs(store, [C1]);
142
+ });
143
+ expect(result.current).toBeNull();
144
+
145
+ act(() => {
146
+ const notebook = store.get(replica.notebookAtom);
147
+ store.set(replica.notebookAtom, { ...notebook, id: "n2" });
148
+ });
149
+ expect(result.current?.data).toBe("c1 value");
150
+ });
151
+ });
@@ -0,0 +1,266 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import type * as Protocol from "@marimo-team/client/protocol";
4
+ import { describe, expect, it } from "vitest";
5
+ import { MockExecutions } from "@/__mocks__/executions";
6
+ import { cellId } from "@/__tests__/branded";
7
+ import {
8
+ type CellOutputInputs,
9
+ cellError,
10
+ cellOutputView,
11
+ scratchOutputView,
12
+ } from "../output";
13
+
14
+ const C1 = cellId("c1");
15
+ const C2 = cellId("c2");
16
+
17
+ const HTML: Protocol.DisplayData = { mimetype: "text/html", data: "<b>1</b>" };
18
+
19
+ function hostError(overrides: Partial<Protocol.Error>): Protocol.Error {
20
+ return {
21
+ kind: "exception",
22
+ message: "boom",
23
+ source: "marimo",
24
+ severity: "error",
25
+ range: null,
26
+ name: "ValueError",
27
+ traceback: null,
28
+ related: [],
29
+ ...overrides,
30
+ };
31
+ }
32
+
33
+ function inputs(
34
+ records: Protocol.Execution[],
35
+ cleared: CellOutputInputs["cleared"] = new Map(),
36
+ ): CellOutputInputs {
37
+ const { executions, results } = MockExecutions.inputs(records);
38
+ return { executions, results, cleared };
39
+ }
40
+
41
+ describe("cellOutputView", () => {
42
+ it("shows a value outcome's display as an output", () => {
43
+ const view = cellOutputView(
44
+ inputs([
45
+ MockExecutions.completed(C1, {
46
+ outcome: { kind: "value", display: HTML },
47
+ }),
48
+ ]),
49
+ C1,
50
+ );
51
+ expect(view).toMatchObject({
52
+ channel: "output",
53
+ mimetype: "text/html",
54
+ data: "<b>1</b>",
55
+ });
56
+ expect(view?.timestamp).toBe(Date.parse(MockExecutions.T1) / 1000);
57
+ });
58
+
59
+ it("shows nothing for a value that is empty, or a cell without a result", () => {
60
+ const state = inputs([MockExecutions.completed(C1)]);
61
+ expect(cellOutputView(state, C1)).toBeNull();
62
+ expect(cellOutputView(state, C2)).toBeNull();
63
+ });
64
+
65
+ it("shows an error outcome as the editor's error output", () => {
66
+ const view = cellOutputView(
67
+ inputs([
68
+ MockExecutions.completed(C1, {
69
+ outcome: {
70
+ kind: "error",
71
+ error: hostError({
72
+ traceback: { mimetype: "text/plain", data: "Traceback..." },
73
+ related: [{ cell_id: C2, range: null, message: "raised" }],
74
+ }),
75
+ },
76
+ }),
77
+ ]),
78
+ C1,
79
+ );
80
+ expect(view).toMatchObject({
81
+ channel: "marimo-error",
82
+ mimetype: "application/vnd.marimo+error",
83
+ data: [
84
+ {
85
+ type: "exception",
86
+ exception_type: "ValueError",
87
+ msg: "boom",
88
+ raising_cell: C2,
89
+ traceback: "Traceback...",
90
+ },
91
+ ],
92
+ });
93
+ });
94
+
95
+ it("shows an interruption and the ancestor notices as the editor does", () => {
96
+ const interrupted = cellOutputView(
97
+ inputs([MockExecutions.interrupted(C1)]),
98
+ C1,
99
+ );
100
+ expect(interrupted?.data).toEqual([{ type: "interruption" }]);
101
+
102
+ const stopped = cellOutputView(
103
+ inputs([
104
+ MockExecutions.completed(C1, {
105
+ outcome: {
106
+ kind: "skipped",
107
+ reason: "upstream-stopped",
108
+ message: "An ancestor stopped",
109
+ related: [
110
+ { cell_id: C2, range: null, message: "stopped" },
111
+ { cell_id: C1, range: null, message: "did not run" },
112
+ ],
113
+ },
114
+ }),
115
+ ]),
116
+ C1,
117
+ );
118
+ expect(stopped?.data).toEqual([
119
+ {
120
+ type: "ancestor-stopped",
121
+ msg: "An ancestor stopped",
122
+ raising_cell: C2,
123
+ },
124
+ ]);
125
+ });
126
+
127
+ it("prefers the running execution's value so far over the retained result", () => {
128
+ const previous = MockExecutions.completed(C1, {
129
+ outcome: { kind: "value", display: HTML },
130
+ });
131
+ const running = MockExecutions.running(C1);
132
+ const silent = inputs([previous, running]);
133
+ expect(cellOutputView(silent, C1)?.data).toBe("<b>1</b>");
134
+
135
+ const showing = inputs([
136
+ previous,
137
+ {
138
+ ...running,
139
+ outcome: {
140
+ kind: "value",
141
+ display: { mimetype: "text/plain", data: "so far" },
142
+ },
143
+ },
144
+ ]);
145
+ expect(cellOutputView(showing, C1)?.data).toBe("so far");
146
+
147
+ const clearedWhileRunning = inputs([
148
+ previous,
149
+ { ...running, outcome: { kind: "value", display: null } },
150
+ ]);
151
+ expect(cellOutputView(clearedWhileRunning, C1)).toBeNull();
152
+ });
153
+
154
+ it("names the failed ancestor and the cell it blamed", () => {
155
+ const C3 = cellId("c3");
156
+ const prevented = cellOutputView(
157
+ inputs([
158
+ MockExecutions.completed(C1, {
159
+ outcome: {
160
+ kind: "skipped",
161
+ reason: "upstream-failed",
162
+ message: "An ancestor failed to resolve `x`",
163
+ related: [
164
+ { cell_id: C2, range: null, message: "could not resolve" },
165
+ { cell_id: C3, range: null, message: "expected to define it" },
166
+ { cell_id: C1, range: null, message: "did not run" },
167
+ ],
168
+ },
169
+ }),
170
+ ]),
171
+ C1,
172
+ );
173
+ expect(prevented?.data).toEqual([
174
+ {
175
+ type: "ancestor-prevented",
176
+ msg: "An ancestor failed to resolve `x`",
177
+ raising_cell: C2,
178
+ blamed_cell: C3,
179
+ },
180
+ ]);
181
+ });
182
+
183
+ it("hides a cleared result until a newer one lands", () => {
184
+ const first = MockExecutions.completed(C1, {
185
+ outcome: { kind: "value", display: HTML },
186
+ });
187
+ const cleared = new Map([[C1, first.id]]);
188
+ expect(cellOutputView(inputs([first], cleared), C1)).toBeNull();
189
+
190
+ const second = MockExecutions.completed(C1, {
191
+ outcome: { kind: "value", display: HTML },
192
+ });
193
+ expect(cellOutputView(inputs([second], cleared), C1)).not.toBeNull();
194
+ });
195
+ });
196
+
197
+ describe("cellError", () => {
198
+ it("keeps a syntax error's line and an internal error's name", () => {
199
+ expect(
200
+ cellError(
201
+ hostError({
202
+ kind: "invalid-syntax",
203
+ name: null,
204
+ message: "bad",
205
+ range: {
206
+ start: { line: 2, character: 0 },
207
+ end: { line: 2, character: 0 },
208
+ },
209
+ }),
210
+ ),
211
+ ).toEqual({ type: "syntax", msg: "bad", lineno: 3 });
212
+ expect(
213
+ cellError(hostError({ kind: "internal", name: "abc", message: "oops" })),
214
+ ).toEqual({ type: "unknown", msg: "oops", error_type: "abc" });
215
+ expect(
216
+ cellError(hostError({ kind: "interrupted", name: null, message: "" })),
217
+ ).toEqual({ type: "interruption" });
218
+ });
219
+
220
+ it("shows any other kind as a diagnostic with the cells involved", () => {
221
+ expect(
222
+ cellError(
223
+ hostError({
224
+ kind: "cycle-dependencies",
225
+ name: null,
226
+ message: "This cell is in a cycle",
227
+ related: [
228
+ { cell_id: C2, range: null, message: "reads x from c1" },
229
+ { cell_id: C1, range: null, message: "reads y from c2" },
230
+ ],
231
+ }),
232
+ ),
233
+ ).toEqual({
234
+ type: "diagnostic",
235
+ kind: "cycle-dependencies",
236
+ msg: "This cell is in a cycle",
237
+ related: [
238
+ { cell_id: C2, message: "reads x from c1" },
239
+ { cell_id: C1, message: "reads y from c2" },
240
+ ],
241
+ });
242
+ });
243
+ });
244
+
245
+ describe("scratchOutputView", () => {
246
+ it("shows the latest scratch execution's outcome, or its value so far", () => {
247
+ const done = MockExecutions.completed("scratch", {
248
+ cell_id: null,
249
+ outcome: { kind: "value", display: HTML },
250
+ });
251
+ expect(scratchOutputView(inputs([done]).executions)?.data).toBe("<b>1</b>");
252
+
253
+ const running = {
254
+ ...MockExecutions.running("scratch"),
255
+ cell_id: null,
256
+ started_at: MockExecutions.T1,
257
+ outcome: {
258
+ kind: "value" as const,
259
+ display: { mimetype: "text/plain", data: "so far" },
260
+ },
261
+ };
262
+ expect(scratchOutputView(inputs([done, running]).executions)?.data).toBe(
263
+ "so far",
264
+ );
265
+ });
266
+ });
@@ -13,6 +13,7 @@ import type {
13
13
  import { activeNotebookReplicaAtom } from "@/core/session/active-notebook";
14
14
  import { waitFor } from "@/core/state/jotai";
15
15
  import { type CellFreshnessInputs, freshnessOf } from "./freshness";
16
+ import type { CellOutputInputs } from "./output";
16
17
  import {
17
18
  anyRunning,
18
19
  type CellExecutionInputs,
@@ -34,6 +35,8 @@ const NO_SUBMISSIONS: ReadonlyMap<
34
35
  Protocol.ExecutionId | null
35
36
  > = new Map();
36
37
  const NO_BLOCKED: ReadonlySet<Protocol.CellId> = new Set();
38
+ const NO_CLEARED: ReadonlyMap<Protocol.CellId, Protocol.ExecutionId> =
39
+ new Map();
37
40
 
38
41
  /**
39
42
  * What the editor marks about cells of one replica's notebook.
@@ -129,6 +132,38 @@ export const cellFreshnessAtom = atom((get) =>
129
132
  freshnessOf(get(cellFreshnessInputsAtom)),
130
133
  );
131
134
 
135
+ /** Results this browser cleared, by execution id, until a newer one lands. */
136
+ const clearedOutputsAtom =
137
+ atom<Marks<ReadonlyMap<Protocol.CellId, Protocol.ExecutionId>>>(null);
138
+
139
+ /** What every cell's output derives from. Pair with `cellOutputView`. */
140
+ export const cellOutputInputsAtom = atom((get): CellOutputInputs => {
141
+ const replica = get(activeNotebookReplicaAtom);
142
+ const notebookId =
143
+ replica === null ? null : (get(replica.notebookAtom)?.id ?? null);
144
+ return {
145
+ executions: replica === null ? NO_EXECUTIONS : get(replica.executionsAtom),
146
+ results: replica === null ? NO_RESULTS : get(replica.resultsAtom),
147
+ cleared: current(get(clearedOutputsAtom), replica, notebookId, NO_CLEARED),
148
+ };
149
+ });
150
+
151
+ /** Hide what `cellIds` show now, until each has a newer result. */
152
+ export function clearCellOutputs(
153
+ store: Store,
154
+ cellIds: readonly Protocol.CellId[],
155
+ ): void {
156
+ const inputs = store.get(cellOutputInputsAtom);
157
+ const next = new Map(inputs.cleared);
158
+ for (const cellId of cellIds) {
159
+ const result = inputs.results.get(cellId);
160
+ if (result !== null && result !== undefined) {
161
+ next.set(cellId, result.id);
162
+ }
163
+ }
164
+ store.set(clearedOutputsAtom, mark(store, next));
165
+ }
166
+
132
167
  /** The runtime's status, null while the notebook has none or the stream is not ready. */
133
168
  export const runtimeStatusAtom = atom((get) => {
134
169
  const replica = get(activeNotebookReplicaAtom);