@marimo-team/islands 0.25.3-dev40 → 0.25.3-dev44

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 (38) hide show
  1. package/dist/{ErrorBoundary-C7__jAZL.js → ErrorBoundary-C0Oq0jHx.js} +1 -1
  2. package/dist/{chat-ui-DGpBSln7.js → chat-ui-DlUp75HS.js} +4 -4
  3. package/dist/{code-visibility-DO4MlViW.js → code-visibility-B1eNzkOg.js} +3 -3
  4. package/dist/{common-Ci7TC3e0.js → common-pqD_dOGD.js} +70 -71
  5. package/dist/{data-grid-overlay-editor-DpH_AKdC.js → data-grid-overlay-editor-pTWEP43w.js} +1 -1
  6. package/dist/{error-entries-D576fzV9.js → error-entries-D3ouOLDe.js} +1 -1
  7. package/dist/{feedback-button-BV5AJ3nl.js → feedback-button-dWEWzzD4.js} +3 -3
  8. package/dist/{formats-DIVMVjeV.js → formats-C24TvExI.js} +1 -1
  9. package/dist/{glide-data-editor-CRK-O0KE.js → glide-data-editor-DBnOUonk.js} +3 -3
  10. package/dist/{globals-H_ILLmr7.js → globals-DYaD1Xz7.js} +1 -1
  11. package/dist/{html-to-image-D3m5Ob5H.js → html-to-image-VZvb968z.js} +2 -2
  12. package/dist/main.js +13 -13
  13. package/dist/{number-overlay-editor-BQ2UqdED.js → number-overlay-editor-BURiB1Nu.js} +1 -1
  14. package/dist/{process-output-C6qc7hPS.js → process-output-CCPgTShO.js} +2 -2
  15. package/dist/{reveal-component-Cs-0GwxY.js → reveal-component-s74n77kc.js} +4 -4
  16. package/dist/style.css +1 -1
  17. package/dist/{toDate-CSY-j1Fi.js → toDate-C0jaysq2.js} +93 -94
  18. package/dist/{vega-component-Df45z17m.js → vega-component-CF9IzE2r.js} +2 -2
  19. package/package.json +2 -4
  20. package/src/__tests__/host-imports.test.ts +1 -0
  21. package/src/components/data-table/__tests__/export-actions.test.tsx +88 -0
  22. package/src/components/data-table/export-actions.tsx +71 -45
  23. package/src/core/attachments/state.ts +2 -2
  24. package/src/core/host/AGENTS.md +6 -2
  25. package/src/core/host/__tests__/attachments.test.ts +9 -10
  26. package/src/core/host/__tests__/document.test.ts +18 -16
  27. package/src/core/host/__tests__/events.test.ts +5 -2
  28. package/src/core/host/__tests__/fixtures.ts +6 -4
  29. package/src/core/host/events.ts +18 -2
  30. package/src/core/host/notebook-client.ts +46 -13
  31. package/src/core/host/resources/attachments.ts +3 -3
  32. package/src/core/host/resources/document.ts +3 -3
  33. package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +1 -1
  34. package/src/core/host/__tests__/protocol.test.ts +0 -229
  35. package/src/core/host/__tests__/stream.test.ts +0 -209
  36. package/src/core/host/protocol.ts +0 -1948
  37. package/src/core/host/resources/resource.ts +0 -47
  38. package/src/core/host/stream.ts +0 -211
@@ -78,7 +78,7 @@ function te() {
78
78
  return e[0] === Symbol.for("react.memo_cache_sentinel") ? (r = new URLSearchParams(window.location.search).get(b.kiosk), e[0] = r) : r = e[0], t !== "read" && !n && r !== "true";
79
79
  }
80
80
  //#endregion
81
- //#region src/core/host/protocol.ts
81
+ //#region ../packages/client/dist/protocol.js
82
82
  var P = c().min(1).describe("Identifies a project. Unique within the host and unchanged while the project exists."), F = c().min(1).describe("Identifies a notebook. Unique within the host and unchanged while the notebook exists."), I = c().min(1).describe("Identifies a runtime. Unique within the host; every start and restart creates a new id."), ne = c().min(1).describe("Identifies an attachment. Unique within the host."), L = c().min(1).describe("Identifies a run independently of the request's `Idempotency-Key`. Events carry the key in `request_id`."), R = c().min(1).describe("Identifies an execution. Unique within the host."), z = c().min(1).describe("Identifies a console, display, or variable item. Unique within the host; sending an item again with the same id replaces it."), B = c().min(1).describe("Identifies a cell within its notebook. Stable while the host serves the notebook; whether it survives a reload of the store depends on the format. `setup` is the setup cell."), re = l({
83
83
  pid: o().min(1).describe("The process id."),
84
84
  started_at: w({ offset: !0 }).describe("When the process started.")
@@ -428,11 +428,7 @@ var ie = l({
428
428
  event: h(["ready"]),
429
429
  id: c().min(1).describe("The resume cursor. Omitted on snapshot and reset events."),
430
430
  data: l({})
431
- }).describe("A `ready` event from a host stream."), mt = i(), ht = l({
432
- event: h(["marimo"]),
433
- id: c().min(1).optional(),
434
- data: l({ marimo: mt })
435
- }).describe("A native marimo message carried by a host stream."), gt = g([
431
+ }).describe("A `ready` event from a host stream."), mt = g([
436
432
  ke,
437
433
  je,
438
434
  Ne,
@@ -458,16 +454,15 @@ var ie = l({
458
454
  ut,
459
455
  dt,
460
456
  ft,
461
- pt,
462
- ht
463
- ]).describe("A record, removal, or control message from a host stream.\nThe data is decoded JSON. Snapshot records and reset events omit\nthe cursor; ready and live events carry it. Unknown event names\nbelong to later versions or host extensions.\n"), _t = l({
457
+ pt
458
+ ]).describe("A record, removal, or control message from a host stream.\nThe data is decoded JSON. Snapshot records and reset events omit\nthe cursor; ready and live events carry it. Unknown event names\nbelong to later versions or host extensions.\n"), ht = l({
464
459
  id: c().describe("Identifies this answer."),
465
460
  label: c().describe("Text to show a person.")
466
- }).describe("One possible answer to a decision."), vt = l({
461
+ }).describe("One possible answer to a decision."), gt = l({
467
462
  id: c().describe("Identifies the question when the client answers it."),
468
463
  prompt: c().describe("The question, worded for a person."),
469
- options: a(_t).describe("The possible answers.")
470
- }).describe("A question the host needs answered before it can carry out a\nrequest. The client answers by repeating the request with\n`decisions` in the body, mapping this `id` to the `id` of an\noption.\n"), yt = l({
464
+ options: a(ht).describe("The possible answers.")
465
+ }).describe("A question the host needs answered before it can carry out a\nrequest. The client answers by repeating the request with\n`decisions` in the body, mapping this `id` to the `id` of an\noption.\n"), _t = l({
471
466
  change: o().min(0).describe("The index of the stale change in the request's `changes`, or of the stale cell in a run's `cells`. `0` for a save with a stale `If-Match`."),
472
467
  cell: g([J, m()]).describe("The cell the change named, as it now is. Null when the document does not have it, or when the change named the order."),
473
468
  document: Y
@@ -477,8 +472,8 @@ l({
477
472
  title: c().describe("A short, human-readable name for the kind of problem."),
478
473
  status: o().min(400).max(599).describe("The HTTP status code of the response."),
479
474
  detail: c().optional().describe("A human-readable explanation of what went wrong this time."),
480
- decisions: a(vt).optional().describe("The choices the client has to make before the host can carry out the request. Only present for `decision-required`."),
481
- edit: yt.optional().describe("Which change was stale and what the host holds instead. Only present for a `conflict` answering an edit, a save, or a run of cells.")
475
+ decisions: a(gt).optional().describe("The choices the client has to make before the host can carry out the request. Only present for `decision-required`."),
476
+ edit: _t.optional().describe("Which change was stale and what the host holds instead. Only present for a `conflict` answering an edit, a save, or a run of cells.")
482
477
  }).describe("An error. Every error response has this one shape, following RFC\n9457, and is served as `application/problem+json`. `status`\nrepeats the HTTP status, and `type` says more precisely what went\nwrong. `decisions` appears only when `type` is\n`tag:marimo.io,2026:host/decision-required`. A client ignores\nmembers it does not recognize. An error never contains a token.\n"), l({
483
478
  project_id: P,
484
479
  path: c().optional().describe("Where to put the file, relative to the project root and written the way the host's operating system writes paths."),
@@ -487,56 +482,56 @@ l({
487
482
  path: c().optional().describe("The new location, relative to the project root and written the way the host's operating system writes paths."),
488
483
  name: c().optional().describe("The new label to show people.")
489
484
  }).describe("The fields to change. At least one is present."), l({ url: c().describe("The URL the host used to show the notebook. It never contains the host's token.") }), l({ decisions: s(c(), c()).optional().describe("Answers to the questions in a `decision-required` problem.\nEach key is a decision's `id` and each value is the `id` of\nthe chosen option. A client that already knows its choices can\nsend them the first time.\n") });
490
- var bt = l({
485
+ var vt = l({
491
486
  column: o().nullish().default(null),
492
487
  disabled: p().default(!1),
493
488
  hide_code: p().default(!1),
494
489
  expand_output: p().default(!1)
495
- }).describe("A cell's settings as a client writes them. A field left out takes its default."), xt = l({
490
+ }).describe("A cell's settings as a client writes them. A field left out takes its default."), yt = l({
496
491
  id: B.describe("The cell's id. A client chooses the id of a cell it creates."),
497
492
  code: c().describe("The cell's source code."),
498
493
  name: c().default("_").describe("The cell's name. `_` for an anonymous cell."),
499
- config: bt.optional()
500
- }).describe("A cell as a client writes it. Code must be a string, even when the host withholds source in cell records. Null is not an edit or a request to preserve existing source. The host derives the etags and the analysis."), St = l({
494
+ config: vt.optional()
495
+ }).describe("A cell as a client writes it. Code must be a string, even when the host withholds source in cell records. Null is not an edit or a request to preserve existing source. The host derives the etags and the analysis."), bt = l({
501
496
  kind: h(["put_cell"]),
502
497
  base_etag: c().nullable().describe("The cell's etag as last read, `*` to skip the check, or null to create the cell. Null when the cell exists, or an etag when it does not, is a `conflict`."),
503
- cell: xt,
498
+ cell: yt,
504
499
  after: B.optional().describe("The cell a created cell goes after. Ignored for an existing cell."),
505
500
  before: B.optional().describe("The cell a created cell goes before. Ignored for an existing cell. With neither `after` nor `before`, a created cell goes at the end.")
506
- }).describe("Replaces a whole cell, or creates one."), Ct = l({
501
+ }).describe("Replaces a whole cell, or creates one."), xt = l({
507
502
  kind: h(["delete_cell"]),
508
503
  id: B.describe("The cell to remove."),
509
504
  base_etag: c().describe("The cell's etag as last read, or `*`.")
510
- }).describe("Removes a cell."), wt = l({
505
+ }).describe("Removes a cell."), St = l({
511
506
  kind: h(["set_order"]),
512
507
  base_etag: c().describe("The document's `order_etag` as last read, or `*`."),
513
508
  order: a(B).describe("Every cell id exactly once, in the new order, counting cells this edit creates and leaving out cells it deletes.")
514
- }).describe("Replaces the cell order."), Tt = g([
515
- St,
516
- Ct,
517
- wt
509
+ }).describe("Replaces the cell order."), Ct = g([
510
+ bt,
511
+ xt,
512
+ St
518
513
  ]).describe("One change to the document, tagged on `kind`.");
519
- l({ changes: a(Tt).describe("The changes, applied in order as one unit.") });
520
- var Et = l({
514
+ l({ changes: a(Ct).describe("The changes, applied in order as one unit.") });
515
+ var wt = l({
521
516
  etag: q,
522
517
  code_hash: q,
523
518
  version: o().min(1).describe("The cell's version after the edit.")
524
519
  }).describe("A cell's etags and version after an edit.");
525
520
  l({
526
521
  document: Y,
527
- cells: s(c(), g([Et, m()])).describe("The version of each cell the request created or changed, by id, and null for each cell it deleted.")
522
+ cells: s(c(), g([wt, m()])).describe("The version of each cell the request created or changed, by id, and null for each cell it deleted.")
528
523
  }).describe("The document as an edit or save left it, or at a later revision, and the cells it touched."), l({ decisions: s(c(), c()).optional().describe("Answers to the questions in a `decision-required` problem, as for `runtime.start`.") }).describe("What a save needs from the client, which is nothing until the host asks a question. `{}` is the usual body.");
529
- var Dt = l({
524
+ var Tt = l({
530
525
  id: B,
531
526
  code_hash: q.optional().describe("The cell's `code_hash` as last read. A cell whose code differs is a `conflict`. Absent, the cell runs as it is.")
532
527
  });
533
528
  l({
534
529
  code: c().optional().describe("Python code to run as scratch code."),
535
- cells: a(Dt).min(1).optional().describe("Cells of the document to run, in no particular order. The runtime's execution configuration determines whether dependent cells run too.")
530
+ cells: a(Tt).min(1).optional().describe("Cells of the document to run, in no particular order. The runtime's execution configuration determines whether dependent cells run too.")
536
531
  }).describe("What to run, exactly one of `code` and `cells`.");
537
532
  //#endregion
538
533
  //#region src/core/host/events.ts
539
- var Ot = [
534
+ var Et = [
540
535
  "notebook",
541
536
  "document",
542
537
  "cell",
@@ -547,10 +542,14 @@ l({
547
542
  event: c().min(1),
548
543
  data: i(),
549
544
  id: c().min(1).optional()
550
- }), new Set(gt.options.flatMap((e) => e.shape.event.options)), l({ data: mt });
545
+ }), new Set(mt.options.flatMap((e) => e.shape.event.options)), l({
546
+ event: u("marimo"),
547
+ id: c().min(1).optional(),
548
+ data: l({ marimo: i() })
549
+ }), l({ data: i() });
551
550
  //#endregion
552
551
  //#region ../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/_u64.js
553
- var kt = /* @__PURE__ */ e(((e) => {
552
+ var Dt = /* @__PURE__ */ e(((e) => {
554
553
  Object.defineProperty(e, "__esModule", { value: !0 }), e.toBig = e.shrSL = e.shrSH = e.rotrSL = e.rotrSH = e.rotrBL = e.rotrBH = e.rotr32L = e.rotr32H = e.rotlSL = e.rotlSH = e.rotlBL = e.rotlBH = e.add5L = e.add5H = e.add4L = e.add4H = e.add3L = e.add3H = void 0, e.add = v, e.fromBig = r, e.split = i;
555
554
  var t = /* @__PURE__ */ BigInt(2 ** 32 - 1), n = /* @__PURE__ */ BigInt(32);
556
555
  function r(e, r = !1) {
@@ -638,11 +637,11 @@ var kt = /* @__PURE__ */ e(((e) => {
638
637
  add5H: w,
639
638
  add5L: C
640
639
  };
641
- })), At = /* @__PURE__ */ e(((e) => {
640
+ })), Ot = /* @__PURE__ */ e(((e) => {
642
641
  Object.defineProperty(e, "__esModule", { value: !0 }), e.crypto = void 0, e.crypto = typeof globalThis == "object" && "crypto" in globalThis ? globalThis.crypto : void 0;
643
- })), jt = /* @__PURE__ */ e(((e) => {
642
+ })), kt = /* @__PURE__ */ e(((e) => {
644
643
  Object.defineProperty(e, "__esModule", { value: !0 }), e.wrapXOFConstructorWithOpts = e.wrapConstructorWithOpts = e.wrapConstructor = e.Hash = e.nextTick = e.swap32IfBE = e.byteSwapIfBE = e.swap8IfBE = e.isLE = void 0, e.isBytes = n, e.anumber = r, e.abytes = i, e.ahash = a, e.aexists = o, e.aoutput = s, e.u8 = c, e.u32 = l, e.clean = u, e.createView = d, e.rotr = f, e.rotl = p, e.byteSwap = m, e.byteSwap32 = h, e.bytesToHex = v, e.hexToBytes = x, e.asyncLoop = S, e.utf8ToBytes = C, e.bytesToUtf8 = w, e.toBytes = T, e.kdfInputToBytes = E, e.concatBytes = D, e.checkOpts = O, e.createHasher = k, e.createOptHasher = A, e.createXOFer = j, e.randomBytes = M;
645
- var t = At();
644
+ var t = Ot();
646
645
  function n(e) {
647
646
  return e instanceof Uint8Array || ArrayBuffer.isView(e) && e.constructor.name === "Uint8Array";
648
647
  }
@@ -788,9 +787,9 @@ var kt = /* @__PURE__ */ e(((e) => {
788
787
  if (t.crypto && typeof t.crypto.randomBytes == "function") return Uint8Array.from(t.crypto.randomBytes(e));
789
788
  throw Error("crypto.getRandomValues must be defined");
790
789
  }
791
- })), Mt = /* @__PURE__ */ e(((e) => {
790
+ })), At = /* @__PURE__ */ e(((e) => {
792
791
  Object.defineProperty(e, "__esModule", { value: !0 }), e.shake256 = e.shake128 = e.keccak_512 = e.keccak_384 = e.keccak_256 = e.keccak_224 = e.sha3_512 = e.sha3_384 = e.sha3_256 = e.sha3_224 = e.Keccak = void 0, e.keccakP = _;
793
- var t = kt(), n = jt(), r = BigInt(0), i = BigInt(1), a = BigInt(2), o = BigInt(7), s = BigInt(256), c = BigInt(113), l = [], u = [], d = [];
792
+ var t = Dt(), n = kt(), r = BigInt(0), i = BigInt(1), a = BigInt(2), o = BigInt(7), s = BigInt(256), c = BigInt(113), l = [], u = [], d = [];
794
793
  for (let e = 0, t = i, n = 1, f = 0; e < 24; e++) {
795
794
  [n, f] = [f, (2 * n + 3 * f) % 5], l.push(2 * (5 * f + n)), u.push((e + 1) * (e + 2) / 2 % 64);
796
795
  let p = r;
@@ -883,8 +882,8 @@ var kt = /* @__PURE__ */ e(((e) => {
883
882
  e.sha3_224 = y(6, 144, 28), e.sha3_256 = y(6, 136, 32), e.sha3_384 = y(6, 104, 48), e.sha3_512 = y(6, 72, 64), e.keccak_224 = y(1, 144, 28), e.keccak_256 = y(1, 136, 32), e.keccak_384 = y(1, 104, 48), e.keccak_512 = y(1, 72, 64);
884
883
  var b = (e, t, r) => (0, n.createXOFer)((n = {}) => new v(t, e, n.dkLen === void 0 ? r : n.dkLen, !0));
885
884
  e.shake128 = b(31, 168, 16), e.shake256 = b(31, 136, 32);
886
- })), Nt = /* @__PURE__ */ e(((e, t) => {
887
- var { sha3_512: n } = Mt(), r = 24, i = 32, a = (e = 4, t = Math.random) => {
885
+ })), jt = /* @__PURE__ */ e(((e, t) => {
886
+ var { sha3_512: n } = At(), r = 24, i = 32, a = (e = 4, t = Math.random) => {
888
887
  let n = "";
889
888
  for (; n.length < e;) n += Math.floor(t() * 36).toString(36);
890
889
  return n;
@@ -914,19 +913,19 @@ var kt = /* @__PURE__ */ e(((e) => {
914
913
  defaultLength: r,
915
914
  bigLength: i
916
915
  }), t.exports.init = p, t.exports.createId = m, t.exports.bufToBigInt = o, t.exports.createCounter = d, t.exports.createFingerprint = u, t.exports.isCuid = h;
917
- })), Pt = /* @__PURE__ */ e(((e, t) => {
918
- var { createId: n, init: r, getConstants: i, isCuid: a } = Nt();
916
+ })), Z = /* @__PURE__ */ e(((e, t) => {
917
+ var { createId: n, init: r, getConstants: i, isCuid: a } = jt();
919
918
  t.exports.createId = n, t.exports.init = r, t.exports.getConstants = i, t.exports.isCuid = a;
920
- })), Ft = Pt();
921
- function It(e) {
919
+ })), Mt = Z();
920
+ function Q(e) {
922
921
  let t = new URL(window.location.href);
923
922
  e(t.searchParams), window.history.replaceState({}, "", t.toString());
924
923
  }
925
- var Lt = /^(https?:\/\/\S+)$/;
926
- function Rt(e) {
927
- return typeof e == "string" && Lt.test(e);
924
+ var Nt = /^(https?:\/\/\S+)$/;
925
+ function Pt(e) {
926
+ return typeof e == "string" && Nt.test(e);
928
927
  }
929
- function zt({ href: e, queryParams: t, keys: n }) {
928
+ function Ft({ href: e, queryParams: t, keys: n }) {
930
929
  let r = typeof t == "string" ? new URLSearchParams(t) : t;
931
930
  if (r.size === 0 || e.startsWith("http://") || e.startsWith("https://")) return e;
932
931
  let i = e.startsWith("#"), a = i && e.includes("?");
@@ -947,53 +946,53 @@ function zt({ href: e, queryParams: t, keys: n }) {
947
946
  }
948
947
  //#endregion
949
948
  //#region src/core/kernel/session.ts
950
- var Bt = v(null), Vt = (0, Ft.init)({ length: 6 });
951
- function Z() {
952
- return `s_${Vt()}`;
949
+ var It = v(null), Lt = (0, Mt.init)({ length: 6 });
950
+ function Rt() {
951
+ return `s_${Lt()}`;
953
952
  }
954
- function Ht(e) {
953
+ function zt(e) {
955
954
  return e ? /^s_[\da-z]{6}$/.test(e) : !1;
956
955
  }
957
- var Q = null;
958
- function Ut() {
959
- let e = y.get(M) === "edit", n = new URL(window.location.href).searchParams.get(b.sessionId), r = Ht(n) ? n : null;
960
- return It((t) => {
956
+ var $ = null;
957
+ function Bt() {
958
+ let e = y.get(M) === "edit", n = new URL(window.location.href).searchParams.get(b.sessionId), r = zt(n) ? n : null;
959
+ return Q((t) => {
961
960
  if (!e) {
962
961
  t.delete(b.sessionId), t.delete(b.kiosk);
963
962
  return;
964
963
  }
965
964
  t.has(b.kiosk) || t.delete(b.sessionId);
966
- }), r === null ? (t.debug("Starting a new session", { sessionId: n }), Z()) : e ? (t.debug("Connecting to existing session", { sessionId: r }), r) : (t.debug("Ignoring session_id from URL outside the editor", { sessionId: r }), Z());
965
+ }), r === null ? (t.debug("Starting a new session", { sessionId: n }), Rt()) : e ? (t.debug("Connecting to existing session", { sessionId: r }), r) : (t.debug("Ignoring session_id from URL outside the editor", { sessionId: r }), Rt());
967
966
  }
968
- function Wt() {
969
- return Q === null && (Q = Ut()), Q;
967
+ function Vt() {
968
+ return $ === null && ($ = Bt()), $;
970
969
  }
971
970
  //#endregion
972
971
  //#region src/core/static/static-state.ts
973
- function Gt(e) {
972
+ function Ht(e) {
974
973
  if (typeof e != "object" || !e || Array.isArray(e)) return !1;
975
974
  for (let t of Object.values(e)) if (typeof t != "string") return !1;
976
975
  return !0;
977
976
  }
978
- function Kt(e) {
977
+ function Ut(e) {
979
978
  if (typeof e != "object" || !e || Array.isArray(e)) return !1;
980
979
  let t = e;
981
- return !(!Gt(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
980
+ return !(!Ht(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
982
981
  }
983
- function qt() {
982
+ function Wt() {
984
983
  let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
985
- return Kt(e) ? e : void 0;
984
+ return Ut(e) ? e : void 0;
986
985
  }
987
- function Jt() {
988
- return qt() !== void 0;
986
+ function Gt() {
987
+ return Wt() !== void 0;
989
988
  }
990
- function Yt() {
991
- let e = qt();
989
+ function Kt() {
990
+ let e = Wt();
992
991
  return S(e !== void 0, "Not a static notebook"), e.files;
993
992
  }
994
993
  //#endregion
995
994
  //#region src/core/runtime/runtime.ts
996
- var Xt = new Set(Object.values(b)), Zt = class {
995
+ var qt = new Set(Object.values(b)), Jt = class {
997
996
  initialHealthyCheck = new O();
998
997
  config;
999
998
  lazy;
@@ -1016,12 +1015,12 @@ var Xt = new Set(Object.values(b)), Zt = class {
1016
1015
  return this.httpURL.origin === window.location.origin;
1017
1016
  }
1018
1017
  get isServerless() {
1019
- return D() || x() || Jt();
1018
+ return D() || x() || Gt();
1020
1019
  }
1021
1020
  formatHttpURL({ path: e = "", searchParams: t, restrictToKnownQueryParams: n = !0 }) {
1022
1021
  let r = this.httpURL, i = new URLSearchParams(window.location.search);
1023
1022
  if (t) for (let [e, n] of t.entries()) r.searchParams.set(e, n);
1024
- for (let [e, t] of i.entries()) n && !Xt.has(e) || r.searchParams.set(e, t);
1023
+ for (let [e, t] of i.entries()) n && !qt.has(e) || r.searchParams.set(e, t);
1025
1024
  return r.pathname = `${r.pathname.replace(/\/$/, "")}/${e.replace(/^\//, "")}`, r.hash = "", r;
1026
1025
  }
1027
1026
  appendCrossOriginAuth(e) {
@@ -1040,7 +1039,7 @@ var Xt = new Set(Object.values(b)), Zt = class {
1040
1039
  searchParams: t,
1041
1040
  restrictToKnownQueryParams: !1
1042
1041
  });
1043
- return Qt(this.appendCrossOriginAuth(n).toString());
1042
+ return Yt(this.appendCrossOriginAuth(n).toString());
1044
1043
  }
1045
1044
  getSessionSearchParams(e) {
1046
1045
  let t = new URL(this.config.url), n = new URLSearchParams(t.search);
@@ -1050,7 +1049,7 @@ var Xt = new Set(Object.values(b)), Zt = class {
1050
1049
  }
1051
1050
  getWsURL(e) {
1052
1051
  let t = this.getSessionSearchParams(e), n = this.config.notebookId, r = n ? `/api/marimo/v1/notebooks/${encodeURIComponent(n)}/events/ws` : "/ws", i = this.formatWsURL(r, t);
1053
- return n && i.searchParams.set("types", Ot.join(",")), i;
1052
+ return n && i.searchParams.set("types", Et.join(",")), i;
1054
1053
  }
1055
1054
  getSseURL(e) {
1056
1055
  let t = this.formatHttpURL({
@@ -1127,17 +1126,17 @@ var Xt = new Set(Object.values(b)), Zt = class {
1127
1126
  }
1128
1127
  headers() {
1129
1128
  let e = {
1130
- "Marimo-Session-Id": Wt(),
1129
+ "Marimo-Session-Id": Vt(),
1131
1130
  "Marimo-Server-Token": this.config.serverToken ?? "",
1132
1131
  "x-runtime-url": this.httpURL.toString()
1133
1132
  };
1134
1133
  return this.config.authToken && (e.Authorization = `Bearer ${this.config.authToken}`), e;
1135
1134
  }
1136
1135
  sessionHeaders() {
1137
- return { "Marimo-Session-Id": Wt() };
1136
+ return { "Marimo-Session-Id": Vt() };
1138
1137
  }
1139
1138
  };
1140
- function Qt(e) {
1139
+ function Yt(e) {
1141
1140
  if (!e.startsWith("http")) {
1142
1141
  t.warn(`URL must start with http: ${e}`);
1143
1142
  let n = new URL(e);
@@ -1147,39 +1146,39 @@ function Qt(e) {
1147
1146
  }
1148
1147
  //#endregion
1149
1148
  //#region src/core/runtime/config.ts
1150
- function $t() {
1149
+ function Xt() {
1151
1150
  let e = new URL(document.baseURI);
1152
1151
  return e.search = "", e.hash = "", e.toString();
1153
1152
  }
1154
- var en = {
1153
+ var Zt = {
1155
1154
  lazy: !0,
1156
- url: $t()
1157
- }, tn = v(en), nn = v((e) => {
1158
- let t = e(tn);
1159
- return new Zt(t, t.lazy);
1155
+ url: Xt()
1156
+ }, Qt = v(Zt), $t = v((e) => {
1157
+ let t = e(Qt);
1158
+ return new Jt(t, t.lazy);
1160
1159
  });
1161
- function rn() {
1162
- return y.get(nn);
1160
+ function en() {
1161
+ return y.get($t);
1163
1162
  }
1164
- function an(e) {
1163
+ function tn(e) {
1165
1164
  if (e.startsWith("http")) return new URL(e);
1166
- let t = rn().httpURL.toString();
1165
+ let t = en().httpURL.toString();
1167
1166
  return t.startsWith("blob:") && (t = t.replace("blob:", "")), new URL(e, t);
1168
1167
  }
1169
1168
  //#endregion
1170
1169
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constants.js
1171
- var on = 365.2425, sn = 6048e5, cn = 864e5, ln = 86400;
1172
- ln * 7, ln * on / 12 * 3;
1173
- var un = Symbol.for("constructDateFrom");
1170
+ var nn = 365.2425, rn = 6048e5, an = 864e5, on = 86400;
1171
+ on * 7, on * nn / 12 * 3;
1172
+ var sn = Symbol.for("constructDateFrom");
1174
1173
  //#endregion
1175
1174
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constructFrom.js
1176
- function $(e, t) {
1177
- return typeof e == "function" ? e(t) : e && typeof e == "object" && un in e ? e[un](t) : e instanceof Date ? new e.constructor(t) : new Date(t);
1175
+ function cn(e, t) {
1176
+ return typeof e == "function" ? e(t) : e && typeof e == "object" && sn in e ? e[sn](t) : e instanceof Date ? new e.constructor(t) : new Date(t);
1178
1177
  }
1179
1178
  //#endregion
1180
1179
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/toDate.js
1181
- function dn(e, t) {
1182
- return $(t || e, e);
1180
+ function ln(e, t) {
1181
+ return cn(t || e, e);
1183
1182
  }
1184
1183
  //#endregion
1185
- export { C, E as S, N as _, an as a, O as b, Jt as c, Rt as d, It as f, ee as g, M as h, sn as i, Bt as l, A as m, $ as n, rn as o, Pt as p, cn as r, Yt as s, dn as t, zt as u, te as v, D as x, j as y };
1184
+ export { C, E as S, N as _, tn as a, O as b, Gt as c, Pt as d, Q as f, ee as g, M as h, rn as i, It as l, A as m, cn as n, en as o, Z as p, an as r, Kt as s, ln as t, Ft as u, te as v, D as x, j as y };
@@ -3,7 +3,7 @@ import { g as t, h as n, m as r, o as i } from "./button-BxB3RDjN.js";
3
3
  import { t as a } from "./react-sHtZdjeP.js";
4
4
  import { t as o } from "./compiler-runtime-CldRdSsv.js";
5
5
  import { t as s } from "./tooltip-BCntm-jf.js";
6
- import { C as c, a as l } from "./toDate-CSY-j1Fi.js";
6
+ import { C as c, a as l } from "./toDate-C0jaysq2.js";
7
7
  import { t as u } from "./jsx-runtime-3BD1kT0s.js";
8
8
  import { n as d } from "./error-banner-DMIrHA-R.js";
9
9
  import { t as f } from "./debounce-C3jyATpc.js";
@@ -11,7 +11,7 @@ import { A as p, n as ee } from "./useTheme-BC8Lof0B.js";
11
11
  import { c as m, t as h } from "./arrays-R6JsImiT.js";
12
12
  import { t as te } from "./objects-DCmMvZtn.js";
13
13
  import { t as ne } from "./useAsyncData-BbuzBAUp.js";
14
- import { a as g, i as re, n as ie, t as ae } from "./formats-DIVMVjeV.js";
14
+ import { a as g, i as re, n as ie, t as ae } from "./formats-C24TvExI.js";
15
15
  import { D as oe, n as _ } from "./vega-loader.browser-B9Pz0EGP.js";
16
16
  import { t as se } from "./react-vega-C4T9Rb_w.js";
17
17
  import { a as ce, n as le } from "./loader-Bm8cy3e8.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev40",
3
+ "version": "0.25.3-dev44",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -57,6 +57,7 @@
57
57
  "@marimo-team/codemirror-mcp": "^0.1.7",
58
58
  "@marimo-team/codemirror-sql": "^0.3.0",
59
59
  "@marimo-team/llm-info": "workspace:*",
60
+ "@marimo-team/client": "workspace:*",
60
61
  "@marimo-team/marimo-api": "workspace:*",
61
62
  "@marimo-team/react-slotz": "^0.2.0",
62
63
  "@marimo-team/smart-cells": "workspace:*",
@@ -185,8 +186,6 @@
185
186
  "storybook": "storybook dev -p 6006",
186
187
  "build-storybook": "storybook build",
187
188
  "sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts",
188
- "codegen": "node --experimental-strip-types scripts/generate-host-protocol.ts",
189
- "codegen:check": "node --experimental-strip-types scripts/generate-host-protocol.ts --check",
190
189
  "doctor": "npx react-doctor@latest"
191
190
  },
192
191
  "peerDependencies": {
@@ -216,7 +215,6 @@
216
215
  "jsdom": "^24.1.3",
217
216
  "msw": "^2.15.0",
218
217
  "npm-run-all2": "^6.2.6",
219
- "orval": "8.40.0",
220
218
  "oxc-transform-react": "0.145.0",
221
219
  "oxfmt": "^0.68.0",
222
220
  "oxlint": "^1.83.0",
@@ -19,6 +19,7 @@ it("enforces host dependencies for runtime and type imports", () => {
19
19
  "src/core/host/allowed.ts": `
20
20
  import { atom } from "jotai/vanilla";
21
21
  import { z } from "zod";
22
+ import * as Protocol from "@marimo-team/client/protocol";
22
23
  import { Logger } from "@/utils/Logger";
23
24
  import type { Document } from "./document";
24
25
  export * from "@/core/host/events";
@@ -914,6 +914,94 @@ describe("ExportActions dialog", () => {
914
914
  expect(within(dialog).queryByRole("group")).not.toBeInTheDocument();
915
915
  });
916
916
 
917
+ it("describes format options with their description and current settings", async () => {
918
+ renderExportActions({
919
+ getExportMetadata: vi.fn().mockResolvedValue(geometryMetadata),
920
+ });
921
+ await openDialog();
922
+ await screen.findByRole("button", { name: "GeoParquet options" });
923
+
924
+ for (const [label, description] of [
925
+ ["CSV", "Comma-separated values Comma · UTF-8"],
926
+ ["TSV", "Best for Excel and Google Sheets UTF-8"],
927
+ ["JSON", "Raw JSON data Escapes non-ASCII"],
928
+ ["GeoParquet", "Parquet with geometry and CRS metadata location"],
929
+ ["GeoJSON", "Geometry in longitude and latitude location"],
930
+ ]) {
931
+ expect(
932
+ screen.getByRole("button", { name: `${label} options` }),
933
+ ).toHaveAccessibleDescription(description);
934
+ }
935
+
936
+ const csvOptions = screen.getByRole("button", { name: "CSV options" });
937
+ fireEvent.click(csvOptions);
938
+ fireEvent.change(screen.getByRole("combobox", { name: "Delimiter" }), {
939
+ target: { value: ";" },
940
+ });
941
+ expect(csvOptions).toHaveAccessibleDescription(
942
+ "Comma-separated values Semicolon · UTF-8",
943
+ );
944
+ fireEvent.click(csvOptions);
945
+ expect(csvOptions).toHaveAccessibleDescription(
946
+ "Comma-separated values Semicolon · UTF-8",
947
+ );
948
+ });
949
+
950
+ it.each([
951
+ ["CSV", "Comma-separated values"],
952
+ ["TSV", "Best for Excel and Google Sheets"],
953
+ ["JSON", "Raw JSON data"],
954
+ ["GeoParquet", "Parquet with geometry and CRS metadata"],
955
+ ["GeoJSON", "Geometry in longitude and latitude"],
956
+ ])(
957
+ "toggles %s options from the row label and description",
958
+ async (label, description) => {
959
+ renderExportActions({
960
+ getExportMetadata: vi.fn().mockResolvedValue(geometryMetadata),
961
+ });
962
+ await openDialog();
963
+ const toggle = await screen.findByRole("button", {
964
+ name: `${label} options`,
965
+ });
966
+
967
+ fireEvent.click(screen.getByText(label));
968
+ expect(toggle).toHaveAttribute("aria-expanded", "true");
969
+ expect(
970
+ screen.getByRole("group", { name: `${label} options` }),
971
+ ).toBeInTheDocument();
972
+
973
+ fireEvent.click(screen.getByText(description));
974
+ expect(toggle).toHaveAttribute("aria-expanded", "false");
975
+ expect(
976
+ screen.queryByRole("group", { name: `${label} options` }),
977
+ ).not.toBeInTheDocument();
978
+ },
979
+ );
980
+
981
+ it("keeps download and copy independent of row expansion", async () => {
982
+ vi.stubGlobal(
983
+ "fetch",
984
+ vi.fn().mockResolvedValue({
985
+ ok: true,
986
+ text: vi.fn().mockResolvedValue("name,value\n"),
987
+ }),
988
+ );
989
+ renderExportActions();
990
+ await openDialog();
991
+ const toggle = screen.getByRole("button", { name: "CSV options" });
992
+
993
+ fireEvent.click(screen.getByRole("button", { name: "Download CSV" }));
994
+ await waitFor(() => expect(downloadByURL).toHaveBeenCalled());
995
+ expect(toggle).toHaveAttribute("aria-expanded", "false");
996
+
997
+ fireEvent.click(screen.getByText("CSV"));
998
+ fireEvent.click(screen.getByRole("button", { name: "Copy CSV" }));
999
+ expect(toggle).toHaveAttribute("aria-expanded", "true");
1000
+ await waitFor(() => {
1001
+ expect(copyToClipboard).toHaveBeenCalledWith("name,value\n");
1002
+ });
1003
+ });
1004
+
917
1005
  it("sends only changed CSV options with a download", async () => {
918
1006
  renderExportActions();
919
1007
  await openDialog();