@marimo-team/islands 0.23.15-dev7 → 0.23.15-dev72

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 (584) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CU4fZJzG.js → ConnectedDataExplorerComponent-CJaUI-S-.js} +85 -84
  2. package/dist/{ErrorBoundary-DE6tzZf-.js → ErrorBoundary-DXlxsrTF.js} +3 -3
  3. package/dist/{ImageComparisonComponent-CHrI72em.js → ImageComparisonComponent-C3y7L3eJ.js} +173 -129
  4. package/dist/{any-language-editor-DN1R-1KZ.js → any-language-editor-P9tjkj4n.js} +21 -21
  5. package/dist/apl-e1B5LPEL.js +4 -0
  6. package/dist/{arc-DfkSnvZm.js → arc-CTIpFoOn.js} +2 -2
  7. package/dist/architecture-7HQA4BMR-DHUrQjL4.js +6 -0
  8. package/dist/{architectureDiagram-VXUJARFQ-CT2SuxNw.js → architectureDiagram-VXUJARFQ-DXwkyAaM.js} +19 -19
  9. package/dist/asciiarmor-B-gwgesP.js +4 -0
  10. package/dist/asn1-DF2ckRB4.js +4 -0
  11. package/dist/assets/__vite-browser-external-DltVXDv7.js +1 -0
  12. package/dist/assets/worker-CDEKsBgX.js +98 -0
  13. package/dist/{blockDiagram-VD42YOAC-Dy7hlFla.js → blockDiagram-VD42YOAC-CIOjvxeD.js} +12 -12
  14. package/dist/brainfuck-4G-7_gq_.js +4 -0
  15. package/dist/{button-BacYv-bE.js → button-BcSml68y.js} +12 -65
  16. package/dist/{c4Diagram-YG6GDRKO-BXlAmZ8Z.js → c4Diagram-YG6GDRKO-B6dZC_oU.js} +6 -6
  17. package/dist/{capabilities-D_4LYhSU.js → capabilities-BYLFYTYv.js} +2 -2
  18. package/dist/{channel-D_PHgcig.js → channel-BN070S0F.js} +1 -1
  19. package/dist/{chat-ui-DinOvbWu.js → chat-ui-BdSDiVjk.js} +3122 -3116
  20. package/dist/{check-C9OoNtR4.js → check-Cs-KV5XY.js} +1 -1
  21. package/dist/{chunk-4BX2VUAB-CzXltWHN.js → chunk-4BX2VUAB-iU5lQTDI.js} +1 -1
  22. package/dist/{chunk-4F5CHEZ2-D9nGEHV8.js → chunk-4F5CHEZ2-VlodlEGo.js} +1 -1
  23. package/dist/{chunk-55IACEB6-B-1mjMMC.js → chunk-55IACEB6-7h71GwyW.js} +1 -1
  24. package/dist/{chunk-5FQGJX7Z-BbqSm5gU.js → chunk-5FQGJX7Z-B9WoXK1R.js} +3 -3
  25. package/dist/{chunk-ABZYJK2D-Dz0-H2B5.js → chunk-ABZYJK2D-BxBDji1u.js} +3 -3
  26. package/dist/{chunk-ATLVNIR6-o0Z5MZLd.js → chunk-ATLVNIR6-qFiszptQ.js} +2 -2
  27. package/dist/{chunk-B2363JML-KEJpLGGP.js → chunk-B2363JML-zL3VngtH.js} +1 -1
  28. package/dist/{chunk-B4BG7PRW-BL98U9B4.js → chunk-B4BG7PRW-B_z2FEHm.js} +7 -7
  29. package/dist/{chunk-CVBHYZKI-B_c5YBcW.js → chunk-CVBHYZKI-CwazXVlJ.js} +1 -1
  30. package/dist/{chunk-DI55MBZ5-Dwkn0LWm.js → chunk-DI55MBZ5-D4Y8yV8B.js} +6 -6
  31. package/dist/{chunk-EXTU4WIE-9sNjmQrB.js → chunk-EXTU4WIE-BQPBhApE.js} +2 -2
  32. package/dist/{chunk-FMBD7UC4-Ie8M9q0W.js → chunk-FMBD7UC4-quJmebXa.js} +1 -1
  33. package/dist/{chunk-FRFDVMJY-DzQqMWrl.js → chunk-FRFDVMJY-BHBqN-vD.js} +1 -1
  34. package/dist/{chunk-HN2XXSSU-E3n-Ys7Z.js → chunk-HN2XXSSU-Bv0QkeMr.js} +1 -1
  35. package/dist/{chunk-JA3XYJ7Z-C32Y7Epf.js → chunk-JA3XYJ7Z-CY4CRbV5.js} +3 -3
  36. package/dist/{chunk-JZLCHNYA-C6ftyVMN.js → chunk-JZLCHNYA-DWIR9m5O.js} +6 -6
  37. package/dist/{chunk-MI3HLSF2-CUYEasXO.js → chunk-MI3HLSF2-HGWI-8Pg.js} +1 -1
  38. package/dist/{chunk-N4CR4FBY-DUhGZhZs.js → chunk-N4CR4FBY-Bw2HcMNc.js} +7 -7
  39. package/dist/{chunk-PL6DKKU2-D7km-08O.js → chunk-PL6DKKU2-CAHKc95s.js} +1 -1
  40. package/dist/{chunk-QN33PNHL-0K6SDYn3.js → chunk-QN33PNHL-DPBNNzpR.js} +2 -2
  41. package/dist/{chunk-QXUST7PY-DMhsRpYK.js → chunk-QXUST7PY-DtC2t9Mk.js} +10 -10
  42. package/dist/{chunk-QZHKN3VN-DRjXVwuJ.js → chunk-QZHKN3VN-Dym5BS7y.js} +1 -1
  43. package/dist/{chunk-S3R3BYOJ-oAe3dEbO.js → chunk-S3R3BYOJ-BdgLc8AM.js} +4 -4
  44. package/dist/{chunk-SJTYNZTY-BkJrPRFC.js → chunk-SJTYNZTY-DnXoKWpW.js} +1 -1
  45. package/dist/{chunk-TCCFYFTB-D58KeXnC.js → chunk-TCCFYFTB-DPWJa9zL.js} +1 -1
  46. package/dist/{chunk-TQ3KTPDO-D_yA_wAb.js → chunk-TQ3KTPDO-CsDx6v37.js} +1 -1
  47. package/dist/{chunk-TZMSLE5B-yBKS_DQU.js → chunk-TZMSLE5B-BzSHcq-K.js} +3 -3
  48. package/dist/{chunk-UMXZTB3W-D7uwvNjd.js → chunk-UMXZTB3W-D1uHz8MN.js} +1 -1
  49. package/dist/classDiagram-2ON5EDUG-BiQPjMNY.js +30 -0
  50. package/dist/classDiagram-v2-WZHVMYZB-YHdR8fqM.js +30 -0
  51. package/dist/{clike-DTxNUn7l.js → clike-7lgyEYRk.js} +1 -1
  52. package/dist/clojure-CUybM11R.js +4 -0
  53. package/dist/cmake-BPjGcuDL.js +4 -0
  54. package/dist/cobol-BETk_nb6.js +4 -0
  55. package/dist/{code-block-37QAKDTI-O6IH6wAi.js → code-block-37QAKDTI-MSxEjskJ.js} +1 -1
  56. package/dist/{code-visibility-B8b6lh5X.js → code-visibility-i9MrZhpb.js} +1554 -1471
  57. package/dist/coffeescript-CManZxXL.js +4 -0
  58. package/dist/commonlisp-DWkn7GW8.js +4 -0
  59. package/dist/{copy-COam1EG7.js → copy-Cs3yt6Vt.js} +2 -2
  60. package/dist/{cose-bilkent-S5V4N54A-kjoZoid4.js → cose-bilkent-S5V4N54A-BYj0aL7z.js} +2 -2
  61. package/dist/crystal-CCbg5EUH.js +4 -0
  62. package/dist/css-By8eo-XS.js +4 -0
  63. package/dist/cypher-DwfHg3nP.js +4 -0
  64. package/dist/d-Brs1wNbw.js +4 -0
  65. package/dist/{dagre-6UL2VRFP-J0JKgwOt.js → dagre-6UL2VRFP-DpYjBqQs.js} +11 -11
  66. package/dist/{data-grid-overlay-editor-C6lxUJp-.js → data-grid-overlay-editor-BWRG2b_o.js} +2 -2
  67. package/dist/{constants-T20xxyNf.js → debounce-BOD3DbfP.js} +1 -24
  68. package/dist/{diagram-PSM6KHXK-DYgJuNk9.js → diagram-PSM6KHXK-D4ftnaua.js} +22 -22
  69. package/dist/{diagram-QEK2KX5R-CKdBR2sb.js → diagram-QEK2KX5R-DVlUOgs1.js} +17 -17
  70. package/dist/{diagram-S2PKOQOG-Dpi7mo5W.js → diagram-S2PKOQOG-CGh4OMEV.js} +17 -17
  71. package/dist/diff-DJIRmJ1g.js +4 -0
  72. package/dist/{dist-DyyjKEYf.js → dist-3NCqaWjt.js} +2 -2
  73. package/dist/{dist-D-W5ny5a.js → dist-4lVIWUT3.js} +1 -1
  74. package/dist/dist-5o9uz19x.js +5 -0
  75. package/dist/{dist-GZXUmt0b.js → dist-B2jmQKKx.js} +2 -2
  76. package/dist/{dist--2Bqjvs0.js → dist-B96tMAst.js} +2 -2
  77. package/dist/{dist-BaoDKvdy.js → dist-BCX980mU.js} +2 -2
  78. package/dist/{dist-DMjWuVs8.js → dist-BIEt-mlF.js} +1 -1
  79. package/dist/{dist-BR_gyG9L.js → dist-BO5HRiTf.js} +2 -2
  80. package/dist/{dist-Dv_Y15yk.js → dist-BOMbzyb3.js} +85 -85
  81. package/dist/{dist-CIYBwstr.js → dist-BP39XM8u.js} +1 -1
  82. package/dist/{dist-DZo4nSS0.js → dist-BPF0gTRZ.js} +6 -6
  83. package/dist/{dist-BSAt6RhH.js → dist-BTdrwBWP.js} +22 -22
  84. package/dist/{dist-BY018Paw.js → dist-BdqCKQ1O.js} +2 -2
  85. package/dist/dist-BpDH0DEP.js +5 -0
  86. package/dist/dist-BpXhbQXO.js +8 -0
  87. package/dist/{dist-CcWX6tmx.js → dist-BpeiYpG2.js} +2 -2
  88. package/dist/{dist-A2846XWO.js → dist-BwhXBwMd.js} +1 -1
  89. package/dist/dist-ByadAk_L.js +5 -0
  90. package/dist/{dist-abid3KgM.js → dist-C18MUWTj.js} +2 -2
  91. package/dist/{dist-DZORgqKY.js → dist-C2_4pjuS.js} +1 -1
  92. package/dist/{dist-BzEzfugY.js → dist-CFSb_Frm.js} +1 -1
  93. package/dist/dist-CK0g7JvP.js +8 -0
  94. package/dist/{dist-C_Y3oV3C.js → dist-CRmSjkLP.js} +2 -2
  95. package/dist/{dist-hT4QzYX-.js → dist-CSlJrrAw.js} +86 -81
  96. package/dist/{dist-Du8WkPuU.js → dist-CV79CsQ0.js} +2 -2
  97. package/dist/dist-CfzCtiq2.js +5 -0
  98. package/dist/{dist-CoXAujgg.js → dist-D3bdsa1d.js} +4 -4
  99. package/dist/dist-D8JtVFrW.js +8 -0
  100. package/dist/dist-DK2Oocpu.js +6 -0
  101. package/dist/{dist-LTU8Hdvn.js → dist-DZwp8lro.js} +3 -3
  102. package/dist/{dist-t9Kf7xqC.js → dist-DaXJPX8F.js} +2 -2
  103. package/dist/{dist-U4F-tbMs.js → dist-De-GlSAs.js} +246 -184
  104. package/dist/{dist-M9Vag9Y0.js → dist-DgjbnqTg.js} +125 -125
  105. package/dist/dist-DnSu977r.js +5 -0
  106. package/dist/{dist-CxJDU6Bh.js → dist-DviUBLUp.js} +4 -4
  107. package/dist/{dist-CpxNdDkw.js → dist-DwqBJ014.js} +2 -2
  108. package/dist/{dist-Bf7SHuNp.js → dist-JGehap7K.js} +5 -5
  109. package/dist/{dist-Bk75fBZA.js → dist-LpLXa9Lb.js} +2 -2
  110. package/dist/{dist-Bf9f8MuT.js → dist-SXNmlE8A.js} +1 -1
  111. package/dist/dist-UmxJm6sW.js +8 -0
  112. package/dist/dist-aYSBQSyM.js +5 -0
  113. package/dist/dist-kkZ1Ztlh.js +6 -0
  114. package/dist/dist-ngPczwNi.js +5 -0
  115. package/dist/{dist-DgGbNavJ.js → dist-pqIwD8VD.js} +2 -2
  116. package/dist/dist-wQRyxyTV.js +5 -0
  117. package/dist/{dist-Dax--nl9.js → dist-w_gWE5Wf.js} +1 -1
  118. package/dist/{dockerfile-twL37N91.js → dockerfile-B82Pkz_V.js} +1 -1
  119. package/dist/dtd-Dyiazv4N.js +4 -0
  120. package/dist/dylan-D8Fcw7NA.js +4 -0
  121. package/dist/ecl-CjKp8Vii.js +4 -0
  122. package/dist/eiffel-K9ViOX5r.js +4 -0
  123. package/dist/elm-B5NVtRco.js +4 -0
  124. package/dist/{erDiagram-Q2GNP2WA-BU-m41EQ.js → erDiagram-Q2GNP2WA-BcKAHFqF.js} +15 -15
  125. package/dist/erlang-BnLzgk7R.js +4 -0
  126. package/dist/{error-banner-DFPfz_Qf.js → error-banner-DR7o3CbX.js} +68 -68
  127. package/dist/{esm-ga2Bf3O2.js → esm-DKOv6P2M.js} +424 -424
  128. package/dist/esm-k8PIvuZW.js +1180 -0
  129. package/dist/{extends-9MVIxxRo.js → extends-Cq2JYHKy.js} +36 -20
  130. package/dist/{factor-CajWS6mS.js → factor-Bq2mGIHt.js} +1 -1
  131. package/dist/factor-C7f9Jz5R.js +4 -0
  132. package/dist/{flowDiagram-NV44I4VS-CRoXKjGq.js → flowDiagram-NV44I4VS-BRhSg-ro.js} +17 -17
  133. package/dist/{formats-Dzx4J_z1.js → formats-BFhkZJwd.js} +3 -3
  134. package/dist/forth-rGM8jLao.js +4 -0
  135. package/dist/fortran-B3acSe0i.js +4 -0
  136. package/dist/{ganttDiagram-JELNMOA3-7mq5f9cO.js → ganttDiagram-JELNMOA3-CXXCN7LN.js} +10 -10
  137. package/dist/gas-Bb1Vmv_N.js +4 -0
  138. package/dist/gherkin-C9Lyidgd.js +4 -0
  139. package/dist/{gitGraph-G5XIXVHT-DiniR35k.js → gitGraph-G5XIXVHT-BjTx0kww.js} +3 -3
  140. package/dist/{gitGraphDiagram-V2S2FVAM-Dfuokq6w.js → gitGraphDiagram-V2S2FVAM-BOlkMSqK.js} +17 -17
  141. package/dist/{glide-data-editor-CjTu7ukN.js → glide-data-editor--CaN-f27.js} +13 -13
  142. package/dist/groovy-DQk6XcGH.js +4 -0
  143. package/dist/haskell-mV0Vw9gv.js +4 -0
  144. package/dist/haxe-DqxN89zH.js +5 -0
  145. package/dist/{html-to-image-_wGfk8V-.js → html-to-image-DDENewl2.js} +2649 -2607
  146. package/dist/idl-ya8W561J.js +4 -0
  147. package/dist/{info-VBDWY6EO-DVZvGhkQ.js → info-VBDWY6EO-CA67FznA.js} +3 -3
  148. package/dist/infoDiagram-HS3SLOUP-D3TyKnL_.js +30 -0
  149. package/dist/{input-DtsN7xm-.js → input-DStQIuqD.js} +51 -51
  150. package/dist/javascript-CgqgptVu.js +4 -0
  151. package/dist/{journeyDiagram-XKPGCS4Q-8XYSU1GI.js → journeyDiagram-XKPGCS4Q-DEal0aT1.js} +7 -7
  152. package/dist/julia-CFQ-HusI.js +4 -0
  153. package/dist/{kanban-definition-3W4ZIXB7--9pT9z1R.js → kanban-definition-3W4ZIXB7-Dl90wENN.js} +12 -12
  154. package/dist/{katex-9-9QRhxz.js → katex-C4t-BmrK.js} +1 -1
  155. package/dist/{label-WfTSU8L4.js → label-DIk0QoFe.js} +2 -2
  156. package/dist/{line-C5s_12ee.js → line-C43FIPBd.js} +3 -3
  157. package/dist/{linear-B5-AFRiR.js → linear-H_vsH9ao.js} +4 -4
  158. package/dist/livescript-D__3TmDo.js +4 -0
  159. package/dist/{loader-Boph2xIS.js → loader-CTHCI-qe.js} +5 -16
  160. package/dist/lua-Bytcgj_W.js +4 -0
  161. package/dist/main.js +2439 -2199
  162. package/dist/mathematica-DJhvVKvl.js +4 -0
  163. package/dist/mbox-IGHPCjfR.js +4 -0
  164. package/dist/{mermaid-4DMBBIKO-Eg3D4FVz.js → mermaid-4DMBBIKO-FXbOziy9.js} +1 -1
  165. package/dist/{mermaid-BYqXy_NE.js → mermaid-CdSvixW2.js} +47 -47
  166. package/dist/{mermaid-parser.core-C3XRsazI.js → mermaid-parser.core-DoivvxPd.js} +8 -8
  167. package/dist/{mhchem-yiCCuiEF.js → mhchem-EGhUZR1V.js} +1 -1
  168. package/dist/{mindmap-definition-VGOIOE7T-B-4mnfFG.js → mindmap-definition-VGOIOE7T-CCDupjWW.js} +14 -14
  169. package/dist/mirc-tcwvVugm.js +4 -0
  170. package/dist/mllike-Dx91i62r.js +6 -0
  171. package/dist/modelica-_SRt-yU5.js +4 -0
  172. package/dist/mscgen-GZrGS9gt.js +6 -0
  173. package/dist/mumps-Cv3ygyod.js +4 -0
  174. package/dist/nsis-BU7GeGbI.js +4 -0
  175. package/dist/{nsis-ClF3r5Tr.js → nsis-i9_sgigf.js} +1 -1
  176. package/dist/ntriples-CL-FCYXb.js +4 -0
  177. package/dist/{number-overlay-editor-BLJXvX9c.js → number-overlay-editor-Ck_mc_gT.js} +1 -1
  178. package/dist/objects-De59twF-.js +56 -0
  179. package/dist/octave-Dc6_3DIu.js +4 -0
  180. package/dist/{ordinal-ArJavP1Q.js → ordinal-Bkv2-veX.js} +1 -1
  181. package/dist/oz-DpUAJCXf.js +4 -0
  182. package/dist/{packet-DYOGHKS2-34raHOiB.js → packet-DYOGHKS2-Bkgofxf3.js} +3 -3
  183. package/dist/pascal-B17mncXs.js +4 -0
  184. package/dist/perl-BTpK97q9.js +4 -0
  185. package/dist/{pie-VRWISCQL-BaLlzZa3.js → pie-VRWISCQL-B1AMhN_7.js} +3 -3
  186. package/dist/{pieDiagram-ADFJNKIX-Cr3cNpZY.js → pieDiagram-ADFJNKIX-JvXG_6hk.js} +22 -22
  187. package/dist/pig-CFb638Ap.js +4 -0
  188. package/dist/powershell-Cxo-_2A5.js +4 -0
  189. package/dist/{precisionRound-Tqb4mg-H.js → precisionRound-CnHPY_5v.js} +1 -1
  190. package/dist/{process-output-Mh4UrjwM.js → process-output-2QPcgBQg.js} +4 -4
  191. package/dist/properties-BPgT1xTB.js +4 -0
  192. package/dist/protobuf-BgHBaIIK.js +4 -0
  193. package/dist/pug-25-oS0SG.js +4 -0
  194. package/dist/{pug-B_rby2yb.js → pug-BhE2JRSg.js} +1 -1
  195. package/dist/puppet-DarIr20S.js +4 -0
  196. package/dist/purify.es-EnR5yhgI.js +783 -0
  197. package/dist/python-BqmOsBsi.js +4 -0
  198. package/dist/q-D3QJCTup.js +4 -0
  199. package/dist/{quadrantDiagram-AYHSOK5B-BuNL8Q93.js → quadrantDiagram-AYHSOK5B-BqDB9tUC.js} +5 -5
  200. package/dist/r-Cz_yBX4z.js +4 -0
  201. package/dist/{radar-ZZBFDIW7-Ci7bfoZa.js → radar-ZZBFDIW7-C2b7A32s.js} +3 -3
  202. package/dist/{react-vega-B0sAlDTL.js → react-vega-BazDALhI.js} +469 -469
  203. package/dist/{requirementDiagram-UZGBJVZJ-BG2lLUN1.js → requirementDiagram-UZGBJVZJ-KbVt8SPH.js} +14 -14
  204. package/dist/{reveal-component-D0fwa0Mk.js → reveal-component-BQQIEJqn.js} +629 -622
  205. package/dist/rpm-DGOtYwAI.js +5 -0
  206. package/dist/ruby-DBZu4rPc.js +4 -0
  207. package/dist/{sankeyDiagram-TZEHDZUN-DMal8sps.js → sankeyDiagram-TZEHDZUN-DgkF38jx.js} +5 -5
  208. package/dist/sas-Dd1D9qTq.js +4 -0
  209. package/dist/scheme-BmDjvTHX.js +4 -0
  210. package/dist/{sequenceDiagram-WL72ISMW-DT6Tk-Eo.js → sequenceDiagram-WL72ISMW-BDmx9n95.js} +8 -8
  211. package/dist/shell-BL8zFSaj.js +4 -0
  212. package/dist/sieve-BAx2WqUP.js +4 -0
  213. package/dist/smalltalk-CYRzF7VV.js +4 -0
  214. package/dist/sparql-YWaDRO4A.js +4 -0
  215. package/dist/{spec-Cz-Bj1JI.js → spec-CnaxwDqy.js} +4 -4
  216. package/dist/{src-Bf2iLOlr.js → src-DV3ha_nA.js} +1 -1
  217. package/dist/{stateDiagram-FKZM4ZOC-CB_lodq3.js → stateDiagram-FKZM4ZOC-ByOvQf2n.js} +17 -17
  218. package/dist/stateDiagram-v2-4FDKWEC3-C3xqeavR.js +29 -0
  219. package/dist/{step-CWipAYTY.js → step-BqHnkgWE.js} +1 -1
  220. package/dist/stex-B5O-env2.js +4 -0
  221. package/dist/{strings-Dq_j3Rxw.js → strings-BYAhZnQi.js} +354 -354
  222. package/dist/style.css +1 -1
  223. package/dist/stylus-lYsyLFc1.js +4 -0
  224. package/dist/swift-ClQz9z1n.js +4 -0
  225. package/dist/{swiper-component-5HoSsPi1.js → swiper-component-DE94711u.js} +4 -4
  226. package/dist/tcl-B3jhsfqY.js +4 -0
  227. package/dist/textile-Cb1Dw7Aq.js +4 -0
  228. package/dist/{time-CsmIF9YZ.js → time-Bb4A7I6a.js} +4 -4
  229. package/dist/{timeline-definition-IT6M3QCI-NfSKRvH0.js → timeline-definition-IT6M3QCI-CkD_trIn.js} +4 -4
  230. package/dist/{toDate-CWNNlFEX.js → toDate-B3IRfHhw.js} +16 -7
  231. package/dist/toml-nHZhetdO.js +4 -0
  232. package/dist/{tooltip-Czds6Qr8.js → tooltip-B-qh7UPB.js} +3 -3
  233. package/dist/{treemap-GDKQZRPO-Cl6OQh8D.js → treemap-GDKQZRPO-SDux0AV8.js} +3 -3
  234. package/dist/troff-DuJAGWKH.js +4 -0
  235. package/dist/ttcn-BxrcwP21.js +4 -0
  236. package/dist/ttcn-cfg-BAg_9dcc.js +4 -0
  237. package/dist/turtle-zCq949as.js +4 -0
  238. package/dist/{types-C2Ir191_.js → types-DQl7jVYK.js} +1 -1
  239. package/dist/use-vega-container-remeasure-DGNrIQSk.js +27 -0
  240. package/dist/{useAsyncData-KfHB8wQR.js → useAsyncData-CvO8WUy3.js} +1 -1
  241. package/dist/{useDateFormatter-CMnRuVmN.js → useDateFormatter-BSoGim-G.js} +2 -2
  242. package/dist/{useDeepCompareMemoize-nJMtxhm4.js → useDeepCompareMemoize-J3MKRdA4.js} +1 -1
  243. package/dist/{useIframeCapabilities-DWIYvDh7.js → useIframeCapabilities-POcFXHbw.js} +1 -1
  244. package/dist/{useLifecycle-DegSo0lV.js → useLifecycle-DqPxHgAN.js} +3 -3
  245. package/dist/{useTheme-6eZ3GOTS.js → useTheme-XMq9mNf_.js} +65 -29
  246. package/dist/vb-De5hElus.js +4 -0
  247. package/dist/vbscript-Cypcpv4F.js +4 -0
  248. package/dist/{vega-component-DzyyM9fc.js → vega-component-CrFoZT1S.js} +225 -223
  249. package/dist/vega-embed-container-DAQAMjiO.js +22 -0
  250. package/dist/vega-loader.browser-DmpxCJqx.js +1353 -0
  251. package/dist/velocity-Di7l-yhe.js +4 -0
  252. package/dist/verilog-Bzi-S3g2.js +4 -0
  253. package/dist/vhdl-B0ZZITaW.js +4 -0
  254. package/dist/webidl-0sviiRcN.js +4 -0
  255. package/dist/xquery-B4qMVWaB.js +4 -0
  256. package/dist/{xychartDiagram-PRI3JC2R-BvwftqMA.js → xychartDiagram-PRI3JC2R-BSkNxYNw.js} +13 -13
  257. package/dist/yacas-Jt25Fuv8.js +4 -0
  258. package/dist/z80-CrcbYzmp.js +4 -0
  259. package/dist/{zod-CijjQh4u.js → zod-D0yOqoGe.js} +26 -26
  260. package/package.json +3 -1
  261. package/src/__mocks__/requests.ts +3 -0
  262. package/src/components/charts/lazy.tsx +3 -1
  263. package/src/components/charts/vega-embed-container.tsx +18 -0
  264. package/src/components/chat/__tests__/chat-utils.test.ts +244 -1
  265. package/src/components/chat/__tests__/message-queue.test.tsx +121 -0
  266. package/src/components/chat/chat-panel.tsx +196 -67
  267. package/src/components/chat/chat-utils.ts +111 -2
  268. package/src/components/editor/RecoveryButton.tsx +2 -2
  269. package/src/components/editor/SortableCell.tsx +6 -2
  270. package/src/components/editor/__tests__/output-persistence.test.tsx +241 -0
  271. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +153 -0
  272. package/src/components/editor/actions/pair-with-agent-commands.ts +109 -0
  273. package/src/components/editor/actions/pair-with-agent-modal.tsx +20 -64
  274. package/src/components/editor/actions/useNotebookActions.tsx +8 -0
  275. package/src/components/editor/ai/add-cell-with-ai.tsx +14 -5
  276. package/src/components/editor/ai/ai-completion-editor.tsx +4 -1
  277. package/src/components/editor/cell/cell-context-menu.tsx +7 -0
  278. package/src/components/editor/chrome/components/__tests__/feedback-button.test.tsx +221 -0
  279. package/src/components/editor/chrome/components/feedback-button.tsx +308 -77
  280. package/src/components/editor/chrome/panels/packages-panel.tsx +11 -1
  281. package/src/components/editor/chrome/panels/write-secret-modal.tsx +3 -2
  282. package/src/components/editor/columns/__tests__/cell-column.test.tsx +105 -0
  283. package/src/components/editor/columns/cell-column.tsx +34 -4
  284. package/src/components/editor/columns/sortable-column.tsx +24 -4
  285. package/src/components/editor/connections/__tests__/secret-combobox.test.ts +134 -0
  286. package/src/components/editor/connections/database/schemas.ts +35 -27
  287. package/src/components/editor/connections/form-renderers.tsx +42 -110
  288. package/src/components/editor/connections/secret-combobox.tsx +253 -0
  289. package/src/components/editor/connections/storage/schemas.ts +12 -6
  290. package/src/components/editor/file-tree/download.ts +46 -0
  291. package/src/components/editor/file-tree/file-explorer.tsx +3 -21
  292. package/src/components/editor/file-tree/file-viewer.tsx +4 -27
  293. package/src/components/editor/navigation/__tests__/navigation.test.ts +33 -0
  294. package/src/components/editor/navigation/navigation.ts +8 -1
  295. package/src/components/editor/notebook-cell.tsx +203 -106
  296. package/src/components/editor/renderers/__tests__/cells-renderer.test.tsx +66 -0
  297. package/src/components/editor/renderers/cell-array.tsx +26 -13
  298. package/src/components/editor/renderers/cells-renderer.tsx +8 -2
  299. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +29 -0
  300. package/src/components/editor/renderers/slides-layout/types.ts +4 -0
  301. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +19 -19
  302. package/src/components/slides/reveal-component.tsx +37 -17
  303. package/src/components/slides/slide-form.tsx +72 -0
  304. package/src/components/ui/toast.tsx +11 -3
  305. package/src/components/ui/toaster.tsx +65 -9
  306. package/src/core/ai/context/providers/error.ts +6 -158
  307. package/src/core/cells/__tests__/utils.test.ts +59 -0
  308. package/src/core/cells/utils.ts +51 -0
  309. package/src/core/codemirror/completion/__tests__/signature-hint.test.ts +97 -3
  310. package/src/core/codemirror/completion/signature-hint.ts +78 -11
  311. package/src/core/constants.ts +8 -0
  312. package/src/core/diagnostics/__tests__/issue-details.test.ts +173 -0
  313. package/src/core/diagnostics/issue-details.ts +139 -0
  314. package/src/core/errors/__tests__/error-entries.test.ts +25 -0
  315. package/src/core/errors/error-entries.ts +176 -0
  316. package/src/core/islands/__tests__/bootstrap.test.ts +61 -0
  317. package/src/core/islands/__tests__/bridge.test.ts +373 -47
  318. package/src/core/islands/__tests__/main.test.ts +176 -0
  319. package/src/core/islands/__tests__/parse.test.ts +105 -0
  320. package/src/core/islands/bootstrap.ts +28 -5
  321. package/src/core/islands/bridge.ts +140 -39
  322. package/src/core/islands/components/__tests__/web-components.test.tsx +248 -0
  323. package/src/core/islands/components/output-wrapper.tsx +4 -1
  324. package/src/core/islands/components/web-components.tsx +76 -15
  325. package/src/core/islands/constants.ts +1 -0
  326. package/src/core/islands/main.ts +69 -3
  327. package/src/core/islands/parse.ts +70 -23
  328. package/src/core/islands/state.ts +9 -0
  329. package/src/core/islands/worker/__tests__/controller.test.ts +173 -0
  330. package/src/core/islands/worker/worker.tsx +159 -63
  331. package/src/core/network/__tests__/requests-lazy.test.ts +18 -0
  332. package/src/core/network/__tests__/requests-network.test.ts +7 -0
  333. package/src/core/network/requests-lazy.ts +13 -1
  334. package/src/core/network/requests-network.ts +3 -0
  335. package/src/core/network/requests-static.ts +1 -0
  336. package/src/core/network/requests-toasting.tsx +1 -0
  337. package/src/core/network/types.ts +3 -0
  338. package/src/core/runtime/__tests__/runtime.test.ts +64 -0
  339. package/src/core/runtime/runtime.ts +30 -10
  340. package/src/core/wasm/bridge.ts +8 -0
  341. package/src/core/wasm/worker/bootstrap.ts +113 -20
  342. package/src/core/wasm/worker/types.ts +2 -0
  343. package/src/css/app/Cell.css +10 -0
  344. package/src/hooks/__tests__/useHotkey.test.tsx +88 -0
  345. package/src/hooks/useHotkey.ts +29 -4
  346. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +7 -1
  347. package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +26 -1
  348. package/src/plugins/impl/anywidget/__tests__/host.test.ts +6 -9
  349. package/src/plugins/impl/anywidget/__tests__/registry.test.ts +3 -1
  350. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +32 -61
  351. package/src/plugins/impl/anywidget/model-proxy.ts +0 -13
  352. package/src/plugins/impl/anywidget/runtime.ts +1 -0
  353. package/src/plugins/impl/anywidget/widget-binding.ts +8 -34
  354. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +53 -2
  355. package/src/plugins/impl/image-comparison/__tests__/ImageComparisonComponent.test.tsx +71 -0
  356. package/src/plugins/impl/vega/__tests__/use-vega-container-remeasure.test.ts +102 -0
  357. package/src/plugins/impl/vega/use-vega-container-remeasure.ts +39 -0
  358. package/src/plugins/impl/vega/vega-component.tsx +5 -4
  359. package/src/plugins/layout/NavigationMenuPlugin.tsx +156 -25
  360. package/src/theme/__tests__/useTheme.test.ts +68 -0
  361. package/src/theme/useTheme.ts +16 -1
  362. package/dist/apl-Bdc61P1y.js +0 -4
  363. package/dist/architecture-7HQA4BMR-Kyc44TmC.js +0 -6
  364. package/dist/asciiarmor-DVRHDGzT.js +0 -4
  365. package/dist/asn1-BmuKfkfu.js +0 -4
  366. package/dist/assets/__vite-browser-external-BQCLNwri.js +0 -1
  367. package/dist/assets/worker-DAWRHcPq.js +0 -73
  368. package/dist/brainfuck-DPrRpyTV.js +0 -4
  369. package/dist/classDiagram-2ON5EDUG-QjoAcuFE.js +0 -30
  370. package/dist/classDiagram-v2-WZHVMYZB-bUCv4gu2.js +0 -30
  371. package/dist/clojure-DEttQW5T.js +0 -4
  372. package/dist/cmake-jNlx_DaM.js +0 -4
  373. package/dist/cobol-BvvIm5MJ.js +0 -4
  374. package/dist/coffeescript-DTpBMyFU.js +0 -4
  375. package/dist/commonlisp-BmmUG8jb.js +0 -4
  376. package/dist/crystal-BxyqmEWC.js +0 -4
  377. package/dist/css-BGoCtuG3.js +0 -4
  378. package/dist/cypher-BmCbdl3u.js +0 -4
  379. package/dist/d-CFrlbjZt.js +0 -4
  380. package/dist/diff-D6XwL6P8.js +0 -4
  381. package/dist/dist-7QfXoMdB.js +0 -5
  382. package/dist/dist-BEXXyZig.js +0 -5
  383. package/dist/dist-BYj57OV4.js +0 -5
  384. package/dist/dist-BlSvQzNr.js +0 -5
  385. package/dist/dist-CCBlxAgS.js +0 -8
  386. package/dist/dist-CIDTVIUf.js +0 -5
  387. package/dist/dist-CqQyhAM8.js +0 -8
  388. package/dist/dist-CwRu2Xzh.js +0 -5
  389. package/dist/dist-D8CDTVgf.js +0 -6
  390. package/dist/dist-D8DNB0nO.js +0 -8
  391. package/dist/dist-DL6N_q-A.js +0 -5
  392. package/dist/dist-DOFbNV_b.js +0 -8
  393. package/dist/dist-DPrYzMY0.js +0 -6
  394. package/dist/dist-cdmMjgsn.js +0 -5
  395. package/dist/dtd-Bw0lRN0-.js +0 -4
  396. package/dist/dylan-B55eBHTt.js +0 -4
  397. package/dist/ecl-C8G4p0wn.js +0 -4
  398. package/dist/eiffel-BmH46VJl.js +0 -4
  399. package/dist/elm-DhzeFqkl.js +0 -4
  400. package/dist/erlang-CY-wdlsU.js +0 -4
  401. package/dist/esm-M837UxV5.js +0 -1171
  402. package/dist/factor-DWkgl0xw.js +0 -4
  403. package/dist/forth-Cij_ie2t.js +0 -4
  404. package/dist/fortran-Br3X9cfm.js +0 -4
  405. package/dist/gas-DYsGcMN2.js +0 -4
  406. package/dist/gherkin-eVgXQ0fQ.js +0 -4
  407. package/dist/groovy-_NFHIXG7.js +0 -4
  408. package/dist/haskell-D6xNG_bH.js +0 -4
  409. package/dist/haxe-sU_rzAwn.js +0 -5
  410. package/dist/idl-Ds_VbrUx.js +0 -4
  411. package/dist/infoDiagram-HS3SLOUP-CEnzWruK.js +0 -30
  412. package/dist/javascript-CztfIl0i.js +0 -4
  413. package/dist/julia-DDv40QMV.js +0 -4
  414. package/dist/livescript-BEOngLLc.js +0 -4
  415. package/dist/lua-9-7BhQ4Y.js +0 -4
  416. package/dist/mathematica-DDa0Pfxm.js +0 -4
  417. package/dist/mbox-iO03mmoE.js +0 -4
  418. package/dist/mirc-C9z5LT4X.js +0 -4
  419. package/dist/mllike-jGJbdm_C.js +0 -6
  420. package/dist/modelica-DzF7oIEL.js +0 -4
  421. package/dist/mscgen-DB-u125o.js +0 -6
  422. package/dist/mumps-CRTFHhzh.js +0 -4
  423. package/dist/nsis-C4NPTuox.js +0 -4
  424. package/dist/ntriples-BCOoGph1.js +0 -4
  425. package/dist/octave-DTwNlazz.js +0 -4
  426. package/dist/oz-DD38AzSz.js +0 -4
  427. package/dist/pascal-BohSp9jV.js +0 -4
  428. package/dist/perl-f5OutoPM.js +0 -4
  429. package/dist/pig-Dv7wSmHb.js +0 -4
  430. package/dist/powershell-rYgjKB39.js +0 -4
  431. package/dist/properties-BFUNLRDN.js +0 -4
  432. package/dist/protobuf-B9QJQPPv.js +0 -4
  433. package/dist/pug-DzvWpaMC.js +0 -4
  434. package/dist/puppet-B_K-n_xK.js +0 -4
  435. package/dist/purify.es-H92eMd9-.js +0 -557
  436. package/dist/python-CAiFcaA2.js +0 -4
  437. package/dist/q-cLeFIBLK.js +0 -4
  438. package/dist/r-04Y-Wco3.js +0 -4
  439. package/dist/react-vega-B6ncY2Tp.js +0 -9
  440. package/dist/rpm-FUdrIia9.js +0 -5
  441. package/dist/ruby-DMjFXuEW.js +0 -4
  442. package/dist/sas-DzHZxjXK.js +0 -4
  443. package/dist/scheme-DxHd_Rb9.js +0 -4
  444. package/dist/shell-C8Kwypgf.js +0 -4
  445. package/dist/sieve-DdyqOKXZ.js +0 -4
  446. package/dist/smalltalk-pB7X1D9y.js +0 -4
  447. package/dist/sparql-NhBO6oOa.js +0 -4
  448. package/dist/stateDiagram-v2-4FDKWEC3-E0RGjKsm.js +0 -29
  449. package/dist/stex-KfRnSHzF.js +0 -4
  450. package/dist/stylus-SfWSnzPv.js +0 -4
  451. package/dist/swift-jRPdq2zR.js +0 -4
  452. package/dist/tcl-_hpTHGX3.js +0 -4
  453. package/dist/textile-C9h8slqH.js +0 -4
  454. package/dist/toml-DWvtinD4.js +0 -4
  455. package/dist/troff-Dwo_A0y7.js +0 -4
  456. package/dist/ttcn-V--CPFKq.js +0 -4
  457. package/dist/ttcn-cfg-CPSMchTG.js +0 -4
  458. package/dist/turtle-B4rPGBWu.js +0 -4
  459. package/dist/vb-DaMBBd4j.js +0 -4
  460. package/dist/vbscript-BMJQqcE2.js +0 -4
  461. package/dist/vega-loader.browser-CZ-J8Py3.js +0 -1321
  462. package/dist/velocity-CGq2QRq2.js +0 -4
  463. package/dist/verilog-CUNo8F5u.js +0 -4
  464. package/dist/vhdl-CCzA0msW.js +0 -4
  465. package/dist/webidl-CqIMDIBL.js +0 -4
  466. package/dist/xquery-XC5Kbr-1.js +0 -4
  467. package/dist/yacas-CGOv7Dzy.js +0 -4
  468. package/dist/z80-CXhVmi-f.js +0 -4
  469. /package/dist/{Plot-CAYS29h9.js → Plot-YQOuVIei.js} +0 -0
  470. /package/dist/{apl-BCgCq9iM.js → apl-99A7dLQe.js} +0 -0
  471. /package/dist/{array-tvvEqPy7.js → array-O78LT16Y.js} +0 -0
  472. /package/dist/{asciiarmor-BtqU-KJQ.js → asciiarmor-DLEhpFDx.js} +0 -0
  473. /package/dist/{asn1-Dmb-dTMx.js → asn1-CMrcTsT4.js} +0 -0
  474. /package/dist/{asterisk-DaVJJDnV.js → asterisk-CqykImq7.js} +0 -0
  475. /package/dist/{brainfuck-C1HoZKlE.js → brainfuck-ChPt5yBe.js} +0 -0
  476. /package/dist/{chunk-DR5Q36YT-BflwErH1.js → chunk-DR5Q36YT-5Yp2GWwR.js} +0 -0
  477. /package/dist/{click-outside-container-BLPjMamz.js → click-outside-container-BSIeYt4y.js} +0 -0
  478. /package/dist/{clike-CdT0yHjt.js → clike-CE0fXfM_.js} +0 -0
  479. /package/dist/{clojure-CdyrCpUv.js → clojure-QkBEMU-g.js} +0 -0
  480. /package/dist/{cmake-BFlPxym7.js → cmake-CU1jX7Mo.js} +0 -0
  481. /package/dist/{cobol-CcJXewp8.js → cobol-DMOKzzky.js} +0 -0
  482. /package/dist/{coffeescript-DnKuIKRo.js → coffeescript-DjnjLyfk.js} +0 -0
  483. /package/dist/{colors-CQAOa8cK.js → colors-DmiH1bIH.js} +0 -0
  484. /package/dist/{common-keywords-FBrXPTcz.js → common-keywords-D3nPJNQP.js} +0 -0
  485. /package/dist/{commonlisp-B-kok83Z.js → commonlisp-CYd9iOSe.js} +0 -0
  486. /package/dist/{crystal-FYRYjI1I.js → crystal-Dy55yoYG.js} +0 -0
  487. /package/dist/{css-B45lc2V3.js → css-CNU8w3HJ.js} +0 -0
  488. /package/dist/{cypher-DZMLyVY_.js → cypher-q47DGzK7.js} +0 -0
  489. /package/dist/{cytoscape.esm-ayF70frT.js → cytoscape.esm-Dr8XzXWK.js} +0 -0
  490. /package/dist/{d-x-VVT4o9.js → d-jEkaLvxX.js} +0 -0
  491. /package/dist/{defaultLocale-u-3osm0P.js → defaultLocale-BpsHxBd7.js} +0 -0
  492. /package/dist/{defaultLocale-BoHTsDG6.js → defaultLocale-DoeErsX2.js} +0 -0
  493. /package/dist/{diff-Dxe2mpXk.js → diff-vb2-unFN.js} +0 -0
  494. /package/dist/{dist-BGdYVvOu.js → dist-DsoKosxi.js} +0 -0
  495. /package/dist/{dtd-C9VM_Wfu.js → dtd-C9kR-bXa.js} +0 -0
  496. /package/dist/{duckdb-keywords-CvJhR_Yd.js → duckdb-keywords-B6HYCMOT.js} +0 -0
  497. /package/dist/{dylan-DTSnEIFO.js → dylan-BLckrK-V.js} +0 -0
  498. /package/dist/{ebnf-2D4Ctp3y.js → ebnf-Cnp3L9jg.js} +0 -0
  499. /package/dist/{ecl-N04ptnRK.js → ecl-CEsf6XVg.js} +0 -0
  500. /package/dist/{eiffel-Dd8rpqr_.js → eiffel-2KGZNzx6.js} +0 -0
  501. /package/dist/{elm-GT2E866W.js → elm-D2s3K5wF.js} +0 -0
  502. /package/dist/{emotion-is-prop-valid.esm-DzSb5hsH.js → emotion-is-prop-valid.esm-DdVSF4FD.js} +0 -0
  503. /package/dist/{erlang-Cf0Bp5pY.js → erlang-0PMFOndk.js} +0 -0
  504. /package/dist/{esm-BaaaPNGl.js → esm-CuQHjs36.js} +0 -0
  505. /package/dist/{fcl-Ccj8Z5Xd.js → fcl-D9nccAWI.js} +0 -0
  506. /package/dist/{forth-wd_XzGTg.js → forth-DG89iUsu.js} +0 -0
  507. /package/dist/{fortran-DcwUTZFe.js → fortran-ytKsAVvu.js} +0 -0
  508. /package/dist/{gas-DeALIER3.js → gas-Cg2Fm0N2.js} +0 -0
  509. /package/dist/{gherkin-CKTqaJNX.js → gherkin-B87FEnZ-.js} +0 -0
  510. /package/dist/{groovy-Bwdp_d8D.js → groovy-Dcs08AWD.js} +0 -0
  511. /package/dist/{haskell-DCdCcPLK.js → haskell-cwkOuhx6.js} +0 -0
  512. /package/dist/{haxe-DAyktQWJ.js → haxe-DWEo4q10.js} +0 -0
  513. /package/dist/{http-_DVAYWoR.js → http-B8jdG64J.js} +0 -0
  514. /package/dist/{idl-CBuZiRYu.js → idl-WWQwDcRV.js} +0 -0
  515. /package/dist/{init-uv0kkh4g.js → init-DNBbYZd_.js} +0 -0
  516. /package/dist/{javascript-DzigE11c.js → javascript-BeR74dxD.js} +0 -0
  517. /package/dist/{julia-PwfB-0Cm.js → julia-UlvCUYGL.js} +0 -0
  518. /package/dist/{katex-C_XRmjAP.js → katex-Bld7b-fk.js} +0 -0
  519. /package/dist/{livescript-BJLz1EbT.js → livescript-GPmFcmYV.js} +0 -0
  520. /package/dist/{lua-ZC-XC2jf.js → lua-DYoT_0zM.js} +0 -0
  521. /package/dist/{main-Tj_-QTyF.js → main-B1Jo_8pC.js} +0 -0
  522. /package/dist/{math-DFcdCCU8.js → math-CBNc2Ib0.js} +0 -0
  523. /package/dist/{mathematica-DCYMx6qB.js → mathematica-DSFIQlbG.js} +0 -0
  524. /package/dist/{mbox-OxMK_9XI.js → mbox-ej8lFMdL.js} +0 -0
  525. /package/dist/{micromark-factory-space-DF2w36zS.js → micromark-factory-space-CwHmg6iz.js} +0 -0
  526. /package/dist/{mirc-nJVyhA0H.js → mirc-CAdIdvHQ.js} +0 -0
  527. /package/dist/{mllike-DRO89bsU.js → mllike-CjTB1lHF.js} +0 -0
  528. /package/dist/{modelica-Don3E6ZD.js → modelica-BB68FYMa.js} +0 -0
  529. /package/dist/{mscgen-DJfqD3bN.js → mscgen-BkbzgGGI.js} +0 -0
  530. /package/dist/{mumps-SjGTvDYL.js → mumps-Cu-28E9F.js} +0 -0
  531. /package/dist/{nginx-DasThI7R.js → nginx-C1ofKPst.js} +0 -0
  532. /package/dist/{node-sql-parser-B8nBD36q.js → node-sql-parser-DLl_zNw0.js} +0 -0
  533. /package/dist/{ntriples-CNBKRl3I.js → ntriples-D9cQiZxZ.js} +0 -0
  534. /package/dist/{octave-DdeVHNlx.js → octave-BvtAnPX0.js} +0 -0
  535. /package/dist/{once-DPuqGUeo.js → once-B60G2fuJ.js} +0 -0
  536. /package/dist/{oz-CcKSoNvN.js → oz-COaVHk2E.js} +0 -0
  537. /package/dist/{pascal-6leftwNj.js → pascal-BFpqVD2x.js} +0 -0
  538. /package/dist/{path-BGaWgPKg.js → path-DwWbhZFI.js} +0 -0
  539. /package/dist/{perl-BhJIwWzN.js → perl-DaiORxHP.js} +0 -0
  540. /package/dist/{pig-r-xDHqRf.js → pig-DFzRhmsF.js} +0 -0
  541. /package/dist/{powershell-D-BELeNi.js → powershell-BG2LQNKN.js} +0 -0
  542. /package/dist/{properties-CnuDhbll.js → properties-CqJJR5QY.js} +0 -0
  543. /package/dist/{protobuf-CO8RBhvX.js → protobuf-WwDYV1yY.js} +0 -0
  544. /package/dist/{puppet-NmXHjLy8.js → puppet-QNY3w_uN.js} +0 -0
  545. /package/dist/{python-DAQXi720.js → python-4QrQ3Ugi.js} +0 -0
  546. /package/dist/{q-DlikXfV0.js → q-DhwXuxE2.js} +0 -0
  547. /package/dist/{r-CuohilwT.js → r-Df-nkR25.js} +0 -0
  548. /package/dist/{range-C-rmrM1O.js → range-BOiA8qqU.js} +0 -0
  549. /package/dist/{rpm-0Pjwp0Pb.js → rpm-Cokue07s.js} +0 -0
  550. /package/dist/{ruby-Dq8NJTDG.js → ruby-DrYcL3qF.js} +0 -0
  551. /package/dist/{sas-CuwonyVP.js → sas-CoiPirA5.js} +0 -0
  552. /package/dist/{scheme-CYU-RRIf.js → scheme-CwFLjzHv.js} +0 -0
  553. /package/dist/{semaphore-CNDGTzkX.js → semaphore-C8rmHdhj.js} +0 -0
  554. /package/dist/{shell-COPmX2qE.js → shell-BFV-R24I.js} +0 -0
  555. /package/dist/{sieve-B_3zyLne.js → sieve-CxwXF5T9.js} +0 -0
  556. /package/dist/{simple-mode-DSBniks8.js → simple-mode-DTaJtKPt.js} +0 -0
  557. /package/dist/{smalltalk-DRft7iPv.js → smalltalk-QivVOCtX.js} +0 -0
  558. /package/dist/{solr-RZ9uTl59.js → solr-BLvysN-c.js} +0 -0
  559. /package/dist/{sparql-CN6qj55H.js → sparql-nKsFk8j7.js} +0 -0
  560. /package/dist/{spreadsheet-BNNUNXA2.js → spreadsheet-BWc8C2FT.js} +0 -0
  561. /package/dist/{sql-B4x8IkwU.js → sql-CWfUjlV1.js} +0 -0
  562. /package/dist/{stex-BIsgBmK4.js → stex-DtMAhV4-.js} +0 -0
  563. /package/dist/{stylus-Bn_ZjOQ3.js → stylus-BLKQAycn.js} +0 -0
  564. /package/dist/{swift-BLUJhMbz.js → swift-CJoKqiKj.js} +0 -0
  565. /package/dist/{tcl-C86fxecl.js → tcl-YTeYFNUc.js} +0 -0
  566. /package/dist/{textile-DmHh2rsK.js → textile-C6rKQqMQ.js} +0 -0
  567. /package/dist/{tiddlywiki-DI0mF2WJ.js → tiddlywiki-ZXwTHGNT.js} +0 -0
  568. /package/dist/{tiki-2HU6XLLn.js → tiki-C628O_u4.js} +0 -0
  569. /package/dist/{timer-YZl28NYN.js → timer-BpI_FKSA.js} +0 -0
  570. /package/dist/{toml-GWANRNAD.js → toml-DxlPGbRy.js} +0 -0
  571. /package/dist/{treemap-D-ka1hvx.js → treemap-DY3NBr79.js} +0 -0
  572. /package/dist/{troff-BHTsomIy.js → troff-DFCfH7Ku.js} +0 -0
  573. /package/dist/{ttcn-DQuhn5Mn.js → ttcn-DAW-ERVP.js} +0 -0
  574. /package/dist/{ttcn-cfg-HjFYtdB-.js → ttcn-cfg-CpJ8b7EN.js} +0 -0
  575. /package/dist/{turtle-nCay33Nv.js → turtle-BneV2f8L.js} +0 -0
  576. /package/dist/{vb-BG-XlqqJ.js → vb-D973Vxxh.js} +0 -0
  577. /package/dist/{vbscript-B6vyW0-D.js → vbscript-Dckaq3YO.js} +0 -0
  578. /package/dist/{velocity-CWegueqO.js → velocity-DKty-GUC.js} +0 -0
  579. /package/dist/{verilog-CzSQm4cG.js → verilog-aNaK_biA.js} +0 -0
  580. /package/dist/{vhdl-DqnNVL7r.js → vhdl-CQuehnQy.js} +0 -0
  581. /package/dist/{webidl-DXEUpDWH.js → webidl-Bhg8vaMr.js} +0 -0
  582. /package/dist/{xquery-Ba_NB5bD.js → xquery-D2q16GaM.js} +0 -0
  583. /package/dist/{yacas-HKQU6hyk.js → yacas-DHGOHnNa.js} +0 -0
  584. /package/dist/{z80-CXkHXLdj.js → z80-BPhTmO22.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
- import { render, waitFor } from "@testing-library/react";
3
+ import { act, render, waitFor } from "@testing-library/react";
4
+ import { Provider, createStore } from "jotai";
4
5
  import {
5
6
  afterEach,
6
7
  beforeEach,
@@ -10,6 +11,7 @@ import {
10
11
  type MockInstance,
11
12
  vi,
12
13
  } from "vitest";
14
+ import { islandsPendingInitialRunsAtom } from "@/core/islands/state";
13
15
  import type { IPluginProps } from "@/plugins/types";
14
16
  import { visibleForTesting } from "../AnyWidgetPlugin";
15
17
  import { Model } from "../model";
@@ -88,6 +90,29 @@ describe("AnyWidgetSlot", () => {
88
90
  });
89
91
  });
90
92
 
93
+ it("waits for islands hydration before resolving the model", async () => {
94
+ const islandsStore = createStore();
95
+ islandsStore.set(islandsPendingInitialRunsAtom, new Set([1]));
96
+ const createViewSpy = vi.spyOn(WIDGET_REGISTRY, "createView");
97
+
98
+ render(
99
+ <Provider store={islandsStore}>
100
+ <AnyWidgetSlot {...props(modelId)} />
101
+ </Provider>,
102
+ );
103
+
104
+ expect(createViewSpy).not.toHaveBeenCalled();
105
+
106
+ act(() => {
107
+ islandsStore.set(islandsPendingInitialRunsAtom, new Set());
108
+ });
109
+
110
+ await waitFor(() => {
111
+ expect(createViewSpy).toHaveBeenCalledOnce();
112
+ });
113
+ createViewSpy.mockRestore();
114
+ });
115
+
91
116
  it("aborts the runtime-owned view on unmount", async () => {
92
117
  const { unmount } = render(<AnyWidgetSlot {...props(modelId)} />);
93
118
  await waitFor(() => {
@@ -277,25 +277,22 @@ describe("WidgetBinding receives a host in render props", () => {
277
277
  });
278
278
  });
279
279
 
280
- describe("host-mounted views hydrate like display-mounted ones", () => {
281
- it("replays current state to a child's render listeners", async () => {
282
- const childId = asModelId("host-hydration-child");
280
+ describe("host-mounted views", () => {
281
+ it("render with the child's current model state", async () => {
282
+ const childId = asModelId("host-child-state");
283
283
  const parentController = new AbortController();
284
284
  const getModuleSpy = vi.spyOn(WIDGET_DEF_REGISTRY, "getModule");
285
285
  try {
286
286
  const childWidget = {
287
287
  render: vi.fn(({ model, el }) => {
288
- el.textContent = "count is 5";
289
- model.on("change:count", () => {
290
- el.textContent = `count is ${model.get("count")}`;
291
- });
288
+ el.textContent = `count is ${model.get("count")}`;
292
289
  }),
293
290
  };
294
291
  const childModel = new Model<ModelState>({ count: 8 }, createMockComm());
295
292
  WIDGET_REGISTRY.setModel(childId, childModel);
296
293
  WIDGET_REGISTRY.setSpec(childId, {
297
- url: "./@file/10-host-hydration-child.js",
298
- hash: "hash-host-hydration-child",
294
+ url: "./@file/10-host-child-state.js",
295
+ hash: "hash-host-child-state",
299
296
  });
300
297
  getModuleSpy.mockResolvedValue({ default: childWidget });
301
298
 
@@ -210,7 +210,7 @@ describe("WidgetRegistry.getWidget", () => {
210
210
  });
211
211
 
212
212
  afterEach(() => {
213
- getModuleSpy.mockRestore();
213
+ vi.restoreAllMocks();
214
214
  });
215
215
 
216
216
  it("binds an undisplayed widget from its ESM spec", async () => {
@@ -309,6 +309,7 @@ describe("WidgetRegistry.getWidget", () => {
309
309
  });
310
310
 
311
311
  it("rejects with the AFM error when the module has no usable exports", async () => {
312
+ const invalidateSpy = vi.spyOn(WIDGET_DEF_REGISTRY, "invalidate");
312
313
  getModuleSpy.mockResolvedValue({ notAWidget: true });
313
314
 
314
315
  const model = new Model<ModelState>({ count: 0 }, createMockComm());
@@ -318,6 +319,7 @@ describe("WidgetRegistry.getWidget", () => {
318
319
  await expect(registry.getWidget(testId)).rejects.toThrow(
319
320
  /missing a default export/,
320
321
  );
322
+ expect(invalidateSpy).toHaveBeenCalledWith(SPEC.hash);
321
323
  });
322
324
 
323
325
  it("rejects when the model never arrives", async () => {
@@ -95,6 +95,16 @@ describe("WidgetDefRegistry", () => {
95
95
  promise1.catch(() => undefined);
96
96
  });
97
97
 
98
+ it("should retry a new URL after invalidating the same hash", () => {
99
+ const promise1 = getModule(registry, "http://localhost/a.js", "same-hash");
100
+ registry.invalidate("same-hash");
101
+ const promise2 = getModule(registry, "http://localhost/b.js", "same-hash");
102
+
103
+ expect(promise1).not.toBe(promise2);
104
+ promise1.catch(() => undefined);
105
+ promise2.catch(() => undefined);
106
+ });
107
+
98
108
  it("should create different promises for different hashes", () => {
99
109
  const promise1 = getModule(registry, "http://localhost/a.js", "hash-a");
100
110
  const promise2 = getModule(registry, "http://localhost/b.js", "hash-b");
@@ -337,13 +347,12 @@ describe("WidgetBinding", () => {
337
347
  { el: document.createElement("div") },
338
348
  { signal: controller.signal },
339
349
  );
340
- // Called once by the hydration replay at mount, once by the set.
341
350
  model.set("count", 1);
342
- expect(onCount).toHaveBeenCalledTimes(2);
351
+ expect(onCount).toHaveBeenCalledTimes(1);
343
352
 
344
353
  controller.abort();
345
354
  model.set("count", 2);
346
- expect(onCount).toHaveBeenCalledTimes(2);
355
+ expect(onCount).toHaveBeenCalledTimes(1);
347
356
  });
348
357
 
349
358
  it("should auto-clear initialize listeners on destroy", async () => {
@@ -366,92 +375,54 @@ describe("WidgetBinding", () => {
366
375
  });
367
376
  });
368
377
 
369
- describe("WidgetBinding hydration replay", () => {
370
- it("replays current state to render listeners exactly once", async () => {
378
+ describe("WidgetBinding render listeners", () => {
379
+ it("fire only for changes after mount, never for pre-existing state", async () => {
371
380
  const model = new Model<ModelState>({ count: 8 }, createMockComm());
372
- const el = document.createElement("div");
373
- const widgetDef = {
374
- render: vi.fn(({ model, el }) => {
375
- // A widget view that starts with a local default and relies on
376
- // change events for hydration.
377
- el.textContent = "count is 5";
378
- model.on("change:count", () => {
379
- el.textContent = `count is ${model.get("count")}`;
380
- });
381
- }),
382
- };
383
- const binding = await createBinding(widgetDef, model);
384
-
385
- const controller = new AbortController();
386
- await binding.createView({ el }, { signal: controller.signal });
387
- expect(el.textContent).toBe("count is 8");
388
- });
389
-
390
- it("does not re-fire listeners of already-mounted views", async () => {
391
- // Mounting view B must not double-paint view A: the replay is
392
- // scoped to the listeners the new render attached.
393
- const model = new Model<ModelState>({ count: 0 }, createMockComm());
394
- const listeners: Array<ReturnType<typeof vi.fn>> = [];
381
+ const onCount = vi.fn();
382
+ const onAnyChange = vi.fn();
395
383
  const widgetDef = {
396
384
  render: vi.fn(({ model }) => {
397
- const listener = vi.fn();
398
- listeners.push(listener);
399
- model.on("change:count", listener);
385
+ model.on("change:count", onCount);
386
+ model.on("change", onAnyChange);
400
387
  }),
401
388
  };
402
389
  const binding = await createBinding(widgetDef, model);
403
390
  const controller = new AbortController();
404
-
405
391
  await binding.createView(
406
392
  { el: document.createElement("div") },
407
393
  { signal: controller.signal },
408
394
  );
409
- expect(listeners[0]).toHaveBeenCalledTimes(1);
395
+ expect(onCount).not.toHaveBeenCalled();
396
+ expect(onAnyChange).not.toHaveBeenCalled();
410
397
 
411
- await binding.createView(
412
- { el: document.createElement("div") },
413
- { signal: controller.signal },
414
- );
415
- // View B's listener hydrated once; view A's was left alone.
416
- expect(listeners[1]).toHaveBeenCalledTimes(1);
417
- expect(listeners[0]).toHaveBeenCalledTimes(1);
398
+ model.set("count", 9);
399
+ expect(onCount).toHaveBeenCalledTimes(1);
400
+ expect(onCount).toHaveBeenCalledWith(9);
418
401
  });
419
402
 
420
- it("replays the any-change event to its listeners", async () => {
421
- const model = new Model<ModelState>({ count: 1 }, createMockComm());
422
- const onAnyChange = vi.fn();
403
+ it("mounting a second view does not fire the first view's listeners", async () => {
404
+ const model = new Model<ModelState>({ count: 0 }, createMockComm());
405
+ const listeners: Array<ReturnType<typeof vi.fn>> = [];
423
406
  const widgetDef = {
424
407
  render: vi.fn(({ model }) => {
425
- model.on("change", onAnyChange);
408
+ const listener = vi.fn();
409
+ listeners.push(listener);
410
+ model.on("change:count", listener);
426
411
  }),
427
412
  };
428
413
  const binding = await createBinding(widgetDef, model);
429
414
  const controller = new AbortController();
415
+
430
416
  await binding.createView(
431
417
  { el: document.createElement("div") },
432
418
  { signal: controller.signal },
433
419
  );
434
- expect(onAnyChange).toHaveBeenCalledTimes(1);
435
- });
436
-
437
- it("does not replay initialize listeners", async () => {
438
- // The guarantee is per-view: initialize listeners existed before
439
- // any view, and replaying at them would fire once per mount.
440
- const model = new Model<ModelState>({ count: 1 }, createMockComm());
441
- const initListener = vi.fn();
442
- const widgetDef = {
443
- initialize: vi.fn(({ model }) => {
444
- model.on("change:count", initListener);
445
- }),
446
- render: vi.fn(),
447
- };
448
- const binding = await createBinding(widgetDef, model);
449
- const controller = new AbortController();
450
420
  await binding.createView(
451
421
  { el: document.createElement("div") },
452
422
  { signal: controller.signal },
453
423
  );
454
- expect(initListener).not.toHaveBeenCalled();
424
+ expect(listeners[0]).not.toHaveBeenCalled();
425
+ expect(listeners[1]).not.toHaveBeenCalled();
455
426
  });
456
427
 
457
428
  it("clears the element before rendering into it", async () => {
@@ -5,15 +5,6 @@ import type { ModelState } from "./types";
5
5
 
6
6
  type ModelEventCallback = Parameters<AnyModel<ModelState>["on"]>[1];
7
7
 
8
- /**
9
- * A listener registered through a model proxy (see the hydration
10
- * replay in `WidgetBinding.createView`).
11
- */
12
- export interface ProxyRegistration {
13
- event: string;
14
- callback: ModelEventCallback;
15
- }
16
-
17
8
  /**
18
9
  * Wrap a model so every `on()` call from inside `initialize` or `render`
19
10
  * is auto-tied to a lifetime `AbortSignal`. When the signal aborts,
@@ -27,14 +18,11 @@ export interface ProxyRegistration {
27
18
  * The proxy is purely a host-side ergonomic helper. The widget author
28
19
  * still writes `model.on("change:foo", handler)` exactly as before; the
29
20
  * cleanup signal is supplied transparently.
30
- *
31
- * `onRegister`, when given, observes each `on()` registration.
32
21
  */
33
22
  // oxlint-disable-next-line marimo/prefer-object-params -- concise internal helper used at protocol call sites
34
23
  export function modelProxy<T extends ModelState>(
35
24
  model: AnyModel<T>,
36
25
  signal: AbortSignal,
37
- onRegister?: (registration: ProxyRegistration) => void,
38
26
  ): AnyModel<T> {
39
27
  return {
40
28
  get(key) {
@@ -55,7 +43,6 @@ export function modelProxy<T extends ModelState>(
55
43
  signal.addEventListener("abort", () => model.off(name, callback), {
56
44
  once: true,
57
45
  });
58
- onRegister?.({ event: name, callback });
59
46
  },
60
47
  off(name?: string | null, callback?: ModelEventCallback | null): void {
61
48
  model.off(name ?? null, callback ?? null);
@@ -211,6 +211,7 @@ export class WidgetRuntime {
211
211
  });
212
212
  const widget = resolveAnyWidget(mod, spec.url);
213
213
  if (!widget) {
214
+ WIDGET_DEF_REGISTRY.invalidate(spec.hash);
214
215
  throw getInvalidAnyWidgetModuleError(mod, spec.url);
215
216
  }
216
217
  return WidgetBinding.create({
@@ -12,7 +12,7 @@ import { isTrustedVirtualFileUrl } from "@/plugins/core/trusted-url";
12
12
  import { Logger } from "@/utils/Logger";
13
13
  import type { Host } from "./host";
14
14
  import type { Model } from "./model";
15
- import { modelProxy, type ProxyRegistration } from "./model-proxy";
15
+ import { modelProxy } from "./model-proxy";
16
16
  import type { ModelState } from "./types";
17
17
 
18
18
  export const experimental: Experimental = {
@@ -80,6 +80,10 @@ class WidgetDefRegistry {
80
80
  return promise;
81
81
  }
82
82
 
83
+ invalidate(jsHash: string): void {
84
+ this.#cache.delete(jsHash);
85
+ }
86
+
83
87
  async #doImport(
84
88
  jsUrl: string,
85
89
  opts: { kernelAuthored?: boolean } = {},
@@ -266,9 +270,8 @@ export class WidgetBinding<T extends ModelState = ModelState> {
266
270
  * when the caller's `signal` fires or the binding is destroyed, and
267
271
  * listeners registered inside `render` auto-clear on abort.
268
272
  *
269
- * Hydration guarantee: listeners attached during `render` observe
270
- * current model state exactly once, after `render` settles. Scoped
271
- * to this view's listeners; re-firing at other views double-paints.
273
+ * `render` reads current state via `model.get`; change listeners
274
+ * observe only subsequent changes, matching Jupyter semantics.
272
275
  */
273
276
  async createView(
274
277
  target: { el: HTMLElement },
@@ -305,11 +308,8 @@ export class WidgetBinding<T extends ModelState = ModelState> {
305
308
  // Each view gets a host scoped to its own signal so child views tear
306
309
  // down with this view.
307
310
  const host = this.#createHost(renderSignal);
308
- const registrations: ProxyRegistration[] = [];
309
311
  const renderCleanup = await widget.render({
310
- model: modelProxy(this.#model, renderSignal, (registration) =>
311
- registrations.push(registration),
312
- ),
312
+ model: modelProxy(this.#model, renderSignal),
313
313
  el: target.el,
314
314
  experimental,
315
315
  signal: renderSignal,
@@ -333,7 +333,6 @@ export class WidgetBinding<T extends ModelState = ModelState> {
333
333
  once: true,
334
334
  });
335
335
  }
336
- this.#replayState(registrations, renderSignal);
337
336
  }
338
337
 
339
338
  #trackCleanup(cleanup: Cleanup, reason: string): Promise<void> {
@@ -343,31 +342,6 @@ export class WidgetBinding<T extends ModelState = ModelState> {
343
342
  return task;
344
343
  }
345
344
 
346
- /**
347
- * The hydration guarantee documented on `createView`.
348
- */
349
- #replayState(
350
- registrations: readonly ProxyRegistration[],
351
- renderSignal: AbortSignal,
352
- ): void {
353
- const changePrefix = "change:";
354
- for (const { event, callback } of registrations) {
355
- if (renderSignal.aborted) {
356
- return;
357
- }
358
- try {
359
- if (event.startsWith(changePrefix)) {
360
- const key = event.slice(changePrefix.length);
361
- callback(this.#model.get(key));
362
- } else if (event === "change") {
363
- callback();
364
- }
365
- } catch (error) {
366
- Logger.error("[WidgetBinding] Error replaying state", error);
367
- }
368
- }
369
- }
370
-
371
345
  /**
372
346
  * Destroy this generation, running initialize/render cleanups and
373
347
  * clearing listeners registered through its model proxies.
@@ -12,6 +12,13 @@ export interface ImageComparisonData {
12
12
  height?: string;
13
13
  }
14
14
 
15
+ // Truncate long sources (e.g. base64 data URLs) so error messages stay
16
+ // readable.
17
+ function truncateSrc(src: string): string {
18
+ const MAX_LENGTH = 100;
19
+ return src.length > MAX_LENGTH ? `${src.slice(0, MAX_LENGTH)}…` : src;
20
+ }
21
+
15
22
  const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
16
23
  beforeSrc,
17
24
  afterSrc,
@@ -20,17 +27,61 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
20
27
  width,
21
28
  height,
22
29
  }) => {
30
+ const [failedSrcs, setFailedSrcs] = React.useState<ReadonlySet<string>>(
31
+ () => new Set(),
32
+ );
33
+
34
+ React.useEffect(() => {
35
+ setFailedSrcs(new Set());
36
+ }, [beforeSrc, afterSrc]);
37
+
38
+ const handleError = React.useCallback((src: string) => {
39
+ setFailedSrcs((prev) => new Set(prev).add(src));
40
+ }, []);
41
+
23
42
  const containerStyle: React.CSSProperties = {
24
43
  width: width || "100%",
25
44
  height: height || (direction === "vertical" ? "400px" : "auto"),
26
45
  maxWidth: "100%",
46
+ // The slider derives its height entirely from its (loaded) images, so a
47
+ // broken/slow-loading source would otherwise collapse it to nothing and
48
+ // render an empty output. Keep a minimum height so it stays visible.
49
+ minHeight: "2rem",
27
50
  };
28
51
 
52
+ // If an image fails to load, the slider collapses to nothing; surface a
53
+ // visible error instead of silently rendering an empty output.
54
+ if (failedSrcs.size > 0) {
55
+ return (
56
+ <div
57
+ style={containerStyle}
58
+ className="flex items-center justify-center rounded border border-destructive/40 bg-destructive/5 p-3 text-sm text-destructive"
59
+ >
60
+ <span>
61
+ Failed to load {failedSrcs.size > 1 ? "images" : "image"}:{" "}
62
+ {[...failedSrcs].map((src) => `"${truncateSrc(src)}"`).join(", ")}
63
+ </span>
64
+ </div>
65
+ );
66
+ }
67
+
29
68
  return (
30
69
  <div style={containerStyle}>
31
70
  <ImgComparisonSlider value={value} direction={direction}>
32
- <img slot="first" src={beforeSrc} alt="Before" width="100%" />
33
- <img slot="second" src={afterSrc} alt="After" width="100%" />
71
+ <img
72
+ slot="first"
73
+ src={beforeSrc}
74
+ alt="Before"
75
+ width="100%"
76
+ onError={() => handleError(beforeSrc)}
77
+ />
78
+ <img
79
+ slot="second"
80
+ src={afterSrc}
81
+ alt="After"
82
+ width="100%"
83
+ onError={() => handleError(afterSrc)}
84
+ />
34
85
  </ImgComparisonSlider>
35
86
  </div>
36
87
  );
@@ -0,0 +1,71 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { fireEvent, render } from "@testing-library/react";
4
+ import { describe, expect, it } from "vitest";
5
+ import ImageComparisonComponent from "../ImageComparisonComponent";
6
+
7
+ const baseProps = {
8
+ beforeSrc: "before.png",
9
+ afterSrc: "after.png",
10
+ value: 50,
11
+ direction: "horizontal" as const,
12
+ };
13
+
14
+ describe("ImageComparisonComponent", () => {
15
+ it("renders the comparison slider with both images", () => {
16
+ const { getByAltText, container } = render(
17
+ <ImageComparisonComponent {...baseProps} />,
18
+ );
19
+ expect(getByAltText("Before")).toBeTruthy();
20
+ expect(getByAltText("After")).toBeTruthy();
21
+ expect(container.querySelector("img-comparison-slider")).toBeTruthy();
22
+ });
23
+
24
+ it("shows a visible error instead of collapsing when an image fails to load", () => {
25
+ const brokenSrc = "https://example.com/does-not-exist.png";
26
+ const { getByAltText, queryByText, container } = render(
27
+ <ImageComparisonComponent {...baseProps} beforeSrc={brokenSrc} />,
28
+ );
29
+
30
+ // No error before the image fails.
31
+ expect(queryByText(/Failed to load/)).toBeNull();
32
+
33
+ fireEvent.error(getByAltText("Before"));
34
+
35
+ // The slider is replaced with a visible error mentioning the source, so
36
+ // the output is never a silent blank.
37
+ expect(container.querySelector("img-comparison-slider")).toBeNull();
38
+ const error = queryByText(/Failed to load image/);
39
+ expect(error).toBeTruthy();
40
+ expect(error?.textContent).toContain(brokenSrc);
41
+ });
42
+
43
+ it("clears the error when the sources change so new images can load", () => {
44
+ const brokenSrc = "https://example.com/does-not-exist.png";
45
+ const { getByAltText, queryByText, container, rerender } = render(
46
+ <ImageComparisonComponent {...baseProps} beforeSrc={brokenSrc} />,
47
+ );
48
+
49
+ fireEvent.error(getByAltText("Before"));
50
+ expect(queryByText(/Failed to load/)).toBeTruthy();
51
+
52
+ // Re-render with a new source (e.g. the user fixed the notebook): the error
53
+ // should clear and the slider should mount again rather than stay stuck.
54
+ rerender(<ImageComparisonComponent {...baseProps} beforeSrc="fixed.png" />);
55
+ expect(queryByText(/Failed to load/)).toBeNull();
56
+ expect(container.querySelector("img-comparison-slider")).toBeTruthy();
57
+ });
58
+
59
+ it("truncates long sources (e.g. data URLs) in the error message", () => {
60
+ const longSrc = `data:image/png;base64,${"A".repeat(200)}`;
61
+ const { getByAltText, queryByText } = render(
62
+ <ImageComparisonComponent {...baseProps} afterSrc={longSrc} />,
63
+ );
64
+
65
+ fireEvent.error(getByAltText("After"));
66
+
67
+ const error = queryByText(/Failed to load image/);
68
+ expect(error?.textContent).toContain("…");
69
+ expect(error?.textContent).not.toContain("A".repeat(200));
70
+ });
71
+ });
@@ -0,0 +1,102 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { renderHook } from "@testing-library/react";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { useRef } from "react";
6
+ import { useVegaContainerRemeasure } from "../use-vega-container-remeasure";
7
+
8
+ describe("useVegaContainerRemeasure", () => {
9
+ let observers: FakeResizeObserver[];
10
+ let OriginalResizeObserver: typeof ResizeObserver;
11
+
12
+ class FakeResizeObserver {
13
+ callback: ResizeObserverCallback;
14
+ el: Element | null = null;
15
+
16
+ constructor(callback: ResizeObserverCallback) {
17
+ this.callback = callback;
18
+ observers.push(this);
19
+ }
20
+
21
+ observe(el: Element) {
22
+ this.el = el;
23
+ }
24
+
25
+ disconnect() {
26
+ this.el = null;
27
+ }
28
+
29
+ unobserve() {
30
+ this.el = null;
31
+ }
32
+
33
+ trigger(width: number) {
34
+ this.callback(
35
+ [
36
+ {
37
+ target: this.el!,
38
+ contentRect: {
39
+ width,
40
+ height: 100,
41
+ x: 0,
42
+ y: 0,
43
+ top: 0,
44
+ left: 0,
45
+ bottom: 100,
46
+ right: width,
47
+ toJSON: () => ({}),
48
+ },
49
+ borderBoxSize: [],
50
+ contentBoxSize: [],
51
+ devicePixelContentBoxSize: [],
52
+ } satisfies ResizeObserverEntry,
53
+ ],
54
+ this,
55
+ );
56
+ }
57
+ }
58
+
59
+ beforeEach(() => {
60
+ observers = [];
61
+ OriginalResizeObserver = globalThis.ResizeObserver;
62
+ globalThis.ResizeObserver =
63
+ FakeResizeObserver as unknown as typeof ResizeObserver;
64
+ vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => {
65
+ cb(0);
66
+ return 0;
67
+ });
68
+ });
69
+
70
+ afterEach(() => {
71
+ globalThis.ResizeObserver = OriginalResizeObserver;
72
+ vi.unstubAllGlobals();
73
+ });
74
+
75
+ it("dispatches window resize when the container gains width", () => {
76
+ const el = document.createElement("div");
77
+ Object.defineProperty(el, "clientWidth", { value: 0, configurable: true });
78
+ const dispatchSpy = vi.spyOn(window, "dispatchEvent");
79
+
80
+ renderHook(() => {
81
+ const ref = useRef<HTMLDivElement>(el);
82
+ useVegaContainerRemeasure(ref, true);
83
+ });
84
+
85
+ expect(observers).toHaveLength(1);
86
+ observers[0].trigger(0);
87
+ expect(dispatchSpy).not.toHaveBeenCalled();
88
+
89
+ observers[0].trigger(640);
90
+ expect(dispatchSpy).toHaveBeenCalledWith(expect.any(Event));
91
+ expect(dispatchSpy.mock.calls[0][0].type).toBe("resize");
92
+ });
93
+
94
+ it("is a no-op when disabled", () => {
95
+ const el = document.createElement("div");
96
+ renderHook(() => {
97
+ const ref = useRef<HTMLDivElement>(el);
98
+ useVegaContainerRemeasure(ref, false);
99
+ });
100
+ expect(observers).toHaveLength(0);
101
+ });
102
+ });
@@ -0,0 +1,39 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { type RefObject, useEffect } from "react";
4
+
5
+ /**
6
+ * Vega-Lite's width:"container" only remeasures on window.resize — not when a
7
+ * parent goes from display:none / zero-size to a real layout size. Observe the
8
+ * embed host and dispatch the event Vega already listens for when the container
9
+ * gains a positive width.
10
+ */
11
+ export function useVegaContainerRemeasure(
12
+ ref: RefObject<HTMLElement | null>,
13
+ enabled: boolean,
14
+ ): void {
15
+ useEffect(() => {
16
+ const el = ref.current;
17
+ if (!el || !enabled || typeof ResizeObserver === "undefined") {
18
+ return;
19
+ }
20
+
21
+ let lastWidth = el.clientWidth;
22
+ const observer = new ResizeObserver((entries) => {
23
+ const width = entries[0]?.contentRect.width ?? 0;
24
+ if (width <= 0) {
25
+ lastWidth = 0;
26
+ return;
27
+ }
28
+ if (Math.round(width) === Math.round(lastWidth)) {
29
+ return;
30
+ }
31
+ lastWidth = width;
32
+ requestAnimationFrame(() => {
33
+ window.dispatchEvent(new Event("resize"));
34
+ });
35
+ });
36
+ observer.observe(el);
37
+ return () => observer.disconnect();
38
+ }, [ref, enabled]);
39
+ }