@marimo-team/islands 0.25.3-dev141 → 0.25.3-dev15

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 (125) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CNSxdKyJ.js → ConnectedDataExplorerComponent-CNMliVzw.js} +1 -1
  2. package/dist/{ErrorBoundary-Cg59O3xL.js → ErrorBoundary-z1rqMOCq.js} +1 -1
  3. package/dist/{abnfDiagram-VCTEODGH-DQDjNXt3.js → abnfDiagram-VCTEODGH-D-Ez91gV.js} +2 -2
  4. package/dist/{any-language-editor-B9REGlD9.js → any-language-editor-DZ_YTVus.js} +1 -1
  5. package/dist/{architectureDiagram-5GKGNRK7-Nmls7Wxn.js → architectureDiagram-5GKGNRK7-CTpcNtO8.js} +1 -1
  6. package/dist/{chat-ui-BDpymeoe.js → chat-ui-DaHynk8g.js} +436 -437
  7. package/dist/{chunk-IMKFNOWR-CoIFEo-1.js → chunk-IMKFNOWR-DGxi-zeo.js} +1 -1
  8. package/dist/{chunk-SHT3W25Y-lHiGx3ZC.js → chunk-SHT3W25Y-CV9J3rAB.js} +1 -1
  9. package/dist/{chunk-SVP7TREG-BvsHIrY_.js → chunk-SVP7TREG-BL-9Fqgg.js} +1 -1
  10. package/dist/{chunk-TICWLB2K-BC8YIm_n.js → chunk-TICWLB2K-Cu_XMjDM.js} +1 -1
  11. package/dist/{classDiagram-ZZMXUADV-Bt98lkkv.js → classDiagram-ZZMXUADV-BXXV13Hq.js} +2 -2
  12. package/dist/{classDiagram-v2-VYDZK3BY-D9bfbcC3.js → classDiagram-v2-VYDZK3BY-B7FXJ1Cp.js} +2 -2
  13. package/dist/{code-visibility-Da3iitn_.js → code-visibility-BFMjPeTv.js} +14 -14
  14. package/dist/{common-C6FHcu5p.js → common-JHV-U5GC.js} +6704 -6409
  15. package/dist/{cynefinDiagram-5FMLGOSQ-CgWra7wt.js → cynefinDiagram-5FMLGOSQ-CH96rwba.js} +1 -1
  16. package/dist/{dagre-GXQ25YYZ-CFZ8-35c.js → dagre-GXQ25YYZ-BD3PmpFY.js} +1 -1
  17. package/dist/{data-grid-overlay-editor-mJt3Pg4S.js → data-grid-overlay-editor-BkL0DXBi.js} +1 -1
  18. package/dist/{diagram-S7CK7UJ4-lCNQrW7d.js → diagram-S7CK7UJ4-BsSJJldB.js} +1 -1
  19. package/dist/{diagram-UQ7AKVKN-CQPQ6pP_.js → diagram-UQ7AKVKN-muQtNZc4.js} +1 -1
  20. package/dist/{diagram-VX7I27RA-Cf3b0llz.js → diagram-VX7I27RA-CdhuZAqR.js} +1 -1
  21. package/dist/{diagram-Z3DM3KII-Bt4QLrpn.js → diagram-Z3DM3KII-BD8mXjOj.js} +1 -1
  22. package/dist/{ebnfDiagram-PWID7BFC-D3NAyPFY.js → ebnfDiagram-PWID7BFC-BIN1sweE.js} +2 -2
  23. package/dist/{erDiagram-RLTQ6QDP-Tlu09_Nm.js → erDiagram-RLTQ6QDP-Ctp5cfoN.js} +1 -1
  24. package/dist/{error-banner-Da600cwz.js → error-banner-D-WCIiMt.js} +10 -5
  25. package/dist/{cells-C8iCYvLU.js → error-entries-Bv6bZPF3.js} +2262 -2206
  26. package/dist/{feedback-button-DaPwHIdM.js → feedback-button-do3RdfYX.js} +115 -116
  27. package/dist/{flowDiagram-HODETNUW-CAYbpJmV.js → flowDiagram-HODETNUW-3EfLrlFb.js} +2 -2
  28. package/dist/{formats-BGh2thRc.js → formats-27CW_UP4.js} +1 -1
  29. package/dist/{glide-data-editor-Ctz2mH6k.js → glide-data-editor-B2KXsLT5.js} +3 -3
  30. package/dist/{globals-EpFoRj_E.js → globals-Cnjg2Own.js} +1 -1
  31. package/dist/{html-to-image-CZY1pIZH.js → html-to-image-Bf8QMGi4.js} +23 -23
  32. package/dist/{infoDiagram-27XIBGKW-XrDxhr0x.js → infoDiagram-27XIBGKW-DipQoHxl.js} +1 -1
  33. package/dist/{ishikawaDiagram-5VMMS53U-CD1muzov.js → ishikawaDiagram-5VMMS53U-DgFMjSGz.js} +1 -1
  34. package/dist/{kanban-definition-UXKFOSKX-Dg9W142_.js → kanban-definition-UXKFOSKX-w1ACVjgl.js} +1 -1
  35. package/dist/main.js +164 -163
  36. package/dist/{mermaid-CiAXjLpA.js → mermaid-CHo49Yv-.js} +33 -33
  37. package/dist/{mindmap-definition-YA3MSWOX-DgCidgYJ.js → mindmap-definition-YA3MSWOX-CrT0KSfX.js} +1 -1
  38. package/dist/{number-overlay-editor-CtxrummL.js → number-overlay-editor-DBsAEYkJ.js} +1 -1
  39. package/dist/{pegDiagram-XKGWAZYB-coOYYKB6.js → pegDiagram-XKGWAZYB-BqvywNJA.js} +2 -2
  40. package/dist/{pieDiagram-E7YTZNPT-BnXTc3bj.js → pieDiagram-E7YTZNPT-BfxJ_XCc.js} +1 -1
  41. package/dist/{process-output-e4jj9Ijt.js → process-output-BZg56CCb.js} +3 -3
  42. package/dist/{railroadDiagram-O6MQD6OU-B28-u83n.js → railroadDiagram-O6MQD6OU-8vFLVTPu.js} +2 -2
  43. package/dist/{requirementDiagram-BXWQKSXE-CdYCTMu0.js → requirementDiagram-BXWQKSXE-a_MxGvxe.js} +1 -1
  44. package/dist/{reveal-component-DrIXvR_7.js → reveal-component-IkMCCFzA.js} +4 -4
  45. package/dist/{sequenceDiagram-WJ2MYXX4-CM3aRAe_.js → sequenceDiagram-WJ2MYXX4-CXFMnxGh.js} +1 -1
  46. package/dist/{stateDiagram-D77RDMKH-DOZUMVj8.js → stateDiagram-D77RDMKH-DQeA_CwI.js} +2 -2
  47. package/dist/{stateDiagram-v2-MP3YSRHH-CISYxma6.js → stateDiagram-v2-MP3YSRHH-BxxQucm1.js} +2 -2
  48. package/dist/style.css +1 -1
  49. package/dist/{swimlanes-42K2YHIH-BkSppxp8.js → swimlanes-42K2YHIH-Do6L-cYg.js} +1 -1
  50. package/dist/{swimlanesDiagram-VR7AAH4N-c8G5pGxC.js → swimlanesDiagram-VR7AAH4N-DUzPvSVU.js} +2 -2
  51. package/dist/{timeline-definition-24CTP7MA-CaMQayqK.js → timeline-definition-24CTP7MA-D3c46WM5.js} +1 -1
  52. package/dist/{toDate-BNJf01u1.js → toDate-UtiwmnH2.js} +41 -39
  53. package/dist/{vega-component-DG29TAB7.js → vega-component-BeF9dfyO.js} +3 -3
  54. package/dist/{vennDiagram-4TSXK5OY-CF8pfaK3.js → vennDiagram-4TSXK5OY-BSZD8JcZ.js} +1 -1
  55. package/dist/{wardleyDiagram-VM6X3IG4-dGPu39d-.js → wardleyDiagram-VM6X3IG4-48cUWkfA.js} +1 -1
  56. package/dist/{xychartDiagram-S5SC5T6Z-CP6-9q56.js → xychartDiagram-S5SC5T6Z-CswYgYeu.js} +1 -1
  57. package/package.json +5 -2
  58. package/src/__tests__/fixtures/{pair-preview.ts → pair-config.ts} +3 -2
  59. package/src/__tests__/host-imports.test.ts +100 -0
  60. package/src/__tests__/mount.test.ts +28 -8
  61. package/src/components/data-table/__tests__/context-menu.test.ts +176 -0
  62. package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +24 -1
  63. package/src/components/data-table/__tests__/export-actions.test.tsx +329 -6
  64. package/src/components/data-table/context-menu.tsx +125 -26
  65. package/src/components/data-table/date-filter-inputs.tsx +15 -42
  66. package/src/components/data-table/export-actions.tsx +192 -116
  67. package/src/components/data-table/schemas.ts +14 -36
  68. package/src/components/data-table/utils.ts +18 -0
  69. package/src/components/editor/Output.tsx +9 -2
  70. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +80 -252
  71. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +186 -34
  72. package/src/components/editor/actions/pair-with-agent-commands.ts +42 -51
  73. package/src/components/editor/actions/pair-with-agent-modal.tsx +96 -36
  74. package/src/components/editor/chrome/panels/error-panel.tsx +1 -0
  75. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +372 -0
  76. package/src/components/editor/chrome/wrapper/footer-item.tsx +32 -24
  77. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +237 -0
  78. package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
  79. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +548 -0
  80. package/src/components/editor/errors/send-error-report-button.tsx +69 -0
  81. package/src/components/editor/output/MarimoErrorOutput.tsx +21 -5
  82. package/src/components/editor/output/MarimoTracebackOutput.tsx +35 -20
  83. package/src/components/editor/output/__tests__/ansi-reduce.test.ts +18 -0
  84. package/src/components/editor/output/ansi-reduce.ts +6 -0
  85. package/src/core/attachments/__tests__/toast.test.tsx +58 -0
  86. package/src/core/attachments/state.ts +21 -0
  87. package/src/core/attachments/toast.ts +15 -0
  88. package/src/core/cells/__tests__/cells.test.ts +52 -0
  89. package/src/core/cells/__tests__/error-report.test.ts +139 -0
  90. package/src/core/cells/__tests__/session.test.ts +50 -1
  91. package/src/core/cells/error-report.ts +63 -0
  92. package/src/core/cells/session.ts +28 -1
  93. package/src/core/config/pair.ts +5 -3
  94. package/src/core/edit-app.tsx +2 -2
  95. package/src/core/host/AGENTS.md +6 -0
  96. package/src/core/host/__tests__/events.test.ts +46 -0
  97. package/src/core/host/__tests__/notebook-client.test.ts +191 -0
  98. package/src/core/host/__tests__/protocol.test.ts +214 -0
  99. package/src/core/host/connection.ts +81 -0
  100. package/src/core/host/events.ts +60 -0
  101. package/src/core/host/notebook-client.ts +226 -0
  102. package/src/core/host/protocol.ts +1943 -0
  103. package/src/core/islands/__tests__/bootstrap.test.ts +26 -0
  104. package/src/core/islands/bootstrap.ts +1 -0
  105. package/src/core/run-app.tsx +2 -2
  106. package/src/core/runtime/__tests__/runtime.test.ts +55 -11
  107. package/src/core/runtime/runtime.ts +14 -1
  108. package/src/core/runtime/types.ts +2 -0
  109. package/src/core/websocket/__tests__/{useMarimoKernelConnection.test.ts → connection-state.test.ts} +15 -17
  110. package/src/core/websocket/__tests__/{useWebSocket.test.ts → createConnectionTransport.test.ts} +1 -1
  111. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +140 -0
  112. package/src/core/websocket/__tests__/{useMarimoKernelConnection.hook.test.tsx → useNotebookSession.hook.test.tsx} +352 -65
  113. package/src/core/websocket/connection-state.ts +70 -0
  114. package/src/core/websocket/transports/__tests__/sse.test.ts +1 -4
  115. package/src/core/websocket/transports/create.ts +31 -0
  116. package/src/core/websocket/transports/transport.ts +12 -23
  117. package/src/core/websocket/types.ts +9 -39
  118. package/src/core/websocket/useNotebookClient.ts +80 -0
  119. package/src/core/websocket/{useMarimoKernelConnection.tsx → useNotebookSession.tsx} +67 -225
  120. package/src/mount.tsx +7 -3
  121. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +84 -0
  122. package/src/utils/__tests__/dates.test.ts +116 -0
  123. package/src/utils/dates.ts +94 -0
  124. package/dist/error-entries-CzoYkIQZ.js +0 -56
  125. package/src/core/websocket/useWebSocket.tsx +0 -88
@@ -9,7 +9,7 @@ import "./chunk-4HAMMTFA-D4eFPyFh.js";
9
9
  import "./chunk-GVQU2GXP-Cwbt-lF0.js";
10
10
  import "./chunk-L3NEJ4N5-n-zgIVSy.js";
11
11
  import { o as n } from "./chunk-OSK3NFVY-DXa-Cxbn.js";
12
- import { c as r } from "./mermaid-CiAXjLpA.js";
12
+ import { c as r } from "./mermaid-CHo49Yv-.js";
13
13
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanes-42K2YHIH.mjs
14
14
  var i = 5, a = 1e-5, o = 1e-6;
15
15
  function s(e) {
@@ -9,11 +9,11 @@ import "./chunk-4HAMMTFA-D4eFPyFh.js";
9
9
  import "./chunk-GVQU2GXP-Cwbt-lF0.js";
10
10
  import "./chunk-L3NEJ4N5-n-zgIVSy.js";
11
11
  import "./chunk-OSK3NFVY-DXa-Cxbn.js";
12
- import "./mermaid-CiAXjLpA.js";
12
+ import "./mermaid-CHo49Yv-.js";
13
13
  import "./chunk-F27PBJKO-ufseIn5y.js";
14
14
  import "./chunk-XXDRQBXY-Dnl5VBqG.js";
15
15
  import "./chunk-POPQ4Y6H-hYOXbYH_.js";
16
- import { r as t, t as n } from "./chunk-SHT3W25Y-lHiGx3ZC.js";
16
+ import { r as t, t as n } from "./chunk-SHT3W25Y-CV9J3rAB.js";
17
17
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/swimlanesDiagram-VR7AAH4N.mjs
18
18
  var r = n({
19
19
  defaultLayout: "swimlane",
@@ -3,7 +3,7 @@ import { p as t } from "./chunk-75Z2AOVW-D7gxIs2Q.js";
3
3
  import { n, t as r } from "./src-CA_m4ONl.js";
4
4
  import { n as i, t as a } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
5
5
  import { $ as o, J as s, a as c, b as l, et as u, nt as d, o as f, x as p } from "./chunk-DU6HZSFF-BwiyaNpg.js";
6
- import { p as m } from "./mermaid-CiAXjLpA.js";
6
+ import { p as m } from "./mermaid-CHo49Yv-.js";
7
7
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/timeline-definition-24CTP7MA.mjs
8
8
  var h = (function() {
9
9
  var e = /* @__PURE__ */ i(function(e, t, n, r) {
@@ -465,54 +465,55 @@ function M({ href: e, queryParams: t, keys: n }) {
465
465
  let m = f.toString();
466
466
  return m ? `${o}?${m}${s}` : e;
467
467
  }
468
- a(null);
469
- var N = (0, O.init)({ length: 6 });
470
- function P() {
471
- return `s_${N()}`;
468
+ //#endregion
469
+ //#region src/core/kernel/session.ts
470
+ var N = a(null), P = (0, O.init)({ length: 6 });
471
+ function F() {
472
+ return `s_${P()}`;
472
473
  }
473
- function F(e) {
474
+ function I(e) {
474
475
  return e ? /^s_[\da-z]{6}$/.test(e) : !1;
475
476
  }
476
- var I = null;
477
- function L() {
478
- let e = o.get(v) === "edit", n = new URL(window.location.href).searchParams.get(s.sessionId), r = F(n) ? n : null;
477
+ var L = null;
478
+ function R() {
479
+ let e = o.get(v) === "edit", n = new URL(window.location.href).searchParams.get(s.sessionId), r = I(n) ? n : null;
479
480
  return k((t) => {
480
481
  if (!e) {
481
482
  t.delete(s.sessionId), t.delete(s.kiosk);
482
483
  return;
483
484
  }
484
485
  t.has(s.kiosk) || t.delete(s.sessionId);
485
- }), r === null ? (t.debug("Starting a new session", { sessionId: n }), P()) : e ? (t.debug("Connecting to existing session", { sessionId: r }), r) : (t.debug("Ignoring session_id from URL outside the editor", { sessionId: r }), P());
486
+ }), r === null ? (t.debug("Starting a new session", { sessionId: n }), F()) : e ? (t.debug("Connecting to existing session", { sessionId: r }), r) : (t.debug("Ignoring session_id from URL outside the editor", { sessionId: r }), F());
486
487
  }
487
- function R() {
488
- return I === null && (I = L()), I;
488
+ function z() {
489
+ return L === null && (L = R()), L;
489
490
  }
490
491
  //#endregion
491
492
  //#region src/core/static/static-state.ts
492
- function z(e) {
493
+ function B(e) {
493
494
  if (typeof e != "object" || !e || Array.isArray(e)) return !1;
494
495
  for (let t of Object.values(e)) if (typeof t != "string") return !1;
495
496
  return !0;
496
497
  }
497
- function B(e) {
498
+ function V(e) {
498
499
  if (typeof e != "object" || !e || Array.isArray(e)) return !1;
499
500
  let t = e;
500
- return !(!z(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
501
- }
502
- function V() {
503
- let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
504
- return B(e) ? e : void 0;
501
+ return !(!B(t.files) || t.modelNotifications !== void 0 && !Array.isArray(t.modelNotifications));
505
502
  }
506
503
  function H() {
507
- return V() !== void 0;
504
+ let e = typeof window > "u" ? void 0 : window.__MARIMO_STATIC__;
505
+ return V(e) ? e : void 0;
508
506
  }
509
507
  function U() {
510
- let e = V();
508
+ return H() !== void 0;
509
+ }
510
+ function W() {
511
+ let e = H();
511
512
  return l(e !== void 0, "Not a static notebook"), e.files;
512
513
  }
513
514
  //#endregion
514
515
  //#region src/core/runtime/runtime.ts
515
- var W = class {
516
+ var G = ["marimo"], K = class {
516
517
  initialHealthyCheck = new m();
517
518
  config;
518
519
  lazy;
@@ -535,7 +536,7 @@ var W = class {
535
536
  return this.httpURL.origin === window.location.origin;
536
537
  }
537
538
  get isServerless() {
538
- return p() || c() || H();
539
+ return p() || c() || U();
539
540
  }
540
541
  formatHttpURL({ path: e = "", searchParams: t, restrictToKnownQueryParams: n = !0 }) {
541
542
  let r = this.httpURL, i = new URLSearchParams(window.location.search);
@@ -559,7 +560,7 @@ var W = class {
559
560
  searchParams: t,
560
561
  restrictToKnownQueryParams: !1
561
562
  });
562
- return G(this.appendCrossOriginAuth(n).toString());
563
+ return q(this.appendCrossOriginAuth(n).toString());
563
564
  }
564
565
  getSessionSearchParams(e) {
565
566
  let t = new URL(this.config.url), n = new URLSearchParams(t.search);
@@ -568,7 +569,8 @@ var W = class {
568
569
  }), n.set(s.sessionId, e), n;
569
570
  }
570
571
  getWsURL(e) {
571
- return this.formatWsURL("/ws", this.getSessionSearchParams(e));
572
+ 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);
573
+ return n && i.searchParams.set("types", G.join(",")), i;
572
574
  }
573
575
  getSseURL(e) {
574
576
  let t = this.formatHttpURL({
@@ -645,17 +647,17 @@ var W = class {
645
647
  }
646
648
  headers() {
647
649
  let e = {
648
- "Marimo-Session-Id": R(),
650
+ "Marimo-Session-Id": z(),
649
651
  "Marimo-Server-Token": this.config.serverToken ?? "",
650
652
  "x-runtime-url": this.httpURL.toString()
651
653
  };
652
654
  return this.config.authToken && (e.Authorization = `Bearer ${this.config.authToken}`), e;
653
655
  }
654
656
  sessionHeaders() {
655
- return { "Marimo-Session-Id": R() };
657
+ return { "Marimo-Session-Id": z() };
656
658
  }
657
659
  };
658
- function G(e) {
660
+ function q(e) {
659
661
  if (!e.startsWith("http")) {
660
662
  t.warn(`URL must start with http: ${e}`);
661
663
  let n = new URL(e);
@@ -665,29 +667,29 @@ function G(e) {
665
667
  }
666
668
  //#endregion
667
669
  //#region src/core/runtime/config.ts
668
- function K() {
670
+ function J() {
669
671
  let e = new URL(document.baseURI);
670
672
  return e.search = "", e.hash = "", e.toString();
671
673
  }
672
- var q = {
674
+ var Y = {
673
675
  lazy: !0,
674
- url: K()
675
- }, J = a(q), Y = a((e) => {
676
- let t = e(J);
677
- return new W(t, t.lazy);
676
+ url: J()
677
+ }, ee = a(Y), te = a((e) => {
678
+ let t = e(ee);
679
+ return new K(t, t.lazy);
678
680
  });
679
681
  function X() {
680
- return o.get(Y);
682
+ return o.get(te);
681
683
  }
682
- function ee(e) {
684
+ function ne(e) {
683
685
  if (e.startsWith("http")) return new URL(e);
684
686
  let t = X().httpURL.toString();
685
687
  return t.startsWith("blob:") && (t = t.replace("blob:", "")), new URL(e, t);
686
688
  }
687
689
  //#endregion
688
690
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constants.js
689
- var te = 365.2425, ne = 6048e5, re = 864e5, Z = 86400;
690
- Z * 7, Z * te / 12 * 3;
691
+ var re = 365.2425, ie = 6048e5, ae = 864e5, Z = 86400;
692
+ Z * 7, Z * re / 12 * 3;
691
693
  var Q = Symbol.for("constructDateFrom");
692
694
  //#endregion
693
695
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/constructFrom.js
@@ -696,8 +698,8 @@ function $(e, t) {
696
698
  }
697
699
  //#endregion
698
700
  //#region ../node_modules/.pnpm/date-fns@4.4.0/node_modules/date-fns/toDate.js
699
- function ie(e, t) {
701
+ function oe(e, t) {
700
702
  return $(t || e, e);
701
703
  }
702
704
  //#endregion
703
- export { u as S, x as _, ee as a, p as b, H as c, k as d, D as f, b as g, y as h, ne as i, M as l, v as m, $ as n, X as o, g as p, re as r, U as s, ie as t, j as u, _ as v, f as x, m as y };
705
+ export { u as C, f as S, b as _, ne as a, m as b, U as c, j as d, k as f, y as g, v as h, ie as i, N as l, g as m, $ as n, X as o, D as p, ae as r, W as s, oe as t, M as u, x as v, p as x, _ as y };
@@ -3,15 +3,15 @@ import { g as t, h as n, m as r, o as i } from "./button-CvjkwdSk.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-BO1REbqs.js";
6
- import { S as c, a as l } from "./toDate-BNJf01u1.js";
6
+ import { C as c, a as l } from "./toDate-UtiwmnH2.js";
7
7
  import { t as u } from "./jsx-runtime-3BD1kT0s.js";
8
- import { n as d } from "./error-banner-Da600cwz.js";
8
+ import { n as d } from "./error-banner-D-WCIiMt.js";
9
9
  import { t as f } from "./debounce-C3jyATpc.js";
10
10
  import { A as p, n as ee } from "./useTheme-CRnjkku0.js";
11
11
  import { c as m } from "./arrays-CN1djC4k.js";
12
12
  import { t as te } from "./objects-CzUgoMIF.js";
13
13
  import { t as h } from "./useAsyncData-Deh5kszT.js";
14
- import { a as ne, i as re, n as ie, t as g } from "./formats-BGh2thRc.js";
14
+ import { a as ne, i as re, n as ie, t as g } from "./formats-27CW_UP4.js";
15
15
  import { M as ae, n as oe } from "./vega-loader.browser-DNST6uVf.js";
16
16
  import { t as se } from "./react-vega-BED0DjiB.js";
17
17
  import { a as ce, n as _ } from "./loader-BQOfjTIJ.js";
@@ -3,7 +3,7 @@ import { t } from "./src-CA_m4ONl.js";
3
3
  import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
4
  import { $ as r, H as i, K as a, U as o, a as s, b as c, c as l, et as u, f as d, nt as f, tt as p, v as m, w as h, y as g } from "./chunk-DU6HZSFF-BwiyaNpg.js";
5
5
  import { t as _ } from "./rough.esm-CtV9AnV1.js";
6
- import { p as v } from "./mermaid-CiAXjLpA.js";
6
+ import { p as v } from "./mermaid-CHo49Yv-.js";
7
7
  //#region ../node_modules/.pnpm/khroma@2.1.0/node_modules/khroma/dist/methods/transparentize.js
8
8
  var y = (e, t) => p(e, "a", -t), b = 1e-10;
9
9
  function x(e, t) {
@@ -2,7 +2,7 @@ import { i as e } from "./chunk-75Z2AOVW-D7gxIs2Q.js";
2
2
  import { n as t } from "./src-CA_m4ONl.js";
3
3
  import { n } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
4
4
  import { D as r, H as i, K as a, U as o, a as s, b as c, c as l, v as u, w as d, x as f, y as p } from "./chunk-DU6HZSFF-BwiyaNpg.js";
5
- import { p as m } from "./mermaid-CiAXjLpA.js";
5
+ import { p as m } from "./mermaid-CHo49Yv-.js";
6
6
  import { n as h } from "./mermaid-parser.core-DxuSfYwJ.js";
7
7
  import { t as g } from "./chunk-JWPE2WC7-DJvv1t8U.js";
8
8
  //#region ../node_modules/.pnpm/mermaid@11.17.2/node_modules/mermaid/dist/chunks/mermaid.core/wardleyDiagram-VM6X3IG4.mjs
@@ -9,7 +9,7 @@ import { n as s } from "./chunk-Y2CYZVJY-DKKS1VyV.js";
9
9
  import { D as c, H as l, K as u, U as d, a as f, b as p, c as m, f as h, v as g, w as _, y as v, z as y } from "./chunk-DU6HZSFF-BwiyaNpg.js";
10
10
  import "./chunk-PWAF6VOD-CQw5qATZ.js";
11
11
  import { t as b } from "./chunk-GMAD6QVW-BhaJx0X3.js";
12
- import { p as x } from "./mermaid-CiAXjLpA.js";
12
+ import { p as x } from "./mermaid-CHo49Yv-.js";
13
13
  //#region ../node_modules/.pnpm/d3-scale@4.0.2/node_modules/d3-scale/src/band.js
14
14
  function S() {
15
15
  var e = t().unknown(void 0), r = e.domain, i = e.range, o = 0, s = 1, c, l, u = !1, d = 0, f = 0, p = .5;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.3-dev141",
3
+ "version": "0.25.3-dev15",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -183,7 +183,9 @@
183
183
  "preview:islands": "cross-env VITE_MARIMO_VERSION='0.4.6' VITE_MARIMO_ISLANDS=true vite --config islands/vite.config.mts build",
184
184
  "storybook": "storybook dev -p 6006",
185
185
  "build-storybook": "storybook build",
186
- "sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts"
186
+ "sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts",
187
+ "codegen": "node --experimental-strip-types scripts/generate-host-protocol.ts",
188
+ "codegen:check": "node --experimental-strip-types scripts/generate-host-protocol.ts --check"
187
189
  },
188
190
  "peerDependencies": {
189
191
  "react": "^17 || ^18 || ^19",
@@ -212,6 +214,7 @@
212
214
  "jsdom": "^24.1.3",
213
215
  "msw": "^2.15.0",
214
216
  "npm-run-all2": "^6.2.6",
217
+ "orval": "8.40.0",
215
218
  "oxc-transform-react": "0.145.0",
216
219
  "oxfmt": "^0.68.0",
217
220
  "oxlint": "^1.83.0",
@@ -2,11 +2,12 @@
2
2
 
3
3
  import { readFileSync } from "node:fs";
4
4
  import path from "node:path";
5
- import { pairPreviewSchema } from "@/core/config/pair";
5
+ import { pairConfigSchema } from "@/core/config/pair";
6
6
 
7
7
  // Read the Python-owned resource only in tests to check the shared contract.
8
- export const PAIR_PREVIEW = pairPreviewSchema.parse({
8
+ export const PAIR_CONFIG = pairConfigSchema.parse({
9
9
  command: "uvx marimo@latest",
10
+ hostEnabled: true,
10
11
  templates: JSON.parse(
11
12
  readFileSync(
12
13
  path.resolve(
@@ -0,0 +1,100 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import NodeChildProcess from "node:child_process";
4
+ import NodeFs from "node:fs";
5
+ import NodeOs from "node:os";
6
+ import NodePath from "node:path";
7
+ import NodeUrl from "node:url";
8
+ import { expect, it } from "vitest";
9
+ import { z } from "zod";
10
+
11
+ it("enforces host dependencies for runtime and type imports", () => {
12
+ const frontend = NodeUrl.fileURLToPath(
13
+ new NodeUrl.URL("../../", import.meta.url),
14
+ );
15
+ const directory = NodeFs.mkdtempSync(
16
+ NodePath.join(NodeOs.tmpdir(), "host-imports-"),
17
+ );
18
+ const files = {
19
+ "src/core/host/allowed.ts": `
20
+ import { atom } from "jotai/vanilla";
21
+ import { z } from "zod";
22
+ import { Logger } from "@/utils/Logger";
23
+ import type { Document } from "./document";
24
+ export * from "@/core/host/events";
25
+ type Event = import("./events").NotebookEvent;
26
+ void import("./protocol");
27
+ `,
28
+ "src/core/host/protocol.ts": `
29
+ import type { NotificationMessage as A } from "../kernel/messages";
30
+ import { type NotificationMessage as B } from "@/core/kernel/messages";
31
+ import { NotificationMessage as C } from "../kernel/messages";
32
+ import type { NotificationPayload } from "../kernel/messages";
33
+ `,
34
+ "src/core/host/forbidden.ts": `
35
+ import { useEffect } from "react";
36
+ import type { NotificationMessage } from "../kernel/messages";
37
+ export * from "../kernel/messages";
38
+ export { Logger } from "@/utils/Logger/../other";
39
+ void import("../kernel/messages");
40
+ type Message = import("../kernel/messages").NotificationMessage;
41
+ const module = require("../kernel/messages");
42
+ void import(module);
43
+ import "./__tests__/allowed";
44
+ import "./allowed.test";
45
+ `,
46
+ "src/core/host/__tests__/allowed.ts": `import { useEffect } from "react";`,
47
+ "src/core/host/allowed.test.ts": `import { useEffect } from "react";`,
48
+ "src/core/host/allowed.spec.ts": `import { useEffect } from "react";`,
49
+ "src/core/websocket/allowed.ts": `import { useEffect } from "react";`,
50
+ };
51
+ try {
52
+ for (const [path, source] of Object.entries(files)) {
53
+ const destination = NodePath.join(directory, path);
54
+ NodeFs.mkdirSync(NodePath.dirname(destination), { recursive: true });
55
+ NodeFs.writeFileSync(destination, source);
56
+ }
57
+ const result = NodeChildProcess.spawnSync(
58
+ NodePath.join(frontend, "node_modules/.bin/oxlint"),
59
+ [
60
+ "--config",
61
+ NodePath.join(frontend, ".oxlintrc.json"),
62
+ "--format",
63
+ "json",
64
+ directory,
65
+ ],
66
+ { cwd: frontend, encoding: "utf8" },
67
+ );
68
+ const report = z
69
+ .object({
70
+ diagnostics: z.array(
71
+ z.object({
72
+ severity: z.string(),
73
+ filename: z.string(),
74
+ labels: z.array(z.object({ span: z.object({ line: z.number() }) })),
75
+ }),
76
+ ),
77
+ })
78
+ .parse(JSON.parse(result.stdout));
79
+ const errors = report.diagnostics.filter(
80
+ (diagnostic) => diagnostic.severity === "error",
81
+ );
82
+ expect(
83
+ errors
84
+ .map((error) => ({
85
+ file: NodePath.basename(error.filename),
86
+ line: error.labels[0].span.line,
87
+ }))
88
+ .toSorted((a, b) => a.file.localeCompare(b.file) || a.line - b.line),
89
+ ).toEqual([
90
+ ...[2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((line) => ({
91
+ file: "forbidden.ts",
92
+ line,
93
+ })),
94
+ ...[2, 3, 4, 5].map((line) => ({ file: "protocol.ts", line })),
95
+ ]);
96
+ expect(result.status).toBe(1);
97
+ } finally {
98
+ NodeFs.rmSync(directory, { recursive: true, force: true });
99
+ }
100
+ });
@@ -6,10 +6,11 @@ import { initialLayoutState, layoutStateAtom } from "@/core/layout/state";
6
6
  import { kioskModeAtom } from "@/core/mode";
7
7
  import { connectionAtom } from "@/core/network/connection";
8
8
  import { store } from "@/core/state/jotai";
9
+ import { runtimeConfigAtom } from "@/core/runtime/config";
9
10
  import { isStaticNotebook } from "@/core/static/static-state";
10
11
  import { ConnectionState } from "@/core/websocket/types";
11
- import { pairPreviewAtom } from "@/core/config/pair";
12
- import { PAIR_PREVIEW } from "./fixtures/pair-preview";
12
+ import { pairConfigAtom } from "@/core/config/pair";
13
+ import { PAIR_CONFIG } from "./fixtures/pair-config";
13
14
  import { mount, visibleForTesting } from "../mount";
14
15
 
15
16
  // Mock React DOM
@@ -84,23 +85,42 @@ describe("mount", () => {
84
85
  mockElement,
85
86
  );
86
87
 
87
- it("hydrates the server's Pair preview configuration", () => {
88
- const error = mountRead({ pairPreview: PAIR_PREVIEW });
88
+ it("hydrates the server's Pair configuration", () => {
89
+ const error = mountRead({ pairConfig: PAIR_CONFIG });
89
90
 
90
91
  expect(error).toBeUndefined();
91
- expect(store.get(pairPreviewAtom)).toEqual(PAIR_PREVIEW);
92
+ expect(store.get(pairConfigAtom)).toEqual(PAIR_CONFIG);
92
93
  });
93
94
 
94
- it("uses legacy Pair behavior when the host omits preview configuration", () => {
95
- store.set(pairPreviewAtom, PAIR_PREVIEW);
95
+ it("clears Pair configuration when the server omits it", () => {
96
+ store.set(pairConfigAtom, PAIR_CONFIG);
96
97
 
97
98
  const error = mountRead();
98
99
 
99
100
  expect(error).toBeUndefined();
100
- expect(store.get(pairPreviewAtom)).toBeUndefined();
101
+ expect(store.get(pairConfigAtom)).toBeUndefined();
101
102
  });
102
103
 
103
104
  describe("connection state initialization", () => {
105
+ it("passes the host notebook identity to the local runtime", () => {
106
+ mount({ ...baseOptions, notebookId: "nb_local" }, mockElement);
107
+ expect(store.get(runtimeConfigAtom).notebookId).toBe("nb_local");
108
+ });
109
+
110
+ it("uses a remote runtime's own notebook identity", () => {
111
+ mount(
112
+ {
113
+ ...baseOptions,
114
+ notebookId: "nb_local",
115
+ runtimeConfig: [
116
+ { url: "https://remote.example", notebookId: "nb_remote" },
117
+ ],
118
+ },
119
+ mockElement,
120
+ );
121
+ expect(store.get(runtimeConfigAtom).notebookId).toBe("nb_remote");
122
+ });
123
+
104
124
  it("should set connection to CONNECTING when runtimeConfig has lazy=false", () => {
105
125
  mount(
106
126
  {
@@ -0,0 +1,176 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
4
+ import { buildCellFilter } from "../context-menu";
5
+
6
+ describe("buildCellFilter", () => {
7
+ // Use a non-UTC, non-DST-ambiguous offset so date-only parsing bugs
8
+ // (UTC vs. local midnight) can't hide behind a host machine that
9
+ // happens to run in UTC.
10
+ let originalTimezone: string | undefined;
11
+ beforeAll(() => {
12
+ originalTimezone = process.env.TZ;
13
+ process.env.TZ = "America/New_York";
14
+ });
15
+ afterAll(() => {
16
+ process.env.TZ = originalTimezone;
17
+ });
18
+
19
+ it("builds an equality filter for a normal date value", () => {
20
+ const filter = buildCellFilter({
21
+ type: "date",
22
+ value: "2024-01-15",
23
+ comparison: "eq",
24
+ dataType: "date",
25
+ dtype: "date",
26
+ });
27
+ expect(filter).toEqual({
28
+ type: "date",
29
+ operator: "==",
30
+ // Must be local midnight, not `new Date("2024-01-15")` (UTC
31
+ // midnight), or the filter shifts by a day in UTC- timezones.
32
+ value: new Date(2024, 0, 15),
33
+ });
34
+ });
35
+
36
+ it("returns undefined for an empty-string date value in a non-temporal-looking context", () => {
37
+ const filter = buildCellFilter({
38
+ type: "date",
39
+ value: "",
40
+ comparison: "eq",
41
+ dataType: "date",
42
+ dtype: "date",
43
+ });
44
+ expect(filter).toBeUndefined();
45
+ });
46
+
47
+ it("returns undefined for an unparsable date value instead of an Invalid Date filter", () => {
48
+ const filter = buildCellFilter({
49
+ type: "date",
50
+ value: "not-a-date",
51
+ comparison: "eq",
52
+ dataType: "date",
53
+ dtype: "date",
54
+ });
55
+ expect(filter).toBeUndefined();
56
+ });
57
+
58
+ it("builds an equality filter for a normal datetime value", () => {
59
+ const filter = buildCellFilter({
60
+ type: "datetime",
61
+ value: "2024-01-15 08:30:00",
62
+ comparison: "eq",
63
+ dataType: "datetime",
64
+ dtype: "datetime64[ns]",
65
+ });
66
+ expect(filter).toEqual({
67
+ type: "datetime",
68
+ operator: "==",
69
+ value: new Date(2024, 0, 15, 8, 30, 0),
70
+ });
71
+ });
72
+
73
+ it("returns undefined for an unparsable datetime value", () => {
74
+ const filter = buildCellFilter({
75
+ type: "datetime",
76
+ value: "not-a-datetime",
77
+ comparison: "eq",
78
+ dataType: "datetime",
79
+ dtype: "datetime64[ns]",
80
+ });
81
+ expect(filter).toBeUndefined();
82
+ });
83
+
84
+ it("builds an equality filter for a normal time value", () => {
85
+ const filter = buildCellFilter({
86
+ type: "time",
87
+ value: "08:30:00",
88
+ comparison: "eq",
89
+ dataType: "time",
90
+ });
91
+ expect(filter).toEqual({
92
+ type: "time",
93
+ operator: "==",
94
+ value: new Date(1970, 0, 1, 8, 30, 0),
95
+ });
96
+ });
97
+
98
+ it("returns undefined instead of an unparsable time value", () => {
99
+ const filter = buildCellFilter({
100
+ type: "time",
101
+ value: "25:00:00",
102
+ comparison: "eq",
103
+ dataType: "time",
104
+ });
105
+ expect(filter).toBeUndefined();
106
+ });
107
+
108
+ it("maps a NaT date value to is_null instead of an invalid Date filter", () => {
109
+ const filter = buildCellFilter({
110
+ type: "date",
111
+ value: "NaT",
112
+ comparison: "eq",
113
+ dataType: "date",
114
+ dtype: "date",
115
+ });
116
+ expect(filter).toEqual({ type: "date", operator: "is_null" });
117
+ });
118
+
119
+ it("maps a NaT datetime value to is_not_null for the neq comparison", () => {
120
+ const filter = buildCellFilter({
121
+ type: "datetime",
122
+ value: "NaT",
123
+ comparison: "neq",
124
+ dataType: "datetime",
125
+ dtype: "datetime64[ns]",
126
+ });
127
+ expect(filter).toEqual({ type: "datetime", operator: "is_not_null" });
128
+ });
129
+
130
+ it("does not treat the string 'NaT' in a non-temporal column as a sentinel", () => {
131
+ const filter = buildCellFilter({
132
+ type: "text",
133
+ value: "NaT",
134
+ comparison: "eq",
135
+ dataType: "string",
136
+ });
137
+ expect(filter).toEqual({ type: "text", operator: "equals", text: "NaT" });
138
+ });
139
+
140
+ it("maps an actual null value to is_null", () => {
141
+ const filter = buildCellFilter({
142
+ type: "number",
143
+ value: null,
144
+ comparison: "eq",
145
+ dataType: "number",
146
+ });
147
+ expect(filter).toEqual({ type: "number", operator: "is_null" });
148
+ });
149
+
150
+ it("builds a literal (always-false) equality filter for a NaN number value", () => {
151
+ // NaN is a real float value, not a missing-value marker like null/NaT,
152
+ // and the backend's is_null() (narwhals/polars semantics) doesn't match
153
+ // it, so it falls through to a normal (if unsatisfiable) == filter.
154
+ const filter = buildCellFilter({
155
+ type: "number",
156
+ value: Number.NaN,
157
+ comparison: "eq",
158
+ dataType: "number",
159
+ });
160
+ expect(filter).toEqual({
161
+ type: "number",
162
+ operator: "==",
163
+ value: Number.NaN,
164
+ });
165
+ });
166
+
167
+ it("builds a literal equality filter for a normal number value", () => {
168
+ const filter = buildCellFilter({
169
+ type: "number",
170
+ value: 42,
171
+ comparison: "eq",
172
+ dataType: "number",
173
+ });
174
+ expect(filter).toEqual({ type: "number", operator: "==", value: 42 });
175
+ });
176
+ });