@marimo-team/islands 0.25.3-dev201 → 0.25.3-dev203
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/{ConnectedDataExplorerComponent-BsWiIPFk.js → ConnectedDataExplorerComponent-DFynurqb.js} +4 -4
- package/dist/{ErrorBoundary-JYAf40sB.js → ErrorBoundary-CYw4nBEN.js} +2 -2
- package/dist/{abnfDiagram-VCTEODGH-I2x4Yu25.js → abnfDiagram-VCTEODGH-DGkUyNdz.js} +2 -2
- package/dist/{architectureDiagram-5GKGNRK7-1bSQMKzK.js → architectureDiagram-5GKGNRK7-Bav9J7uF.js} +1 -1
- package/dist/{chat-ui-DXDoSuS4.js → chat-ui-Dorq26Pp.js} +7 -7
- package/dist/{chunk-IMKFNOWR-fsCGAJ9G.js → chunk-IMKFNOWR-1UCTsTqh.js} +1 -1
- package/dist/{chunk-SHT3W25Y-D2STW4hj.js → chunk-SHT3W25Y-Bige_rTb.js} +1 -1
- package/dist/{chunk-SVP7TREG-CiY7cQG-.js → chunk-SVP7TREG-Cmr0Anfb.js} +1 -1
- package/dist/{chunk-TICWLB2K-C_t5RBp9.js → chunk-TICWLB2K-IWykFldb.js} +1 -1
- package/dist/{classDiagram-ZZMXUADV-B2JvZAP4.js → classDiagram-ZZMXUADV-BH73ECRQ.js} +2 -2
- package/dist/{classDiagram-v2-VYDZK3BY-L8VsZG5A.js → classDiagram-v2-VYDZK3BY-CCuCgq0H.js} +2 -2
- package/dist/{code-visibility-BKyYMfr_.js → code-visibility-WinzKDYd.js} +4 -4
- package/dist/{common-BCY25vum.js → common-D1st4ghC.js} +9 -9
- package/dist/{cynefinDiagram-5FMLGOSQ-DdllC264.js → cynefinDiagram-5FMLGOSQ-CWtL7MIJ.js} +1 -1
- package/dist/{dagre-GXQ25YYZ-BaWHw4_f.js → dagre-GXQ25YYZ-DsVO2pVC.js} +1 -1
- package/dist/{data-grid-overlay-editor-gQmJxgU-.js → data-grid-overlay-editor-Ct_7pOS8.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-pFt-tUDe.js → diagram-S7CK7UJ4-BuAktgZv.js} +1 -1
- package/dist/{diagram-UQ7AKVKN-DqGJiBp4.js → diagram-UQ7AKVKN-DlkAXHu5.js} +1 -1
- package/dist/{diagram-VX7I27RA-Dr-yzMjf.js → diagram-VX7I27RA-B9U9H0E8.js} +1 -1
- package/dist/{diagram-Z3DM3KII-8xzJzv-w.js → diagram-Z3DM3KII-BqmfxzUL.js} +1 -1
- package/dist/{dropdown-menu-NlnsmNA6.js → dropdown-menu-BFQYzWmC.js} +1 -1
- package/dist/{ebnfDiagram-PWID7BFC-Br04Wy-E.js → ebnfDiagram-PWID7BFC-CH5t8ATi.js} +2 -2
- package/dist/{erDiagram-RLTQ6QDP-D5-XVgvv.js → erDiagram-RLTQ6QDP-DdIo2BIb.js} +1 -1
- package/dist/{error-entries-C2Ux0Fjt.js → error-entries-B0bcEwXm.js} +4 -4
- package/dist/{feedback-button-BKgw9MHY.js → feedback-button-BYqWGSOj.js} +5 -5
- package/dist/{flowDiagram-HODETNUW-CVl2kREF.js → flowDiagram-HODETNUW-BmYk_-Na.js} +2 -2
- package/dist/{formats-BCYthwyc.js → formats-DyYnckF5.js} +1 -1
- package/dist/{glide-data-editor-CzS51bb2.js → glide-data-editor-odIdinCX.js} +5 -5
- package/dist/{globals-DQ4tv_a-.js → globals-Pb4d_RfL.js} +2 -2
- package/dist/{html-to-image-CkH7vdBZ.js → html-to-image-BOd7ryZJ.js} +5 -5
- package/dist/{infoDiagram-27XIBGKW-BJ4vNcZE.js → infoDiagram-27XIBGKW-DvYh-Sbk.js} +1 -1
- package/dist/{ishikawaDiagram-5VMMS53U-B_Jy1Dsm.js → ishikawaDiagram-5VMMS53U-BdHnYq8s.js} +1 -1
- package/dist/{kanban-definition-UXKFOSKX-C6MkS9vw.js → kanban-definition-UXKFOSKX-Bf8CT_tU.js} +1 -1
- package/dist/main.js +48 -70
- package/dist/{mermaid-Bh918qrq.js → mermaid-DBpOnw8c.js} +34 -34
- package/dist/{mindmap-definition-YA3MSWOX-BP3ZTuir.js → mindmap-definition-YA3MSWOX-DkYG8ltR.js} +1 -1
- package/dist/{number-overlay-editor-B3ZE3-6d.js → number-overlay-editor-CaCxGSux.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-nNGOQtnt.js → pegDiagram-XKGWAZYB-DM7BQ0ip.js} +2 -2
- package/dist/{pieDiagram-E7YTZNPT-CpRz5BZz.js → pieDiagram-E7YTZNPT-CPFGg4YS.js} +1 -1
- package/dist/{process-output-OujAtFW4.js → process-output-8BbxxGrz.js} +2 -2
- package/dist/{railroadDiagram-O6MQD6OU-BqOEN4I0.js → railroadDiagram-O6MQD6OU-4rUJlIpQ.js} +2 -2
- package/dist/{requirementDiagram-BXWQKSXE-CEfg6vu9.js → requirementDiagram-BXWQKSXE-F6ffUUQC.js} +1 -1
- package/dist/{reveal-component-DXa9FXf6.js → reveal-component-Dlt6nj0h.js} +6 -6
- package/dist/{sequenceDiagram-WJ2MYXX4-IOmpQcOi.js → sequenceDiagram-WJ2MYXX4-tNU95HVS.js} +1 -1
- package/dist/{spec-Dkp64vVQ.js → spec-Alkla7dB.js} +1 -1
- package/dist/{stateDiagram-D77RDMKH-tgU-EY9_.js → stateDiagram-D77RDMKH-BA8Modqv.js} +2 -2
- package/dist/{stateDiagram-v2-MP3YSRHH-BofhG6q1.js → stateDiagram-v2-MP3YSRHH-CFmickht.js} +2 -2
- package/dist/{swimlanes-42K2YHIH-DW4vWDBd.js → swimlanes-42K2YHIH-DBiYZZZc.js} +1 -1
- package/dist/{swimlanesDiagram-VR7AAH4N-BJcrqUJr.js → swimlanesDiagram-VR7AAH4N-CsgR851k.js} +2 -2
- package/dist/{timeline-definition-24CTP7MA-D_QU3NGs.js → timeline-definition-24CTP7MA-Dfj0CMXY.js} +1 -1
- package/dist/{toDate-BNDEXbfV.js → toDate-B0-Y0SEW.js} +1 -1
- package/dist/{useAsyncData-ASDni9vH.js → useAsyncData-Phxf6GCd.js} +1 -1
- package/dist/{useDeepCompareMemoize-B1Ogyf53.js → useDeepCompareMemoize-BXv7DUcU.js} +1 -1
- package/dist/{useLifecycle-Bfpa2m7k.js → useLifecycle-DDDsO4O2.js} +1 -1
- package/dist/{useTheme-5TwyOh3B.js → useTheme-DbBkeP6Z.js} +65 -60
- package/dist/{vega-component-BHS9UOtC.js → vega-component-C_dhEynE.js} +5 -5
- package/dist/{vennDiagram-4TSXK5OY-YFYsNIAh.js → vennDiagram-4TSXK5OY-fJ83Z7FE.js} +1 -1
- package/dist/{wardleyDiagram-VM6X3IG4-i_n8mAWC.js → wardleyDiagram-VM6X3IG4-DbO9cD15.js} +1 -1
- package/dist/{xychartDiagram-S5SC5T6Z-BYGN95wW.js → xychartDiagram-S5SC5T6Z-DmsdQJG7.js} +1 -1
- package/package.json +1 -1
- package/src/__mocks__/requests.ts +1 -1
- package/src/components/editor/header/__tests__/filename-form.test.tsx +1 -4
- package/src/components/editor/header/filename-form.tsx +1 -1
- package/src/core/cells/__tests__/document.test.ts +1 -22
- package/src/core/cells/document.ts +0 -33
- package/src/core/islands/bridge.ts +1 -1
- package/src/core/network/requests-lazy.ts +1 -1
- package/src/core/network/requests-network.ts +8 -9
- package/src/core/network/requests-static.ts +1 -1
- package/src/core/network/requests-toasting.tsx +1 -1
- package/src/core/network/types.ts +6 -2
- package/src/core/notebook/document/model.ts +0 -3
- package/src/core/notebook/document/sync.ts +4 -53
- package/src/core/saving/__tests__/document.test.tsx +123 -0
- package/src/core/saving/document.ts +33 -0
- package/src/core/saving/save-component.tsx +24 -37
- package/src/core/session/active-notebook.ts +6 -0
- package/src/core/wasm/__tests__/bridge.test.ts +2 -126
- package/src/core/wasm/bridge.ts +1 -18
- package/src/core/wasm/worker/worker.ts +2 -2
- package/src/core/cells/__tests__/with-document-save.test.ts +0 -67
- package/src/core/notebook/document/__tests__/hold.test.ts +0 -88
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
|
|
3
|
-
import { atom } from "jotai";
|
|
4
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
5
|
-
import { createDocumentModel } from "@/core/notebook/document";
|
|
6
|
-
import { document } from "@/core/notebook/document/__tests__/fixtures";
|
|
7
|
-
import type { Document } from "@/core/notebook/replica/resources/document";
|
|
8
|
-
import {
|
|
9
|
-
type FakeEdit,
|
|
10
|
-
fakeBackend,
|
|
11
|
-
} from "@/core/notebook/replica/__tests__/fixtures";
|
|
12
|
-
import { activeDocumentModelAtom } from "@/core/session/active-notebook";
|
|
13
|
-
import { store } from "@/core/state/jotai";
|
|
14
|
-
import { Deferred } from "@/utils/Deferred";
|
|
15
|
-
import { withDocumentSave } from "../document";
|
|
16
|
-
|
|
17
|
-
const lifetimes: AbortController[] = [];
|
|
18
|
-
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
lifetimes.splice(0).forEach((controller) => controller.abort());
|
|
21
|
-
store.set(activeDocumentModelAtom, null);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe("withDocumentSave", () => {
|
|
25
|
-
it("sends an edit made during the save only after the save finishes", async () => {
|
|
26
|
-
const source = atom<Document | null>(document());
|
|
27
|
-
const base = document();
|
|
28
|
-
const accepted: Document = {
|
|
29
|
-
...base,
|
|
30
|
-
revision: { ...base.revision, version: 2, etag: "document-2" },
|
|
31
|
-
};
|
|
32
|
-
// Answer the edit, then publish the accepted document as the host would.
|
|
33
|
-
const edit = vi.fn<FakeEdit>().mockImplementation(async () => {
|
|
34
|
-
queueMicrotask(() => store.set(source, accepted));
|
|
35
|
-
return {
|
|
36
|
-
ok: true,
|
|
37
|
-
status: 200,
|
|
38
|
-
data: { document: accepted.revision, cells: {} },
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
const model = createDocumentModel({
|
|
42
|
-
store,
|
|
43
|
-
documentAtom: source,
|
|
44
|
-
backendAtom: atom(fakeBackend({ edit })),
|
|
45
|
-
});
|
|
46
|
-
const controller = new AbortController();
|
|
47
|
-
lifetimes.push(controller);
|
|
48
|
-
model.start({ signal: controller.signal });
|
|
49
|
-
store.set(activeDocumentModelAtom, model);
|
|
50
|
-
|
|
51
|
-
const saving = new Deferred<void>();
|
|
52
|
-
let flushing: Promise<unknown> | undefined;
|
|
53
|
-
const saved = withDocumentSave(async () => {
|
|
54
|
-
store.set(model.editAtom, (tx) => tx.setCode("c1", "x = 2"));
|
|
55
|
-
flushing = model.flush();
|
|
56
|
-
await Promise.resolve();
|
|
57
|
-
expect(edit).not.toHaveBeenCalled();
|
|
58
|
-
await saving.promise;
|
|
59
|
-
return "saved";
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
saving.resolve();
|
|
63
|
-
await expect(saved).resolves.toBe("saved");
|
|
64
|
-
await flushing;
|
|
65
|
-
expect(edit).toHaveBeenCalledTimes(1);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
|
|
3
|
-
import { atom, createStore } from "jotai";
|
|
4
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
5
|
-
import type { Document } from "../../replica/resources/document";
|
|
6
|
-
import { createDocumentModel } from "..";
|
|
7
|
-
import { type FakeEdit, fakeBackend } from "../../replica/__tests__/fixtures";
|
|
8
|
-
import { document } from "./fixtures";
|
|
9
|
-
|
|
10
|
-
const lifetimes: AbortController[] = [];
|
|
11
|
-
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
lifetimes.splice(0).forEach((controller) => controller.abort());
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
/** The document after the host accepts one edit. */
|
|
17
|
-
function accepted(): Document {
|
|
18
|
-
const base = document();
|
|
19
|
-
return {
|
|
20
|
-
...base,
|
|
21
|
-
revision: { ...base.revision, version: 2, etag: "document-2" },
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function setup() {
|
|
26
|
-
const store = createStore();
|
|
27
|
-
const source = atom<Document | null>(document());
|
|
28
|
-
// Answer the edit, then publish the accepted document as the host would.
|
|
29
|
-
const edit = vi.fn<FakeEdit>().mockImplementation(async () => {
|
|
30
|
-
queueMicrotask(() => store.set(source, accepted()));
|
|
31
|
-
return {
|
|
32
|
-
ok: true,
|
|
33
|
-
status: 200,
|
|
34
|
-
data: { document: accepted().revision, cells: {} },
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
const model = createDocumentModel({
|
|
38
|
-
store,
|
|
39
|
-
documentAtom: source,
|
|
40
|
-
backendAtom: atom(fakeBackend({ edit })),
|
|
41
|
-
});
|
|
42
|
-
const controller = new AbortController();
|
|
43
|
-
lifetimes.push(controller);
|
|
44
|
-
model.start({ signal: controller.signal });
|
|
45
|
-
return { store, model, edit, controller };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
describe("document sync hold", () => {
|
|
49
|
-
it("keeps an edit local until released, then lets a waiting flush send it", async () => {
|
|
50
|
-
const { store, model, edit } = setup();
|
|
51
|
-
const release = model.hold();
|
|
52
|
-
store.set(model.editAtom, (tx) => tx.setCode("c1", "x = 2"));
|
|
53
|
-
const flushing = model.flush();
|
|
54
|
-
await Promise.resolve();
|
|
55
|
-
expect(edit).not.toHaveBeenCalled();
|
|
56
|
-
expect(store.get(model.syncStatusAtom)).toEqual({ status: "pending" });
|
|
57
|
-
|
|
58
|
-
release();
|
|
59
|
-
await flushing;
|
|
60
|
-
expect(edit).toHaveBeenCalledTimes(1);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it("releases once the last of nested holds is released", async () => {
|
|
64
|
-
const { store, model, edit } = setup();
|
|
65
|
-
const outer = model.hold();
|
|
66
|
-
const inner = model.hold();
|
|
67
|
-
store.set(model.editAtom, (tx) => tx.setCode("c1", "x = 2"));
|
|
68
|
-
const flushing = model.flush();
|
|
69
|
-
|
|
70
|
-
inner();
|
|
71
|
-
inner();
|
|
72
|
-
await Promise.resolve();
|
|
73
|
-
expect(edit).not.toHaveBeenCalled();
|
|
74
|
-
|
|
75
|
-
outer();
|
|
76
|
-
await flushing;
|
|
77
|
-
expect(edit).toHaveBeenCalledTimes(1);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("rejects a flush waiting on a hold when the model stops", async () => {
|
|
81
|
-
const { store, model, controller } = setup();
|
|
82
|
-
model.hold();
|
|
83
|
-
store.set(model.editAtom, (tx) => tx.setCode("c1", "x = 2"));
|
|
84
|
-
const flushing = model.flush();
|
|
85
|
-
controller.abort(new Error("session ended"));
|
|
86
|
-
await expect(flushing).rejects.toThrow("session ended");
|
|
87
|
-
});
|
|
88
|
-
});
|