@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.
- package/dist/{ErrorBoundary-CTJ1U1fx.js → ErrorBoundary-DxdeETpm.js} +1 -1
- package/dist/{code-visibility-C1jZfwPW.js → code-visibility-CO8abjLo.js} +1 -1
- package/dist/{common-CNv_7gvI.js → common-CbFJQhaI.js} +1 -1
- package/dist/{data-grid-overlay-editor-t0t17DPI.js → data-grid-overlay-editor-DBjVUS2K.js} +1 -1
- package/dist/{feedback-button-JzaiyZZm.js → feedback-button-CWQoIUKQ.js} +2 -2
- package/dist/{glide-data-editor-B3eq-1SC.js → glide-data-editor-BxT8eGip.js} +3 -3
- package/dist/{globals-BW8TOLYQ.js → globals-f0UxWZkr.js} +1 -1
- package/dist/main.js +9 -8
- package/dist/{number-overlay-editor-DoUnDbPE.js → number-overlay-editor-Dso2H7DV.js} +1 -1
- package/dist/{reveal-component-ClNn1CDl.js → reveal-component-DMglhlng.js} +2 -2
- package/package.json +1 -1
- package/src/core/host/__tests__/fixtures.ts +9 -1
- package/src/core/host/__tests__/static.test.ts +18 -12
- package/src/core/host/__tests__/wasm.test.ts +63 -60
- package/src/core/host/backend.ts +1 -1
- package/src/core/host/static.ts +10 -5
- package/src/core/host/wasm.ts +2 -12
- package/src/core/saving/save-component.tsx +12 -3
- package/src/core/wasm/__tests__/bridge.test.ts +177 -55
- package/src/core/wasm/__tests__/worker.test.ts +6 -1
- package/src/core/wasm/bridge.ts +48 -38
- package/src/core/wasm/rpc.ts +15 -2
- package/src/core/wasm/worker/save-worker.ts +9 -10
- package/src/core/wasm/worker/types.ts +6 -4
- package/src/core/wasm/worker/worker.ts +29 -17
- package/src/core/websocket/__tests__/backend.test.ts +10 -3
- package/src/core/websocket/backend.ts +9 -10
|
@@ -12,6 +12,7 @@ import type { UserConfig } from "@/core/config/config-schema";
|
|
|
12
12
|
import type {
|
|
13
13
|
ListPackagesResponse,
|
|
14
14
|
PackageOperationResponse,
|
|
15
|
+
NotebookDocumentTransactionRequest,
|
|
15
16
|
SaveNotebookRequest,
|
|
16
17
|
} from "@/core/network/types";
|
|
17
18
|
import { decodeUtf8 } from "@/utils/strings";
|
|
@@ -83,14 +84,6 @@ async function getNotebook() {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
const requestHandler = createRPCRequestHandler({
|
|
86
|
-
notebookInfo: async () => {
|
|
87
|
-
const notebook = await getNotebook();
|
|
88
|
-
try {
|
|
89
|
-
return { id: notebook.id };
|
|
90
|
-
} finally {
|
|
91
|
-
notebook.destroy();
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
87
|
notebookSubscribe: (request: { id: string; cursor: string | null }) => {
|
|
95
88
|
let canceled = false;
|
|
96
89
|
const subscribing = (async () => {
|
|
@@ -172,6 +165,17 @@ const requestHandler = createRPCRequestHandler({
|
|
|
172
165
|
queryParameters: opts.queryParameters,
|
|
173
166
|
userConfig: opts.userConfig,
|
|
174
167
|
});
|
|
168
|
+
const notebook = session.bridge.notebook;
|
|
169
|
+
try {
|
|
170
|
+
notebook.set_persistence(async (contents, filename) => {
|
|
171
|
+
// Keep file operations in the execution worker from syncing stale source.
|
|
172
|
+
self.pyodide.FS.writeFile(filename, contents);
|
|
173
|
+
self.pyodide.FS.writeFile(WasmFileSystem.NOTEBOOK_FILENAME, contents);
|
|
174
|
+
await rpc.proxy.request.persistNotebook({ filename, contents });
|
|
175
|
+
});
|
|
176
|
+
} finally {
|
|
177
|
+
notebook.destroy();
|
|
178
|
+
}
|
|
175
179
|
sessionReady.resolve(session);
|
|
176
180
|
rpc.send.initializingMessage({
|
|
177
181
|
message: "Initializing notebook...",
|
|
@@ -298,13 +302,21 @@ const requestHandler = createRPCRequestHandler({
|
|
|
298
302
|
};
|
|
299
303
|
},
|
|
300
304
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
305
|
+
documentTransaction: async (request: NotebookDocumentTransactionRequest) => {
|
|
306
|
+
const notebook = await getNotebook();
|
|
307
|
+
try {
|
|
308
|
+
await notebook.transaction(JSON.stringify(request));
|
|
309
|
+
} finally {
|
|
310
|
+
notebook.destroy();
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
setNotebookLayout: async (layout: SaveNotebookRequest["layout"]) => {
|
|
314
|
+
const notebook = await getNotebook();
|
|
315
|
+
try {
|
|
316
|
+
await notebook.set_layout(JSON.stringify(layout));
|
|
317
|
+
} finally {
|
|
318
|
+
notebook.destroy();
|
|
319
|
+
}
|
|
308
320
|
},
|
|
309
321
|
|
|
310
322
|
/**
|
|
@@ -403,6 +415,8 @@ const rpc = createRPC<WorkerSchema, ParentSchema>({
|
|
|
403
415
|
transportId: TRANSPORT_ID,
|
|
404
416
|
}),
|
|
405
417
|
requestHandler,
|
|
418
|
+
// Persistence can include bootstrapping the storage worker.
|
|
419
|
+
maxRequestTime: Infinity,
|
|
406
420
|
});
|
|
407
421
|
|
|
408
422
|
rpc.addMessageListener("bootstrap", (config) => runtimeConfig.resolve(config));
|
|
@@ -410,8 +424,6 @@ rpc.addMessageListener("bootstrap", (config) => runtimeConfig.resolve(config));
|
|
|
410
424
|
rpc.send("ready", {});
|
|
411
425
|
|
|
412
426
|
const namesThatRequireSync = new Set<keyof RawBridge>([
|
|
413
|
-
"save",
|
|
414
|
-
"save_app_config",
|
|
415
427
|
"rename_file",
|
|
416
428
|
"create_file_or_directory",
|
|
417
429
|
"delete_file_or_directory",
|
|
@@ -5,7 +5,11 @@ import { createStore } from "jotai/vanilla";
|
|
|
5
5
|
import { afterEach, describe, expect, it, onTestFinished, vi } from "vitest";
|
|
6
6
|
import { Deferred } from "@/utils/Deferred";
|
|
7
7
|
import { ConnectionState } from "../../host/connection";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type FakeEdit,
|
|
10
|
+
type FakeSave,
|
|
11
|
+
fakeBackend,
|
|
12
|
+
} from "../../host/__tests__/fixtures";
|
|
9
13
|
import { createNotebookReplica } from "../../host/replica";
|
|
10
14
|
import { createEditorBackend } from "../backend";
|
|
11
15
|
|
|
@@ -119,11 +123,12 @@ describe("createEditorBackend", () => {
|
|
|
119
123
|
expect(fetch).not.toHaveBeenCalled();
|
|
120
124
|
});
|
|
121
125
|
|
|
122
|
-
it("
|
|
126
|
+
it("routes WASM commands through the worker once its stream starts", async () => {
|
|
123
127
|
wasm.enabled = true;
|
|
124
128
|
const edit = vi.fn<FakeEdit>();
|
|
129
|
+
const save = vi.fn<FakeSave>();
|
|
125
130
|
const transport = vi.fn(async () => undefined);
|
|
126
|
-
wasm.create.mockResolvedValue(fakeBackend({ transport, edit }));
|
|
131
|
+
wasm.create.mockResolvedValue(fakeBackend({ transport, edit, save }));
|
|
127
132
|
const backend = createEditorBackend(options);
|
|
128
133
|
expect(wasm.create).not.toHaveBeenCalled();
|
|
129
134
|
expect(() => backend.notebook("n1")).toThrow("has not started");
|
|
@@ -136,6 +141,8 @@ describe("createEditorBackend", () => {
|
|
|
136
141
|
expect(transport).toHaveBeenCalledWith(attempt, handlers);
|
|
137
142
|
await backend.notebook("n1").edit([], { idempotencyKey: "edit-1" });
|
|
138
143
|
expect(edit).toHaveBeenCalledWith("n1", [], { idempotencyKey: "edit-1" });
|
|
144
|
+
await backend.notebook("n2").save({ idempotencyKey: "save-1" });
|
|
145
|
+
expect(save).toHaveBeenCalledWith("n2", { idempotencyKey: "save-1" });
|
|
139
146
|
});
|
|
140
147
|
|
|
141
148
|
it("stops following WASM when the worker does not start", async () => {
|
|
@@ -92,17 +92,16 @@ function wasm(): NotebookBackend {
|
|
|
92
92
|
|
|
93
93
|
/** Commands for a notebook the editor cannot change through its backend. */
|
|
94
94
|
function uneditable(): ReturnType<NotebookBackend["notebook"]> {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
const unsupported: NotebookClient["save"] = async () => ({
|
|
96
|
+
ok: false,
|
|
97
|
+
status: 501,
|
|
98
|
+
problem: {
|
|
99
|
+
type: "tag:marimo.io,2026:host/unsupported-operation",
|
|
100
|
+
title: "Document mutations are unavailable on this connection",
|
|
98
101
|
status: 501,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
status: 501,
|
|
103
|
-
},
|
|
104
|
-
}),
|
|
105
|
-
};
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
return { edit: () => unsupported(), save: unsupported };
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
/** Choose the backend for the editor's notebook. */
|