@marimo-team/islands 0.20.4-dev1 → 0.20.4

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
@@ -27007,7 +27007,6 @@ ${c.sqlString}
27007
27007
  rtc_v2: false,
27008
27008
  cache_panel: false,
27009
27009
  external_agents: false,
27010
- server_side_pdf_export: true,
27011
27010
  storage_inspector: false
27012
27011
  };
27013
27012
  function getFeatureFlag(e) {
@@ -70358,7 +70357,7 @@ Image URL: ${r.imageUrl}`)), contextToXml({
70358
70357
  return Logger.warn("Failed to get version from mount config"), null;
70359
70358
  }
70360
70359
  }
70361
- const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.20.4-dev1"), showCodeInRunModeAtom = atom(true);
70360
+ const marimoVersionAtom = atom(getVersionFromMountConfig() || "0.20.4"), showCodeInRunModeAtom = atom(true);
70362
70361
  atom(null);
70363
70362
  var import_compiler_runtime$88 = require_compiler_runtime();
70364
70363
  function useKeydownOnElement(e, r) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.20.4-dev1",
3
+ "version": "0.20.4",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -1371,39 +1371,6 @@ export const UserConfigForm: React.FC = () => {
1371
1371
  </div>
1372
1372
  )}
1373
1373
  />
1374
- <FormField
1375
- control={form.control}
1376
- name="experimental.server_side_pdf_export"
1377
- render={({ field }) => (
1378
- <div className="flex flex-col gap-y-1">
1379
- <FormItem className={formItemClasses}>
1380
- <FormLabel className="font-normal">
1381
- Better PDF Export
1382
- </FormLabel>
1383
- <FormControl>
1384
- <Checkbox
1385
- data-testid="server-side-pdf-export-checkbox"
1386
- checked={field.value === true}
1387
- onCheckedChange={field.onChange}
1388
- />
1389
- </FormControl>
1390
- </FormItem>
1391
- <IsOverridden
1392
- userConfig={config}
1393
- name="experimental.server_side_pdf_export"
1394
- />
1395
- <FormDescription>
1396
- Enable PDF export using{" "}
1397
- <Kbd className="inline">nbconvert</Kbd> and{" "}
1398
- <Kbd className="inline">playwright</Kbd>. Refer to{" "}
1399
- <ExternalLink href="https://docs.marimo.io/guides/exporting/#exporting-to-pdf-slides-or-rst">
1400
- the docs
1401
- </ExternalLink>
1402
- .
1403
- </FormDescription>
1404
- </div>
1405
- )}
1406
- />
1407
1374
  <FormField
1408
1375
  control={form.control}
1409
1376
  name="experimental.storage_inspector"
@@ -15,10 +15,10 @@ describe("runServerSidePDFDownload", () => {
15
15
 
16
16
  expect(downloadPDF).toHaveBeenCalledWith({
17
17
  filename: "slides.py",
18
- webpdf: true,
18
+ webpdf: false,
19
19
  preset: "document",
20
- includeInputs: false,
21
- rasterServer: "live",
20
+ includeInputs: true,
21
+ rasterServer: "static",
22
22
  });
23
23
  });
24
24
 
@@ -33,10 +33,10 @@ describe("runServerSidePDFDownload", () => {
33
33
 
34
34
  expect(downloadPDF).toHaveBeenCalledWith({
35
35
  filename: "slides.py",
36
- webpdf: true,
36
+ webpdf: false,
37
37
  preset: "slides",
38
- includeInputs: false,
39
- rasterServer: "live",
38
+ includeInputs: true,
39
+ rasterServer: "static",
40
40
  });
41
41
  });
42
42
  });
@@ -18,9 +18,9 @@ export async function runServerSidePDFDownload(opts: {
18
18
 
19
19
  await downloadPDF({
20
20
  filename,
21
- webpdf: true,
21
+ webpdf: false,
22
22
  preset,
23
- includeInputs: false,
24
- rasterServer: "live",
23
+ includeInputs: true,
24
+ rasterServer: "static",
25
25
  });
26
26
  }
@@ -55,8 +55,11 @@ import {
55
55
  } from "@/core/cells/cells";
56
56
  import { disabledCellIds } from "@/core/cells/utils";
57
57
  import { useResolvedMarimoConfig } from "@/core/config/config";
58
- import { getFeatureFlag } from "@/core/config/feature-flag";
59
58
  import { Constants } from "@/core/constants";
59
+ import {
60
+ updateCellOutputsWithScreenshots,
61
+ useEnrichCellOutputs,
62
+ } from "@/core/export/hooks";
60
63
  import { useLayoutActions, useLayoutState } from "@/core/layout/layout";
61
64
  import { useTogglePresenting } from "@/core/layout/useTogglePresenting";
62
65
  import { kioskModeAtom, viewStateAtom } from "@/core/mode";
@@ -75,6 +78,7 @@ import {
75
78
  } from "@/utils/download";
76
79
  import { Filenames } from "@/utils/filenames";
77
80
  import { Objects } from "@/utils/objects";
81
+ import type { ProgressState } from "@/utils/progress";
78
82
  import { newNotebookURL } from "@/utils/urls";
79
83
  import { useRunAllCells } from "../cell/useRunCells";
80
84
  import { useChromeActions, useChromeState } from "../chrome/state";
@@ -119,7 +123,9 @@ export function useNotebookActions() {
119
123
  const setCommandPaletteOpen = useSetAtom(commandPaletteAtom);
120
124
  const setSettingsDialogOpen = useSetAtom(settingDialogAtom);
121
125
  const setKeyboardShortcutsOpen = useSetAtom(keyboardShortcutsAtom);
122
- const { exportAsMarkdown, readCode, saveCellConfig } = useRequestClient();
126
+ const { exportAsMarkdown, readCode, saveCellConfig, updateCellOutputs } =
127
+ useRequestClient();
128
+ const takeScreenshots = useEnrichCellOutputs();
123
129
 
124
130
  const hasDisabledCells = useAtomValue(hasDisabledCellsAtom);
125
131
  const canUndoDeletes = useAtomValue(canUndoDeletesAtom);
@@ -130,11 +136,9 @@ export function useNotebookActions() {
130
136
  const sharingHtmlEnabled = resolvedConfig.sharing?.html ?? true;
131
137
  const sharingWasmEnabled = resolvedConfig.sharing?.wasm ?? true;
132
138
 
133
- const isServerSidePdfExportEnabled = getFeatureFlag("server_side_pdf_export");
134
- // With server side pdf export, it doesn't matter what mode we are in,
135
- // Default export uses browser print, which is better in present mode
136
- const pdfDownloadEnabled =
137
- isServerSidePdfExportEnabled || viewState.mode === "present";
139
+ // Server-side PDF export is always available outside WASM.
140
+ // Browser print fallback is used in WASM.
141
+ const serverSidePdfEnabled = !isWasm();
138
142
  const isSlidesLayout = selectedLayout === "slides";
139
143
 
140
144
  const renderCheckboxElement = (checked: boolean) => (
@@ -166,7 +170,11 @@ export function useNotebookActions() {
166
170
  return;
167
171
  }
168
172
 
169
- const runDownload = async () => {
173
+ const runDownload = async (progress: ProgressState) => {
174
+ await updateCellOutputsWithScreenshots({
175
+ takeScreenshots: () => takeScreenshots({ progress }),
176
+ updateCellOutputs,
177
+ });
170
178
  await runServerSidePDFDownload({
171
179
  filename,
172
180
  preset,
@@ -176,6 +184,21 @@ export function useNotebookActions() {
176
184
  await withLoadingToast(title, runDownload);
177
185
  };
178
186
 
187
+ const handleDocumentPDF = async () => {
188
+ if (serverSidePdfEnabled) {
189
+ await downloadServerSidePDF({
190
+ preset: "document",
191
+ title: "Downloading Document PDF...",
192
+ });
193
+ return;
194
+ }
195
+ const beforeprint = new Event("export-beforeprint");
196
+ const afterprint = new Event("export-afterprint");
197
+ window.dispatchEvent(beforeprint);
198
+ setTimeout(() => window.print(), 0);
199
+ setTimeout(() => window.dispatchEvent(afterprint), 0);
200
+ };
201
+
179
202
  const actions: ActionButton[] = [
180
203
  {
181
204
  icon: <DownloadIcon size={14} strokeWidth={1.5} />,
@@ -253,62 +276,38 @@ export function useNotebookActions() {
253
276
  });
254
277
  },
255
278
  },
256
- {
257
- divider: true,
258
- icon: <FileIcon size={14} strokeWidth={1.5} />,
259
- label: "Download as PDF",
260
- handle: NOOP_HANDLER,
261
- disabled: !pdfDownloadEnabled && !isServerSidePdfExportEnabled,
262
- dropdown: [
263
- {
279
+ isSlidesLayout
280
+ ? {
281
+ divider: true,
264
282
  icon: <FileIcon size={14} strokeWidth={1.5} />,
265
- label: "Document Layout",
266
- rightElement: renderRecommendedElement(!isSlidesLayout),
267
- disabled: !pdfDownloadEnabled,
268
- tooltip: pdfDownloadEnabled ? undefined : (
269
- <span>
270
- Only available in app view. <br />
271
- Toggle with: {renderShortcut("global.hideCode", false)}
272
- </span>
273
- ),
274
- handle: async () => {
275
- if (isServerSidePdfExportEnabled) {
276
- await downloadServerSidePDF({
277
- preset: "document",
278
- title: "Downloading Document PDF...",
279
- });
280
- return;
281
- }
282
-
283
- const beforeprint = new Event("export-beforeprint");
284
- const afterprint = new Event("export-afterprint");
285
- function print() {
286
- window.dispatchEvent(beforeprint);
287
- setTimeout(() => window.print(), 0);
288
- setTimeout(() => window.dispatchEvent(afterprint), 0);
289
- }
290
- print();
291
- },
292
- },
293
- {
283
+ label: "Download as PDF",
284
+ handle: NOOP_HANDLER,
285
+ dropdown: [
286
+ {
287
+ icon: <FileIcon size={14} strokeWidth={1.5} />,
288
+ label: "Document Layout",
289
+ handle: handleDocumentPDF,
290
+ },
291
+ {
292
+ icon: <FileIcon size={14} strokeWidth={1.5} />,
293
+ label: "Slides Layout",
294
+ rightElement: renderRecommendedElement(true),
295
+ hidden: !serverSidePdfEnabled,
296
+ handle: async () => {
297
+ await downloadServerSidePDF({
298
+ preset: "slides",
299
+ title: "Downloading Slides PDF...",
300
+ });
301
+ },
302
+ },
303
+ ],
304
+ }
305
+ : {
306
+ divider: true,
294
307
  icon: <FileIcon size={14} strokeWidth={1.5} />,
295
- label: "Slides Layout",
296
- rightElement: renderRecommendedElement(isSlidesLayout),
297
- disabled: !isServerSidePdfExportEnabled,
298
- tooltip: isServerSidePdfExportEnabled ? undefined : (
299
- <span>
300
- Requires Better PDF Export in Settings &gt; Experimental.
301
- </span>
302
- ),
303
- handle: async () => {
304
- await downloadServerSidePDF({
305
- preset: "slides",
306
- title: "Downloading Slides PDF...",
307
- });
308
- },
308
+ label: "Download as PDF",
309
+ handle: handleDocumentPDF,
309
310
  },
310
- ],
311
- },
312
311
  ],
313
312
  },
314
313
 
@@ -11,7 +11,6 @@ export interface ExperimentalFeatures {
11
11
  rtc_v2: boolean;
12
12
  cache_panel: boolean;
13
13
  external_agents: boolean;
14
- server_side_pdf_export: boolean;
15
14
  storage_inspector: boolean;
16
15
  // Add new feature flags here
17
16
  }
@@ -22,7 +21,6 @@ const defaultValues: ExperimentalFeatures = {
22
21
  rtc_v2: false,
23
22
  cache_panel: false,
24
23
  external_agents: import.meta.env.DEV,
25
- server_side_pdf_export: true,
26
24
  storage_inspector: false,
27
25
  };
28
26
 
@@ -205,7 +205,7 @@ describe("downloadAsPDF", () => {
205
205
  expect(mockExportAsPDF).toHaveBeenCalledWith({
206
206
  webpdf: false,
207
207
  preset: "slides",
208
- includeInputs: false,
208
+ includeInputs: true,
209
209
  rasterizeOutputs: true,
210
210
  rasterScale: 4,
211
211
  rasterServer: "static",
@@ -210,7 +210,7 @@ export async function downloadAsPDF(opts: {
210
210
  filename,
211
211
  webpdf,
212
212
  preset = "document",
213
- includeInputs = false,
213
+ includeInputs = true,
214
214
  rasterizeOutputs = true,
215
215
  rasterScale = 4,
216
216
  rasterServer = "static",