@marimo-team/islands 0.25.3-dev3 → 0.25.3-dev31

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 (172) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CNSxdKyJ.js → ConnectedDataExplorerComponent-7EaP9VWb.js} +12 -12
  2. package/dist/{ErrorBoundary-iHE9DnZC.js → ErrorBoundary-DrVykO0s.js} +8 -8
  3. package/dist/{abnfDiagram-VCTEODGH-DQDjNXt3.js → abnfDiagram-VCTEODGH-z_OSynK8.js} +2 -2
  4. package/dist/{any-language-editor-B9REGlD9.js → any-language-editor-D4q-IFcM.js} +2 -2
  5. package/dist/{architectureDiagram-5GKGNRK7-Nmls7Wxn.js → architectureDiagram-5GKGNRK7-Cs8J8BZr.js} +1 -1
  6. package/dist/{chat-ui-BDpymeoe.js → chat-ui-BeKQyQQI.js} +1151 -1152
  7. package/dist/{check-EDwSwP89.js → check-BMKBBrdc.js} +1 -1
  8. package/dist/{chunk-IMKFNOWR-CoIFEo-1.js → chunk-IMKFNOWR-aoSFasqF.js} +1 -1
  9. package/dist/{chunk-SHT3W25Y-lHiGx3ZC.js → chunk-SHT3W25Y-CMaybO3O.js} +1 -1
  10. package/dist/{chunk-SVP7TREG-BvsHIrY_.js → chunk-SVP7TREG-BNBrTAw1.js} +1 -1
  11. package/dist/{chunk-TICWLB2K-BC8YIm_n.js → chunk-TICWLB2K-DXNxvUJn.js} +1 -1
  12. package/dist/{chunk-YOKDWASO-DPZk8vhS.js → chunk-YOKDWASO-DKplTrBY.js} +20 -20
  13. package/dist/{classDiagram-ZZMXUADV-Bt98lkkv.js → classDiagram-ZZMXUADV-DXdCCDOg.js} +2 -2
  14. package/dist/{classDiagram-v2-VYDZK3BY-D9bfbcC3.js → classDiagram-v2-VYDZK3BY-DyZqrtLP.js} +2 -2
  15. package/dist/{code-visibility-BCpXa0Xh.js → code-visibility-UR3IN3fl.js} +16 -16
  16. package/dist/{common-BrBUdtPy.js → common-C6uebScP.js} +5737 -5439
  17. package/dist/{copy-icon-Ft7t9bqz.js → copy-icon-BgUO8jsi.js} +2 -2
  18. package/dist/{cynefinDiagram-5FMLGOSQ-CgWra7wt.js → cynefinDiagram-5FMLGOSQ-DWHuKJs8.js} +1 -1
  19. package/dist/{dagre-GXQ25YYZ-CFZ8-35c.js → dagre-GXQ25YYZ-DYLu-OCU.js} +1 -1
  20. package/dist/{data-grid-overlay-editor-Ch2SgmvG.js → data-grid-overlay-editor-DhdeVwuk.js} +5 -5
  21. package/dist/{data-grid-types-BH_r7g7l.js → data-grid-types-0PJ-9N5n.js} +1 -1
  22. package/dist/{diagram-S7CK7UJ4-lCNQrW7d.js → diagram-S7CK7UJ4-PwwcUOHP.js} +1 -1
  23. package/dist/{diagram-UQ7AKVKN-CQPQ6pP_.js → diagram-UQ7AKVKN-CvJbL_IM.js} +1 -1
  24. package/dist/{diagram-VX7I27RA-Cf3b0llz.js → diagram-VX7I27RA-B5RkqnzN.js} +1 -1
  25. package/dist/{diagram-Z3DM3KII-Bt4QLrpn.js → diagram-Z3DM3KII-CyijwTR2.js} +1 -1
  26. package/dist/{dialog-CEBFZNyc.js → dialog-Cc479ZEH.js} +24 -24
  27. package/dist/{dist-DpBpA_n1.js → dist-Lm-D-Vr6.js} +3 -3
  28. package/dist/{dropdown-menu-CP_qCYHC.js → dropdown-menu-BuE2b8Yb.js} +790 -790
  29. package/dist/{ebnfDiagram-PWID7BFC-D3NAyPFY.js → ebnfDiagram-PWID7BFC-DG90ELFp.js} +2 -2
  30. package/dist/{erDiagram-RLTQ6QDP-Tlu09_Nm.js → erDiagram-RLTQ6QDP-FMo_SpyX.js} +1 -1
  31. package/dist/{error-banner-Da600cwz.js → error-banner-CFPHFw4h.js} +26 -21
  32. package/dist/{cells-C8iCYvLU.js → error-entries-CnqKxhU9.js} +1370 -1314
  33. package/dist/{feedback-button-DxXNcC6q.js → feedback-button-DGkGODB3.js} +121 -122
  34. package/dist/{flowDiagram-HODETNUW-CAYbpJmV.js → flowDiagram-HODETNUW-DQ4JuadE.js} +2 -2
  35. package/dist/{formats-BGh2thRc.js → formats-DRHUWwSK.js} +2 -2
  36. package/dist/{ganttDiagram-EL5Y4UJY-BQT16JSc.js → ganttDiagram-EL5Y4UJY-Dh_4cBJZ.js} +2 -2
  37. package/dist/{glide-data-editor-BQ7uKbeo.js → glide-data-editor-E8Z7sC5t.js} +55 -55
  38. package/dist/{glide-utils-DJyqh0EM.js → glide-utils-pisbYVjH.js} +3 -3
  39. package/dist/{globals-DSavh2ZB.js → globals-D7sKfXY8.js} +3 -3
  40. package/dist/{highlighted-body-KPVGNVTW-zwjq21tf.js → highlighted-body-KPVGNVTW-3Ziwfz-V.js} +2 -2
  41. package/dist/{html-to-image-CZY1pIZH.js → html-to-image-BsG_zyNW.js} +68 -68
  42. package/dist/{infoDiagram-27XIBGKW-XrDxhr0x.js → infoDiagram-27XIBGKW-CRSDtRrd.js} +1 -1
  43. package/dist/{ishikawaDiagram-5VMMS53U-CD1muzov.js → ishikawaDiagram-5VMMS53U-DxLEUldB.js} +1 -1
  44. package/dist/{kanban-definition-UXKFOSKX-Dg9W142_.js → kanban-definition-UXKFOSKX-BLhvu8o4.js} +1 -1
  45. package/dist/{label-BDKF3Afc.js → label-DoysmLMW.js} +1 -1
  46. package/dist/{linear-Cnaq3Tfb.js → linear-DWERh7eI.js} +121 -73
  47. package/dist/{loader-BQOfjTIJ.js → loader-BPdQhmlq.js} +10 -10
  48. package/dist/main.js +759 -759
  49. package/dist/{mermaid-CiAXjLpA.js → mermaid-Bjm6C1qN.js} +37 -37
  50. package/dist/mermaid-HWGCJPDP-Du3-HPQA.js +2 -0
  51. package/dist/{mindmap-definition-YA3MSWOX-DgCidgYJ.js → mindmap-definition-YA3MSWOX-g2LwxnYQ.js} +1 -1
  52. package/dist/{number-overlay-editor-D6kYaqh5.js → number-overlay-editor-BV4UMoL2.js} +3 -3
  53. package/dist/{pegDiagram-XKGWAZYB-coOYYKB6.js → pegDiagram-XKGWAZYB-CpMAt3Qs.js} +2 -2
  54. package/dist/{pieDiagram-E7YTZNPT-BnXTc3bj.js → pieDiagram-E7YTZNPT-CVTthoZo.js} +1 -1
  55. package/dist/precisionRound-DhAzeRcm.js +49 -0
  56. package/dist/{process-output-e4jj9Ijt.js → process-output-DgQrilBD.js} +5 -5
  57. package/dist/{quadrantDiagram-AXDQQJYC-Ccw0xMjN.js → quadrantDiagram-AXDQQJYC-Blrm7V7_.js} +1 -1
  58. package/dist/{railroadDiagram-O6MQD6OU-B28-u83n.js → railroadDiagram-O6MQD6OU-ao8cqqFB.js} +2 -2
  59. package/dist/{react-vega-BED0DjiB.js → react-vega-BDpbvBCb.js} +12284 -12270
  60. package/dist/{requirementDiagram-BXWQKSXE-CdYCTMu0.js → requirementDiagram-BXWQKSXE--J8vyfm-.js} +1 -1
  61. package/dist/{reveal-component-BTBfJ3ju.js → reveal-component-CpEtzUCU.js} +9 -9
  62. package/dist/{select-BButFi-d.js → select-DemoKT4G.js} +199 -199
  63. package/dist/{sequenceDiagram-WJ2MYXX4-CM3aRAe_.js → sequenceDiagram-WJ2MYXX4-CiQbn62x.js} +1 -1
  64. package/dist/{spec-BwarBpUJ.js → spec-D_u2ipzF.js} +4 -4
  65. package/dist/{stateDiagram-D77RDMKH-DOZUMVj8.js → stateDiagram-D77RDMKH-DVEeGs5b.js} +2 -2
  66. package/dist/{stateDiagram-v2-MP3YSRHH-CISYxma6.js → stateDiagram-v2-MP3YSRHH-1OQRe6iA.js} +2 -2
  67. package/dist/style.css +1 -1
  68. package/dist/{swimlanes-42K2YHIH-BkSppxp8.js → swimlanes-42K2YHIH-CqkGoGqn.js} +1 -1
  69. package/dist/{swimlanesDiagram-VR7AAH4N-c8G5pGxC.js → swimlanesDiagram-VR7AAH4N-CszjkrKo.js} +2 -2
  70. package/dist/{time-BieKwdYS.js → time-BaMbJs4z.js} +18 -18
  71. package/dist/{timeline-definition-24CTP7MA-CaMQayqK.js → timeline-definition-24CTP7MA-DLRUNVAx.js} +1 -1
  72. package/dist/toDate-gyi35XS2.js +1185 -0
  73. package/dist/{toast-B9UMEi8u.js → toast-PkdZraM8.js} +221 -221
  74. package/dist/{tooltip-BO1REbqs.js → tooltip-CtBZ5q8p.js} +51 -51
  75. package/dist/{use-restore-focus-BEM7sFWl.js → use-restore-focus-CKjfFjLM.js} +1 -1
  76. package/dist/{useAsyncData-Deh5kszT.js → useAsyncData-BneN349z.js} +1 -1
  77. package/dist/{useDateFormatter-D8XruNGG.js → useDateFormatter-DkajGwwd.js} +2 -2
  78. package/dist/{useDeepCompareMemoize-DXwzRINI.js → useDeepCompareMemoize-Z_7R8wTt.js} +1 -1
  79. package/dist/{useLifecycle-j7D9uD1o.js → useLifecycle-Dfq8UD-b.js} +2 -2
  80. package/dist/{useTheme-CRnjkku0.js → useTheme-Bu5bBgrh.js} +86 -86
  81. package/dist/{vega-component-DG29TAB7.js → vega-component-1lFfDE_8.js} +10 -10
  82. package/dist/{vega-embed-container-BNHE18G9.js → vega-embed-container-BgKnsDbB.js} +2 -2
  83. package/dist/{vega-loader.browser-DNST6uVf.js → vega-loader.browser-CpbZAXub.js} +297 -506
  84. package/dist/{vennDiagram-4TSXK5OY-CF8pfaK3.js → vennDiagram-4TSXK5OY-CypgoBVZ.js} +1 -1
  85. package/dist/{wardleyDiagram-VM6X3IG4-dGPu39d-.js → wardleyDiagram-VM6X3IG4-B6xjiQ_g.js} +1 -1
  86. package/dist/{xychartDiagram-S5SC5T6Z-CP6-9q56.js → xychartDiagram-S5SC5T6Z-e0PefDVs.js} +2 -2
  87. package/package.json +4 -2
  88. package/src/__tests__/fixtures/{pair-preview.ts → pair-config.ts} +3 -2
  89. package/src/__tests__/mount.test.ts +28 -8
  90. package/src/components/data-table/__tests__/context-menu.test.ts +176 -0
  91. package/src/components/data-table/__tests__/date-filter-inputs.test.tsx +24 -1
  92. package/src/components/data-table/__tests__/export-actions.test.tsx +329 -6
  93. package/src/components/data-table/context-menu.tsx +125 -26
  94. package/src/components/data-table/date-filter-inputs.tsx +15 -42
  95. package/src/components/data-table/export-actions.tsx +192 -116
  96. package/src/components/data-table/schemas.ts +14 -36
  97. package/src/components/data-table/utils.ts +18 -0
  98. package/src/components/editor/Output.tsx +9 -2
  99. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +111 -18
  100. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +80 -252
  101. package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +186 -34
  102. package/src/components/editor/actions/pair-with-agent-commands.ts +42 -51
  103. package/src/components/editor/actions/pair-with-agent-modal.tsx +96 -36
  104. package/src/components/editor/chrome/panels/error-panel.tsx +1 -0
  105. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +366 -0
  106. package/src/components/editor/chrome/wrapper/footer-item.tsx +32 -24
  107. package/src/components/editor/chrome/wrapper/footer-items/attachment-status.tsx +237 -0
  108. package/src/components/editor/chrome/wrapper/footer.tsx +2 -0
  109. package/src/components/editor/controls/__tests__/command-palette.test.tsx +53 -0
  110. package/src/components/editor/controls/command-palette.tsx +22 -10
  111. package/src/components/editor/dynamic-favicon.tsx +21 -40
  112. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +537 -0
  113. package/src/components/editor/errors/send-error-report-button.tsx +69 -0
  114. package/src/components/editor/output/MarimoErrorOutput.tsx +21 -5
  115. package/src/components/editor/output/MarimoTracebackOutput.tsx +35 -20
  116. package/src/components/editor/output/__tests__/ansi-reduce.test.ts +18 -0
  117. package/src/components/editor/output/ansi-reduce.ts +6 -0
  118. package/src/core/attachments/__tests__/toast.test.tsx +58 -0
  119. package/src/core/attachments/state.ts +18 -0
  120. package/src/core/attachments/toast.ts +15 -0
  121. package/src/core/cells/__tests__/cells.test.ts +52 -0
  122. package/src/core/cells/__tests__/error-report.test.ts +139 -0
  123. package/src/core/cells/__tests__/notebook-outline.test.ts +113 -0
  124. package/src/core/cells/__tests__/session.test.ts +50 -1
  125. package/src/core/cells/cells.ts +2 -1
  126. package/src/core/cells/error-report.ts +63 -0
  127. package/src/core/cells/session.ts +28 -1
  128. package/src/core/config/pair.ts +5 -3
  129. package/src/core/edit-app.tsx +2 -2
  130. package/src/core/host/AGENTS.md +5 -0
  131. package/src/core/host/__tests__/attachments.test.ts +57 -0
  132. package/src/core/host/__tests__/document.test.ts +124 -0
  133. package/src/core/host/__tests__/events.test.ts +46 -0
  134. package/src/core/host/__tests__/fixtures.ts +39 -0
  135. package/src/core/host/__tests__/notebook-client.test.ts +433 -0
  136. package/src/core/host/__tests__/protocol.test.ts +15 -0
  137. package/src/core/host/__tests__/stream.test.ts +209 -0
  138. package/src/core/host/connection.ts +81 -0
  139. package/src/core/host/events.ts +61 -0
  140. package/src/core/host/notebook-client.ts +290 -0
  141. package/src/core/host/protocol.ts +11 -6
  142. package/src/core/host/resources/attachments.ts +19 -0
  143. package/src/core/host/resources/document.ts +101 -0
  144. package/src/core/host/resources/resource.ts +47 -0
  145. package/src/core/host/stream.ts +211 -0
  146. package/src/core/network/connection.ts +4 -2
  147. package/src/core/run-app.tsx +2 -2
  148. package/src/core/runtime/__tests__/runtime.test.ts +55 -11
  149. package/src/core/runtime/runtime.ts +15 -1
  150. package/src/core/runtime/types.ts +2 -0
  151. package/src/core/websocket/__tests__/{useMarimoKernelConnection.test.ts → connection-state.test.ts} +15 -17
  152. package/src/core/websocket/__tests__/{useWebSocket.test.ts → createConnectionTransport.test.ts} +1 -1
  153. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +170 -0
  154. package/src/core/websocket/__tests__/{useMarimoKernelConnection.hook.test.tsx → useNotebookSession.hook.test.tsx} +181 -65
  155. package/src/core/websocket/connection-state.ts +70 -0
  156. package/src/core/websocket/state.ts +7 -0
  157. package/src/core/websocket/transports/__tests__/sse.test.ts +1 -4
  158. package/src/core/websocket/transports/create.ts +31 -0
  159. package/src/core/websocket/transports/transport.ts +12 -23
  160. package/src/core/websocket/types.ts +9 -39
  161. package/src/core/websocket/useNotebookClient.ts +88 -0
  162. package/src/core/websocket/{useMarimoKernelConnection.tsx → useNotebookSession.tsx} +59 -225
  163. package/src/mount.tsx +7 -3
  164. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +84 -0
  165. package/src/utils/__tests__/dates.test.ts +116 -0
  166. package/src/utils/dates.ts +94 -0
  167. package/src/utils/once.ts +19 -19
  168. package/dist/error-entries-CzoYkIQZ.js +0 -56
  169. package/dist/mermaid-HWGCJPDP-ByCsZnYF.js +0 -2
  170. package/dist/precisionRound-DMIVQrt2.js +0 -97
  171. package/dist/toDate-BNJf01u1.js +0 -703
  172. package/src/core/websocket/useWebSocket.tsx +0 -88
@@ -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-Bjm6C1qN.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-Bjm6C1qN.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
@@ -1,4 +1,4 @@
1
- import { t as e } from "./linear-Cnaq3Tfb.js";
1
+ import { t as e } from "./linear-DWERh7eI.js";
2
2
  import { n as t } from "./ordinal-c7efuCSS.js";
3
3
  import { t as n } from "./range-BAIvbVHp.js";
4
4
  import { q as r } from "./cubic-OaEBhQPK.js";
@@ -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-Bjm6C1qN.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-dev3",
3
+ "version": "0.25.3-dev31",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -152,6 +152,7 @@
152
152
  "typescript-memoize": "^1.1.1",
153
153
  "use-acp": "0.2.6",
154
154
  "use-resize-observer": "^9.1.0",
155
+ "vega": "6.2.0",
155
156
  "vega-lite": "6.4.3",
156
157
  "vega-loader": "^5.1.3",
157
158
  "vega-parser": "^7.1.3",
@@ -185,7 +186,8 @@
185
186
  "build-storybook": "storybook build",
186
187
  "sync-katex-css": "node --experimental-strip-types scripts/sync-katex-css.ts",
187
188
  "codegen": "node --experimental-strip-types scripts/generate-host-protocol.ts",
188
- "codegen:check": "node --experimental-strip-types scripts/generate-host-protocol.ts --check"
189
+ "codegen:check": "node --experimental-strip-types scripts/generate-host-protocol.ts --check",
190
+ "doctor": "npx react-doctor@latest"
189
191
  },
190
192
  "peerDependencies": {
191
193
  "react": "^17 || ^18 || ^19",
@@ -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(
@@ -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
+ });
@@ -1,7 +1,30 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { describe, expect, it } from "vitest";
3
3
  import { dateToLocalISODate } from "@/utils/dates";
4
- import { parsePastedRange } from "../date-filter-inputs";
4
+ import { parsePastedDate, parsePastedRange } from "../date-filter-inputs";
5
+
6
+ describe("parsePastedDate", () => {
7
+ it("parses a time-only string for the time filter type", () => {
8
+ const result = parsePastedDate("time", "2:30 PM");
9
+ expect(result).toEqual(new Date(1970, 0, 1, 14, 30));
10
+ });
11
+
12
+ it("parses a local ISO datetime for the datetime filter type", () => {
13
+ const result = parsePastedDate("datetime", "2026-02-01T08:30:00");
14
+ expect(result).toEqual(new Date(2026, 1, 1, 8, 30, 0));
15
+ });
16
+
17
+ it("falls back to the Date constructor for other formats", () => {
18
+ const result = parsePastedDate("datetime", "Feb 1, 2026 08:30:00");
19
+ expect(result).toBeDefined();
20
+ expect(result?.getFullYear()).toBe(2026);
21
+ });
22
+
23
+ it("returns undefined for an empty or unparsable string", () => {
24
+ expect(parsePastedDate("date", "")).toBeUndefined();
25
+ expect(parsePastedDate("time", "not-a-time")).toBeUndefined();
26
+ });
27
+ });
5
28
 
6
29
  describe("parsePastedRange", () => {
7
30
  it.each([