@marimo-team/islands 0.24.3-dev55 → 0.24.3-dev58

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 (29) hide show
  1. package/dist/{ErrorBoundary-uQMMsMtf.js → ErrorBoundary-D1_JTlgF.js} +1 -1
  2. package/dist/assets/__vite-browser-external-C9iR87Zl.js +1 -0
  3. package/dist/assets/{worker-BemUy60C.js → worker-D7hWi02M.js} +2 -2
  4. package/dist/{code-visibility-DXFlGQTg.js → code-visibility-Ct164a9c.js} +1 -1
  5. package/dist/{common-DHIrhrev.js → common-B8x6sgCj.js} +1 -1
  6. package/dist/{data-grid-overlay-editor-DhUvLXgC.js → data-grid-overlay-editor-DOiNVNSM.js} +1 -1
  7. package/dist/{feedback-button-DejCYgl6.js → feedback-button-ajITqvHB.js} +2 -2
  8. package/dist/{glide-data-editor-BeDrnFzb.js → glide-data-editor-BZeeQUSi.js} +3 -3
  9. package/dist/{globals-DIuJGoqK.js → globals-S6heT9pz.js} +1 -1
  10. package/dist/main.js +42 -30
  11. package/dist/{number-overlay-editor-CKgrZ6UJ.js → number-overlay-editor-DSBousWi.js} +1 -1
  12. package/dist/{reveal-component-sLNrYulm.js → reveal-component-CegCLPOh.js} +2 -2
  13. package/package.json +1 -1
  14. package/src/core/islands/worker-factory.ts +2 -12
  15. package/src/core/wasm/__tests__/bootstrap.test.ts +63 -0
  16. package/src/core/wasm/__tests__/bridge.test.ts +8 -0
  17. package/src/core/wasm/__tests__/fs.test.ts +22 -0
  18. package/src/core/wasm/__tests__/runtime-config.test.ts +58 -0
  19. package/src/core/wasm/bridge.ts +18 -16
  20. package/src/core/wasm/rpc.ts +2 -0
  21. package/src/core/wasm/runtime-config.ts +27 -0
  22. package/src/core/wasm/worker/bootstrap.ts +21 -11
  23. package/src/core/wasm/worker/fs.ts +4 -0
  24. package/src/core/wasm/worker/save-worker.ts +7 -0
  25. package/src/core/wasm/worker/types.ts +7 -4
  26. package/src/core/wasm/worker/worker.ts +6 -0
  27. package/src/utils/__tests__/worker.test.ts +81 -0
  28. package/src/utils/worker.ts +22 -0
  29. package/dist/assets/__vite-browser-external-BajL8aoc.js +0 -1
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { PyodideInterface } from "pyodide";
3
+ import type { WasmRuntimeConfig } from "../runtime-config";
3
4
  import type { UserConfig } from "@/core/config/config-schema";
4
5
  import type {
5
6
  CommandMessage,
@@ -43,10 +44,12 @@ export interface WasmController {
43
44
  * Prepare the wasm environment
44
45
  * @param opts.version - The marimo version
45
46
  */
46
- bootstrap(opts: {
47
- version: string;
48
- pyodideVersion: string;
49
- }): Promise<PyodideInterface>;
47
+ bootstrap(
48
+ opts: WasmRuntimeConfig & {
49
+ version: string;
50
+ pyodideVersion: string;
51
+ },
52
+ ): Promise<PyodideInterface>;
50
53
  /**
51
54
  * Mount the filesystem
52
55
  * @param opts.code - The code to mount
@@ -22,6 +22,7 @@ import { prettyError } from "../../../utils/errors";
22
22
  import { invariant } from "../../../utils/invariant";
23
23
  import { Logger } from "../../../utils/Logger";
24
24
  import type { ParentSchema } from "../rpc";
25
+ import type { WasmRuntimeConfig } from "../runtime-config";
25
26
  import { TRANSPORT_ID } from "./constants";
26
27
  import { WasmFileSystem } from "./fs";
27
28
  import { getController } from "./getController";
@@ -47,6 +48,8 @@ declare const self: Window & {
47
48
 
48
49
  const workerInitSpan = t.startSpan("worker:init");
49
50
 
51
+ const runtimeConfig = new Deferred<WasmRuntimeConfig>();
52
+
50
53
  // Initialize pyodide
51
54
  async function loadPyodideAndPackages() {
52
55
  try {
@@ -58,6 +61,7 @@ async function loadPyodideAndPackages() {
58
61
  message: "Loading marimo...",
59
62
  });
60
63
  self.pyodide = await t.wrapAsync(controller.bootstrap.bind(controller))({
64
+ ...(await runtimeConfig.promise),
61
65
  version: marimoVersion,
62
66
  pyodideVersion: pyodideVersion,
63
67
  });
@@ -354,6 +358,8 @@ const rpc = createRPC<WorkerSchema, ParentSchema>({
354
358
  requestHandler,
355
359
  });
356
360
 
361
+ rpc.addMessageListener("bootstrap", (config) => runtimeConfig.resolve(config));
362
+
357
363
  rpc.send("ready", {});
358
364
 
359
365
  /// Listeners
@@ -0,0 +1,81 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import { createModuleWorker } from "../worker";
4
+
5
+ afterEach(() => {
6
+ vi.unstubAllGlobals();
7
+ vi.restoreAllMocks();
8
+ });
9
+
10
+ describe("createModuleWorker", () => {
11
+ it.each(["http", "blob"])(
12
+ "preserves caller-owned %s worker URLs",
13
+ (scheme) => {
14
+ const Worker = vi.fn(function (
15
+ _url: string | URL,
16
+ _options: WorkerOptions,
17
+ ) {
18
+ return {};
19
+ });
20
+ vi.stubGlobal("Worker", Worker);
21
+ const url = new URL(
22
+ scheme === "blob"
23
+ ? `blob:${location.origin}/worker`
24
+ : new URL("/worker.js", location.href),
25
+ );
26
+ const revoke = vi.spyOn(URL, "revokeObjectURL");
27
+ createModuleWorker(url, { name: "marimo" });
28
+ expect(Worker).toHaveBeenCalledWith(url.href, {
29
+ type: "module",
30
+ name: "marimo",
31
+ });
32
+ expect(revoke).not.toHaveBeenCalled();
33
+ },
34
+ );
35
+
36
+ it("preserves the page origin for hosted CDN workers", () => {
37
+ const Worker = vi.fn(function (
38
+ _url: string | URL,
39
+ _options: WorkerOptions,
40
+ ) {
41
+ return {};
42
+ });
43
+ vi.stubGlobal("Worker", Worker);
44
+ const create = vi
45
+ .spyOn(URL, "createObjectURL")
46
+ .mockReturnValue("blob:worker");
47
+ const revoke = vi
48
+ .spyOn(URL, "revokeObjectURL")
49
+ .mockImplementation(() => undefined);
50
+ createModuleWorker(new URL("https://cdn.example.com/worker.js"), {
51
+ name: "islands",
52
+ });
53
+ expect(create).toHaveBeenCalledWith(expect.any(Blob));
54
+ expect(Worker).toHaveBeenCalledWith("blob:worker", {
55
+ type: "module",
56
+ name: "islands",
57
+ });
58
+ expect(revoke).toHaveBeenCalledWith("blob:worker");
59
+ });
60
+
61
+ it("imports a CDN worker from an opaque origin", () => {
62
+ const Worker = vi.fn(function (
63
+ _url: string | URL,
64
+ _options: WorkerOptions,
65
+ ) {
66
+ return {};
67
+ });
68
+ vi.stubGlobal("Worker", Worker);
69
+ vi.stubGlobal("origin", "null");
70
+ const url = new URL("https://cdn.example.com/worker.js");
71
+ createModuleWorker(url, { name: "0.24.2::controller" });
72
+ const [source, options] = Worker.mock.calls[0];
73
+ expect(decodeURIComponent(String(source))).toBe(
74
+ 'data:application/javascript,import "https://cdn.example.com/worker.js"',
75
+ );
76
+ expect(options).toEqual({
77
+ type: "module",
78
+ name: "0.24.2::controller",
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,22 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ /** Load a module worker across origins, including from file:// pages. */
4
+ export function createModuleWorker(url: URL, options: WorkerOptions): Worker {
5
+ if (url.origin === globalThis.origin) {
6
+ return new Worker(url.href, { ...options, type: "module" });
7
+ }
8
+ const js = `import ${JSON.stringify(url.href)}`;
9
+ // Blob workers preserve the page origin, but file:// needs a data URL.
10
+ const source =
11
+ globalThis.origin === "null"
12
+ ? `data:application/javascript,${encodeURIComponent(js)}`
13
+ : URL.createObjectURL(new Blob([js], { type: "application/javascript" }));
14
+ try {
15
+ return new Worker(source, { ...options, type: "module" });
16
+ } finally {
17
+ if (source.startsWith("blob:")) {
18
+ // Worker() captures the Blob before returning, even while imports load.
19
+ URL.revokeObjectURL(source);
20
+ }
21
+ }
22
+ }
@@ -1 +0,0 @@
1
- import{t as e}from"./worker-BemUy60C.js";var t=e(((e,t)=>{t.exports={}}));export default t();