@marimo-team/islands 0.19.10-dev42 → 0.19.10-dev45

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/main.js CHANGED
@@ -40229,6 +40229,12 @@ ${c.sqlString}
40229
40229
  }
40230
40230
  });
40231
40231
  }
40232
+ function isStaticNotebook() {
40233
+ return (window == null ? void 0 : window.__MARIMO_STATIC__) !== void 0;
40234
+ }
40235
+ function getStaticVirtualFiles() {
40236
+ return invariant(window.__MARIMO_STATIC__ !== void 0, "Not a static notebook"), window.__MARIMO_STATIC__.files;
40237
+ }
40232
40238
  function base64ToDataURL(e, r) {
40233
40239
  return `data:${r};base64,${e}`;
40234
40240
  }
@@ -40319,12 +40325,6 @@ ${c.sqlString}
40319
40325
  type: d
40320
40326
  });
40321
40327
  }
40322
- function isStaticNotebook() {
40323
- return (window == null ? void 0 : window.__MARIMO_STATIC__) !== void 0;
40324
- }
40325
- function getStaticVirtualFiles() {
40326
- return invariant(window.__MARIMO_STATIC__ !== void 0, "Not a static notebook"), window.__MARIMO_STATIC__.files;
40327
- }
40328
40328
  function withoutLeadingDot(e) {
40329
40329
  return e.startsWith(".") ? e.slice(1) : e;
40330
40330
  }
@@ -40571,7 +40571,10 @@ ${c.sqlString}
40571
40571
  getMarimoInternal(y).updateAndEmitDiffs(v);
40572
40572
  return;
40573
40573
  }
40574
- e.create(c, (e2) => new Model(v, {
40574
+ e.create(c, (e2) => new Model(v, isStaticNotebook() ? {
40575
+ sendUpdate: async () => void 0,
40576
+ sendCustomMessage: async () => void 0
40577
+ } : {
40575
40578
  async sendUpdate(r3) {
40576
40579
  if (e2.aborted) {
40577
40580
  Logger.debug(`[Model] sendUpdate suppressed for model=${c} (signal aborted)`);
@@ -73306,7 +73309,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
73306
73309
  return Logger.warn("Failed to get version from mount config"), null;
73307
73310
  }
73308
73311
  }
73309
- const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.10-dev42"), showCodeInRunModeAtom = atom(true);
73312
+ const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.10-dev45"), showCodeInRunModeAtom = atom(true);
73310
73313
  atom(null);
73311
73314
  var import_compiler_runtime$88 = require_compiler_runtime();
73312
73315
  function useKeydownOnElement(e, r) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.19.10-dev42",
3
+ "version": "0.19.10-dev45",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -13,6 +13,7 @@ export const DATA_TYPES = [
13
13
  "time",
14
14
  "unknown",
15
15
  ] as const;
16
+ export type ModelLifecycle = NotificationMessageData<"model-lifecycle">;
16
17
  export type Banner = NotificationMessageData<"banner">;
17
18
  export type AiInlineCompletionRequest = schemas["AiInlineCompletionRequest"];
18
19
  export type DataTableColumn = schemas["DataTableColumn"];
@@ -1,5 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { invariant } from "@/utils/invariant";
3
+ import type { ModelLifecycle } from "../kernel/messages";
3
4
  import type { MarimoStaticState, StaticVirtualFiles } from "./types";
4
5
 
5
6
  declare global {
@@ -17,3 +18,7 @@ export function getStaticVirtualFiles(): StaticVirtualFiles {
17
18
 
18
19
  return window.__MARIMO_STATIC__.files;
19
20
  }
21
+
22
+ export function getStaticModelNotifications(): ModelLifecycle[] | undefined {
23
+ return window?.__MARIMO_STATIC__?.modelNotifications;
24
+ }
@@ -1,8 +1,10 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import type { DataURLString } from "@/utils/json/base64";
3
+ import type { ModelLifecycle } from "../kernel/messages";
3
4
 
4
5
  export type StaticVirtualFiles = Record<string, DataURLString>;
5
6
 
6
7
  export interface MarimoStaticState {
7
8
  files: StaticVirtualFiles;
9
+ modelNotifications?: ModelLifecycle[];
8
10
  }
package/src/mount.tsx CHANGED
@@ -39,11 +39,18 @@ import {
39
39
  import { codeAtom, filenameAtom } from "./core/saving/file-state";
40
40
  import { store } from "./core/state/jotai";
41
41
  import { patchFetch, patchVegaLoader } from "./core/static/files";
42
- import { isStaticNotebook } from "./core/static/static-state";
42
+ import {
43
+ getStaticModelNotifications,
44
+ isStaticNotebook,
45
+ } from "./core/static/static-state";
43
46
  import { maybeRegisterVSCodeBindings } from "./core/vscode/vscode-bindings";
44
47
  import type { FileStore } from "./core/wasm/store";
45
48
  import { notebookFileStore } from "./core/wasm/store";
46
49
  import { WebSocketState } from "./core/websocket/types";
50
+ import {
51
+ handleWidgetMessage,
52
+ MODEL_MANAGER,
53
+ } from "./plugins/impl/anywidget/model";
47
54
  import { vegaLoader } from "./plugins/impl/vega/loader";
48
55
  import { initializePlugins } from "./plugins/plugins";
49
56
  import { ThemeProvider } from "./theme/ThemeProvider";
@@ -77,6 +84,7 @@ export function mount(options: unknown, el: Element): Error | undefined {
77
84
  // If we're in static mode, we need to patch fetch to use the virtual file
78
85
  patchFetch();
79
86
  patchVegaLoader(vegaLoader);
87
+ hydrateStaticModels();
80
88
  }
81
89
 
82
90
  // Init store
@@ -330,6 +338,20 @@ function initStore(options: unknown) {
330
338
  }
331
339
  }
332
340
 
341
+ /**
342
+ * Hydrate anywidget models from embedded static state so widgets
343
+ * render immediately without a kernel connection.
344
+ */
345
+ function hydrateStaticModels(): void {
346
+ const notifications = getStaticModelNotifications();
347
+ if (!notifications) {
348
+ return;
349
+ }
350
+ for (const notification of notifications) {
351
+ handleWidgetMessage(MODEL_MANAGER, notification);
352
+ }
353
+ }
354
+
333
355
  export const visibleForTesting = {
334
356
  reset: () => {
335
357
  hasMounted = false;
@@ -31,6 +31,12 @@ vi.mock("@/core/network/requests", () => ({
31
31
  }),
32
32
  }));
33
33
 
34
+ // Mock isStaticNotebook — default to false (normal mode)
35
+ const mockIsStatic = vi.fn().mockReturnValue(false);
36
+ vi.mock("@/core/static/static-state", () => ({
37
+ isStaticNotebook: () => mockIsStatic(),
38
+ }));
39
+
34
40
  // Helper to create a mock MarimoComm
35
41
  function createMockComm<T>() {
36
42
  return {
@@ -393,4 +399,51 @@ describe("ModelManager", () => {
393
399
 
394
400
  expect(BINDING_MANAGER.has(testId)).toBe(false);
395
401
  });
402
+
403
+ describe("static mode", () => {
404
+ beforeEach(() => {
405
+ mockIsStatic.mockReturnValue(true);
406
+ });
407
+
408
+ afterAll(() => {
409
+ mockIsStatic.mockReturnValue(false);
410
+ });
411
+
412
+ it("should create model with no-op comm in static mode", async () => {
413
+ await handleWidgetMessage(modelManager, {
414
+ model_id: testId,
415
+ message: {
416
+ method: "open",
417
+ state: { count: 42 },
418
+ buffer_paths: [],
419
+ buffers: [],
420
+ },
421
+ });
422
+
423
+ const model = await modelManager.get(testId);
424
+ expect(model.get("count")).toBe(42);
425
+
426
+ // save_changes should not call the real request client
427
+ model.set("count", 100);
428
+ model.save_changes();
429
+ expect(mockSendModelValue).not.toHaveBeenCalled();
430
+ });
431
+
432
+ it("should not throw on send in static mode", async () => {
433
+ await handleWidgetMessage(modelManager, {
434
+ model_id: testId,
435
+ message: {
436
+ method: "open",
437
+ state: { count: 0 },
438
+ buffer_paths: [],
439
+ buffers: [],
440
+ },
441
+ });
442
+
443
+ const model = await modelManager.get(testId);
444
+ // send() should silently no-op
445
+ await expect(model.send({ test: true })).resolves.toBeUndefined();
446
+ expect(mockSendModelValue).not.toHaveBeenCalled();
447
+ });
448
+ });
396
449
  });
@@ -5,6 +5,7 @@ import type { AnyModel } from "@anywidget/types";
5
5
  import { debounce } from "lodash-es";
6
6
  import type { NotificationMessageData } from "@/core/kernel/messages";
7
7
  import { getRequestClient } from "@/core/network/requests";
8
+ import { isStaticNotebook } from "@/core/static/static-state";
8
9
  import {
9
10
  decodeFromWire,
10
11
  serializeBuffersToBase64,
@@ -343,12 +344,14 @@ export async function handleWidgetMessage(
343
344
  return;
344
345
  }
345
346
 
346
- modelManager.create(
347
- modelId,
348
- (signal) =>
349
- new Model(
350
- stateWithBuffers,
351
- {
347
+ modelManager.create(modelId, (signal) => {
348
+ // In static exports there is no kernel, so comm calls are no-ops.
349
+ const comm: MarimoComm<ModelState> = isStaticNotebook()
350
+ ? {
351
+ sendUpdate: async () => undefined,
352
+ sendCustomMessage: async () => undefined,
353
+ }
354
+ : {
352
355
  async sendUpdate(changeData) {
353
356
  if (signal.aborted) {
354
357
  Logger.debug(
@@ -377,10 +380,10 @@ export async function handleWidgetMessage(
377
380
  buffers: buffers.map(dataViewToBase64),
378
381
  });
379
382
  },
380
- },
381
- signal,
382
- ),
383
- );
383
+ };
384
+
385
+ return new Model(stateWithBuffers, comm, signal);
386
+ });
384
387
  return;
385
388
  }
386
389