@marimo-team/islands 0.23.16-dev5 → 0.23.16-dev50

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 (156) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CJaUI-S-.js → ConnectedDataExplorerComponent-f9vLjQiF.js} +13 -13
  2. package/dist/{ErrorBoundary-DXlxsrTF.js → ErrorBoundary-DhLqwSWA.js} +3 -3
  3. package/dist/{any-language-editor-P9tjkj4n.js → any-language-editor-DifE-fl7.js} +5 -5
  4. package/dist/{button-BcSml68y.js → button-BSm8IXRU.js} +2 -4
  5. package/dist/{capabilities-BYLFYTYv.js → capabilities-C6OQ5YBO.js} +1 -1
  6. package/dist/{chat-ui-BdSDiVjk.js → chat-ui-1e7PcW56.js} +3117 -3120
  7. package/dist/{check-Cs-KV5XY.js → check-DP7U0H0G.js} +1 -1
  8. package/dist/{code-visibility-C4wLKnSb.js → common-BcbT1FqC.js} +1046 -1014
  9. package/dist/{copy-Cs3yt6Vt.js → copy-DNq8q3zw.js} +2 -2
  10. package/dist/{dist-B96tMAst.js → dist-DIlxLFXG.js} +2 -2
  11. package/dist/{error-banner-DR7o3CbX.js → error-banner-B_GQfxxD.js} +2 -2
  12. package/dist/{esm-k8PIvuZW.js → esm-DzZVaNH4.js} +1 -1
  13. package/dist/{extends-Cq2JYHKy.js → extends-w2_S44bV.js} +4 -4
  14. package/dist/{formats-BFhkZJwd.js → formats-Dwq1THhr.js} +3 -3
  15. package/dist/{glide-data-editor--CaN-f27.js → glide-data-editor-B9K6-MJe.js} +9 -9
  16. package/dist/{html-to-image-DDENewl2.js → html-to-image-3w0AakWW.js} +7164 -6240
  17. package/dist/{input-DStQIuqD.js → input-C5K4VBvB.js} +7 -7
  18. package/dist/{label-DIk0QoFe.js → label-DjoYwqmj.js} +2 -2
  19. package/dist/{loader-CTHCI-qe.js → loader-DX-IDS7n.js} +1 -1
  20. package/dist/main.js +1010 -1019
  21. package/dist/{mermaid-CdSvixW2.js → mermaid-hv6IckVw.js} +5 -5
  22. package/dist/{node-sql-parser-DLl_zNw0.js → node-sql-parser-v1Vi-Fft.js} +16867 -16665
  23. package/dist/{process-output-2QPcgBQg.js → process-output-BRwR4QGs.js} +32 -28
  24. package/dist/{reveal-component-BSD4w8YU.js → reveal-component-D7xmRQQ_.js} +725 -643
  25. package/dist/{spec-CnaxwDqy.js → spec-CQKL_D3i.js} +4 -4
  26. package/dist/{strings-BYAhZnQi.js → strings-DIy9NAmg.js} +4 -4
  27. package/dist/style.css +1 -1
  28. package/dist/{swiper-component-DE94711u.js → swiper-component-CEdAYjb7.js} +2 -2
  29. package/dist/toDate-CqhBWjvO.js +713 -0
  30. package/dist/{tooltip-B-qh7UPB.js → tooltip-f-qR0iUx.js} +3 -3
  31. package/dist/{types-DQl7jVYK.js → types-DicH9Oi0.js} +1 -1
  32. package/dist/{useAsyncData-CvO8WUy3.js → useAsyncData-CYOQb1EW.js} +1 -1
  33. package/dist/{useDateFormatter-BSoGim-G.js → useDateFormatter-Bt2qr_XS.js} +2 -2
  34. package/dist/{useDeepCompareMemoize-J3MKRdA4.js → useDeepCompareMemoize-CSHQeQEI.js} +1 -1
  35. package/dist/{useIframeCapabilities-POcFXHbw.js → useIframeCapabilities-kA09ykNq.js} +1 -1
  36. package/dist/{useLifecycle-DqPxHgAN.js → useLifecycle-CMJGqBaY.js} +3 -3
  37. package/dist/{useTheme-XMq9mNf_.js → useTheme-DYfby65G.js} +2 -2
  38. package/dist/{vega-component-CrFoZT1S.js → vega-component-C7nO5zcf.js} +10 -10
  39. package/dist/{zod-D0yOqoGe.js → zod-BUcyXSdR.js} +1 -1
  40. package/package.json +3 -4
  41. package/src/__mocks__/requests.ts +45 -4
  42. package/src/components/data-table/__tests__/__snapshots__/chart-spec-model.test.ts.snap +174 -21
  43. package/src/components/data-table/__tests__/chart-spec-model.test.ts +102 -1
  44. package/src/components/data-table/column-summary/chart-spec-model.tsx +163 -103
  45. package/src/components/data-table/column-summary/legacy-chart-spec.ts +15 -7
  46. package/src/components/data-table/column-summary/utils.ts +26 -7
  47. package/src/components/data-table/types.ts +1 -1
  48. package/src/components/editor/__tests__/viewer-banner.test.tsx +14 -0
  49. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +99 -18
  50. package/src/components/editor/actions/__tests__/pdf-export.test.ts +32 -13
  51. package/src/components/editor/actions/pair-with-agent-commands.ts +21 -10
  52. package/src/components/editor/actions/pair-with-agent-modal.tsx +2 -2
  53. package/src/components/editor/actions/pdf-export.ts +11 -14
  54. package/src/components/editor/actions/useNotebookActions.tsx +18 -18
  55. package/src/components/editor/cell/code/__tests__/cell-editor-activity-lifecycle.test.ts +250 -0
  56. package/src/components/editor/cell/code/cell-editor.tsx +13 -7
  57. package/src/components/editor/chrome/panels/__tests__/logs-panel.test.tsx +25 -0
  58. package/src/components/editor/chrome/panels/logs-panel.tsx +12 -2
  59. package/src/components/editor/chrome/panels/write-secret-modal.tsx +40 -12
  60. package/src/components/editor/connections/__tests__/json-credentials.test.ts +114 -0
  61. package/src/components/editor/connections/__tests__/paths.test.ts +39 -0
  62. package/src/components/editor/connections/components.tsx +6 -2
  63. package/src/components/editor/connections/database/__tests__/__snapshots__/as-code.test.ts.snap +21 -5
  64. package/src/components/editor/connections/database/__tests__/as-code.test.ts +17 -0
  65. package/src/components/editor/connections/database/as-code.ts +16 -2
  66. package/src/components/editor/connections/database/schemas.ts +6 -5
  67. package/src/components/editor/connections/form-renderers.tsx +99 -1
  68. package/src/components/editor/connections/json-credentials.ts +57 -0
  69. package/src/components/editor/connections/paths.ts +21 -0
  70. package/src/components/editor/connections/secret-combobox.tsx +41 -20
  71. package/src/components/editor/connections/storage/__tests__/__snapshots__/as-code.test.ts.snap +88 -2
  72. package/src/components/editor/connections/storage/__tests__/as-code.test.ts +128 -8
  73. package/src/components/editor/connections/storage/as-code.ts +79 -36
  74. package/src/components/editor/connections/storage/schemas.ts +85 -44
  75. package/src/components/editor/file-tree/__tests__/renderers.test.ts +31 -0
  76. package/src/components/editor/file-tree/file-viewer.tsx +11 -7
  77. package/src/components/editor/file-tree/renderers.tsx +21 -0
  78. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +1 -1
  79. package/src/components/editor/viewer-banner.tsx +4 -1
  80. package/src/components/forms/options.ts +2 -1
  81. package/src/components/slides/__tests__/cell-output-block.test.tsx +40 -0
  82. package/src/components/slides/__tests__/slide-cell-view.test.tsx +33 -0
  83. package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +198 -0
  84. package/src/components/slides/reveal-component.tsx +25 -19
  85. package/src/components/slides/slide-cell-view.tsx +1 -1
  86. package/src/components/slides/slide-scroll-hint.tsx +161 -0
  87. package/src/components/slides/slides.css +4 -2
  88. package/src/components/static-html/share-modal.tsx +1 -1
  89. package/src/components/ui/input.tsx +1 -1
  90. package/src/core/ai/context/providers/file.ts +8 -29
  91. package/src/core/cells/__tests__/cells.test.ts +12 -2
  92. package/src/core/cells/__tests__/logs.test.ts +5 -5
  93. package/src/core/cells/cells.ts +17 -4
  94. package/src/core/cells/document-changes.ts +1 -0
  95. package/src/core/cells/logs.ts +14 -4
  96. package/src/core/codemirror/copilot/__tests__/language-server.test.ts +396 -100
  97. package/src/core/codemirror/copilot/__tests__/transport.test.ts +128 -540
  98. package/src/core/codemirror/copilot/language-server.ts +182 -70
  99. package/src/core/codemirror/copilot/transport.ts +15 -207
  100. package/src/core/codemirror/copilot/types.ts +9 -2
  101. package/src/core/codemirror/find-replace/__tests__/navigate.test.ts +42 -30
  102. package/src/core/codemirror/find-replace/navigate.ts +2 -0
  103. package/src/core/codemirror/go-to-definition/__tests__/commands.test.ts +24 -3
  104. package/src/core/codemirror/go-to-definition/commands.ts +3 -0
  105. package/src/core/codemirror/keymaps/__tests__/keymaps.test.ts +31 -2
  106. package/src/core/codemirror/keymaps/keymaps.ts +12 -0
  107. package/src/core/codemirror/language/__tests__/sql.test.ts +443 -61
  108. package/src/core/codemirror/language/languages/python.ts +23 -11
  109. package/src/core/codemirror/language/languages/sql/completion-store.ts +5 -1
  110. package/src/core/codemirror/language/languages/sql/sql.ts +210 -3
  111. package/src/core/codemirror/lsp/__tests__/federated-lsp.test.ts +161 -0
  112. package/src/core/codemirror/lsp/__tests__/log-messages.test.ts +53 -0
  113. package/src/core/codemirror/lsp/__tests__/normalize-markdown-math.test.ts +25 -0
  114. package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +598 -156
  115. package/src/core/codemirror/lsp/__tests__/transports.test.ts +112 -0
  116. package/src/core/codemirror/lsp/federated-lsp.ts +76 -23
  117. package/src/core/codemirror/lsp/log-messages.ts +37 -0
  118. package/src/core/codemirror/lsp/normalize-markdown-math.ts +8 -4
  119. package/src/core/codemirror/lsp/notebook-lsp.ts +220 -56
  120. package/src/core/codemirror/lsp/transports.ts +8 -1
  121. package/src/core/codemirror/lsp/types.ts +68 -8
  122. package/src/core/codemirror/lsp/utils.ts +14 -0
  123. package/src/core/codemirror/utils.ts +28 -0
  124. package/src/core/edit-app.tsx +1 -2
  125. package/src/core/export/__tests__/hooks.test.ts +2 -4
  126. package/src/core/export/hooks.ts +4 -3
  127. package/src/core/hotkeys/hotkeys.ts +0 -2
  128. package/src/core/islands/__tests__/bridge.test.ts +107 -0
  129. package/src/core/islands/bridge.ts +16 -0
  130. package/src/core/lsp/__tests__/transport.test.ts +509 -337
  131. package/src/core/lsp/transport.ts +304 -132
  132. package/src/core/mode.ts +10 -0
  133. package/src/core/network/__tests__/api.test.ts +42 -0
  134. package/src/core/network/__tests__/connection.test.ts +45 -0
  135. package/src/core/network/__tests__/requests-lazy.test.ts +32 -1
  136. package/src/core/network/__tests__/requests-network.test.ts +21 -0
  137. package/src/core/network/api.ts +27 -0
  138. package/src/core/network/connection.ts +15 -0
  139. package/src/core/network/requests-lazy.ts +1 -0
  140. package/src/core/network/requests-network.ts +14 -8
  141. package/src/core/network/requests-static.ts +1 -0
  142. package/src/core/network/requests-toasting.tsx +1 -0
  143. package/src/core/network/types.ts +22 -6
  144. package/src/core/rtc/state.ts +9 -0
  145. package/src/core/static/download-html.ts +5 -14
  146. package/src/core/wasm/bridge.ts +4 -2
  147. package/src/core/wasm/worker/types.ts +5 -2
  148. package/src/css/app/codemirror.css +16 -2
  149. package/src/plugins/impl/FormPlugin.tsx +1 -1
  150. package/src/plugins/impl/__tests__/FormPlugin.test.tsx +162 -0
  151. package/src/stories/log-viewer.stories.tsx +12 -6
  152. package/src/utils/__tests__/blob.test.ts +27 -1
  153. package/src/utils/__tests__/download.test.tsx +44 -4
  154. package/src/utils/blob.ts +24 -1
  155. package/src/utils/download.ts +14 -15
  156. package/dist/toDate-B3IRfHhw.js +0 -692
@@ -8,6 +8,7 @@ import {
8
8
  downloadAsPDF,
9
9
  downloadByURL,
10
10
  downloadCellOutputAsImage,
11
+ downloadExportedFile,
11
12
  downloadHTMLAsImage,
12
13
  getImageDataUrlForCell,
13
14
  withLoadingToast,
@@ -195,7 +196,6 @@ describe("downloadAsPDF", () => {
195
196
 
196
197
  await expect(
197
198
  downloadAsPDF({
198
- filename: "path/to/notebook.py",
199
199
  webpdf: false,
200
200
  preset: "slides",
201
201
  }),
@@ -205,9 +205,26 @@ describe("downloadAsPDF", () => {
205
205
  webpdf: false,
206
206
  preset: "slides",
207
207
  includeInputs: true,
208
- rasterizeOutputs: true,
209
- rasterScale: 4,
210
- rasterServer: "static",
208
+ includeOutputs: true,
209
+ });
210
+ });
211
+
212
+ it("should send input and output selections", async () => {
213
+ mockExportAsPDF.mockRejectedValue(new Error("network"));
214
+
215
+ await expect(
216
+ downloadAsPDF({
217
+ webpdf: true,
218
+ includeInputs: false,
219
+ includeOutputs: false,
220
+ }),
221
+ ).rejects.toThrow("network");
222
+
223
+ expect(mockExportAsPDF).toHaveBeenCalledWith({
224
+ webpdf: true,
225
+ preset: "document",
226
+ includeInputs: false,
227
+ includeOutputs: false,
211
228
  });
212
229
  });
213
230
  });
@@ -572,6 +589,7 @@ describe("downloadByURL", () => {
572
589
 
573
590
  afterEach(() => {
574
591
  vi.restoreAllMocks();
592
+ vi.unstubAllGlobals();
575
593
  });
576
594
 
577
595
  it("should create anchor, set attributes, click, and remove", () => {
@@ -583,4 +601,26 @@ describe("downloadByURL", () => {
583
601
  expect(mockAnchor.click).toHaveBeenCalled();
584
602
  expect(mockAnchor.remove).toHaveBeenCalled();
585
603
  });
604
+
605
+ it("downloads an exported file with its returned metadata", async () => {
606
+ let downloadedBlob: Blob | undefined;
607
+ vi.stubGlobal("URL", {
608
+ createObjectURL: vi.fn((blob: Blob) => {
609
+ downloadedBlob = blob;
610
+ return "blob:export";
611
+ }),
612
+ revokeObjectURL: vi.fn(),
613
+ });
614
+
615
+ downloadExportedFile({
616
+ contents: "notebook",
617
+ filename: "résumé.qmd",
618
+ mediaType: "text/plain; charset=utf-8",
619
+ });
620
+
621
+ expect(downloadedBlob?.type).toBe("text/plain; charset=utf-8");
622
+ expect(await downloadedBlob?.text()).toBe("notebook");
623
+ expect(mockAnchor.download).toBe("résumé.qmd");
624
+ expect(URL.revokeObjectURL).toHaveBeenCalledWith("blob:export");
625
+ });
586
626
  });
package/src/utils/blob.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import type { DataURLString } from "./json/base64";
2
+ import {
3
+ type Base64String,
4
+ base64ToDataURL,
5
+ type DataURLString,
6
+ } from "./json/base64";
3
7
 
4
8
  export function serializeBlob<T>(blob: Blob): Promise<DataURLString> {
5
9
  return new Promise<DataURLString>((resolve, reject) => {
@@ -30,3 +34,22 @@ export function deserializeBlob(serializedBlob: DataURLString): Blob {
30
34
  const blob = new Blob([bytes], { type: mimeType });
31
35
  return blob;
32
36
  }
37
+
38
+ /**
39
+ * Convert file details into a `Blob`, using the authoritative `isBase64` flag
40
+ * to decide between decoding base64 bytes and treating contents as UTF-8 text.
41
+ */
42
+ export function fileDetailsToBlob({
43
+ contents,
44
+ mimeType,
45
+ isBase64,
46
+ }: {
47
+ contents: string;
48
+ mimeType: string;
49
+ isBase64: boolean;
50
+ }): Blob {
51
+ if (isBase64) {
52
+ return deserializeBlob(base64ToDataURL(contents as Base64String, mimeType));
53
+ }
54
+ return new Blob([contents], { type: mimeType });
55
+ }
@@ -4,8 +4,8 @@ import React from "react";
4
4
  import { toast } from "@/components/ui/use-toast";
5
5
  import { type CellId, CellOutputId } from "@/core/cells/ids";
6
6
  import { getRequestClient } from "@/core/network/requests";
7
+ import type { ExportedFile } from "@/core/network/types";
7
8
  import { Filenames } from "@/utils/filenames";
8
- import { Paths } from "@/utils/paths";
9
9
  import { prettyError } from "./errors";
10
10
  import { toPng } from "./html-to-image";
11
11
  import { captureExternalIframes } from "./iframe";
@@ -191,6 +191,14 @@ export function downloadBlob(blob: Blob, filename: string) {
191
191
  URL.revokeObjectURL(url);
192
192
  }
193
193
 
194
+ export function downloadExportedFile({
195
+ contents,
196
+ filename,
197
+ mediaType,
198
+ }: ExportedFile) {
199
+ downloadBlob(new Blob([contents], { type: mediaType }), filename);
200
+ }
201
+
194
202
  export type PDFExportPreset = "document" | "slides";
195
203
 
196
204
  /**
@@ -200,37 +208,28 @@ export type PDFExportPreset = "document" | "slides";
200
208
  * Standard PDF requires Pandoc & TeX (~few GBs) but is of higher quality.
201
209
  */
202
210
  export async function downloadAsPDF(opts: {
203
- filename: string;
204
211
  webpdf: boolean;
205
212
  preset?: PDFExportPreset;
206
213
  includeInputs?: boolean;
207
- rasterizeOutputs?: boolean;
208
- rasterScale?: number;
209
- rasterServer?: "static" | "live";
214
+ includeOutputs?: boolean;
210
215
  }) {
211
216
  const client = getRequestClient();
212
217
  const {
213
- filename,
214
218
  webpdf,
215
219
  preset = "document",
216
220
  includeInputs = true,
217
- rasterizeOutputs = true,
218
- rasterScale = 4,
219
- rasterServer = "static",
221
+ includeOutputs = true,
220
222
  } = opts;
221
223
 
222
224
  try {
223
- const pdfBlob = await client.exportAsPDF({
225
+ const exportedFile = await client.exportAsPDF({
224
226
  webpdf,
225
227
  preset,
226
228
  includeInputs,
227
- rasterizeOutputs,
228
- rasterScale,
229
- rasterServer,
229
+ includeOutputs,
230
230
  });
231
231
 
232
- const filenameWithoutPath = Paths.basename(filename);
233
- downloadBlob(pdfBlob, Filenames.toPDF(filenameWithoutPath));
232
+ downloadExportedFile(exportedFile);
234
233
  } catch (error) {
235
234
  toast({
236
235
  title: "Failed to download",