@marimo-team/islands 0.19.7-dev43 → 0.19.7-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
@@ -18703,7 +18703,7 @@ ${JSON.stringify(e2, null, 4)}`);
18703
18703
  }
18704
18704
  function singleFacet() {
18705
18705
  return Facet$1.define({
18706
- combine: (e) => e[0]
18706
+ combine: (e) => e.find((e2) => e2 !== void 0)
18707
18707
  });
18708
18708
  }
18709
18709
  singleFacet(), singleFacet(), singleFacet();
@@ -73168,7 +73168,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
73168
73168
  return Logger.warn("Failed to get version from mount config"), null;
73169
73169
  }
73170
73170
  }
73171
- const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.7-dev43"), showCodeInRunModeAtom = atom(true);
73171
+ const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.19.7-dev45"), showCodeInRunModeAtom = atom(true);
73172
73172
  atom(null);
73173
73173
  var import_compiler_runtime$88 = require_compiler_runtime();
73174
73174
  function useKeydownOnElement(e, r) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.19.7-dev43",
3
+ "version": "0.19.7-dev45",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -44,6 +44,7 @@ function createMockEditorView(code: string): EditorView {
44
44
  lspConfig: {},
45
45
  }),
46
46
  cellConfigExtension({
47
+ cellId: "cell1" as CellId,
47
48
  completionConfig: {
48
49
  copilot: false,
49
50
  activate_on_typing: true,
@@ -115,6 +115,7 @@ export const setupCodeMirror = (opts: CodeMirrorSetupOpts): Extension[] => {
115
115
  jupyterHelpExtension(),
116
116
  // Cell editing
117
117
  cellConfigExtension({
118
+ cellId,
118
119
  completionConfig,
119
120
  hotkeys,
120
121
  placeholderType,
@@ -41,12 +41,14 @@ export const lspConfigState = singleFacet<
41
41
  * Extension for cell config
42
42
  */
43
43
  export function cellConfigExtension({
44
+ cellId,
44
45
  completionConfig,
45
46
  hotkeys,
46
47
  placeholderType,
47
48
  lspConfig,
48
49
  diagnosticsConfig,
49
50
  }: {
51
+ cellId: CellId;
50
52
  completionConfig: CompletionConfig;
51
53
  hotkeys: HotkeyProvider;
52
54
  placeholderType: PlaceholderType;
@@ -55,6 +57,7 @@ export function cellConfigExtension({
55
57
  }) {
56
58
  return [
57
59
  // Store state
60
+ cellIdState.of(cellId),
58
61
  completionConfigState.of(completionConfig),
59
62
  hotkeysProviderState.of(hotkeys),
60
63
  placeholderState.of(placeholderType),
@@ -45,6 +45,7 @@ function createMockEditorView(code: string) {
45
45
  lspConfig: {},
46
46
  }),
47
47
  cellConfigExtension({
48
+ cellId: "cell1" as CellId,
48
49
  completionConfig: {
49
50
  copilot: false,
50
51
  activate_on_typing: true,
@@ -14,6 +14,9 @@ import { Facet } from "@codemirror/state";
14
14
  */
15
15
  export function singleFacet<T>() {
16
16
  return Facet.define<T, T>({
17
- combine: (values) => values[0],
17
+ combine: (values) => {
18
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
19
+ return values.find((v) => v !== undefined)!;
20
+ },
18
21
  });
19
22
  }
@@ -49,6 +49,7 @@ function createState(content: string, selection?: { anchor: number }) {
49
49
  placeholderType: "marimo-import",
50
50
  }),
51
51
  cellConfigExtension({
52
+ cellId: "cell1" as CellId,
52
53
  completionConfig: {
53
54
  copilot: false,
54
55
  activate_on_typing: true,
@@ -31,6 +31,7 @@ function createEditor(doc: string) {
31
31
  lspConfig: {},
32
32
  }),
33
33
  cellConfigExtension({
34
+ cellId: "cell1" as CellId,
34
35
  completionConfig: {
35
36
  activate_on_typing: true,
36
37
  signature_hint_on_typing: false,
@@ -15,6 +15,7 @@ import type {
15
15
  LSPConfig,
16
16
  } from "@/core/config/config-schema";
17
17
  import type { HotkeyProvider } from "@/core/hotkeys/hotkeys";
18
+ import { Logger } from "@/utils/Logger";
18
19
  import { clamp } from "@/utils/math";
19
20
  import {
20
21
  cellIdState,
@@ -310,6 +311,17 @@ export function reconfigureLanguageEffect(
310
311
  const language = view.state.field(languageAdapterState);
311
312
  const placeholderType = view.state.facet(placeholderState);
312
313
  const cellId = view.state.facet(cellIdState);
314
+
315
+ if (cellId === undefined) {
316
+ Logger.error("Cell ID is undefined in reconfigureLanguageEffect");
317
+ }
318
+ if (placeholderType === undefined) {
319
+ Logger.error("Placeholder type is undefined in reconfigureLanguageEffect");
320
+ }
321
+ if (completionConfig === undefined) {
322
+ Logger.error("Completion config is undefined in reconfigureLanguageEffect");
323
+ }
324
+
313
325
  return languageCompartment.reconfigure(
314
326
  language.getExtension(
315
327
  cellId,
@@ -1,13 +1,8 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
- import { captureIframeAsImage } from "../iframe";
3
+ import { captureExternalIframes } from "../iframe";
4
4
 
5
- // Mock html-to-image
6
- vi.mock("html-to-image", () => ({
7
- toPng: vi.fn().mockResolvedValue("data:image/png;base64,mock"),
8
- }));
9
-
10
- describe("captureIframeAsImage", () => {
5
+ describe("captureExternalIframes", () => {
11
6
  const originalCreateElement = document.createElement.bind(document);
12
7
 
13
8
  beforeEach(() => {
@@ -53,7 +48,7 @@ describe("captureIframeAsImage", () => {
53
48
  const element = document.createElement("div");
54
49
  element.innerHTML = "<p>No iframe here</p>";
55
50
 
56
- const result = await captureIframeAsImage(element);
51
+ const result = await captureExternalIframes(element);
57
52
  expect(result).toBeNull();
58
53
  });
59
54
 
@@ -61,7 +56,7 @@ describe("captureIframeAsImage", () => {
61
56
  const element = document.createElement("div");
62
57
  element.innerHTML = '<iframe src="https://external.com/page"></iframe>';
63
58
 
64
- const result = await captureIframeAsImage(element);
59
+ const result = await captureExternalIframes(element);
65
60
 
66
61
  expect(result).not.toBeNull();
67
62
  expect(result).toMatch(/^data:image\/png;base64,/);
@@ -72,7 +67,7 @@ describe("captureIframeAsImage", () => {
72
67
  element.innerHTML =
73
68
  '<iframe src="https://www.openstreetmap.org/export/embed.html"></iframe>';
74
69
 
75
- const result = await captureIframeAsImage(element);
70
+ const result = await captureExternalIframes(element);
76
71
 
77
72
  expect(result).not.toBeNull();
78
73
  expect(result).toMatch(/^data:image\/png;base64,/);
@@ -85,7 +80,7 @@ describe("captureIframeAsImage", () => {
85
80
  element.append(iframe);
86
81
 
87
82
  // The iframe has no body accessible in jsdom
88
- const result = await captureIframeAsImage(element);
83
+ const result = await captureExternalIframes(element);
89
84
 
90
85
  // In jsdom, contentDocument may not be accessible
91
86
  expect(result).toBeNull();
@@ -96,7 +91,7 @@ describe("captureIframeAsImage", () => {
96
91
  element.innerHTML = '<iframe src="./@file/123.html"></iframe>';
97
92
 
98
93
  // Same-origin relative URL, but contentDocument not accessible in jsdom
99
- const result = await captureIframeAsImage(element);
94
+ const result = await captureExternalIframes(element);
100
95
 
101
96
  // Returns null because jsdom can't access contentDocument for file URLs
102
97
  expect(result).toBeNull();
@@ -113,7 +108,7 @@ describe("captureIframeAsImage", () => {
113
108
  const element = document.createElement("div");
114
109
  element.innerHTML = `<iframe src="${url}"></iframe>`;
115
110
 
116
- const result = await captureIframeAsImage(element);
111
+ const result = await captureExternalIframes(element);
117
112
 
118
113
  expect(result).not.toBeNull();
119
114
  expect(result).toMatch(/^data:image\/png;base64,/);
@@ -128,7 +123,7 @@ describe("captureIframeAsImage", () => {
128
123
  const element = document.createElement("div");
129
124
  element.innerHTML = `<iframe src="${url}"></iframe>`;
130
125
 
131
- const result = await captureIframeAsImage(element);
126
+ const result = await captureExternalIframes(element);
132
127
 
133
128
  // In jsdom, these return null because contentDocument isn't accessible
134
129
  // but they should NOT return a placeholder (which would indicate external detection)
@@ -8,7 +8,7 @@ import { Filenames } from "@/utils/filenames";
8
8
  import { Paths } from "@/utils/paths";
9
9
  import { prettyError } from "./errors";
10
10
  import { toPng } from "./html-to-image";
11
- import { captureIframeAsImage } from "./iframe";
11
+ import { captureExternalIframes } from "./iframe";
12
12
  import { Logger } from "./Logger";
13
13
  import { ProgressState } from "./progress";
14
14
  import { ToastProgress } from "./toast-progress";
@@ -66,9 +66,11 @@ export async function getImageDataUrlForCell(
66
66
  return;
67
67
  }
68
68
 
69
- const iframeDataUrl = await captureIframeAsImage(element);
70
- if (iframeDataUrl) {
71
- return iframeDataUrl;
69
+ // TODO: This doesn't handle external iframes + normal elements together (eg. in vstack).
70
+ // It will return the iframe only
71
+ const externalIframeDataUrl = await captureExternalIframes(element);
72
+ if (externalIframeDataUrl) {
73
+ return externalIframeDataUrl;
72
74
  }
73
75
 
74
76
  const startTime = Date.now();
@@ -1,7 +1,5 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { toPng } from "./html-to-image";
4
-
5
3
  const PLACEHOLDER_WIDTH = 320;
6
4
  const PLACEHOLDER_HEIGHT = 180;
7
5
 
@@ -95,11 +93,11 @@ function createPlaceholderImage(url: string | null): string {
95
93
  }
96
94
 
97
95
  /**
98
- * Capture an iframe as a PNG image. We need to do this because external iframes are not supported by html-to-image.
96
+ * Capture external iframes as a PNG image. External iframes are not supported by html-to-image.
99
97
  * @param element - The element to capture the iframe from
100
98
  * @returns The image data URL of the iframe, or a placeholder image if the iframe is external
101
99
  */
102
- export async function captureIframeAsImage(
100
+ export async function captureExternalIframes(
103
101
  element: HTMLElement,
104
102
  ): Promise<string | null> {
105
103
  const iframe = element.querySelector("iframe");
@@ -133,10 +131,5 @@ export async function captureIframeAsImage(
133
131
  }
134
132
  }
135
133
 
136
- // Capture the iframe content
137
- try {
138
- return await toPng(doc.body);
139
- } catch {
140
- return createPlaceholderImage(null);
141
- }
134
+ return null;
142
135
  }