@marimo-team/islands 0.25.3-dev140 → 0.25.3-dev142

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 (27) hide show
  1. package/dist/{ErrorBoundary-CTJ1U1fx.js → ErrorBoundary-DxdeETpm.js} +1 -1
  2. package/dist/{code-visibility-C1jZfwPW.js → code-visibility-CO8abjLo.js} +1 -1
  3. package/dist/{common-CNv_7gvI.js → common-CbFJQhaI.js} +1 -1
  4. package/dist/{data-grid-overlay-editor-t0t17DPI.js → data-grid-overlay-editor-DBjVUS2K.js} +1 -1
  5. package/dist/{feedback-button-JzaiyZZm.js → feedback-button-CWQoIUKQ.js} +2 -2
  6. package/dist/{glide-data-editor-B3eq-1SC.js → glide-data-editor-BxT8eGip.js} +3 -3
  7. package/dist/{globals-BW8TOLYQ.js → globals-f0UxWZkr.js} +1 -1
  8. package/dist/main.js +9 -8
  9. package/dist/{number-overlay-editor-DoUnDbPE.js → number-overlay-editor-Dso2H7DV.js} +1 -1
  10. package/dist/{reveal-component-ClNn1CDl.js → reveal-component-DMglhlng.js} +2 -2
  11. package/package.json +1 -1
  12. package/src/core/host/__tests__/fixtures.ts +9 -1
  13. package/src/core/host/__tests__/static.test.ts +18 -12
  14. package/src/core/host/__tests__/wasm.test.ts +63 -60
  15. package/src/core/host/backend.ts +1 -1
  16. package/src/core/host/static.ts +10 -5
  17. package/src/core/host/wasm.ts +2 -12
  18. package/src/core/saving/save-component.tsx +12 -3
  19. package/src/core/wasm/__tests__/bridge.test.ts +177 -55
  20. package/src/core/wasm/__tests__/worker.test.ts +6 -1
  21. package/src/core/wasm/bridge.ts +48 -38
  22. package/src/core/wasm/rpc.ts +15 -2
  23. package/src/core/wasm/worker/save-worker.ts +9 -10
  24. package/src/core/wasm/worker/types.ts +6 -4
  25. package/src/core/wasm/worker/worker.ts +29 -17
  26. package/src/core/websocket/__tests__/backend.test.ts +10 -3
  27. package/src/core/websocket/backend.ts +9 -10
@@ -135,7 +135,7 @@ function F(e) {
135
135
  }
136
136
  //#endregion
137
137
  //#region src/components/editor/boundary/ErrorBoundary.tsx
138
- var I = (0, T.lazy)(() => import("./feedback-button-JzaiyZZm.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
138
+ var I = (0, T.lazy)(() => import("./feedback-button-CWQoIUKQ.js").then((e) => ({ default: e.FeedbackModal }))), L = (e) => {
139
139
  let t = (0, w.c)(2), n;
140
140
  return t[0] === e.children ? n = t[1] : (n = /* @__PURE__ */ (0, j.jsx)(O, {
141
141
  FallbackComponent: R,
@@ -18,7 +18,7 @@ function x() {
18
18
  return e.warn("Failed to get version from mount config"), null;
19
19
  }
20
20
  }
21
- var S = x() || "0.25.3-dev140", C = u(S), w = u(!0);
21
+ var S = x() || "0.25.3-dev142", C = u(S), w = u(!0);
22
22
  u(null);
23
23
  //#endregion
24
24
  //#region src/core/wasm/state.ts
@@ -12,7 +12,7 @@ import { t as ut } from "./check-SpOMoCLP.js";
12
12
  import { A as dt, C as ft, D as pt, M as mt, S as ht, _ as gt, b as _t, c as vt, d as yt, g as bt, h as xt, i as St, l as Ct, m as wt, n as Tt, p as Et, s as Dt, t as Ot, u as kt, v as At, y as jt } from "./select-CkF_GBxO.js";
13
13
  import { $ as Mt, $t as Nt, A as Pt, At as Ft, B as It, Bt as Lt, C as Rt, Ct as zt, D as Bt, Dt as Vt, E as Ht, Et as Ut, F as Wt, Ft as Gt, G as Kt, Gt as qt, H as Jt, Ht as Yt, I as Xt, It as Zt, Jt as Qt, K as $t, Kt as en, L as tn, Lt as nn, M as rn, Mt as an, N as on, Nt as sn, O as cn, Ot as ln, P as un, Pt as dn, Q as fn, Qt as pn, R as mn, Rt as hn, S as gn, St as _n, T as vn, Tt as yn, U as bn, Ut as xn, V as Sn, Vt as Cn, W as wn, Wt as Tn, X as En, Xt as Dn, Y as On, Yt as kn, Z as An, Zt as jn, _ as Mn, _n as Nn, _t as Pn, a as Fn, an as In, at as Ln, b as Rn, bn as zn, bt as Bn, ct as Vn, d as Hn, dt as Un, en as Wn, et as Gn, f as Kn, fn as qn, gn as Jn, gt as Yn, h as Xn, hn as Zn, ht as Qn, i as $n, in as er, it as tr, j as nr, jt as rr, k as ir, kt as ar, l as or, ln as sr, lt as cr, mn as lr, mt as ur, n as dr, nn as fr, nt as pr, o as mr, on as hr, ot as gr, pn as _r, pt as vr, qt as yr, rt as br, s as xr, sn as Sr, st as Cr, t as wr, tn as Tr, tt as Er, u as Dr, un as Or, ut as kr, vn as Ar, vt as jr, wt as Mr, x as Nr, xt as Pr, yn as Fr, yt as Ir, z as Lr, zt as Rr } from "./dropdown-menu-GWcGCcxE.js";
14
14
  import { a as zr, c as Br, d as Vr, i as Hr, l as Ur, n as Wr, o as Gr, r as Kr, t as qr, v as Jr, x as Yr, y as Xr } from "./toDate-DGvRHwTk.js";
15
- import { n as Zr, t as Qr } from "./ErrorBoundary-CTJ1U1fx.js";
15
+ import { n as Zr, t as Qr } from "./ErrorBoundary-DxdeETpm.js";
16
16
  import { t as $r } from "./clsx-CoeGtWvn.js";
17
17
  import { t as ei } from "./react-dom-DUmH0GXv.js";
18
18
  import { t as ti } from "./jsx-runtime-3BD1kT0s.js";
@@ -2,7 +2,7 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
2
2
  import { t } from "./react-sHtZdjeP.js";
3
3
  import { t as n } from "./react-dom-DUmH0GXv.js";
4
4
  import { c as r, l as i, u as a } from "./data-grid-types-0PJ-9N5n.js";
5
- import { a as o, i as s, n as c, r as l } from "./glide-data-editor-B3eq-1SC.js";
5
+ import { a as o, i as s, n as c, r as l } from "./glide-data-editor-BxT8eGip.js";
6
6
  //#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/data-grid-overlay-editor-style.js
7
7
  var u = /* @__PURE__ */ e(t(), 1), d = /* @__PURE__ */ e(n(), 1), f = /*#__PURE__*/ o("div")({
8
8
  name: "DataGridOverlayEditorStyle",
@@ -5,12 +5,12 @@ import { t as i } from "./compiler-runtime-CldRdSsv.js";
5
5
  import { t as a } from "./copy-icon-C1trdvVt.js";
6
6
  import { H as o, K as s, Lt as c, Ot as l, fn as u, h as d, i as f, n as p, q as m, zt as h } from "./error-entries-CmFDQ9CA.js";
7
7
  import { b as g } from "./select-CkF_GBxO.js";
8
- import { n as ee, t as te } from "./globals-BW8TOLYQ.js";
8
+ import { n as ee, t as te } from "./globals-f0UxWZkr.js";
9
9
  import { t as _ } from "./jsx-runtime-3BD1kT0s.js";
10
10
  import { C as v, _ as ne, i as y } from "./useTheme-Bq9pi_vz.js";
11
11
  import { a as re, i as ie, n as ae, r as oe } from "./dialog-DgeqyrEZ.js";
12
12
  import { t as se } from "./useAsyncData-BmVgnMP5.js";
13
- import { t as ce } from "./code-visibility-C1jZfwPW.js";
13
+ import { t as ce } from "./code-visibility-CO8abjLo.js";
14
14
  //#region src/components/ui/skeleton.tsx
15
15
  var b = /* @__PURE__ */ e(r(), 1), x = i(), S = _(), le = (e) => {
16
16
  let n = (0, x.c)(8), r, i;
@@ -6,7 +6,7 @@ import { i as s, n as c, r as l } from "./copy-icon-C1trdvVt.js";
6
6
  import { C as u, c as d, i as f, n as p, s as m, t as h, x as g } from "./select-CkF_GBxO.js";
7
7
  import { d as _, h as v, i as y, l as b, n as x, o as S, s as C, t as w, u as T } from "./dropdown-menu-GWcGCcxE.js";
8
8
  import { c as E, d as D, l as O, n as k, o as A, s as ee, t as j, u as te } from "./glide-utils-Dz_F4pAY.js";
9
- import { n as ne, t as re } from "./ErrorBoundary-CTJ1U1fx.js";
9
+ import { n as ne, t as re } from "./ErrorBoundary-DxdeETpm.js";
10
10
  import { t as ie } from "./react-dom-DUmH0GXv.js";
11
11
  import { t as M } from "./jsx-runtime-3BD1kT0s.js";
12
12
  import { t as N } from "./label-D9_-zSg-.js";
@@ -7062,7 +7062,7 @@ function rs(e, t, n, r, i) {
7062
7062
  }
7063
7063
  //#endregion
7064
7064
  //#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
7065
- var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-t0t17DPI.js")), ss = 0;
7065
+ var is = /* @__PURE__ */ e(_r(), 1), as = /* @__PURE__ */ e(xr(), 1), os = K.lazy(async () => await import("./data-grid-overlay-editor-DBjVUS2K.js")), ss = 0;
7066
7066
  function cs(e) {
7067
7067
  return (0, is.default)((0, as.default)((0, as.default)(e).filter((e) => e.span !== void 0).map((e) => (0, Za.default)((e.span?.[0] ?? 0) + 1, (e.span?.[1] ?? 0) + 1))));
7068
7068
  }
@@ -9293,7 +9293,7 @@ function Vs(e, t, n, r, i) {
9293
9293
  }
9294
9294
  //#endregion
9295
9295
  //#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
9296
- var Hs = K.lazy(async () => await import("./number-overlay-editor-DoUnDbPE.js")), Us = {
9296
+ var Hs = K.lazy(async () => await import("./number-overlay-editor-Dso2H7DV.js")), Us = {
9297
9297
  getAccessibilityString: (e) => e.data?.toString() ?? "",
9298
9298
  kind: W.Number,
9299
9299
  needsHover: (e) => e.hoverEffect === !0,
@@ -1,6 +1,6 @@
1
1
  import { m as e } from "./tooltip-CJ4Rqasp.js";
2
2
  import { _ as t } from "./useTheme-Bq9pi_vz.js";
3
- import { r as n } from "./code-visibility-C1jZfwPW.js";
3
+ import { r as n } from "./code-visibility-CO8abjLo.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",
package/dist/main.js CHANGED
@@ -7,7 +7,7 @@ import { C as T, F as E, G as D, I as O, J as k, K as A, L as j, P as M, R as N,
7
7
  import { a as oe, d as se, i as ce, m as le, n as ue, o as de, p as fe, r as pe, t as me } from "./tooltip-CJ4Rqasp.js";
8
8
  import { $ as he, A as ge, At as _e, B as ve, Bt as ye, D as be, Dt as xe, G as Se, H as Ce, Ht as we, It as Te, J as Ee, Jt as De, Kt as Oe, M as ke, Mt as Ae, N as je, Nt as Me, O as Ne, Ot as Pe, P as Fe, Q as Ie, S as Le, Tt as Re, V as ze, Vt as Be, Wt as Ve, X as He, Xt as Ue, Y as We, Yt as Ge, _ as Ke, _n as qe, _t as Je, an as Ye, b as Xe, cn as Ze, ct as Qe, dn as $e, dt as et, en as tt, f as nt, ft as rt, g as it, gn as at, gt as ot, h as st, it as ct, jt as lt, k as ut, kt as dt, ln as ft, m as pt, mn as mt, nn as ht, o as gt, p as _t, pn as vt, pt as yt, qt as bt, rn as xt, rt as St, s as Ct, tn as wt, u as Tt, un as Et, v as Dt, xt as Ot, y as kt, z as At } from "./error-entries-CmFDQ9CA.js";
9
9
  import { D as jt, E as Mt, O as Nt, S as Pt, T as Ft, _ as It, a as Lt, c as Rt, d as zt, f as Bt, g as Vt, h as Ht, i as Ut, l as Wt, m as Gt, n as Kt, o as qt, p as Jt, r as Yt, s as Xt, t as Zt, u as Qt, v as $t, w as en, x as tn, y as nn } from "./spec-DiSh_qJC.js";
10
- import { $t as rn, A as an, At as on, B as sn, Bt as cn, C as ln, Ct as un, D as dn, Dt as fn, E as pn, Et as mn, F as hn, Ft as gn, G as _n, Gt as vn, H as yn, Ht as bn, I as xn, It as Sn, J as Cn, Jt as wn, K as Tn, Kt as En, L as Dn, Lt as On, M as kn, Mt as An, N as jn, Nt as Mn, O as Nn, Ot as Pn, P as Fn, Pt as In, Qt as Ln, R as Rn, Rt as zn, S as Bn, St as Vn, T as Hn, Tt as Un, U as Wn, Ut as Gn, V as Kn, Vt as qn, W as Jn, Wt as Yn, X as Xn, Xt as Zn, Y as Qn, Yt as $n, Zt as er, _ as tr, _t as nr, an as rr, at as ir, b as ar, c as or, cn as sr, ct as cr, d as lr, dn as ur, dt as dr, en as fr, et as pr, f as mr, fn as hr, ft as gr, g as _r, gt as vr, h as yr, hn as br, ht as xr, in as Sr, it as Cr, j as wr, jt as Tr, k as Er, kt as Dr, ln as Or, lt as kr, m as Ar, mn as jr, mt as Mr, nn as Nr, nt as Pr, ot as Fr, p as Ir, pn as Lr, pt as Rr, q as zr, qt as Br, r as Vr, rn as Hr, rt as Ur, sn as Wr, st as Gr, t as Kr, tn as qr, tt as Jr, u as Yr, un as Xr, ut as Zr, v as Qr, vt as $r, w as ei, wt as ti, x as ni, y as ri, yt as ii, z as ai, zt as oi } from "./common-CNv_7gvI.js";
10
+ import { $t as rn, A as an, At as on, B as sn, Bt as cn, C as ln, Ct as un, D as dn, Dt as fn, E as pn, Et as mn, F as hn, Ft as gn, G as _n, Gt as vn, H as yn, Ht as bn, I as xn, It as Sn, J as Cn, Jt as wn, K as Tn, Kt as En, L as Dn, Lt as On, M as kn, Mt as An, N as jn, Nt as Mn, O as Nn, Ot as Pn, P as Fn, Pt as In, Qt as Ln, R as Rn, Rt as zn, S as Bn, St as Vn, T as Hn, Tt as Un, U as Wn, Ut as Gn, V as Kn, Vt as qn, W as Jn, Wt as Yn, X as Xn, Xt as Zn, Y as Qn, Yt as $n, Zt as er, _ as tr, _t as nr, an as rr, at as ir, b as ar, c as or, cn as sr, ct as cr, d as lr, dn as ur, dt as dr, en as fr, et as pr, f as mr, fn as hr, ft as gr, g as _r, gt as vr, h as yr, hn as br, ht as xr, in as Sr, it as Cr, j as wr, jt as Tr, k as Er, kt as Dr, ln as Or, lt as kr, m as Ar, mn as jr, mt as Mr, nn as Nr, nt as Pr, ot as Fr, p as Ir, pn as Lr, pt as Rr, q as zr, qt as Br, r as Vr, rn as Hr, rt as Ur, sn as Wr, st as Gr, t as Kr, tn as qr, tt as Jr, u as Yr, un as Xr, ut as Zr, v as Qr, vt as $r, w as ei, wt as ti, x as ni, y as ri, yt as ii, z as ai, zt as oi } from "./common-CbFJQhaI.js";
11
11
  import { c as si, i as ci, n as li, o as ui, t as di } from "./useLifecycle-B5BX921H.js";
12
12
  import { t as fi } from "./check-SpOMoCLP.js";
13
13
  import { A as pi, C as mi, D as hi, E as gi, M as _i, O as vi, S as yi, T as bi, a as xi, b as Si, c as Ci, i as wi, l as Ti, n as Ei, o as Di, r as Oi, s as ki, t as Ai, w as ji, x as Mi } from "./select-CkF_GBxO.js";
@@ -15,8 +15,8 @@ import { B as Ni, C as Pi, J as Fi, Ot as Ii, S as Li, W as Ri, X as zi, Y as Bi
15
15
  import { C as fa, _ as pa, a as ma, b as ha, c as ga, f as _a, h as va, m as ya, p as ba, s as xa, u as Sa, x as Ca, y as wa } from "./toDate-DGvRHwTk.js";
16
16
  import { a as Ta, c as Ea, d as Da, f as Oa, i as ka, l as Aa, n as ja, o as Ma, r as Na, s as Pa, t as Fa } from "./process-output-Bw-vzyoy.js";
17
17
  import { a as Ia, c as La, d as Ra, i as za, l as Ba, r as Va, u as Ha } from "./glide-utils-Dz_F4pAY.js";
18
- import { n as Ua, t as Wa } from "./ErrorBoundary-CTJ1U1fx.js";
19
- import { n as Ga, t as Ka } from "./globals-BW8TOLYQ.js";
18
+ import { n as Ua, t as Wa } from "./ErrorBoundary-DxdeETpm.js";
19
+ import { n as Ga, t as Ka } from "./globals-f0UxWZkr.js";
20
20
  import { t as qa } from "./react-dom-DUmH0GXv.js";
21
21
  import { t as Ja } from "./jsx-runtime-3BD1kT0s.js";
22
22
  import { B as Ya, C as H, Ct as Xa, D as Za, Dt as Qa, E as $a, Et as eo, F as U, G as to, H as no, I as ro, L as io, M as W, N as ao, O as oo, P as so, Q as co, R as lo, S as G, St as uo, Tt as fo, U as po, W as mo, Y as ho, Z as go, _ as _o, _t as vo, a as yo, b as bo, bt as xo, c as So, d as Co, f as wo, g as To, h as Eo, i as Do, j as K, k as Oo, l as ko, m as Ao, n as jo, o as Mo, p as No, r as Po, s as Fo, u as Io, ut as Lo, v as Ro, w as zo, wt as Bo, x as Vo, xt as Ho, y as Uo, yt as Wo } from "./use-restore-focus-CmGwRNId.js";
@@ -39,7 +39,7 @@ import { t as Ps } from "./useAsyncData-BmVgnMP5.js";
39
39
  import { i as Fs, n as Is, r as Ls } from "./formats-CCxaLPNs.js";
40
40
  import { D as Rs, O as zs } from "./vega-loader.browser-B9Pz0EGP.js";
41
41
  import { a as Bs, n as Vs } from "./loader-DOVB0Syl.js";
42
- import { c as Hs, d as Us, i as Ws, l as Gs, o as Ks, s as qs, t as Js, u as Ys } from "./code-visibility-C1jZfwPW.js";
42
+ import { c as Hs, d as Us, i as Ws, l as Gs, o as Ks, s as qs, t as Js, u as Ys } from "./code-visibility-CO8abjLo.js";
43
43
  import { t as Xs } from "./useDeepCompareMemoize-Ch_AeGu6.js";
44
44
  import { t as Zs } from "./esm-D2gTsXEV.js";
45
45
  //#region ../node_modules/.pnpm/iconify-icon@2.3.0/node_modules/iconify-icon/dist/iconify-icon.mjs
@@ -10635,7 +10635,7 @@ function WC(e, t) {
10635
10635
  }
10636
10636
  //#endregion
10637
10637
  //#region src/plugins/impl/DataEditorPlugin.tsx
10638
- var GC = J.lazy(() => import("./glide-data-editor-B3eq-1SC.js").then((e) => e.t)), KC = DS("marimo-data-editor", { cssStyles: [XS] }).withData(W({
10638
+ var GC = J.lazy(() => import("./glide-data-editor-BxT8eGip.js").then((e) => e.t)), KC = DS("marimo-data-editor", { cssStyles: [XS] }).withData(W({
10639
10639
  initialValue: W({ edits: G(W({
10640
10640
  rowIdx: K(),
10641
10641
  columnId: U(),
@@ -30407,7 +30407,7 @@ function WR(e) {
30407
30407
  }
30408
30408
  //#endregion
30409
30409
  //#region src/components/editor/renderers/slides-layout/slides-layout.tsx
30410
- var GR = J.lazy(() => import("./reveal-component-ClNn1CDl.js")), KR = (e) => {
30410
+ var GR = J.lazy(() => import("./reveal-component-DMglhlng.js")), KR = (e) => {
30411
30411
  let t = (0, X.c)(33), { layout: n, setLayout: r, cells: i, mode: a } = e, o = is(pa), s = a === "read" || o, c = is(Ke) > 1, [l, u] = (0, J.useState)(null), d;
30412
30412
  t[0] !== i || t[1] !== n ? (d = HP(i, n), t[0] = i, t[1] = n, t[2] = d) : d = t[2];
30413
30413
  let { slideCells: f, skippedIds: p, noOutputIds: m, slideTypes: h, startCellIndex: g } = d, _;
@@ -32411,10 +32411,11 @@ function YB(e, t) {
32411
32411
  var XB = "marimo-transport";
32412
32412
  //#endregion
32413
32413
  //#region src/core/wasm/rpc.ts
32414
- function ZB(e) {
32414
+ function ZB(e, t, n = 2e4) {
32415
32415
  return WB({
32416
32416
  transport: YB(e, { transportId: XB }),
32417
- maxRequestTime: 2e4,
32417
+ requestHandler: t,
32418
+ maxRequestTime: n,
32418
32419
  _debugHooks: {
32419
32420
  onSend: (e) => {
32420
32421
  c.debug("[rpc] Parent -> Worker", e);
@@ -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-B3eq-1SC.js";
3
+ import { a as n } from "./glide-data-editor-BxT8eGip.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",
@@ -4,14 +4,14 @@ 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-CJ4Rqasp.js";
6
6
  import { k as u } from "./error-entries-CmFDQ9CA.js";
7
- import { $ as d, Q as f, Z as p, an as m, i as h, l as g, ln as _, n as v, on as y, r as b, t as x, u as S } from "./common-CNv_7gvI.js";
7
+ import { $ as d, Q as f, Z as p, an as m, i as h, l as g, ln as _, n as v, on as y, r as b, t as x, u as S } from "./common-CbFJQhaI.js";
8
8
  import { M as C } from "./select-CkF_GBxO.js";
9
9
  import { J as ee } from "./dropdown-menu-GWcGCcxE.js";
10
10
  import { _ as w } from "./toDate-DGvRHwTk.js";
11
11
  import { t as T } from "./jsx-runtime-3BD1kT0s.js";
12
12
  import { q as E } from "./use-restore-focus-CmGwRNId.js";
13
13
  import { A as D, C as O, b as k } from "./useTheme-Bq9pi_vz.js";
14
- import { a as A, n as te, t as ne } from "./code-visibility-C1jZfwPW.js";
14
+ import { a as A, n as te, t as ne } from "./code-visibility-CO8abjLo.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-dev140",
3
+ "version": "0.25.3-dev142",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -15,20 +15,28 @@ export type FakeEdit = (
15
15
  ...args: Parameters<Commands["edit"]>
16
16
  ) => ReturnType<Commands["edit"]>;
17
17
 
18
- /** A backend over `transport` whose edits go to `edit`. */
18
+ export type FakeSave = (
19
+ notebookId: Protocol.NotebookId,
20
+ ...args: Parameters<Commands["save"]>
21
+ ) => ReturnType<Commands["save"]>;
22
+
23
+ /** A backend over `transport` whose commands go to `edit` and `save`. */
19
24
  export function fakeBackend({
20
25
  transport = async () => undefined,
21
26
  edit = vi.fn<FakeEdit>(),
27
+ save = vi.fn<FakeSave>(),
22
28
  checkHealth,
23
29
  }: {
24
30
  transport?: NotebookTransport;
25
31
  edit?: FakeEdit;
32
+ save?: FakeSave;
26
33
  checkHealth?: () => Promise<boolean>;
27
34
  } = {}): NotebookBackend {
28
35
  return {
29
36
  transport,
30
37
  notebook: (notebookId) => ({
31
38
  edit: (...args) => edit(notebookId, ...args),
39
+ save: (...args) => save(notebookId, ...args),
32
40
  }),
33
41
  checkHealth,
34
42
  };
@@ -127,19 +127,25 @@ describe("static notebook backend", () => {
127
127
  expect(events.at(-1)).toEqual({ event: "ready", id: "static", data: {} });
128
128
  });
129
129
 
130
- it("advertises no mutations and returns a protocol failure for direct edits", async () => {
131
- const backend = createStaticNotebookBackend(snapshot());
132
- expect(await backend.notebook(snapshot().notebook.id).edit([])).toEqual({
133
- ok: false,
134
- status: 501,
135
- problem: {
136
- type: "tag:marimo.io,2026:host/unsupported-operation",
137
- title: "Unsupported operation",
130
+ it.each(["edit", "save"] as const)(
131
+ "rejects direct %s commands",
132
+ async (operation) => {
133
+ const backend = createStaticNotebookBackend(snapshot());
134
+ const client = backend.notebook(snapshot().notebook.id);
135
+ const result =
136
+ operation === "edit" ? await client.edit([]) : await client.save();
137
+ expect(result).toEqual({
138
+ ok: false,
138
139
  status: 501,
139
- detail: "Static notebooks do not support editing",
140
- },
141
- });
142
- });
140
+ problem: {
141
+ type: "tag:marimo.io,2026:host/unsupported-operation",
142
+ title: "Unsupported operation",
143
+ status: 501,
144
+ detail: "Static notebooks do not support mutations",
145
+ },
146
+ });
147
+ },
148
+ );
143
149
 
144
150
  it("respects cancellation before opening, during delivery, and for commands", async () => {
145
151
  const backend = createStaticNotebookBackend(snapshot());
@@ -23,7 +23,6 @@ function worker() {
23
23
  const reply = { ok: true, status: 200, data: { document, cells: {} } };
24
24
  const wire = { status: 200, body: reply.data };
25
25
  const bridge = {
26
- notebookId: "n1",
27
26
  subscribe: vi.fn(
28
27
  async (_cursor: string | null, emit: (event: unknown) => void) => {
29
28
  listeners.add(emit);
@@ -100,64 +99,68 @@ describe("WASM notebook backend", () => {
100
99
  ).rejects.toBeInstanceOf(StreamStopped);
101
100
  });
102
101
 
103
- it("refuses commands for any notebook but the worker's", () => {
104
- const { bridge } = worker();
105
- expect(() => createWasmNotebookBackend(bridge).notebook("n2")).toThrow(
106
- "serves notebook n1, not n2",
107
- );
108
- expect(bridge.call).not.toHaveBeenCalled();
109
- });
110
-
111
- it("sends edits as calls with the retry key and validates replies", async () => {
112
- const { bridge, reply } = worker();
113
- const backend = createWasmNotebookBackend(bridge);
114
- expect(
115
- await backend.notebook("n1").edit([], { idempotencyKey: "edit-7" }),
116
- ).toEqual(reply);
117
- expect(bridge.call).toHaveBeenCalledWith({
118
- operation: "notebook.edit",
119
- params: { notebook_id: "n1" },
120
- headers: { "idempotency-key": "edit-7" },
121
- body: { changes: [] },
122
- });
123
- const problem = {
124
- type: "tag:marimo.io,2026:host/forbidden",
125
- title: "Forbidden",
126
- status: 403,
127
- };
128
- bridge.call.mockResolvedValue({ status: 403, body: problem });
129
- expect(await backend.notebook("n1").edit([])).toEqual({
130
- ok: false,
131
- status: 403,
132
- problem,
133
- });
134
- bridge.call.mockResolvedValue({ status: 200, body: {} });
135
- await expect(backend.notebook("n1").edit([])).rejects.toThrow(
136
- /Invalid input/,
137
- );
138
- });
102
+ it.each(["edit", "save"] as const)(
103
+ "sends %s calls with the retry key and validates replies",
104
+ async (operation) => {
105
+ const { bridge, reply } = worker();
106
+ const notebook = createWasmNotebookBackend(bridge).notebook("n1");
107
+ const command =
108
+ operation === "edit"
109
+ ? notebook.edit.bind(notebook, [])
110
+ : notebook.save.bind(notebook);
111
+ expect(await command({ idempotencyKey: `${operation}-7` })).toEqual(
112
+ reply,
113
+ );
114
+ expect(bridge.call).toHaveBeenCalledWith({
115
+ operation: `notebook.${operation}`,
116
+ params: { notebook_id: "n1" },
117
+ headers: { "idempotency-key": `${operation}-7` },
118
+ body: operation === "edit" ? { changes: [] } : {},
119
+ });
120
+ const problem = {
121
+ type: "tag:marimo.io,2026:host/forbidden",
122
+ title: "Forbidden",
123
+ status: 403,
124
+ };
125
+ bridge.call.mockResolvedValue({ status: 403, body: problem });
126
+ expect(await command()).toEqual({
127
+ ok: false,
128
+ status: 403,
129
+ problem,
130
+ });
131
+ bridge.call.mockResolvedValue({ status: 200, body: {} });
132
+ await expect(command()).rejects.toThrow(/Invalid input/);
133
+ },
134
+ );
139
135
 
140
- it("cancels waiting for an accepted edit and permits retry with the same key", async () => {
141
- const { bridge, reply, wire } = worker();
142
- const pending = new Deferred<unknown>();
143
- bridge.call.mockReturnValue(pending.promise);
144
- const backend = createWasmNotebookBackend(bridge);
145
- const controller = new AbortController();
146
- const editing = backend.notebook("n1").edit([], {
147
- signal: controller.signal,
148
- idempotencyKey: "edit-8",
149
- });
150
- await vi.waitFor(() => expect(bridge.call).toHaveBeenCalledOnce());
151
- controller.abort();
152
- await expect(editing).rejects.toBe(controller.signal.reason);
153
- pending.resolve(wire);
154
- expect(
155
- await backend.notebook("n1").edit([], { idempotencyKey: "edit-8" }),
156
- ).toEqual(reply);
157
- expect(bridge.call.mock.calls[0]).toEqual(bridge.call.mock.calls[1]);
158
- await expect(
159
- backend.notebook("n1").edit([], { signal: controller.signal }),
160
- ).rejects.toBe(controller.signal.reason);
161
- expect(bridge.call).toHaveBeenCalledTimes(2);
162
- });
136
+ it.each(["edit", "save"] as const)(
137
+ "cancels waiting for an accepted %s and permits retry with the same key",
138
+ async (operation) => {
139
+ const { bridge, reply, wire } = worker();
140
+ const pending = new Deferred<unknown>();
141
+ bridge.call.mockReturnValue(pending.promise);
142
+ const notebook = createWasmNotebookBackend(bridge).notebook("n1");
143
+ const command =
144
+ operation === "edit"
145
+ ? notebook.edit.bind(notebook, [])
146
+ : notebook.save.bind(notebook);
147
+ const controller = new AbortController();
148
+ const pendingCommand = command({
149
+ signal: controller.signal,
150
+ idempotencyKey: `${operation}-8`,
151
+ });
152
+ await vi.waitFor(() => expect(bridge.call).toHaveBeenCalledOnce());
153
+ controller.abort();
154
+ await expect(pendingCommand).rejects.toBe(controller.signal.reason);
155
+ pending.resolve(wire);
156
+ expect(await command({ idempotencyKey: `${operation}-8` })).toEqual(
157
+ reply,
158
+ );
159
+ expect(bridge.call.mock.calls[0]).toEqual(bridge.call.mock.calls[1]);
160
+ await expect(command({ signal: controller.signal })).rejects.toBe(
161
+ controller.signal.reason,
162
+ );
163
+ expect(bridge.call).toHaveBeenCalledTimes(2);
164
+ },
165
+ );
163
166
  });
@@ -13,7 +13,7 @@ export interface NotebookBackend {
13
13
  *
14
14
  * Method presence is not permission. The notebook advertises its operations.
15
15
  */
16
- notebook(id: NotebookId): Pick<NotebookClient, "edit">;
16
+ notebook(id: NotebookId): Pick<NotebookClient, "edit" | "save">;
17
17
  /** Whether the host is reachable before an explicit reconnect. Absent means always. */
18
18
  checkHealth?(): Promise<boolean>;
19
19
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  /** A backend that serves a document snapshot without a host. */
4
4
 
5
+ import type { NotebookClient } from "@marimo-team/client";
5
6
  import type * as Protocol from "@marimo-team/client/protocol";
6
7
  import type { NotebookBackend } from "./backend";
7
8
 
@@ -53,8 +54,8 @@ export function createStaticNotebookBackend(
53
54
  message(frame);
54
55
  }
55
56
  }),
56
- notebook: () => ({
57
- edit: async (_changes, options) => {
57
+ notebook: () => {
58
+ const unsupported: NotebookClient["save"] = async (options) => {
58
59
  options?.signal?.throwIfAborted();
59
60
  return {
60
61
  ok: false,
@@ -63,10 +64,14 @@ export function createStaticNotebookBackend(
63
64
  type: "tag:marimo.io,2026:host/unsupported-operation",
64
65
  title: "Unsupported operation",
65
66
  status: 501,
66
- detail: "Static notebooks do not support editing",
67
+ detail: "Static notebooks do not support mutations",
67
68
  },
68
69
  };
69
- },
70
- }),
70
+ };
71
+ return {
72
+ edit: (_changes, options) => unsupported(options),
73
+ save: unsupported,
74
+ };
75
+ },
71
76
  };
72
77
  }
@@ -11,7 +11,6 @@ import type { NotebookBackend } from "./backend";
11
11
 
12
12
  /** The worker owns the notebook; this interface only carries commands and events. */
13
13
  export interface WasmNotebookBridge {
14
- readonly notebookId: string;
15
14
  subscribe(
16
15
  cursor: string | null,
17
16
  emit: (event: unknown) => void,
@@ -42,9 +41,6 @@ function abortable<T>(
42
41
  export function createWasmNotebookBackend(
43
42
  bridge: WasmNotebookBridge,
44
43
  ): NotebookBackend {
45
- const client = NotebookClient.unstable_over((call) => bridge.call(call), {
46
- notebookId: bridge.notebookId,
47
- });
48
44
  return {
49
45
  transport: async ({ cursor, signal }, { open, message }) => {
50
46
  if (signal.aborted) {
@@ -95,13 +91,7 @@ export function createWasmNotebookBackend(
95
91
  signal.removeEventListener("abort", abort);
96
92
  }
97
93
  },
98
- notebook: (id) => {
99
- if (id !== bridge.notebookId) {
100
- throw new Error(
101
- `The worker serves notebook ${bridge.notebookId}, not ${id}`,
102
- );
103
- }
104
- return client;
105
- },
94
+ notebook: (notebookId) =>
95
+ NotebookClient.unstable_over((call) => bridge.call(call), { notebookId }),
106
96
  };
107
97
  }
@@ -21,7 +21,10 @@ import { Label } from "../../components/ui/label";
21
21
  import { useEvent } from "../../hooks/useEvent";
22
22
  import { Logger } from "../../utils/Logger";
23
23
  import { getCellConfigs, getNotebook, useNotebook } from "../cells/cells";
24
- import { withDocumentSave } from "../cells/document-changes";
24
+ import {
25
+ flushDocumentChanges,
26
+ withDocumentSave,
27
+ } from "../cells/document-changes";
25
28
  import { notebookCells } from "../cells/utils";
26
29
  import { formatAll } from "../codemirror/format";
27
30
  import { autoSaveConfigAtom } from "../config/config";
@@ -32,6 +35,7 @@ import { kioskModeAtom } from "../mode";
32
35
  import { connectionAtom } from "../network/connection";
33
36
  import { useRequestClient } from "../network/requests";
34
37
  import { ConnectionState } from "../websocket/types";
38
+ import { isWasm } from "../wasm/utils";
35
39
  import { filenameAtom } from "./file-state";
36
40
  import { useFilename, useUpdateFilename } from "./filename";
37
41
  import { lastSavedNotebookAtom, needsSaveAtom } from "./state";
@@ -136,7 +140,7 @@ export function useSaveNotebook() {
136
140
  return;
137
141
  }
138
142
 
139
- const savedNotebook = await withDocumentSave(async () => {
143
+ const save = async () => {
140
144
  // Grab the latest notebook state after formatting and after every
141
145
  // earlier document transaction has reached the server.
142
146
  const notebook = getNotebook();
@@ -157,7 +161,12 @@ export function useSaveNotebook() {
157
161
  persist: true,
158
162
  });
159
163
  return { names: cellNames, codes, configs, layout };
160
- });
164
+ };
165
+ // TODO(MO-7955): Remove this conditional once all frontend saves use
166
+ // the host protocol. Host saves cannot recover edits from an editor snapshot.
167
+ const savedNotebook = isWasm()
168
+ ? await flushDocumentChanges().then(save)
169
+ : await withDocumentSave(save);
161
170
  setLastSavedNotebook(savedNotebook);
162
171
  }),
163
172
  );