@marimo-team/islands 0.24.1-dev73 → 0.24.1-dev76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{common-D37C4Qj7.js → common-nuR9LfxI.js} +13 -12
- package/dist/main.js +2 -2
- package/dist/{reveal-component-B3r0D5zd.js → reveal-component-CzLgRK9f.js} +1 -1
- package/package.json +1 -1
- package/src/core/packages/__tests__/useInstallPackage.test.tsx +123 -0
- package/src/core/packages/toast-components.tsx +16 -5
- package/src/core/packages/useInstallPackage.ts +12 -11
|
@@ -18570,19 +18570,23 @@ function Kj(e, t) {
|
|
|
18570
18570
|
//#endregion
|
|
18571
18571
|
//#region src/core/packages/toast-components.tsx
|
|
18572
18572
|
var qj = (e, t) => {
|
|
18573
|
+
let n = Array.isArray(e) ? e : [e];
|
|
18573
18574
|
m(t ? {
|
|
18574
|
-
title: "Failed to add package",
|
|
18575
|
+
title: n.length > 1 ? "Failed to add packages" : "Failed to add package",
|
|
18575
18576
|
description: t,
|
|
18576
18577
|
variant: "danger"
|
|
18577
18578
|
} : {
|
|
18578
|
-
title: "Package added",
|
|
18579
|
+
title: n.length > 1 ? "Packages added" : "Package added",
|
|
18579
18580
|
description: /* @__PURE__ */ (0, U.jsxs)("div", { children: [/* @__PURE__ */ (0, U.jsxs)("div", { children: [
|
|
18580
|
-
"The package ",
|
|
18581
|
-
/* @__PURE__ */ (0, U.jsx)(ej, {
|
|
18581
|
+
n.length > 1 ? "The packages " : "The package ",
|
|
18582
|
+
n.map((e, t) => /* @__PURE__ */ (0, U.jsxs)("span", { children: [t > 0 && ", ", /* @__PURE__ */ (0, U.jsx)(ej, {
|
|
18582
18583
|
className: "inline",
|
|
18583
18584
|
children: e
|
|
18584
|
-
}),
|
|
18585
|
-
"
|
|
18585
|
+
})] }, e)),
|
|
18586
|
+
" ",
|
|
18587
|
+
"and ",
|
|
18588
|
+
n.length > 1 ? "their" : "its",
|
|
18589
|
+
" dependencies have been added to your environment."
|
|
18586
18590
|
] }), /* @__PURE__ */ (0, U.jsx)("div", {
|
|
18587
18591
|
className: "text-xs text-muted-foreground mt-1",
|
|
18588
18592
|
children: "Some Python packages may require a kernel restart to see changes."
|
|
@@ -18598,11 +18602,8 @@ function Jj() {
|
|
|
18598
18602
|
handleInstallPackages: async (e, r) => {
|
|
18599
18603
|
t(!0);
|
|
18600
18604
|
try {
|
|
18601
|
-
|
|
18602
|
-
|
|
18603
|
-
i.success ? qj(r) : qj(r, i.error), t < e.length - 1 && await new Promise((e) => setTimeout(e, 1e3));
|
|
18604
|
-
}
|
|
18605
|
-
r?.();
|
|
18605
|
+
let t = await n({ package: e.join(" ") });
|
|
18606
|
+
t.success ? qj(e) : qj(e, t.error), r?.();
|
|
18606
18607
|
} catch (e) {
|
|
18607
18608
|
i.error(e);
|
|
18608
18609
|
} finally {
|
|
@@ -31786,7 +31787,7 @@ function QG() {
|
|
|
31786
31787
|
return i.warn("Failed to get version from mount config"), null;
|
|
31787
31788
|
}
|
|
31788
31789
|
}
|
|
31789
|
-
var $G = QG() || "0.24.1-
|
|
31790
|
+
var $G = QG() || "0.24.1-dev76", eK = Ci($G), tK = Ci(!0);
|
|
31790
31791
|
Ci(null);
|
|
31791
31792
|
//#endregion
|
|
31792
31793
|
//#region src/core/meta/code-visibility.ts
|
package/dist/main.js
CHANGED
|
@@ -6,7 +6,7 @@ import { n as x, r as S, t as C } from "./copy-D9h0DuU7.js";
|
|
|
6
6
|
import { $ as w, $n as T, B as E, Bn as D, C as O, Cn as k, Ct as A, Dn as j, Dt as M, Et as N, F as P, Fn as F, Ft as I, G as L, Gn as R, Ht as ee, I as z, It as te, J as ne, K as re, Kn as ie, Kt as ae, L as oe, Ln as se, Mn as ce, Mt as le, Nn as ue, On as de, Ot as fe, P as pe, Pn as me, Qn as he, R as ge, Rn as _e, Sn as ve, St as ye, U as be, Un as xe, Ut as Se, W as Ce, Wn as we, Wt as Te, X as Ee, Xn as De, Xt as Oe, Y as ke, Yn as Ae, Z as je, _ as Me, _t as Ne, a as Pe, an as Fe, at as Ie, b as Le, bn as Re, bt as ze, ct as Be, dn as Ve, en as He, g as Ue, gn as We, hn as Ge, i as Ke, in as qe, it as Je, j as Ye, jt as Xe, k as Ze, kn as Qe, kt as $e, lt as et, mn as tt, n as nt, nn as rt, o as it, on as at, q as ot, qn as st, qt as ct, rn as lt, rt as ut, st as dt, tn as ft, v as pt, vn as mt, vt as ht, wn as gt, wt as _t, xn as vt, xt as yt, y as bt, yt as xt, z as St, zt as Ct } from "./html-to-image-B7RQgQQy.js";
|
|
7
7
|
import { o as wt, s as Tt, u as Et } from "./dist-wdOJ5T7-.js";
|
|
8
8
|
import { D as Dt, E as Ot, O as kt, S as At, T as jt, _ as Mt, a as Nt, c as Pt, d as Ft, f as It, g as Lt, h as Rt, i as zt, l as Bt, m as Vt, n as Ht, o as Ut, p as Wt, r as Gt, s as Kt, t as qt, u as Jt, v as Yt, w as Xt, x as Zt, y as Qt } from "./spec-BQ36ell9.js";
|
|
9
|
-
import { $ as $t, $t as en, A as tn, At as nn, B as rn, Bt as an, C as on, Ct as sn, D as cn, Dt as ln, E as un, Et as dn, F as fn, Ft as pn, G as mn, Gt as hn, H as gn, Ht as _n, I as vn, It as yn, Jt as bn, K as xn, Kt as Sn, L as Cn, Lt as wn, M as Tn, Mt as En, N as Dn, Nt as On, O as kn, Ot as An, P as jn, Pt as Mn, Q as Nn, Qt as Pn, R as Fn, Rt as In, S as Ln, St as Rn, T as zn, Tt as Bn, U as Vn, Ut as Hn, V as Un, Vt as Wn, W as Gn, Wt as Kn, Xt as qn, Yt as Jn, Z as Yn, Zt as Xn, _ as Zn, an as Qn, at as $n, b as er, bt as tr, c as nr, cn as rr, ct as ir, d as ar, dn as or, dt as sr, en as cr, et as lr, f as ur, fn as dr, ft as fr, g as pr, gt as mr, h as hr, ht as gr, i as _r, it as vr, j as yr, jt as br, k as xr, kt as Sr, ln as Cr, lt as wr, m as Tr, mt as Er, n as Dr, nn as Or, nt as kr, on as Ar, ot as jr, p as Mr, pn as Nr, pt as Pr, q as Fr, qt as Ir, r as Lr, rn as Rr, rt as zr, sn as Br, st as Vr, t as Hr, tn as Ur, tt as Wr, u as Gr, un as Kr, ut as qr, v as Jr, w as Yr, wt as Xr, x as Zr, xt as Qr, y as $r, yt as ei, z as ti, zt as ni } from "./common-
|
|
9
|
+
import { $ as $t, $t as en, A as tn, At as nn, B as rn, Bt as an, C as on, Ct as sn, D as cn, Dt as ln, E as un, Et as dn, F as fn, Ft as pn, G as mn, Gt as hn, H as gn, Ht as _n, I as vn, It as yn, Jt as bn, K as xn, Kt as Sn, L as Cn, Lt as wn, M as Tn, Mt as En, N as Dn, Nt as On, O as kn, Ot as An, P as jn, Pt as Mn, Q as Nn, Qt as Pn, R as Fn, Rt as In, S as Ln, St as Rn, T as zn, Tt as Bn, U as Vn, Ut as Hn, V as Un, Vt as Wn, W as Gn, Wt as Kn, Xt as qn, Yt as Jn, Z as Yn, Zt as Xn, _ as Zn, an as Qn, at as $n, b as er, bt as tr, c as nr, cn as rr, ct as ir, d as ar, dn as or, dt as sr, en as cr, et as lr, f as ur, fn as dr, ft as fr, g as pr, gt as mr, h as hr, ht as gr, i as _r, it as vr, j as yr, jt as br, k as xr, kt as Sr, ln as Cr, lt as wr, m as Tr, mt as Er, n as Dr, nn as Or, nt as kr, on as Ar, ot as jr, p as Mr, pn as Nr, pt as Pr, q as Fr, qt as Ir, r as Lr, rn as Rr, rt as zr, sn as Br, st as Vr, t as Hr, tn as Ur, tt as Wr, u as Gr, un as Kr, ut as qr, v as Jr, w as Yr, wt as Xr, x as Zr, xt as Qr, y as $r, yt as ei, z as ti, zt as ni } from "./common-nuR9LfxI.js";
|
|
10
10
|
import { c as ri, i as ii, n as ai, o as oi, t as si } from "./useLifecycle-hEcsyQ2P.js";
|
|
11
11
|
import { t as ci } from "./check-BcJDmQdF.js";
|
|
12
12
|
import { A as li, C as ui, D as di, E as fi, F as pi, I as mi, M as hi, N as gi, P as _i, R as vi, S as yi, a as bi, b as xi, c as Si, i as Ci, j 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-DQ9jU_B_.js";
|
|
@@ -35256,7 +35256,7 @@ function Gq(e) {
|
|
|
35256
35256
|
}
|
|
35257
35257
|
//#endregion
|
|
35258
35258
|
//#region src/components/editor/renderers/slides-layout/slides-layout.tsx
|
|
35259
|
-
var Kq = q.lazy(() => import("./reveal-component-
|
|
35259
|
+
var Kq = q.lazy(() => import("./reveal-component-CzLgRK9f.js")), qq = (e) => {
|
|
35260
35260
|
let t = (0, Y.c)(33), { layout: n, setLayout: r, cells: i, mode: a } = e, o = Nm(_t), s = a === "read" || o, c = Nm(ne) > 1, [l, u] = (0, q.useState)(null), d;
|
|
35261
35261
|
t[0] !== i || t[1] !== n ? (d = UU(i, n), t[0] = i, t[1] = n, t[2] = d) : d = t[2];
|
|
35262
35262
|
let { slideCells: f, skippedIds: p, noOutputIds: m, slideTypes: h, startCellIndex: g } = d, _;
|
|
@@ -4,7 +4,7 @@ import { t as o } from "./react-DMWcHin-.js";
|
|
|
4
4
|
import { t as s } from "./compiler-runtime-CAH9RLw2.js";
|
|
5
5
|
import { it as c, wt as l } from "./html-to-image-B7RQgQQy.js";
|
|
6
6
|
import { u } from "./dist-wdOJ5T7-.js";
|
|
7
|
-
import { J as d, X as f, Y as p, in as m, l as h, n as g, rn as _, sn as v, t as y, u as b } from "./common-
|
|
7
|
+
import { J as d, X as f, Y as p, in as m, l as h, n as g, rn as _, sn as v, t as y, u as b } from "./common-nuR9LfxI.js";
|
|
8
8
|
import { R as x } from "./select-DQ9jU_B_.js";
|
|
9
9
|
import { X as S } from "./dropdown-menu-C8N-kZzD.js";
|
|
10
10
|
import { t as C } from "./jsx-runtime-CpoKNRgu.js";
|
package/package.json
CHANGED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
import { act, renderHook } from "@testing-library/react";
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { useInstallPackages } from "../useInstallPackage";
|
|
5
|
+
|
|
6
|
+
const toast = vi.fn();
|
|
7
|
+
const addPackage = vi.fn();
|
|
8
|
+
|
|
9
|
+
vi.mock("@/components/ui/use-toast", () => ({
|
|
10
|
+
toast: (...args: unknown[]) => toast(...args),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
vi.mock("../../network/requests", () => ({
|
|
14
|
+
useRequestClient: () => ({
|
|
15
|
+
addPackage: (...args: unknown[]) => addPackage(...args),
|
|
16
|
+
}),
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
describe("useInstallPackages", () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
toast.mockClear();
|
|
22
|
+
addPackage.mockClear();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("batches all packages into a single install call", async () => {
|
|
26
|
+
addPackage.mockResolvedValue({ success: true, error: null });
|
|
27
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
28
|
+
|
|
29
|
+
await act(async () => {
|
|
30
|
+
await result.current.handleInstallPackages(["numpy", "pandas", "scipy"]);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// A single batched install call, not one per package.
|
|
34
|
+
expect(addPackage).toHaveBeenCalledTimes(1);
|
|
35
|
+
expect(addPackage).toHaveBeenCalledWith({ package: "numpy pandas scipy" });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("shows a single aggregate success toast for multiple packages", async () => {
|
|
39
|
+
addPackage.mockResolvedValue({ success: true, error: null });
|
|
40
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
41
|
+
|
|
42
|
+
await act(async () => {
|
|
43
|
+
await result.current.handleInstallPackages(["numpy", "pandas", "scipy"]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Only one toast, regardless of package count — no false per-package status.
|
|
47
|
+
expect(toast).toHaveBeenCalledTimes(1);
|
|
48
|
+
expect(toast).toHaveBeenCalledWith(
|
|
49
|
+
expect.objectContaining({ title: "Packages added" }),
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("shows a single aggregate error toast when the batch fails", async () => {
|
|
54
|
+
addPackage.mockResolvedValue({ success: false, error: "boom" });
|
|
55
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
56
|
+
|
|
57
|
+
await act(async () => {
|
|
58
|
+
await result.current.handleInstallPackages(["numpy", "pandas"]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
expect(toast).toHaveBeenCalledTimes(1);
|
|
62
|
+
expect(toast).toHaveBeenCalledWith(
|
|
63
|
+
expect.objectContaining({
|
|
64
|
+
title: "Failed to add packages",
|
|
65
|
+
description: "boom",
|
|
66
|
+
variant: "danger",
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("collapses a partial (mixed) failure into one aggregate error toast", async () => {
|
|
72
|
+
// The backend resolves the batch as a single transaction and reports an
|
|
73
|
+
// aggregate outcome, so even when only some packages fail we surface a
|
|
74
|
+
// single error toast covering the whole batch — never a per-package
|
|
75
|
+
// success/failure split the response can't actually represent.
|
|
76
|
+
addPackage.mockResolvedValue({
|
|
77
|
+
success: false,
|
|
78
|
+
error: "pandas failed to install",
|
|
79
|
+
});
|
|
80
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
81
|
+
|
|
82
|
+
await act(async () => {
|
|
83
|
+
await result.current.handleInstallPackages(["numpy", "pandas"]);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(addPackage).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(addPackage).toHaveBeenCalledWith({ package: "numpy pandas" });
|
|
88
|
+
expect(toast).toHaveBeenCalledTimes(1);
|
|
89
|
+
expect(toast).toHaveBeenCalledWith(
|
|
90
|
+
expect.objectContaining({
|
|
91
|
+
title: "Failed to add packages",
|
|
92
|
+
description: "pandas failed to install",
|
|
93
|
+
variant: "danger",
|
|
94
|
+
}),
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("uses singular wording for a single package", async () => {
|
|
99
|
+
addPackage.mockResolvedValue({ success: true, error: null });
|
|
100
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
101
|
+
|
|
102
|
+
await act(async () => {
|
|
103
|
+
await result.current.handleInstallPackages(["numpy"]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
expect(toast).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(toast).toHaveBeenCalledWith(
|
|
108
|
+
expect.objectContaining({ title: "Package added" }),
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("calls onSuccess after a successful install", async () => {
|
|
113
|
+
addPackage.mockResolvedValue({ success: true, error: null });
|
|
114
|
+
const onSuccess = vi.fn();
|
|
115
|
+
const { result } = renderHook(() => useInstallPackages());
|
|
116
|
+
|
|
117
|
+
await act(async () => {
|
|
118
|
+
await result.current.handleInstallPackages(["numpy"], onSuccess);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(onSuccess).toHaveBeenCalledTimes(1);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -4,23 +4,34 @@ import { Kbd } from "@/components/ui/kbd";
|
|
|
4
4
|
import { toast } from "@/components/ui/use-toast";
|
|
5
5
|
|
|
6
6
|
export const showAddPackageToast = (
|
|
7
|
-
packageName: string,
|
|
7
|
+
packageName: string | string[],
|
|
8
8
|
error?: string | null,
|
|
9
9
|
) => {
|
|
10
|
+
const packageNames = Array.isArray(packageName) ? packageName : [packageName];
|
|
10
11
|
if (error) {
|
|
11
12
|
toast({
|
|
12
|
-
title:
|
|
13
|
+
title:
|
|
14
|
+
packageNames.length > 1
|
|
15
|
+
? "Failed to add packages"
|
|
16
|
+
: "Failed to add package",
|
|
13
17
|
description: error,
|
|
14
18
|
variant: "danger",
|
|
15
19
|
});
|
|
16
20
|
} else {
|
|
17
21
|
toast({
|
|
18
|
-
title: "Package added",
|
|
22
|
+
title: packageNames.length > 1 ? "Packages added" : "Package added",
|
|
19
23
|
description: (
|
|
20
24
|
<div>
|
|
21
25
|
<div>
|
|
22
|
-
The
|
|
23
|
-
|
|
26
|
+
{packageNames.length > 1 ? "The packages " : "The package "}
|
|
27
|
+
{packageNames.map((name, index) => (
|
|
28
|
+
<span key={name}>
|
|
29
|
+
{index > 0 && ", "}
|
|
30
|
+
<Kbd className="inline">{name}</Kbd>
|
|
31
|
+
</span>
|
|
32
|
+
))}{" "}
|
|
33
|
+
and {packageNames.length > 1 ? "their" : "its"} dependencies have
|
|
34
|
+
been added to your environment.
|
|
24
35
|
</div>
|
|
25
36
|
<div className="text-xs text-muted-foreground mt-1">
|
|
26
37
|
Some Python packages may require a kernel restart to see changes.
|
|
@@ -22,17 +22,18 @@ export function useInstallPackages(): {
|
|
|
22
22
|
setLoading(true);
|
|
23
23
|
|
|
24
24
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
// Batch all packages into a single install call.
|
|
26
|
+
// The worker splits by space and passes the full list to micropip,
|
|
27
|
+
// which resolves and downloads in parallel internally.
|
|
28
|
+
const response = await addPackage({ package: packages.join(" ") });
|
|
29
|
+
// The backend resolves the whole list as a single transaction, so the
|
|
30
|
+
// response only carries an aggregate success/error. Report a single
|
|
31
|
+
// toast covering all requested packages rather than implying a
|
|
32
|
+
// per-package outcome we don't actually have.
|
|
33
|
+
if (response.success) {
|
|
34
|
+
showAddPackageToast(packages);
|
|
35
|
+
} else {
|
|
36
|
+
showAddPackageToast(packages, response.error);
|
|
36
37
|
}
|
|
37
38
|
onSuccess?.();
|
|
38
39
|
} catch (error) {
|