@marimo-team/islands 0.23.9-dev36 → 0.23.9-dev38

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
@@ -22,17 +22,17 @@ import { _ as Logger, c as Objects, g as cn, h as Events, i as NOT_SET, l as use
22
22
  import { t as require_react } from "./react-DA-nE2FX.js";
23
23
  import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
24
24
  import { n as Copy, r as toast, t as copyToClipboard } from "./copy-BuQpJEzp.js";
25
- import { $ as useCellActions, At as DeferredRequestRegistry, B as safeExtractSetUIElementMessageBuffers, Bn as CircleAlert, Bt as getDataTypeColor, C as AccordionContent, Cn as Root2$1, Ct as customPythonLanguageSupport, Dn as Table2, Dt as Paths, E as BorderAllIcon, En as Trash2, Et as PathBuilder, F as base64ToDataView, Fn as Eye, Ft as jotaiJsonStorage, Gt as convertStatsName, H as getMarimoExportContext, J as getCellNames, Jt as useRequestClient, K as createActions, Kt as getRequestClient, L as dataViewToBase64, Ln as Database, Mn as Layers, Nn as Info, Nt as repl, On as PaintRoller, Pn as FileText, Q as reducer, Rn as Columns2, Rt as PluralWords, S as Accordion, Sn as Item$1, St as Checkbox, T as AccordionTrigger, U as hasTrustedExportContext, V as renderHTML, Vn as Braces, Vt as require_client, W as hasRunAnyCellAtom, X as notebookOutline, Y as notebookAtom, Yt as isUninstantiated, Z as numColumnsAtom, _n as atomWithStorage, a as useCellFocusActions, an as parseInitialValue, bt as isInternalCellName, ct as kioskModeAtom, dn as OBJECT_ID_ATTR, dt as outputIsLoading, en as NotebookScopedLocalStorage, et as useCellIds, f as isOutputEmpty, fn as RANDOM_ID_ATTR, ft as outputIsStale, gn as atomWithReducer, i as LazyAnyLanguageCodeMirror, in as parseDataset, jn as LoaderCircle, jt as generateUUID, k as ChevronDownIcon, ln as UIElementId, mt as headingToIdentifier, n as Spinner, nt as createCell, o as useLastFocusedCellId, ot as getInitialAppMode, p as useExpandedConsoleOutput, pn as jsonParseWithSpecialChar, pt as isErrorMime, qt as requestClientAtom, rn as parseAttrValue, s as maybeAddAltairImport, sn as HTMLCellId, st as initialModeAtom, un as findCellId, vn as selectAtom, w as AccordionItem, wn as Trigger2, wt as MarkdownLanguageAdapter, xn as Content2, xt as normalizeName, yt as getValidName, zt as DATA_TYPE_ICON, __tla as __tla_0 } from "./html-to-image-CGbhD84m.js";
25
+ import { $ as useCellActions, An as LoaderCircle, At as DeferredRequestRegistry, B as safeExtractSetUIElementMessageBuffers, Bn as Braces, Bt as getDataTypeColor, C as AccordionContent, Cn as Trigger2, Ct as customPythonLanguageSupport, Dn as PaintRoller, Dt as Paths, E as BorderAllIcon, En as Table2, Et as PathBuilder, F as base64ToDataView, Ft as jotaiJsonStorage, Gt as convertStatsName, H as getMarimoExportContext, In as Database, J as getCellNames, Jt as useRequestClient, K as createActions, Kt as getRequestClient, L as dataViewToBase64, Ln as Columns2, Mn as Info, Nn as FileText, Nt as repl, Pn as Eye, Q as reducer, Rt as PluralWords, S as Accordion, Sn as Root2$1, St as Checkbox, T as AccordionTrigger, Tn as Trash2, U as hasTrustedExportContext, V as renderHTML, Vt as require_client, W as hasRunAnyCellAtom, X as notebookOutline, Y as notebookAtom, Yt as isUninstantiated, Z as numColumnsAtom, _n as selectAtom, a as useCellFocusActions, an as parseInitialValue, bn as Content2, bt as isInternalCellName, ct as kioskModeAtom, dn as OBJECT_ID_ATTR, dt as outputIsLoading, en as NotebookScopedLocalStorage, et as useCellIds, f as isOutputEmpty, fn as RANDOM_ID_ATTR, ft as outputIsStale, gn as atomWithStorage, hn as atomWithReducer, i as LazyAnyLanguageCodeMirror, in as parseDataset, jn as Layers, jt as generateUUID, k as ChevronDownIcon, ln as UIElementId, mt as headingToIdentifier, n as Spinner, nt as createCell, o as useLastFocusedCellId, ot as getInitialAppMode, p as useExpandedConsoleOutput, pn as jsonParseWithSpecialChar, pt as isErrorMime, qt as requestClientAtom, rn as parseAttrValue, s as maybeAddAltairImport, sn as HTMLCellId, st as initialModeAtom, un as findCellId, w as AccordionItem, wt as MarkdownLanguageAdapter, xn as Item$1, xt as normalizeName, yt as getValidName, zn as CircleAlert, zt as DATA_TYPE_ICON, __tla as __tla_0 } from "./html-to-image-BAPmFVwS.js";
26
26
  import { __tla as __tla_1 } from "./chunk-5FQGJX7Z-BNjes6Yx.js";
27
27
  import { o as useSize, s as Root$2, u as createLucideIcon } from "./dist-C1BYNeCR.js";
28
28
  import { A as SquareFunction, C as DEFAULT_COLOR_SCHEME, D as SCALE_TYPE_DESCRIPTIONS, E as EMPTY_VALUE$1, O as TIME_UNIT_DESCRIPTIONS, S as DEFAULT_AGGREGATION, T as DEFAULT_TIME_UNIT, _ as AGGREGATION_TYPE_DESCRIPTIONS, a as AGGREGATION_FNS$1, b as COLOR_SCHEMES, c as COLOR_BY_FIELDS, d as NONE_VALUE, f as SELECTABLE_DATA_TYPES, g as TIME_UNITS, h as STRING_AGGREGATION_FNS, i as convertDataTypeToSelectable, j as ChartColumn, k as escapeFieldName, l as COMBINED_TIME_UNITS, m as SORT_TYPES, n as createSpecWithoutData, o as BIN_AGGREGATION, p as SINGLE_TIME_UNITS, r as isFieldSet, s as CHART_TYPES, t as augmentSpecWithData, u as ChartType, v as AGGREGATION_TYPE_ICON, w as DEFAULT_MAX_BINS_FACET, x as COUNT_FIELD, y as CHART_TYPE_ICON } from "./spec-nqxKYdNH.js";
29
- import { $ as TableBody, $t as ChevronLeft, A as ComboboxItem, At as ChartErrorState, B as contextAwarePanelOpen, Bt as $fae977aafc393c5c$export$6b862160d295c8e, C as prettifyRowColumnCount, Ct as dateToLocalISODate, D as DatePicker, Dt as TabsContent, E as useInternalStateWithSync, Et as Tabs, F as CommandList, Ft as RenderTextWithLinks, G as slotsController, H as contextAwarePanelType, Ht as GripHorizontal, I as CommandSeparator, It as Kbd, Jt as Code, K as Toggle, Kt as Ellipsis, L as smartMatch, Lt as HtmlOutput, M as CommandEmpty, Mt as ChartLoadingState, N as CommandInput, Nt as LazyVegaEmbed, O as DateRangePicker, Ot as TabsList, P as CommandItem, Pt as useOverflowDetection, Q as Table, Qt as ChevronsDownUp, R as ContextAwarePanelItem, Rt as EmotionCacheProvider, S as downloadSizeLimitAtom, St as Maps, T as getColumnCountForDisplay, Tt as dateToLocalISOTime, U as isCellAwareAtom, Ut as Funnel, V as contextAwarePanelOwner, Vt as TextWrap, W as SlotNames, Wt as EyeOff, X as Fill, Xt as ChevronsRight, Yt as ChevronsUpDown, Z as Provider$1, Zt as ChevronsLeft, _ as downloadBlob, _t as SELECT_COLUMN_ID, at as generateColumns, b as Progress, bt as getMimeValues, c as Slide, ct as ColumnChartContext, d as JsonOutput, dt as useIntersectionObserver, en as ArrowDownWideNarrow, et as TableCell, f as OutputArea, ft as usePrevious$1, g as ADD_PRINTING_CLASS, gt as INDEX_COLUMN_NAME, h as InstallPackageButton, ht as loadTableData, it as NAMELESS_COLUMN_PREFIX, j as Command, jt as ChartInfoState, k as Combobox, kt as TabsTrigger, l as RadioGroup, lt as ColumnChartSpecModel, m as DataTable, mt as loadTableAndRawData, n as marimoVersionAtom, nt as TableHeader, o as SLIDE_TYPE_OPTIONS_BY_VALUE, ot as inferFieldTypes, p as OutputRenderer, pt as getPageIndexForRow, qt as Download, r as showCodeInRunModeAtom, rt as TableRow, st as renderCellValue, t as useNotebookCodeAvailable, tt as TableHead, u as RadioGroupItem, ut as DelayMount, v as downloadByURL, vt as TOO_MANY_ROWS, w as prettifyRowCount, wt as dateToLocalISODateTime, x as Filenames, xt as isNullishFilter, y as downloadHTMLAsImage, yt as toFieldTypes, z as PANEL_TYPES, zt as $fae977aafc393c5c$export$588937bcd60ade55, __tla as __tla_2 } from "./code-visibility-DP2xSfeW.js";
29
+ import { $ as TableBody, $t as ChevronLeft, A as ComboboxItem, At as ChartErrorState, B as contextAwarePanelOpen, Bt as $fae977aafc393c5c$export$6b862160d295c8e, C as prettifyRowColumnCount, Ct as dateToLocalISODate, D as DatePicker, Dt as TabsContent, E as useInternalStateWithSync, Et as Tabs, F as CommandList, Ft as RenderTextWithLinks, G as slotsController, H as contextAwarePanelType, Ht as GripHorizontal, I as CommandSeparator, It as Kbd, Jt as Code, K as Toggle, Kt as Ellipsis, L as smartMatch, Lt as HtmlOutput, M as CommandEmpty, Mt as ChartLoadingState, N as CommandInput, Nt as LazyVegaEmbed, O as DateRangePicker, Ot as TabsList, P as CommandItem, Pt as useOverflowDetection, Q as Table, Qt as ChevronsDownUp, R as ContextAwarePanelItem, Rt as EmotionCacheProvider, S as downloadSizeLimitAtom, St as Maps, T as getColumnCountForDisplay, Tt as dateToLocalISOTime, U as isCellAwareAtom, Ut as Funnel, V as contextAwarePanelOwner, Vt as TextWrap, W as SlotNames, Wt as EyeOff, X as Fill, Xt as ChevronsRight, Yt as ChevronsUpDown, Z as Provider$1, Zt as ChevronsLeft, _ as downloadBlob, _t as SELECT_COLUMN_ID, at as generateColumns, b as Progress, bt as getMimeValues, c as Slide, ct as ColumnChartContext, d as JsonOutput, dt as useIntersectionObserver, en as ArrowDownWideNarrow, et as TableCell, f as OutputArea, ft as usePrevious$1, g as ADD_PRINTING_CLASS, gt as INDEX_COLUMN_NAME, h as InstallPackageButton, ht as loadTableData, it as NAMELESS_COLUMN_PREFIX, j as Command, jt as ChartInfoState, k as Combobox, kt as TabsTrigger, l as RadioGroup, lt as ColumnChartSpecModel, m as DataTable, mt as loadTableAndRawData, n as marimoVersionAtom, nt as TableHeader, o as SLIDE_TYPE_OPTIONS_BY_VALUE, ot as inferFieldTypes, p as OutputRenderer, pt as getPageIndexForRow, qt as Download, r as showCodeInRunModeAtom, rt as TableRow, st as renderCellValue, t as useNotebookCodeAvailable, tt as TableHead, u as RadioGroupItem, ut as DelayMount, v as downloadByURL, vt as TOO_MANY_ROWS, w as prettifyRowCount, wt as dateToLocalISODateTime, x as Filenames, xt as isNullishFilter, y as downloadHTMLAsImage, yt as toFieldTypes, z as PANEL_TYPES, zt as $fae977aafc393c5c$export$588937bcd60ade55, __tla as __tla_2 } from "./code-visibility-NEnlle3q.js";
30
30
  import { c as Calendar, i as createReducerAndAtoms, n as useOnUnmount, o as ToggleLeft, t as useOnMount } from "./useLifecycle-DVkMZA_I.js";
31
31
  import { t as Check } from "./check-DTbrK0zt.js";
32
32
  import { A as Trigger$1, C as $a916eb452884faea$export$b7a616150fdb9f44, E as $18f2051aff69b9bf$export$a54013f0d02a8f82, F as X, L as ChevronDown, M as usePrevious$2, N as useDirection, P as createCollection, S as logNever, T as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7, a as SelectGroup, c as SelectSeparator, d as NativeSelect, i as SelectContent, j as clamp$2, k as Icon, l as SelectTrigger, n as capitalize, o as SelectItem, r as Select, s as SelectLabel, t as Strings, u as SelectValue, x as assertNever } from "./strings-Bu3vlb6W.js";
33
33
  import { I as $64fa3d84918910a7$export$29f1550f4b0d4415, K as useDebounceControlledState, L as $64fa3d84918910a7$export$4d86445c2cf5e3, Mt as $65484d02dcb7eb3e$export$457c3d6518dd4c6f, Nt as $3ef42575df84b30b$export$9d1611c77c2fe928, V as $64fa3d84918910a7$export$df3a06d6289f983e, Vt as $ff5963eb1fccf552$export$e08e3b67e392101e, a as NumberField, b as DropdownMenuTrigger, c as prettyNumber, d as DropdownMenuContent, f as DropdownMenuGroup, fn as Circle, g as DropdownMenuSeparator, i as OnBlurredInput, it as $701a24aa0da5b062$export$ea18c227d4417cc3, l as prettyScientificNumber, m as DropdownMenuLabel, n as DebouncedNumberInput, p as DropdownMenuItem, pn as ChevronRight, q as useDebouncedCallback, r as Input, rt as $f7dceffc5ad7768b$export$4e328f61c538687f, t as DebouncedInput, u as DropdownMenu, ut as $6179b936705e76d3$export$ae780daf29e6d456, vt as $458b0a5536c1a7cf$export$40bfa8c7b0832715 } from "./input-Ld3tUgdF.js";
34
34
  import { _ as isWasm, c as asRemoteURL, d as isStaticNotebook, f as appendQueryParams, g as Deferred, m as require_cuid2, u as getStaticVirtualFiles, v as CircleQuestionMark } from "./toDate-DLCQY32Y.js";
35
- import { a as MarimoIncomingMessageEvent, c as MarimoValueUpdateEvent, d as Square, f as File, i as PythonIcon, l as createInputEvent, n as blobToString, o as MarimoValueInputEvent, r as filesToBase64, s as MarimoValueReadyEvent, t as processOutput, u as deserializeBlob } from "./process-output-B8Cqiywi.js";
35
+ import { a as MarimoIncomingMessageEvent, c as MarimoValueUpdateEvent, d as Square, f as File, i as PythonIcon, l as createInputEvent, n as blobToString, o as MarimoValueInputEvent, r as filesToBase64, s as MarimoValueReadyEvent, t as processOutput, u as deserializeBlob } from "./process-output-B55jxGI5.js";
36
36
  import { n as Trash, r as Pencil, t as BulkEdit } from "./types-CVvp1fKr.js";
37
37
  import { n as require_prop_types, r as Plus, t as ErrorBoundary } from "./ErrorBoundary-rULOrC_p.js";
38
38
  import { t as require_react_dom } from "./react-dom-BTJzcVJ9.js";
@@ -5590,7 +5590,7 @@ let __tla = Promise.all([
5590
5590
  };
5591
5591
  }
5592
5592
  };
5593
- var LazyChatbot = import_react.lazy(() => import("./chat-ui-IyGT4sju.js").then((e) => ({
5593
+ var LazyChatbot = import_react.lazy(() => import("./chat-ui-BQqY0W74.js").then((e) => ({
5594
5594
  default: e.Chatbot
5595
5595
  }))), messageSchema = array(object({
5596
5596
  id: string(),
@@ -13049,7 +13049,8 @@ ${c}
13049
13049
  format: zod_default.enum([
13050
13050
  "csv",
13051
13051
  "json",
13052
- "parquet"
13052
+ "parquet",
13053
+ "tsv"
13053
13054
  ])
13054
13055
  })).output(zod_default.object({
13055
13056
  url: zod_default.string(),
@@ -16911,51 +16912,51 @@ ${c}
16911
16912
  "SQL Code"
16912
16913
  ]
16913
16914
  }), r[20] = W, r[21] = XU);
16914
- let ZU;
16915
- r[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (ZU = (0, import_jsx_runtime.jsx)("div", {
16916
- className: "grow"
16917
- }), r[22] = ZU) : ZU = r[22];
16918
16915
  let QU;
16919
- r[23] !== YU || r[24] !== XU ? (QU = (0, import_jsx_runtime.jsxs)(TabsList, {
16916
+ r[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (QU = (0, import_jsx_runtime.jsx)("div", {
16917
+ className: "grow"
16918
+ }), r[22] = QU) : QU = r[22];
16919
+ let $U;
16920
+ r[23] !== YU || r[24] !== XU ? ($U = (0, import_jsx_runtime.jsxs)(TabsList, {
16920
16921
  className: "h-8",
16921
16922
  children: [
16922
16923
  JU,
16923
16924
  YU,
16924
16925
  XU,
16925
- ZU
16926
+ QU
16926
16927
  ]
16927
- }), r[23] = YU, r[24] = XU, r[25] = QU) : QU = r[25];
16928
- let $U;
16929
- r[26] === j ? $U = r[27] : ($U = j && (0, import_jsx_runtime.jsx)(Spinner, {
16930
- size: "small"
16931
- }), r[26] = j, r[27] = $U);
16928
+ }), r[23] = YU, r[24] = XU, r[25] = $U) : $U = r[25];
16932
16929
  let eW;
16933
- r[28] !== QU || r[29] !== $U ? (eW = (0, import_jsx_runtime.jsxs)("div", {
16930
+ r[26] === j ? eW = r[27] : (eW = j && (0, import_jsx_runtime.jsx)(Spinner, {
16931
+ size: "small"
16932
+ }), r[26] = j, r[27] = eW);
16933
+ let tW;
16934
+ r[28] !== $U || r[29] !== eW ? (tW = (0, import_jsx_runtime.jsxs)("div", {
16934
16935
  className: "flex items-center gap-2",
16935
16936
  children: [
16936
- QU,
16937
- $U
16937
+ $U,
16938
+ eW
16938
16939
  ]
16939
- }), r[28] = QU, r[29] = $U, r[30] = eW) : eW = r[30];
16940
- let tW;
16941
- r[31] !== p || r[32] !== f ? (tW = (e2) => {
16940
+ }), r[28] = $U, r[29] = eW, r[30] = tW) : tW = r[30];
16941
+ let nW;
16942
+ r[31] !== p || r[32] !== f ? (nW = (e2) => {
16942
16943
  dequal(e2, f) || (p(e2), VU(e2));
16943
- }, r[31] = p, r[32] = f, r[33] = tW) : tW = r[33];
16944
+ }, r[31] = p, r[32] = f, r[33] = nW) : nW = r[33];
16944
16945
  let rW;
16945
- r[34] !== B || r[35] !== c || r[36] !== h || r[37] !== G || r[38] !== d || r[39] !== tW ? (rW = (0, import_jsx_runtime.jsx)(TabsContent, {
16946
+ r[34] !== B || r[35] !== c || r[36] !== h || r[37] !== G || r[38] !== d || r[39] !== nW ? (rW = (0, import_jsx_runtime.jsx)(TabsContent, {
16946
16947
  value: "transform",
16947
16948
  className: "mt-1 border rounded-t overflow-hidden",
16948
16949
  children: (0, import_jsx_runtime.jsx)(TransformPanel, {
16949
16950
  ref: q,
16950
16951
  initialValue: G,
16951
16952
  columns: c,
16952
- onChange: tW,
16953
+ onChange: nW,
16953
16954
  onInvalidChange: VU,
16954
16955
  getColumnValues: h,
16955
16956
  columnTypesPerStep: B,
16956
16957
  lazy: d
16957
16958
  })
16958
- }), r[34] = B, r[35] = c, r[36] = h, r[37] = G, r[38] = d, r[39] = tW, r[40] = rW) : rW = r[40];
16959
+ }), r[34] = B, r[35] = c, r[36] = h, r[37] = G, r[38] = d, r[39] = nW, r[40] = rW) : rW = r[40];
16959
16960
  let iW;
16960
16961
  r[41] === H ? iW = r[42] : (iW = H && (0, import_jsx_runtime.jsx)(TabsContent, {
16961
16962
  value: "python-code",
@@ -16979,16 +16980,16 @@ ${c}
16979
16980
  })
16980
16981
  }), r[43] = W, r[44] = aW);
16981
16982
  let oW;
16982
- r[45] !== HU || r[46] !== eW || r[47] !== rW || r[48] !== iW || r[49] !== aW ? (oW = (0, import_jsx_runtime.jsxs)(Tabs, {
16983
+ r[45] !== HU || r[46] !== tW || r[47] !== rW || r[48] !== iW || r[49] !== aW ? (oW = (0, import_jsx_runtime.jsxs)(Tabs, {
16983
16984
  defaultValue: "transform",
16984
16985
  onValueChange: HU,
16985
16986
  children: [
16986
- eW,
16987
+ tW,
16987
16988
  rW,
16988
16989
  iW,
16989
16990
  aW
16990
16991
  ]
16991
- }), r[45] = HU, r[46] = eW, r[47] = rW, r[48] = iW, r[49] = aW, r[50] = oW) : oW = r[50];
16992
+ }), r[45] = HU, r[46] = tW, r[47] = rW, r[48] = iW, r[49] = aW, r[50] = oW) : oW = r[50];
16992
16993
  let sW;
16993
16994
  r[51] === O ? sW = r[52] : (sW = O && (0, import_jsx_runtime.jsx)(ErrorBanner, {
16994
16995
  error: O
@@ -17220,7 +17221,7 @@ ${c}
17220
17221
  }, W = [
17221
17222
  B
17222
17223
  ], r[8] = B, r[9] = H, r[10] = W), (0, import_react.useEffect)(H, W);
17223
- let BU, G, VU, q, Z, UU, WU, KU, qU;
17224
+ let BU, G, VU, q, Z, HU, WU, GU, qU;
17224
17225
  if (r[11] !== R || r[12] !== z || r[13] !== u || r[14] !== b || r[15] !== f || r[16] !== v || r[17] !== h || r[18] !== d || r[19] !== y || r[20] !== l || r[21] !== c) {
17225
17226
  qU = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
17226
17227
  bb0: {
@@ -17262,7 +17263,7 @@ ${c}
17262
17263
  return;
17263
17264
  }
17264
17265
  y(e3), S(false);
17265
- }, r[42] = G, r[43] = u, r[44] = b, r[45] = v, r[46] = h, r[47] = y, r[48] = j2) : j2 = r[48], KU = j2;
17266
+ }, r[42] = G, r[43] = u, r[44] = b, r[45] = v, r[46] = h, r[47] = y, r[48] = j2) : j2 = r[48], GU = j2;
17266
17267
  let M2;
17267
17268
  r[49] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (M2 = function(e3) {
17268
17269
  let { path: r2, name: c2, isDirectory: l2 } = e3;
@@ -17290,7 +17291,7 @@ ${c}
17290
17291
  let H2 = B2, W2;
17291
17292
  r[55] !== v || r[56] !== l || r[57] !== c ? (W2 = function() {
17292
17293
  l(c.filter((e3) => Paths.dirname(e3.path) !== v));
17293
- }, r[55] = v, r[56] = l, r[57] = c, r[58] = W2) : W2 = r[58], VU = W2, UU = function() {
17294
+ }, r[55] = v, r[56] = l, r[57] = c, r[58] = W2) : W2 = r[58], VU = W2, HU = function() {
17294
17295
  let e3 = [];
17295
17296
  for (let r2 of Z) {
17296
17297
  if (!g2 && r2.is_directory || m2.has(r2.path)) continue;
@@ -17307,7 +17308,7 @@ ${c}
17307
17308
  ]);
17308
17309
  }, q = [];
17309
17310
  let JU2;
17310
- r[59] === KU ? JU2 = r[60] : (JU2 = () => KU(PARENT_DIRECTORY), r[59] = KU, r[60] = JU2);
17311
+ r[59] === GU ? JU2 = r[60] : (JU2 = () => GU(PARENT_DIRECTORY), r[59] = GU, r[60] = JU2);
17311
17312
  let YU2, XU2;
17312
17313
  r[61] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (YU2 = (0, import_jsx_runtime.jsx)(TableCell, {
17313
17314
  className: "w-[50px] pl-4",
@@ -17331,7 +17332,7 @@ ${c}
17331
17332
  r2.startsWith("//") && (r2 = r2.slice(1));
17332
17333
  let c2 = e3.is_directory ? (e4) => {
17333
17334
  let { path: r3 } = e4;
17334
- return KU(r3);
17335
+ return GU(r3);
17335
17336
  } : H2, l2 = FILE_ICON[e3.is_directory ? "directory" : guessFileIconType(e3.name)], u2 = m2.has(r2);
17336
17337
  q.push((0, import_jsx_runtime.jsxs)(TableRow, {
17337
17338
  className: cn("hover:bg-accent group select-none", {
@@ -17363,11 +17364,11 @@ ${c}
17363
17364
  }, e3.id));
17364
17365
  }
17365
17366
  }
17366
- r[11] = R, r[12] = z, r[13] = u, r[14] = b, r[15] = f, r[16] = v, r[17] = h, r[18] = d, r[19] = y, r[20] = l, r[21] = c, r[22] = BU, r[23] = G, r[24] = VU, r[25] = q, r[26] = Z, r[27] = UU, r[28] = WU, r[29] = KU, r[30] = qU;
17367
- } else BU = r[22], G = r[23], VU = r[24], q = r[25], Z = r[26], UU = r[27], WU = r[28], KU = r[29], qU = r[30];
17367
+ r[11] = R, r[12] = z, r[13] = u, r[14] = b, r[15] = f, r[16] = v, r[17] = h, r[18] = d, r[19] = y, r[20] = l, r[21] = c, r[22] = BU, r[23] = G, r[24] = VU, r[25] = q, r[26] = Z, r[27] = HU, r[28] = WU, r[29] = GU, r[30] = qU;
17368
+ } else BU = r[22], G = r[23], VU = r[24], q = r[25], Z = r[26], HU = r[27], WU = r[28], GU = r[29], qU = r[30];
17368
17369
  if (qU !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) return qU;
17369
17370
  let JU, YU, XU, ZU, QU, $U, eW;
17370
- if (r[65] !== BU || r[66] !== R || r[67] !== G || r[68] !== VU || r[69] !== z || r[70] !== q || r[71] !== Z || r[72] !== u || r[73] !== B || r[74] !== m || r[75] !== f || r[76] !== v || r[77] !== h || r[78] !== UU || r[79] !== WU || r[80] !== d || r[81] !== KU || r[82] !== l || r[83] !== T || r[84] !== c.length) {
17371
+ if (r[65] !== BU || r[66] !== R || r[67] !== G || r[68] !== VU || r[69] !== z || r[70] !== q || r[71] !== Z || r[72] !== u || r[73] !== B || r[74] !== m || r[75] !== f || r[76] !== v || r[77] !== h || r[78] !== HU || r[79] !== WU || r[80] !== d || r[81] !== GU || r[82] !== l || r[83] !== T || r[84] !== c.length) {
17371
17372
  let { parentDirectories: e2 } = getProtocolAndParentDirectories({
17372
17373
  path: v,
17373
17374
  delimiter: G,
@@ -17394,7 +17395,7 @@ ${c}
17394
17395
  children: (0, import_jsx_runtime.jsx)(Button, {
17395
17396
  size: "xs",
17396
17397
  variant: "link",
17397
- onClick: BU ? VU : UU,
17398
+ onClick: BU ? VU : HU,
17398
17399
  children: BU ? "Deselect all" : "Select all"
17399
17400
  })
17400
17401
  })
@@ -17402,7 +17403,7 @@ ${c}
17402
17403
  }) : e3;
17403
17404
  })();
17404
17405
  let _2;
17405
- r[94] === KU ? _2 = r[95] : (_2 = (e3) => KU(e3.target.value), r[94] = KU, r[95] = _2);
17406
+ r[94] === GU ? _2 = r[95] : (_2 = (e3) => GU(e3.target.value), r[94] = GU, r[95] = _2);
17406
17407
  let y2 = e2.map(_temp3$5);
17407
17408
  r[96] !== v || r[97] !== _2 || r[98] !== y2 ? (YU = (0, import_jsx_runtime.jsx)(NativeSelect, {
17408
17409
  className: "mt-2 w-full",
@@ -17480,7 +17481,7 @@ ${c}
17480
17481
  })
17481
17482
  })
17482
17483
  ]
17483
- }), r[65] = BU, r[66] = R, r[67] = G, r[68] = VU, r[69] = z, r[70] = q, r[71] = Z, r[72] = u, r[73] = B, r[74] = m, r[75] = f, r[76] = v, r[77] = h, r[78] = UU, r[79] = WU, r[80] = d, r[81] = KU, r[82] = l, r[83] = T, r[84] = c.length, r[85] = JU, r[86] = YU, r[87] = XU, r[88] = ZU, r[89] = QU, r[90] = $U, r[91] = eW;
17484
+ }), r[65] = BU, r[66] = R, r[67] = G, r[68] = VU, r[69] = z, r[70] = q, r[71] = Z, r[72] = u, r[73] = B, r[74] = m, r[75] = f, r[76] = v, r[77] = h, r[78] = HU, r[79] = WU, r[80] = d, r[81] = GU, r[82] = l, r[83] = T, r[84] = c.length, r[85] = JU, r[86] = YU, r[87] = XU, r[88] = ZU, r[89] = QU, r[90] = $U, r[91] = eW;
17484
17485
  } else JU = r[85], YU = r[86], XU = r[87], ZU = r[88], QU = r[89], $U = r[90], eW = r[91];
17485
17486
  let tW;
17486
17487
  r[112] !== QU || r[113] !== $U ? (tW = (0, import_jsx_runtime.jsx)("div", {
@@ -23591,8 +23592,8 @@ ${c}
23591
23592
  r[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (z = () => {
23592
23593
  j.current && clearInputs(j.current);
23593
23594
  }, r[0] = z) : z = r[0];
23594
- let B = z, H;
23595
- r[1] !== y || r[2] !== u || r[3] !== d || r[4] !== O || r[5] !== E ? (H = async (e2) => {
23595
+ let H = z, W;
23596
+ r[1] !== y || r[2] !== u || r[3] !== d || r[4] !== O || r[5] !== E ? (W = async (e2) => {
23596
23597
  if (e2.preventDefault(), O) {
23597
23598
  let e3 = await E({
23598
23599
  value: u
@@ -23604,86 +23605,86 @@ ${c}
23604
23605
  return;
23605
23606
  }
23606
23607
  }
23607
- R(null), d(u), y && B();
23608
- }, r[1] = y, r[2] = u, r[3] = d, r[4] = O, r[5] = E, r[6] = H) : H = r[6];
23609
- let W = !M && m, BU;
23610
- r[7] !== m || r[8] !== W ? (BU = cn("flex flex-col gap-4 rounded-lg py-4 px-8", {
23608
+ R(null), d(u), y && H();
23609
+ }, r[1] = y, r[2] = u, r[3] = d, r[4] = O, r[5] = E, r[6] = W) : W = r[6];
23610
+ let BU = !M && m, G;
23611
+ r[7] !== m || r[8] !== BU ? (G = cn("flex flex-col gap-4 rounded-lg py-4 px-8", {
23611
23612
  "bg-(--gray-1) shadow-md border border-input": m,
23612
- "bg-(--amber-1) border-(--amber-7)": W
23613
- }), r[7] = m, r[8] = W, r[9] = BU) : BU = r[9];
23614
- let G;
23615
- r[10] !== u || r[11] !== d ? (G = (e2) => {
23616
- e2.key === "Enter" && (e2.ctrlKey || e2.metaKey) && (e2.preventDefault(), e2.stopPropagation(), d(u));
23617
- }, r[10] = u, r[11] = d, r[12] = G) : G = r[12];
23613
+ "bg-(--amber-1) border-(--amber-7)": BU
23614
+ }), r[7] = m, r[8] = BU, r[9] = G) : G = r[9];
23618
23615
  let VU;
23619
- r[13] === f ? VU = r[14] : (VU = f === null ? null : (0, import_jsx_runtime.jsx)("div", {
23616
+ r[10] !== u || r[11] !== d ? (VU = (e2) => {
23617
+ e2.key === "Enter" && (e2.ctrlKey || e2.metaKey) && (e2.preventDefault(), e2.stopPropagation(), d(u));
23618
+ }, r[10] = u, r[11] = d, r[12] = VU) : VU = r[12];
23619
+ let q;
23620
+ r[13] === f ? q = r[14] : (q = f === null ? null : (0, import_jsx_runtime.jsx)("div", {
23620
23621
  className: "text-center",
23621
23622
  children: renderHTML({
23622
23623
  html: f
23623
23624
  })
23624
- }), r[13] = f, r[14] = VU);
23625
- let q;
23626
- r[15] === L ? q = r[16] : (q = L != null && (0, import_jsx_runtime.jsx)(Banner, {
23625
+ }), r[13] = f, r[14] = q);
23626
+ let Z;
23627
+ r[15] === L ? Z = r[16] : (Z = L != null && (0, import_jsx_runtime.jsx)(Banner, {
23627
23628
  kind: "danger",
23628
23629
  className: "rounded",
23629
23630
  children: L ?? "Invalid input"
23630
- }), r[15] = L, r[16] = q);
23631
- let Z;
23632
- r[17] === c ? Z = r[18] : (Z = (0, import_jsx_runtime.jsx)("div", {
23633
- children: c
23634
- }), r[17] = c, r[18] = Z);
23631
+ }), r[15] = L, r[16] = Z);
23635
23632
  let HU;
23636
- r[19] !== S || r[20] !== T || r[21] !== b ? (HU = b && withTooltip((0, import_jsx_runtime.jsx)(Button, {
23633
+ r[17] === c ? HU = r[18] : (HU = (0, import_jsx_runtime.jsx)("div", {
23634
+ children: c
23635
+ }), r[17] = c, r[18] = HU);
23636
+ let UU;
23637
+ r[19] !== S || r[20] !== T || r[21] !== b ? (UU = b && withTooltip((0, import_jsx_runtime.jsx)(Button, {
23637
23638
  "data-testid": "marimo-plugin-form-clear-button",
23638
23639
  variant: "text",
23639
23640
  onClick: (e2) => {
23640
- e2.preventDefault(), B();
23641
+ e2.preventDefault(), H();
23641
23642
  },
23642
23643
  children: S
23643
- }), T), r[19] = S, r[20] = T, r[21] = b, r[22] = HU) : HU = r[22];
23644
- let UU = v || h, WU;
23645
- r[23] === h ? WU = r[24] : (WU = h && (0, import_jsx_runtime.jsx)(LoaderCircle, {
23644
+ }), T), r[19] = S, r[20] = T, r[21] = b, r[22] = UU) : UU = r[22];
23645
+ let WU = v || h, GU;
23646
+ r[23] === h ? GU = r[24] : (GU = h && (0, import_jsx_runtime.jsx)(LoaderCircle, {
23646
23647
  className: "h-4 w-4 mr-2 animate-spin"
23647
- }), r[23] = h, r[24] = WU);
23648
- let GU;
23649
- r[25] !== g || r[26] !== UU || r[27] !== WU || r[28] !== I ? (GU = (0, import_jsx_runtime.jsxs)(Button, {
23648
+ }), r[23] = h, r[24] = GU);
23649
+ let KU;
23650
+ r[25] !== g || r[26] !== WU || r[27] !== GU || r[28] !== I ? (KU = (0, import_jsx_runtime.jsxs)(Button, {
23650
23651
  "data-testid": "marimo-plugin-form-submit-button",
23651
23652
  variant: I,
23652
- disabled: UU,
23653
+ disabled: WU,
23653
23654
  type: "submit",
23654
23655
  children: [
23655
- WU,
23656
+ GU,
23656
23657
  g
23657
23658
  ]
23658
- }), r[25] = g, r[26] = UU, r[27] = WU, r[28] = I, r[29] = GU) : GU = r[29];
23659
- let KU;
23660
- r[30] !== _ || r[31] !== GU ? (KU = withTooltip(GU, _), r[30] = _, r[31] = GU, r[32] = KU) : KU = r[32];
23659
+ }), r[25] = g, r[26] = WU, r[27] = GU, r[28] = I, r[29] = KU) : KU = r[29];
23661
23660
  let qU;
23662
- r[33] !== KU || r[34] !== HU ? (qU = (0, import_jsx_runtime.jsxs)("div", {
23661
+ r[30] !== _ || r[31] !== KU ? (qU = withTooltip(KU, _), r[30] = _, r[31] = KU, r[32] = qU) : qU = r[32];
23662
+ let JU;
23663
+ r[33] !== qU || r[34] !== UU ? (JU = (0, import_jsx_runtime.jsxs)("div", {
23663
23664
  className: "flex justify-end gap-2 font-code",
23664
23665
  children: [
23665
- HU,
23666
- KU
23666
+ UU,
23667
+ qU
23667
23668
  ]
23668
- }), r[33] = KU, r[34] = HU, r[35] = qU) : qU = r[35];
23669
- let JU;
23670
- r[36] !== qU || r[37] !== BU || r[38] !== G || r[39] !== VU || r[40] !== q || r[41] !== Z ? (JU = (0, import_jsx_runtime.jsxs)("div", {
23671
- className: BU,
23672
- onKeyDown: G,
23669
+ }), r[33] = qU, r[34] = UU, r[35] = JU) : JU = r[35];
23670
+ let YU;
23671
+ r[36] !== JU || r[37] !== G || r[38] !== VU || r[39] !== q || r[40] !== Z || r[41] !== HU ? (YU = (0, import_jsx_runtime.jsxs)("div", {
23672
+ className: G,
23673
+ onKeyDown: VU,
23673
23674
  children: [
23674
- VU,
23675
23675
  q,
23676
23676
  Z,
23677
- qU
23677
+ HU,
23678
+ JU
23678
23679
  ]
23679
- }), r[36] = qU, r[37] = BU, r[38] = G, r[39] = VU, r[40] = q, r[41] = Z, r[42] = JU) : JU = r[42];
23680
- let YU;
23681
- return r[43] !== JU || r[44] !== H ? (YU = (0, import_jsx_runtime.jsx)("form", {
23680
+ }), r[36] = JU, r[37] = G, r[38] = VU, r[39] = q, r[40] = Z, r[41] = HU, r[42] = YU) : YU = r[42];
23681
+ let XU;
23682
+ return r[43] !== YU || r[44] !== W ? (XU = (0, import_jsx_runtime.jsx)("form", {
23682
23683
  className: "contents",
23683
23684
  ref: j,
23684
- onSubmit: H,
23685
- children: JU
23686
- }), r[43] = JU, r[44] = H, r[45] = YU) : YU = r[45], YU;
23685
+ onSubmit: W,
23686
+ children: YU
23687
+ }), r[43] = YU, r[44] = W, r[45] = XU) : XU = r[45], XU;
23687
23688
  };
23688
23689
  var Form = (e) => {
23689
23690
  let r = (0, import_compiler_runtime$42.c)(24), c, l, u, d, f, p;
@@ -36093,7 +36094,7 @@ ${c}
36093
36094
  if (l && l !== "slide") return l;
36094
36095
  if (c == null ? void 0 : c.has(e)) return "skip";
36095
36096
  }
36096
- var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-B7RA3HR2.js"));
36097
+ var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-DSKBnskA.js"));
36097
36098
  const SlidesLayoutRenderer = ({ layout: e, setLayout: r, cells: c, mode: l }) => {
36098
36099
  var _a3;
36099
36100
  let u = useAtomValue(kioskModeAtom), d = l === "read" || u, f = useAtomValue(numColumnsAtom) > 1, [p, m] = (0, import_react.useState)(null), { cellsWithOutput: h, skippedIds: g, slideTypes: _, startCellIndex: v } = (0, import_react.useMemo)(() => computeSlideCellsInfo(c, e), [
@@ -36837,18 +36838,18 @@ ${c}
36837
36838
  showCode: b,
36838
36839
  onToggleShowCode: () => S(_temp$1)
36839
36840
  }), r[23] = w, r[24] = u, r[25] = b, r[26] = z) : z = r[26];
36840
- let B;
36841
- r[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (B = (0, import_jsx_runtime.jsx)(FloatingOutline, {}), r[27] = B) : B = r[27];
36842
36841
  let H;
36843
- return r[28] !== l || r[29] !== d || r[30] !== R || r[31] !== z ? (H = (0, import_jsx_runtime.jsxs)(VerticalLayoutWrapper, {
36842
+ r[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (H = (0, import_jsx_runtime.jsx)(FloatingOutline, {}), r[27] = H) : H = r[27];
36843
+ let W;
36844
+ return r[28] !== l || r[29] !== d || r[30] !== R || r[31] !== z ? (W = (0, import_jsx_runtime.jsxs)(VerticalLayoutWrapper, {
36844
36845
  invisible: d,
36845
36846
  appConfig: l,
36846
36847
  children: [
36847
36848
  R,
36848
36849
  z,
36849
- B
36850
+ H
36850
36851
  ]
36851
- }), r[28] = l, r[29] = d, r[30] = R, r[31] = z, r[32] = H) : H = r[32], H;
36852
+ }), r[28] = l, r[29] = d, r[30] = R, r[31] = z, r[32] = W) : W = r[32], W;
36852
36853
  }, ActionButtons = (e) => {
36853
36854
  let r = (0, import_compiler_runtime$3.c)(26), { canShowCode: c, showCode: l, onToggleShowCode: u } = e, { readCode: d } = useRequestClient(), f = _temp2, m = _temp3, h;
36854
36855
  r[0] === d ? h = r[1] : (h = async () => {
@@ -1,6 +1,6 @@
1
1
  import { s as __toESM } from "./chunk-BNovOVIE.js";
2
2
  import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
3
- import { it as parseHtmlContent, rt as ansiToPlainText } from "./html-to-image-CGbhD84m.js";
3
+ import { it as parseHtmlContent, rt as ansiToPlainText } from "./html-to-image-BAPmFVwS.js";
4
4
  import { u as createLucideIcon } from "./dist-C1BYNeCR.js";
5
5
  import { t as Strings } from "./strings-Bu3vlb6W.js";
6
6
  import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
@@ -6,10 +6,10 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
6
6
  import { _ as Logger, g as cn, h as Events, l as useEventListener, t as Button } from "./button-C5K9fIPF.js";
7
7
  import { t as require_react } from "./react-DA-nE2FX.js";
8
8
  import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
9
- import { ct as kioskModeAtom } from "./html-to-image-CGbhD84m.js";
9
+ import { ct as kioskModeAtom } from "./html-to-image-BAPmFVwS.js";
10
10
  import "./chunk-5FQGJX7Z-BNjes6Yx.js";
11
11
  import { u as createLucideIcon } from "./dist-C1BYNeCR.js";
12
- import { Gt as Expand, J as PanelGroup, Jt as Code, Wt as EyeOff, Y as PanelResizeHandle, a as DEFAULT_SLIDE_TYPE, c as Slide, i as DEFAULT_DECK_TRANSITION, q as Panel, s as SlideSidebar, t as useNotebookCodeAvailable } from "./code-visibility-DP2xSfeW.js";
12
+ import { Gt as Expand, J as PanelGroup, Jt as Code, Wt as EyeOff, Y as PanelResizeHandle, a as DEFAULT_SLIDE_TYPE, c as Slide, i as DEFAULT_DECK_TRANSITION, q as Panel, s as SlideSidebar, t as useNotebookCodeAvailable } from "./code-visibility-NEnlle3q.js";
13
13
  import { q as useDebouncedCallback } from "./input-Ld3tUgdF.js";
14
14
  import "./toDate-DLCQY32Y.js";
15
15
  import "./react-dom-BTJzcVJ9.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.23.9-dev36",
3
+ "version": "0.23.9-dev38",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -9,7 +9,6 @@ import {
9
9
  TableIcon,
10
10
  } from "lucide-react";
11
11
  import React from "react";
12
- import { useLocale } from "react-aria";
13
12
  import { downloadSizeLimitAtom } from "./download-policy/atoms";
14
13
  import { logNever } from "@/utils/assertNever";
15
14
  import { cn } from "@/utils/cn";
@@ -20,7 +19,6 @@ import { Filenames } from "@/utils/filenames";
20
19
  import {
21
20
  jsonParseWithSpecialChar,
22
21
  jsonToMarkdown,
23
- jsonToTSV,
24
22
  } from "@/utils/json/json-parser";
25
23
  import { MissingPackagePrompt } from "../datasources/missing-package-prompt";
26
24
  import { Button } from "../ui/button";
@@ -68,7 +66,12 @@ const FILE_TYPES = {
68
66
  },
69
67
  } as const;
70
68
 
71
- const downloadOptions = [FILE_TYPES.CSV, FILE_TYPES.JSON, FILE_TYPES.PARQUET];
69
+ const downloadOptions = [
70
+ FILE_TYPES.CSV,
71
+ FILE_TYPES.TSV,
72
+ FILE_TYPES.JSON,
73
+ FILE_TYPES.PARQUET,
74
+ ];
72
75
  const copyOptions = [
73
76
  FILE_TYPES.TSV,
74
77
  FILE_TYPES.JSON,
@@ -79,6 +82,15 @@ const copyOptions = [
79
82
  type DownloadFormat = (typeof downloadOptions)[number]["format"];
80
83
  type CopyFormat = (typeof copyOptions)[number]["format"];
81
84
 
85
+ // Each clipboard-copy format fetches from a backend download format, then
86
+ // transforms the payload client-side as needed.
87
+ const COPY_SOURCE_FORMAT: Record<CopyFormat, DownloadFormat> = {
88
+ csv: "csv",
89
+ tsv: "tsv",
90
+ json: "json",
91
+ markdown: "json",
92
+ };
93
+
82
94
  export interface ExportActionProps {
83
95
  downloadAs: (req: { format: DownloadFormat }) => Promise<{
84
96
  url: string;
@@ -100,7 +112,6 @@ const labelForCopyFormat = (format: CopyFormat): string =>
100
112
  copyOptions.find((opt) => opt.format === format)?.label ?? format;
101
113
 
102
114
  export const ExportMenu: React.FC<ExportActionProps> = (props) => {
103
- const { locale } = useLocale();
104
115
  const [downloadMenuOpen, setDownloadMenuOpen] = React.useState(false);
105
116
  const policy = useAtomValue(downloadSizeLimitAtom);
106
117
  const overLimit = !!(
@@ -213,7 +224,7 @@ export const ExportMenu: React.FC<ExportActionProps> = (props) => {
213
224
  await withLoadingToast(
214
225
  `Preparing ${labelForCopyFormat(format)} for clipboard...`,
215
226
  async () => {
216
- const sourceFormat: DownloadFormat = format === "csv" ? "csv" : "json";
227
+ const sourceFormat = COPY_SOURCE_FORMAT[format];
217
228
  const result = await resolveDownloadUrl(sourceFormat, () => {
218
229
  void handleClipboardCopy(format);
219
230
  });
@@ -223,19 +234,15 @@ export const ExportMenu: React.FC<ExportActionProps> = (props) => {
223
234
 
224
235
  let text: string;
225
236
  switch (format) {
226
- case "tsv": {
227
- const json = await fetchJson(result.url);
228
- text = jsonToTSV(json, locale);
237
+ case "tsv":
238
+ case "csv":
239
+ text = await fetchText(result.url);
229
240
  break;
230
- }
231
241
  case "json": {
232
242
  const json = await fetchJson(result.url);
233
243
  text = JSON.stringify(json, null, 2);
234
244
  break;
235
245
  }
236
- case "csv":
237
- text = await fetchText(result.url);
238
- break;
239
246
  case "markdown": {
240
247
  const json = await fetchJson(result.url);
241
248
  text = jsonToMarkdown(json);
@@ -4,7 +4,7 @@ import z from "zod";
4
4
  import { rpc } from "@/plugins/core/rpc";
5
5
 
6
6
  export type DownloadAsArgs = (req: {
7
- format: "csv" | "json" | "parquet";
7
+ format: "csv" | "json" | "parquet" | "tsv";
8
8
  }) => Promise<{
9
9
  url: string;
10
10
  filename: string;
@@ -15,7 +15,7 @@ export type DownloadAsArgs = (req: {
15
15
  export const DownloadAsSchema = rpc
16
16
  .input(
17
17
  z.object({
18
- format: z.enum(["csv", "json", "parquet"]),
18
+ format: z.enum(["csv", "json", "parquet", "tsv"]),
19
19
  }),
20
20
  )
21
21
  .output(
@@ -1,10 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { expect, it } from "vitest";
3
- import {
4
- jsonParseWithSpecialChar,
5
- jsonToMarkdown,
6
- jsonToTSV,
7
- } from "../json/json-parser";
3
+ import { jsonParseWithSpecialChar, jsonToMarkdown } from "../json/json-parser";
8
4
 
9
5
  it("can jsonParseWithSpecialChar happy path", () => {
10
6
  expect(jsonParseWithSpecialChar('"hello"')).toEqual("hello");
@@ -72,70 +68,6 @@ it("can parse bigInts", () => {
72
68
  });
73
69
  });
74
70
 
75
- it("can convert json to tsv with en-US locale", () => {
76
- const locale = "en-US";
77
-
78
- expect(jsonToTSV([], locale)).toEqual("");
79
-
80
- expect(jsonToTSV([{ a: 1, b: 2 }], locale)).toEqual("a\tb\n1\t2");
81
-
82
- expect(
83
- jsonToTSV(
84
- [
85
- { a: 1, b: 2 },
86
- { a: 3, b: 4 },
87
- ],
88
- locale,
89
- ),
90
- ).toEqual("a\tb\n1\t2\n3\t4");
91
-
92
- // Does not handle sparse arrays
93
- expect(jsonToTSV([{ a: 1 }, { a: 2, b: 3 }], locale)).toMatchInlineSnapshot(
94
- '"a\n1\n2"',
95
- );
96
-
97
- // Handles special characters
98
- expect(
99
- jsonToTSV([{ a: "hello\tworld", b: "new\nline" }], locale),
100
- ).toMatchInlineSnapshot('"a\tb\nhello\tworld\tnew\nline"');
101
-
102
- // Handles floats with en-US locale (uses . as decimal separator)
103
- expect(jsonToTSV([{ a: 1.5, b: 2.7 }], locale)).toEqual("a\tb\n1.5\t2.7");
104
- });
105
-
106
- it("can convert json to tsv with de-DE locale", () => {
107
- const locale = "de-DE";
108
-
109
- // Handles floats with de-DE locale (uses , as decimal separator)
110
- expect(jsonToTSV([{ a: 1.5, b: 2.7 }], locale)).toEqual("a\tb\n1,5\t2,7");
111
-
112
- // Handles integers (no change)
113
- expect(jsonToTSV([{ a: 1, b: 2 }], locale)).toEqual("a\tb\n1\t2");
114
- });
115
-
116
- it("can convert json to tsv with fr-FR locale", () => {
117
- const locale = "fr-FR";
118
-
119
- // Handles floats with fr-FR locale (uses , as decimal separator)
120
- expect(jsonToTSV([{ a: 3.14, b: 2.123_45 }], locale)).toEqual(
121
- "a\tb\n3,14\t2,12345",
122
- );
123
- });
124
-
125
- it("handles null and undefined values in TSV", () => {
126
- const locale = "en-US";
127
-
128
- expect(jsonToTSV([{ a: null, b: undefined, c: 1 }], locale)).toEqual(
129
- "a\tb\tc\n\t\t1",
130
- );
131
- });
132
-
133
- it("handles NaN values in TSV", () => {
134
- const locale = "en-US";
135
-
136
- expect(jsonToTSV([{ a: Number.NaN, b: 1 }], locale)).toEqual("a\tb\nNaN\t1");
137
- });
138
-
139
71
  it("can convert json to markdown - basic table", () => {
140
72
  expect(jsonToMarkdown([])).toMatchInlineSnapshot(`""`);
141
73