@marimo-team/frontend 0.19.8-dev1 → 0.19.8-dev11

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 (286) hide show
  1. package/dist/assets/{CellStatus-CTtb89yx.js → CellStatus-DbwQRhK0.js} +1 -1
  2. package/dist/assets/{Combination-C_mRvd_Z.js → Combination-izwufzWe.js} +1 -1
  3. package/dist/assets/{ConnectedDataExplorerComponent-CX7YQX42.js → ConnectedDataExplorerComponent-B098edeX.js} +1 -1
  4. package/dist/assets/{DeferredRequestRegistry-CO2AyNfd.js → DeferredRequestRegistry-tv0PqJZ0.js} +1 -1
  5. package/dist/assets/{ErrorBoundary-ChCiwl15.js → ErrorBoundary-B9Ifj8Jf.js} +1 -1
  6. package/dist/assets/{ImageComparisonComponent-BVBGmVcA.js → ImageComparisonComponent-BVXYpigZ.js} +1 -1
  7. package/dist/assets/{ImperativeModal-CKeCkc1k.js → ImperativeModal-DZr52ffu.js} +1 -1
  8. package/dist/assets/{Inputs-CBxLLWdV.js → Inputs-CbenuziM.js} +1 -1
  9. package/dist/assets/{JsonOutput-BTBD86gT.js → JsonOutput-BTXiwFjF.js} +3 -3
  10. package/dist/assets/{LazyAnyLanguageCodeMirror-Be7SB10I.js → LazyAnyLanguageCodeMirror-CQP8KZWO.js} +2 -2
  11. package/dist/assets/{MarimoErrorOutput-DuaUr0W-.js → MarimoErrorOutput-lr6vqAph.js} +1 -1
  12. package/dist/assets/{RenderHTML-IBhB_MjX.js → RenderHTML-hMZtS42w.js} +1 -1
  13. package/dist/assets/{SSRProvider-DBS9qs3r.js → SSRProvider-DrpctNAg.js} +1 -1
  14. package/dist/assets/__vite-browser-external-D-ioOGDE.js +1 -0
  15. package/dist/assets/__vite-browser-external-DBckR0WR.js +1 -0
  16. package/dist/assets/{add-cell-with-ai-DsiiVErB.js → add-cell-with-ai-DdyvzMmu.js} +2 -2
  17. package/dist/assets/{add-database-form-B1frIn24.js → add-database-form-CUZKNC1e.js} +1 -1
  18. package/dist/assets/{agent-panel-B_Ur2utx.js → agent-panel-IMNT3-jn.js} +5 -5
  19. package/dist/assets/{ai-model-dropdown-Dix8JIRc.js → ai-model-dropdown-C_Fhvna-.js} +1 -1
  20. package/dist/assets/{alert-adkp2Qj8.js → alert-BOoN6gJ1.js} +1 -1
  21. package/dist/assets/{alert-dialog-CordKci7.js → alert-dialog-Ctz24SMn.js} +1 -1
  22. package/dist/assets/{any-language-editor-Z9d2XKUM.js → any-language-editor-B1WBkbF4.js} +1 -1
  23. package/dist/assets/{app-config-button-CYFJH9oz.js → app-config-button-BqV8GA-q.js} +1 -1
  24. package/dist/assets/{architectureDiagram-VXUJARFQ-B-zQV2Ro.js → architectureDiagram-VXUJARFQ-BsTgqTsh.js} +1 -1
  25. package/dist/assets/{arrow-left-Cb_73j1f.js → arrow-left-VDC1u5rq.js} +1 -1
  26. package/dist/assets/{badge-Ce8wRjuQ.js → badge-D4keL3YC.js} +1 -1
  27. package/dist/assets/{blockDiagram-VD42YOAC-B7BRAty8.js → blockDiagram-VD42YOAC-CeZonq9z.js} +1 -1
  28. package/dist/assets/{bundle.esm-B-jCcPJK.js → bundle.esm-CBAPjfrh.js} +1 -1
  29. package/dist/assets/{button-YC1gW_kJ.js → button-CZ3Cs4qb.js} +1 -1
  30. package/dist/assets/{c4Diagram-YG6GDRKO-C5JyC9v_.js → c4Diagram-YG6GDRKO-CDPGRzUd.js} +1 -1
  31. package/dist/assets/{cache-panel-BfCxvTOh.js → cache-panel-gTIhwBeU.js} +1 -1
  32. package/dist/assets/{card-BAxUmnnT.js → card-DdlNjkEA.js} +1 -1
  33. package/dist/assets/{cell-editor-BQ5bBOiS.js → cell-editor-COnUMHxW.js} +14 -14
  34. package/dist/assets/{cell-link-DW0zobk9.js → cell-link-OwIbBa8Q.js} +1 -1
  35. package/dist/assets/{cells-BcMpgRWV.js → cells-DdLMh4kY.js} +2 -2
  36. package/dist/assets/channel-CUmF6tDU.js +1 -0
  37. package/dist/assets/{chart-no-axes-column-W42b2ZIs.js → chart-no-axes-column-qvVRjhv1.js} +1 -1
  38. package/dist/assets/{chat-components-BpIX7pUp.js → chat-components-jnrAy95o.js} +1 -1
  39. package/dist/assets/{chat-display-CVXM0cmr.js → chat-display-rXqWwmbx.js} +1 -1
  40. package/dist/assets/{chat-panel-FiDMP_Qr.js → chat-panel-ims98I-K.js} +1 -1
  41. package/dist/assets/check-Dr3SxUsb.js +1 -0
  42. package/dist/assets/{chevron-right-DwagBitu.js → chevron-right--18M_6o9.js} +1 -1
  43. package/dist/assets/{chunk-5FQGJX7Z-Bmb7yu_c.js → chunk-5FQGJX7Z-CwvgJCug.js} +3 -3
  44. package/dist/assets/{chunk-ABZYJK2D-Coo5qi7b.js → chunk-ABZYJK2D-CtRGq-db.js} +2 -2
  45. package/dist/assets/{chunk-ATLVNIR6-C0ULYreM.js → chunk-ATLVNIR6-CXEe2jMF.js} +1 -1
  46. package/dist/assets/{chunk-B4BG7PRW-D6Q5lT5Z.js → chunk-B4BG7PRW-BVqt-NSK.js} +1 -1
  47. package/dist/assets/{chunk-DI55MBZ5-BUUtkB-8.js → chunk-DI55MBZ5-C_mlVJmb.js} +1 -1
  48. package/dist/assets/{chunk-EXTU4WIE-DQy5cN5X.js → chunk-EXTU4WIE-CN3BqsR0.js} +1 -1
  49. package/dist/assets/{chunk-JA3XYJ7Z-99Y1UR46.js → chunk-JA3XYJ7Z-B5-JYmoA.js} +1 -1
  50. package/dist/assets/{chunk-JZLCHNYA-DRGkEV50.js → chunk-JZLCHNYA-UFlatyc1.js} +1 -1
  51. package/dist/assets/{chunk-N4CR4FBY-DHFG9ldR.js → chunk-N4CR4FBY-BFF_Z7sG.js} +2 -2
  52. package/dist/assets/{chunk-QN33PNHL-DB8FgLRd.js → chunk-QN33PNHL-DOgXIePg.js} +1 -1
  53. package/dist/assets/{chunk-QXUST7PY-_zxuSm7L.js → chunk-QXUST7PY-CbBaWlhv.js} +1 -1
  54. package/dist/assets/{chunk-S3R3BYOJ-PVCoxQeQ.js → chunk-S3R3BYOJ-CM-pQ0EF.js} +1 -1
  55. package/dist/assets/{chunk-TZMSLE5B-KYGSDxPK.js → chunk-TZMSLE5B-Bs5ERkTF.js} +1 -1
  56. package/dist/assets/{circle-check-C57eOpl0.js → circle-check-DquVD4wZ.js} +1 -1
  57. package/dist/assets/{circle-play-BuOtSgid.js → circle-play-EowqxNIC.js} +1 -1
  58. package/dist/assets/{circle-plus-CnWl9uZo.js → circle-plus-haI9GLDP.js} +1 -1
  59. package/dist/assets/classDiagram-2ON5EDUG-DLI68D-F.js +1 -0
  60. package/dist/assets/classDiagram-v2-WZHVMYZB-yfw4NTdf.js +1 -0
  61. package/dist/assets/{clear-button-CF0iBcV9.js → clear-button-DI7_bdOB.js} +1 -1
  62. package/dist/assets/{click-outside-container-B12FHFHm.js → click-outside-container-Npdlddni.js} +1 -1
  63. package/dist/assets/{clipboard-paste-BiDF-cqm.js → clipboard-paste-CpyPR-HZ.js} +1 -1
  64. package/dist/assets/{code-block-37QAKDTI-D5PRUB7R.js → code-block-37QAKDTI-CT7W9knZ.js} +1 -1
  65. package/dist/assets/{code-xml-XLwHyDBr.js → code-xml-CgN_Yig7.js} +1 -1
  66. package/dist/assets/{column-preview-v3J210SK.js → column-preview-t0CyBVJf.js} +1 -1
  67. package/dist/assets/{command-DOzj5zu3.js → command-cs3Dd1TU.js} +1 -1
  68. package/dist/assets/{command-palette-B94wuFEk.js → command-palette-DJg1FMo6.js} +1 -1
  69. package/dist/assets/{common-DHF6uQdA.js → common-VAE3DrnP.js} +1 -1
  70. package/dist/assets/compiler-runtime-B3qBwwSJ.js +1 -0
  71. package/dist/assets/{config-C3-Nti03.js → config-D2-Bw6QC.js} +1 -1
  72. package/dist/assets/{context-CJp-B2dx.js → context-Ga_vV5mE.js} +1 -1
  73. package/dist/assets/{copy-CQ15EONK.js → copy-D-8y6iMN.js} +1 -1
  74. package/dist/assets/{copy-icon-C1fNHY3M.js → copy-icon-B9w72gBC.js} +1 -1
  75. package/dist/assets/createLucideIcon-BCdY6lG5.js +1 -0
  76. package/dist/assets/{createReducer-Dnna-AUO.js → createReducer-B3rBsy4P.js} +1 -1
  77. package/dist/assets/{dagre-6UL2VRFP-khPiqbzB.js → dagre-6UL2VRFP-UK8bracd.js} +1 -1
  78. package/dist/assets/{data-grid-overlay-editor-Ca1ELXWD.js → data-grid-overlay-editor-2vr_zUfM.js} +1 -1
  79. package/dist/assets/{database-zap-B9y7063w.js → database-zap-k4ePIFAU.js} +1 -1
  80. package/dist/assets/{datasource-BZ3O2HG1.js → datasource-BBMMxrje.js} +1 -1
  81. package/dist/assets/{dates-Cx863TsG.js → dates-CT5PUuFo.js} +1 -1
  82. package/dist/assets/{dependency-graph-panel-s45LIDec.js → dependency-graph-panel-D16tZkyM.js} +1 -1
  83. package/dist/assets/{diagram-PSM6KHXK-C7-DZLOE.js → diagram-PSM6KHXK-7QiPU-26.js} +1 -1
  84. package/dist/assets/{diagram-QEK2KX5R-Ct2_XsRV.js → diagram-QEK2KX5R-BbZsWUC4.js} +1 -1
  85. package/dist/assets/{diagram-S2PKOQOG-C82IZoPA.js → diagram-S2PKOQOG-SZ-twU4B.js} +1 -1
  86. package/dist/assets/{dialog-Dstm3Ubn.js → dialog-tQELcltn.js} +1 -1
  87. package/dist/assets/{dist-oarhZoo6.js → dist-CDXJRSCj.js} +1 -1
  88. package/dist/assets/{dist-PT7WsOdN.js → dist-DDGMbl6p.js} +1 -1
  89. package/dist/assets/{dist-BhLw_JdQ.js → dist-DY1C8dgM.js} +1 -1
  90. package/dist/assets/{documentation-panel-DRqbOPwM.js → documentation-panel-0BCnCatP.js} +1 -1
  91. package/dist/assets/{download-zuPzhwvm.js → download-BodpSpiQ.js} +1 -1
  92. package/dist/assets/{download-B9SUL40m.js → download-Dg7clfkc.js} +1 -1
  93. package/dist/assets/{dropdown-menu-D8v7RjW8.js → dropdown-menu-BUgFWmX1.js} +1 -1
  94. package/dist/assets/{edit-page-Dlr4v1eI.js → edit-page-D6pSQMQE.js} +3 -3
  95. package/dist/assets/{ellipsis-5ip-qDfN.js → ellipsis-DfDsMPvA.js} +1 -1
  96. package/dist/assets/{ellipsis-vertical-C7jYiLCo.js → ellipsis-vertical-J1F7_WS9.js} +1 -1
  97. package/dist/assets/{empty-state-BAGXXrn8.js → empty-state-DrmGF88A.js} +1 -1
  98. package/dist/assets/{en-US-XLBup7bs.js → en-US-DU2jJCpg.js} +1 -1
  99. package/dist/assets/{erDiagram-Q2GNP2WA-Ftt2qDiM.js → erDiagram-Q2GNP2WA-BSmVh3Kt.js} +1 -1
  100. package/dist/assets/{error-banner-JIexM8h5.js → error-banner-Dlrzo_Ay.js} +1 -1
  101. package/dist/assets/{error-panel-TqjIx6nC.js → error-panel-D7CVHSby.js} +1 -1
  102. package/dist/assets/{errors-B5AI4nf5.js → errors-CPlNr33a.js} +1 -1
  103. package/dist/assets/{es-CPSXxuS6.js → es-CerBf9Z6.js} +5 -5
  104. package/dist/assets/{esm-BbNm2fB0.js → esm-C-53tlK5.js} +1 -1
  105. package/dist/assets/{eye-off-BhExYOph.js → eye-off-AK_9uodG.js} +1 -1
  106. package/dist/assets/{field-1uCBX4j4.js → field-D9jE8HEt.js} +1 -1
  107. package/dist/assets/{file-Cs1JbsV6.js → file-Ch78NKWp.js} +1 -1
  108. package/dist/assets/{file-explorer-panel-jku_uMQn.js → file-explorer-panel-d9LDZt_k.js} +1 -1
  109. package/dist/assets/{file-plus-corner-Da9I6dgU.js → file-plus-corner-CvAy4H5W.js} +1 -1
  110. package/dist/assets/{file-video-camera-DW3v07j2.js → file-video-camera-C3wGzBnE.js} +1 -1
  111. package/dist/assets/{floating-outline-CZbF47gm.js → floating-outline-C8UBGhNL.js} +1 -1
  112. package/dist/assets/{flowDiagram-NV44I4VS-Ca9aZp-3.js → flowDiagram-NV44I4VS-2nYUYKvI.js} +1 -1
  113. package/dist/assets/{focus-BxGelf2n.js → focus-Bd_p77qK.js} +1 -1
  114. package/dist/assets/{form-DQt-Ldr4.js → form-D23zs2fF.js} +1 -1
  115. package/dist/assets/{gallery-page-D_5X4kKx.js → gallery-page-Yq7Go5FK.js} +1 -1
  116. package/dist/assets/{ganttDiagram-JELNMOA3-PYFPdyuJ.js → ganttDiagram-JELNMOA3-B77PnMPw.js} +1 -1
  117. package/dist/assets/{gitGraphDiagram-NY62KEGX-CfGWoYOo.js → gitGraphDiagram-NY62KEGX-B-3aRelz.js} +1 -1
  118. package/dist/assets/{glide-data-editor-8ek3zzAO.js → glide-data-editor-B5UMCoFz.js} +4 -4
  119. package/dist/assets/globals-BgJBhxFI.js +1 -0
  120. package/dist/assets/{home-page-xDhfcHL1.js → home-page-DXMa3CyZ.js} +1 -1
  121. package/dist/assets/{hooks-MQa8CSUr.js → hooks-jQB62wos.js} +1 -1
  122. package/dist/assets/{house-DhFkiXz7.js → house-BI81AWSn.js} +1 -1
  123. package/dist/assets/{html-to-image-DKqpcM7V.js → html-to-image-Bc6qDa9c.js} +1 -1
  124. package/dist/assets/{icons-Dw4USSvE.js → icons-DjR3qLG_.js} +1 -1
  125. package/dist/assets/{index-DuqUGjtK.js → index-BIkg-BTu.js} +10 -10
  126. package/dist/assets/{index-CikhHYAB.css → index-BTVKRPtt.css} +1 -1
  127. package/dist/assets/{infoDiagram-WHAUD3N6-Csbwq6Ks.js → infoDiagram-WHAUD3N6-_vys04Gc.js} +1 -1
  128. package/dist/assets/{input-DcAGg_4_.js → input-DHHmNa19.js} +1 -1
  129. package/dist/assets/{isValid-BLB2jskA.js → isValid-DpSSOU5z.js} +1 -1
  130. package/dist/assets/{journeyDiagram-XKPGCS4Q-DArwMxlY.js → journeyDiagram-XKPGCS4Q-CkD6eopP.js} +1 -1
  131. package/dist/assets/{kanban-definition-3W4ZIXB7-CPjBJiO_.js → kanban-definition-3W4ZIXB7-kX5aL9Ug.js} +1 -1
  132. package/dist/assets/{katex-DYp6oq7P.js → katex-CDLTCvjQ.js} +1 -1
  133. package/dist/assets/katex-DF982Ty5.js +1 -0
  134. package/dist/assets/{kbd-uRyPZ9w_.js → kbd-Cm6Ba9qg.js} +1 -1
  135. package/dist/assets/kiosk-mode-BlAqMmYG.js +1 -0
  136. package/dist/assets/{label-CL9Xfexh.js → label-C9wP7Kp2.js} +1 -1
  137. package/dist/assets/{layout-D-YPCWvX.js → layout-BztBqV-1.js} +3 -3
  138. package/dist/assets/{link-BsTPF7B0.js → link-DxicfMbs.js} +1 -1
  139. package/dist/assets/{links-BhgWpHdU.js → links-7AQBmdyV.js} +1 -1
  140. package/dist/assets/{logs-panel-DKSJRyF4.js → logs-panel-B3aMPrwV.js} +1 -1
  141. package/dist/assets/{loro_wasm_bg-BnAHSQ7o.js → loro_wasm_bg-CdafknAX.js} +2 -2
  142. package/dist/assets/loro_wasm_bg-WKwciKJa.wasm +0 -0
  143. package/dist/assets/{loro_wasm_bg-CKQGJrH5.js → loro_wasm_bg-aCueZs8k.js} +1 -1
  144. package/dist/assets/{maps-t9yNKYA8.js → maps-D2_Mq1pZ.js} +1 -1
  145. package/dist/assets/{markdown-renderer-Bu12gPyJ.js → markdown-renderer-Dy-FX527.js} +1 -1
  146. package/dist/assets/{menu-items-NblnuU_B.js → menu-items-vwmjPhjW.js} +1 -1
  147. package/dist/assets/mermaid-4DMBBIKO-DQz_QvBC.js +1 -0
  148. package/dist/assets/{mermaid-Bzaf_nA9.js → mermaid-Caj4ROsO.js} +3 -3
  149. package/dist/assets/{mhchem-DLDYYsJK.js → mhchem-CJmb5HsA.js} +1 -1
  150. package/dist/assets/{mindmap-definition-VGOIOE7T-DVB4z5Yy.js → mindmap-definition-VGOIOE7T-BJ9zWUqW.js} +1 -1
  151. package/dist/assets/{mode-CevBiFCd.js → mode-BfhhQnCm.js} +1 -1
  152. package/dist/assets/{multi-icon-CLzAg610.js → multi-icon-BWLbAXq5.js} +1 -1
  153. package/dist/assets/{multi-map-W4zci54U.js → multi-map-t2yhdp8D.js} +1 -1
  154. package/dist/assets/{name-cell-input-DwvdP1Ck.js → name-cell-input-DvFZv__e.js} +1 -1
  155. package/dist/assets/{number-overlay-editor-CvIcqV0W.js → number-overlay-editor-DIy8e1ST.js} +1 -1
  156. package/dist/assets/{outline-panel-Bg_CP1WV.js → outline-panel-DH2X9Yaa.js} +1 -1
  157. package/dist/assets/{packages-panel-DBgrbk-q.js → packages-panel-BWx1vxzx.js} +1 -1
  158. package/dist/assets/{panel-context-C-UJlFyL.js → panel-context-2mVKaSYm.js} +1 -1
  159. package/dist/assets/{panels-CaoDGKmF.js → panels-vsOIbBB6.js} +1 -1
  160. package/dist/assets/{pieDiagram-ADFJNKIX-vwwb5uL8.js → pieDiagram-ADFJNKIX-Mf2FMnt9.js} +1 -1
  161. package/dist/assets/{play-BPIh-ZEU.js → play-GLWQQs7F.js} +1 -1
  162. package/dist/assets/{plus-BD5o34_i.js → plus-B7DF33lD.js} +1 -1
  163. package/dist/assets/{popover-BZZFx3Q8.js → popover-B-131r4d.js} +1 -1
  164. package/dist/assets/{process-output-Cl2N-HlT.js → process-output-CHXcfo-X.js} +1 -1
  165. package/dist/assets/{quadrantDiagram-AYHSOK5B-Y8bEZ32G.js → quadrantDiagram-AYHSOK5B-B04U71uV.js} +1 -1
  166. package/dist/assets/{react-BGmjiNul.js → react-Bj1aDYRI.js} +1 -1
  167. package/dist/assets/{react-dom-C9fstfnp.js → react-dom-CSu739Rf.js} +1 -1
  168. package/dist/assets/{react-plotly-CZMBCa5P.js → react-plotly-D4UaXGJL.js} +1 -1
  169. package/dist/assets/{react-resizable-panels.browser.esm-BFvP7Upm.js → react-resizable-panels.browser.esm-Mq45xjWt.js} +1 -1
  170. package/dist/assets/{react-vega-DkHO4e2L.js → react-vega-CP7NqbRQ.js} +1 -1
  171. package/dist/assets/{react-vega-BCDifxTe.js → react-vega-CqegDZRQ.js} +1 -1
  172. package/dist/assets/{readonly-python-code-H1kzT-lB.js → readonly-python-code-Drm-iT2o.js} +1 -1
  173. package/dist/assets/{refresh-ccw-DLEiQDS3.js → refresh-ccw-DN_xCV6A.js} +1 -1
  174. package/dist/assets/{refresh-cw-CQd-1kjx.js → refresh-cw-Dx8TEWFP.js} +1 -1
  175. package/dist/assets/{renderShortcut-zxgoVTeP.js → renderShortcut-B1jzzLJw.js} +1 -1
  176. package/dist/assets/request-registry-BWqkV683.js +1 -0
  177. package/dist/assets/{requests-BsVD4CdD.js → requests-B4FYHTZl.js} +1 -1
  178. package/dist/assets/requests-BQkjRazP.js +1 -0
  179. package/dist/assets/{requirementDiagram-UZGBJVZJ-ChckaTrX.js → requirementDiagram-UZGBJVZJ-oJlPs172.js} +1 -1
  180. package/dist/assets/{rotate-ccw-B_yU4f05.js → rotate-ccw-DPbJxVVN.js} +1 -1
  181. package/dist/assets/run-page-CM1n8muV.js +1 -0
  182. package/dist/assets/{runs-X54OGDTq.js → runs-DyBOFmAK.js} +1 -1
  183. package/dist/assets/{sankeyDiagram-TZEHDZUN-DtU4O0-i.js → sankeyDiagram-TZEHDZUN-aplEbaHE.js} +1 -1
  184. package/dist/assets/{save-PMHbdtqc.js → save-DZodxFnE.js} +1 -1
  185. package/dist/assets/{save-worker-DtF6B3PS.js → save-worker-CtJsIYIM.js} +3 -3
  186. package/dist/assets/{scratchpad-panel-CIxZIJ-1.js → scratchpad-panel-BFFeceHa.js} +1 -1
  187. package/dist/assets/{secrets-panel-TwfjwIVv.js → secrets-panel-vKKBtc8G.js} +1 -1
  188. package/dist/assets/{select-CX1Yi8J8.js → select-B7bfltkI.js} +1 -1
  189. package/dist/assets/{sequenceDiagram-WL72ISMW-BGXrTemh.js → sequenceDiagram-WL72ISMW-WAUwGkkd.js} +1 -1
  190. package/dist/assets/{session-panel-CNeWVmTR.js → session-panel-IeLEqwsB.js} +1 -1
  191. package/dist/assets/{settings-DOXWMfVd.js → settings-OBbrbhij.js} +1 -1
  192. package/dist/assets/{share-Ba-pHZtq.js → share-rXkgGlhr.js} +1 -1
  193. package/dist/assets/{slides-component-CGMJm_kL.js → slides-component-CeMnlG8H.js} +1 -1
  194. package/dist/assets/{snippets-panel-DMN_ZSXA.js → snippets-panel-nld0VX-j.js} +1 -1
  195. package/dist/assets/{spec-D1kBp3jX.js → spec-Ch0xnJY4.js} +1 -1
  196. package/dist/assets/{spinner-DaIKav-i.js → spinner-DA8-7wQv.js} +1 -1
  197. package/dist/assets/{square-C8Tw_XXG.js → square-DPZjfUaq.js} +1 -1
  198. package/dist/assets/{square-function-CqXXKtIq.js → square-function-B6mgCeFJ.js} +1 -1
  199. package/dist/assets/{state-n1Xz9vt7.js → state-DAl4qLSi.js} +1 -1
  200. package/dist/assets/{state-BLsnFVwy.js → state-yRkQ_uSW.js} +1 -1
  201. package/dist/assets/{stateDiagram-FKZM4ZOC-BwSf7RIr.js → stateDiagram-FKZM4ZOC-DUDhr_Gg.js} +1 -1
  202. package/dist/assets/stateDiagram-v2-4FDKWEC3-yH9Rugj-.js +1 -0
  203. package/dist/assets/{switch-CfRu5JBF.js → switch-D-TxHKpg.js} +1 -1
  204. package/dist/assets/{table-DZR6ewbN.js → table-CfDbAm78.js} +1 -1
  205. package/dist/assets/{table-qbh6Daed.js → table-DScsXgJW.js} +1 -1
  206. package/dist/assets/{terminal-C0fH4d_0.js → terminal-CF-esPMT.js} +1 -1
  207. package/dist/assets/{textarea-3ZXdUni1.js → textarea-BFfMAEaQ.js} +1 -1
  208. package/dist/assets/{timeline-definition-IT6M3QCI-BZakpQwy.js → timeline-definition-IT6M3QCI-D93LYpWp.js} +1 -1
  209. package/dist/assets/{toDate-CgbKQM5E.js → toDate-DETS9bBd.js} +1 -1
  210. package/dist/assets/{toggle-CWS-iCmF.js → toggle-CriARMQK.js} +1 -1
  211. package/dist/assets/{tooltip-DH6k_bBY.js → tooltip-C_WgOOcZ.js} +1 -1
  212. package/dist/assets/{tracing-zzjDz6Hy.js → tracing-DB7ckaG0.js} +1 -1
  213. package/dist/assets/tracing-panel-CxTR1RYC.js +2 -0
  214. package/dist/assets/{trash-2-CyqGun26.js → trash-2-B8SQYdQq.js} +1 -1
  215. package/dist/assets/{trash-DMqDgJ5r.js → trash-Cv0yH8fs.js} +1 -1
  216. package/dist/assets/{tree-DHpFOpHo.js → tree-B8r7cwRm.js} +1 -1
  217. package/dist/assets/{triangle-alert-B65rDESJ.js → triangle-alert-U93NZYDl.js} +1 -1
  218. package/dist/assets/{types-CS34eOZi.js → types-C1UhS3qM.js} +1 -1
  219. package/dist/assets/{types-CW-zyy80.js → types-D-xsoOE8.js} +1 -1
  220. package/dist/assets/{use-toast-rmUWldD_.js → use-toast-T0_cQDma.js} +1 -1
  221. package/dist/assets/useAddCell-Bc2_jloT.js +1 -0
  222. package/dist/assets/{useAsyncData-BAVCkkQP.js → useAsyncData-BMGLSTg8.js} +1 -1
  223. package/dist/assets/{useBoolean-BjVFTMam.js → useBoolean-IZsSX_XF.js} +1 -1
  224. package/dist/assets/{useCellActionButton-BZ46_Pdt.js → useCellActionButton-DUpWwYW8.js} +1 -1
  225. package/dist/assets/{useDateFormatter-D89e9xZY.js → useDateFormatter-CieT0-H-.js} +1 -1
  226. package/dist/assets/{useDebounce-CU_caGaU.js → useDebounce-B28kFfrM.js} +1 -1
  227. package/dist/assets/{useDeepCompareMemoize-DiyglPgJ.js → useDeepCompareMemoize-ChxLMT9E.js} +1 -1
  228. package/dist/assets/{useDeleteCell-B8CxYiji.js → useDeleteCell-6jBNYEDG.js} +1 -1
  229. package/dist/assets/{useDependencyPanelTab-YtWR0xDK.js → useDependencyPanelTab-Dq7NTXk8.js} +1 -1
  230. package/dist/assets/useEvent-BhXAndur.js +1 -0
  231. package/dist/assets/{useEventListener-DIUKKfEy.js → useEventListener-Cb-RVVEn.js} +1 -1
  232. package/dist/assets/{useIframeCapabilities-DzIlROXe.js → useIframeCapabilities-B_pQb20b.js} +1 -1
  233. package/dist/assets/{useInstallPackage-C-gjrVjb.js → useInstallPackage-xrG_Tm9T.js} +1 -1
  234. package/dist/assets/{useInterval-y9MtYlSD.js → useInterval-BNfubus2.js} +1 -1
  235. package/dist/assets/{useLifecycle-D35CBukS.js → useLifecycle-ClI_npeg.js} +1 -1
  236. package/dist/assets/{useNonce-_Aax6sXd.js → useNonce-CS26E0hA.js} +1 -1
  237. package/dist/assets/{useNotebookActions-Dfh_7NPm.js → useNotebookActions-DRVyh52j.js} +1 -1
  238. package/dist/assets/{useNumberFormatter-CTkflual.js → useNumberFormatter-BX4DTYtT.js} +1 -1
  239. package/dist/assets/{usePress-CoEeT5jq.js → usePress-3CRs0fQg.js} +1 -1
  240. package/dist/assets/{useRunCells-rjrIgU8v.js → useRunCells-CmbQTUeO.js} +1 -1
  241. package/dist/assets/{useSplitCell-fcjSuBNO.js → useSplitCell-DE71CDKv.js} +1 -1
  242. package/dist/assets/{useTheme-EGf2UOFo.js → useTheme-CTORu22_.js} +1 -1
  243. package/dist/assets/{utilities.esm-CkqwfzLw.js → utilities.esm-8Diy8be3.js} +3 -3
  244. package/dist/assets/{utils-DXvhzCGS.js → utils-YqBXNpsM.js} +1 -1
  245. package/dist/assets/{vega-component-DAJbxD47.js → vega-component-D4ZTpyiq.js} +1 -1
  246. package/dist/assets/{worker-CUL1lW-N.js → worker-CyCdlLVf.js} +3 -3
  247. package/dist/assets/{workflow-CMjI9cxl.js → workflow-B12dAR4X.js} +1 -1
  248. package/dist/assets/{write-secret-modal-CgAvgY9w.js → write-secret-modal-BodBOJkR.js} +1 -1
  249. package/dist/assets/{x-CoXDX2vQ.js → x-ZP5cObgf.js} +1 -1
  250. package/dist/assets/{xychartDiagram-PRI3JC2R-CAHFvN1H.js → xychartDiagram-PRI3JC2R-C8jV7uCC.js} +1 -1
  251. package/dist/assets/{youtube-8p26v8EM.js → youtube--tNPNRy6.js} +1 -1
  252. package/dist/assets/zod-H_cgTO0M.js +40 -0
  253. package/dist/index.html +126 -126
  254. package/package.json +17 -17
  255. package/src/components/chat/acp/__tests__/state.test.ts +69 -0
  256. package/src/components/chat/acp/state.ts +6 -6
  257. package/src/components/data-table/__tests__/data-table.test.tsx +94 -2
  258. package/src/core/MarimoApp.tsx +12 -8
  259. package/src/core/islands/__tests__/bridge.test.ts +241 -0
  260. package/src/core/islands/bridge.ts +22 -6
  261. package/src/core/run-app.tsx +11 -4
  262. package/src/plugins/core/registerReactComponent.tsx +9 -1
  263. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +164 -0
  264. package/src/utils/__tests__/mime-types.test.ts +8 -10
  265. package/src/utils/mime-types.ts +5 -5
  266. package/dist/assets/__vite-browser-external-BkzFKOxE.js +0 -1
  267. package/dist/assets/__vite-browser-external-CPyDqUtZ.js +0 -1
  268. package/dist/assets/channel-ownMsSXG.js +0 -1
  269. package/dist/assets/check-DdfN0k2d.js +0 -1
  270. package/dist/assets/classDiagram-2ON5EDUG-CSgD2v8F.js +0 -1
  271. package/dist/assets/classDiagram-v2-WZHVMYZB-YTETTIT0.js +0 -1
  272. package/dist/assets/compiler-runtime-DeeZ7FnK.js +0 -1
  273. package/dist/assets/createLucideIcon-CnW3RofX.js +0 -1
  274. package/dist/assets/globals-D4t_HyAp.js +0 -1
  275. package/dist/assets/katex-BZrXWsTs.js +0 -1
  276. package/dist/assets/kiosk-mode-C9XznhoS.js +0 -1
  277. package/dist/assets/loro_wasm_bg-DV7Kb4_M.wasm +0 -0
  278. package/dist/assets/mermaid-4DMBBIKO-RE7Z6-fl.js +0 -1
  279. package/dist/assets/request-registry-CjZcQuTP.js +0 -1
  280. package/dist/assets/requests-BSPGoGJL.js +0 -1
  281. package/dist/assets/run-page-BmTC7uxn.js +0 -1
  282. package/dist/assets/stateDiagram-v2-4FDKWEC3-SWMI9LKY.js +0 -1
  283. package/dist/assets/tracing-panel-DogOVTzf.js +0 -2
  284. package/dist/assets/useAddCell-mkD8zurm.js +0 -1
  285. package/dist/assets/useEvent-DO6uJBas.js +0 -1
  286. package/dist/assets/zod-Cg4WLWh2.js +0 -40
@@ -1,6 +1,11 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import type { ColumnDef, RowSelectionState } from "@tanstack/react-table";
3
- import { render, screen } from "@testing-library/react";
2
+ import type {
3
+ ColumnDef,
4
+ PaginationState,
5
+ RowSelectionState,
6
+ SortingState,
7
+ } from "@tanstack/react-table";
8
+ import { render, screen, within } from "@testing-library/react";
4
9
  import { describe, expect, it, vi } from "vitest";
5
10
  import { TooltipProvider } from "@/components/ui/tooltip";
6
11
  import { DataTable } from "../data-table";
@@ -95,4 +100,91 @@ describe("DataTable", () => {
95
100
  expect(rows[1]).toHaveAttribute("title", "Michael Scott");
96
101
  expect(rows[2]).toHaveAttribute("title", "Jim Halpert");
97
102
  });
103
+
104
+ it("should display updated data after rerender with manual sorting and pagination", () => {
105
+ // Simulates the bug from issue #8023:
106
+ // When a user sorts a table, rows that moved from page 2 to page 1
107
+ // don't visually refresh after the underlying data is updated.
108
+
109
+ interface RowData {
110
+ id: number;
111
+ status: string;
112
+ value: number;
113
+ }
114
+
115
+ // Initial data: 4 rows, page_size=3
116
+ const initialData: RowData[] = [
117
+ { id: 4, status: "pending", value: 40 },
118
+ { id: 3, status: "pending", value: 30 },
119
+ { id: 2, status: "pending", value: 20 },
120
+ ];
121
+
122
+ const columns: ColumnDef<RowData>[] = [
123
+ { id: "id", accessorFn: (row) => row.id, header: "id" },
124
+ { id: "status", accessorFn: (row) => row.status, header: "status" },
125
+ { id: "value", accessorFn: (row) => row.value, header: "value" },
126
+ ];
127
+
128
+ // Simulate sorted state (value descending) - manual sorting means
129
+ // data comes pre-sorted from backend
130
+ const sorting: SortingState = [{ id: "value", desc: true }];
131
+ const setSorting = vi.fn();
132
+
133
+ const paginationState: PaginationState = { pageIndex: 0, pageSize: 3 };
134
+ const setPaginationState = vi.fn();
135
+
136
+ const commonProps = {
137
+ columns,
138
+ selection: null as "single" | "multi" | null,
139
+ totalRows: 4,
140
+ totalColumns: 3,
141
+ pagination: true,
142
+ manualPagination: true,
143
+ paginationState,
144
+ setPaginationState,
145
+ manualSorting: true,
146
+ sorting,
147
+ setSorting,
148
+ };
149
+
150
+ const { rerender } = render(
151
+ <TooltipProvider>
152
+ <DataTable {...commonProps} data={initialData} />
153
+ </TooltipProvider>,
154
+ );
155
+
156
+ // Verify initial data is displayed - look for "pending" in cells
157
+ const rows = screen.getAllByRole("row");
158
+ // Row 0 is header, rows 1-3 are data rows
159
+ expect(rows).toHaveLength(4); // 1 header + 3 data rows
160
+ // All rows should show "pending"
161
+ expect(within(rows[1]).getByText("pending")).toBeTruthy();
162
+ expect(within(rows[2]).getByText("pending")).toBeTruthy();
163
+ expect(within(rows[3]).getByText("pending")).toBeTruthy();
164
+
165
+ // Now simulate data update: row with id=4 is now "approved"
166
+ // Backend returns sorted data with the update applied
167
+ const updatedData: RowData[] = [
168
+ { id: 4, status: "approved", value: 40 },
169
+ { id: 3, status: "pending", value: 30 },
170
+ { id: 2, status: "pending", value: 20 },
171
+ ];
172
+
173
+ // Rerender with updated data (same sorting, same pagination)
174
+ rerender(
175
+ <TooltipProvider>
176
+ <DataTable {...commonProps} data={updatedData} />
177
+ </TooltipProvider>,
178
+ );
179
+
180
+ // BUG: The row should show "approved" but might show stale "pending"
181
+ const updatedRows = screen.getAllByRole("row");
182
+ expect(updatedRows).toHaveLength(4);
183
+
184
+ // The first data row (id=4) should now show "approved"
185
+ expect(within(updatedRows[1]).getByText("approved")).toBeTruthy();
186
+ // Other rows should still show "pending"
187
+ expect(within(updatedRows[2]).getByText("pending")).toBeTruthy();
188
+ expect(within(updatedRows[3]).getByText("pending")).toBeTruthy();
189
+ });
98
190
  });
@@ -39,14 +39,18 @@ const LazyGalleryPage = reactLazyWithPreload(
39
39
  );
40
40
 
41
41
  export function preloadPage(mode: string) {
42
- if (mode === "home") {
43
- LazyHomePage.preload();
44
- } else if (mode === "gallery") {
45
- LazyGalleryPage.preload();
46
- } else if (mode === "read") {
47
- LazyRunPage.preload();
48
- } else {
49
- LazyEditPage.preload();
42
+ switch (mode) {
43
+ case "home":
44
+ LazyHomePage.preload();
45
+ break;
46
+ case "gallery":
47
+ LazyGalleryPage.preload();
48
+ break;
49
+ case "read":
50
+ LazyRunPage.preload();
51
+ break;
52
+ default:
53
+ LazyEditPage.preload();
50
54
  }
51
55
  }
52
56
 
@@ -0,0 +1,241 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+
4
+ // Mock browser APIs before any imports
5
+ vi.stubGlobal(
6
+ "Worker",
7
+ vi.fn(() => ({
8
+ addEventListener: vi.fn(),
9
+ postMessage: vi.fn(),
10
+ terminate: vi.fn(),
11
+ })),
12
+ );
13
+
14
+ // Create a mock URL class that works as a constructor
15
+ class MockURL {
16
+ href: string;
17
+ constructor(url: string, base?: string | URL) {
18
+ this.href = base ? `${base}/${url}` : url;
19
+ }
20
+ static createObjectURL = vi.fn(() => "blob:mock-url");
21
+ static revokeObjectURL = vi.fn();
22
+ }
23
+ vi.stubGlobal("URL", MockURL);
24
+
25
+ // Mock the worker RPC before importing the bridge
26
+ const mockBridge = vi.fn();
27
+ const mockLoadPackages = vi.fn();
28
+
29
+ vi.mock("@/core/wasm/rpc", () => ({
30
+ getWorkerRPC: () => ({
31
+ proxy: {
32
+ request: {
33
+ bridge: mockBridge,
34
+ loadPackages: mockLoadPackages,
35
+ startSession: vi.fn(),
36
+ },
37
+ send: {
38
+ consumerReady: vi.fn(),
39
+ },
40
+ },
41
+ addMessageListener: vi.fn(),
42
+ }),
43
+ }));
44
+
45
+ // Mock the parse module to avoid DOM dependencies
46
+ vi.mock("../parse", () => ({
47
+ parseMarimoIslandApps: () => [],
48
+ createMarimoFile: vi.fn(),
49
+ }));
50
+
51
+ // Mock uuid to have predictable tokens
52
+ vi.mock("@/utils/uuid", () => ({
53
+ generateUUID: () => "test-uuid-12345",
54
+ }));
55
+
56
+ // Mock getMarimoVersion
57
+ vi.mock("@/core/meta/globals", () => ({
58
+ getMarimoVersion: () => "0.0.0-test",
59
+ }));
60
+
61
+ // Mock the jotai store
62
+ vi.mock("@/core/state/jotai", () => ({
63
+ store: {
64
+ set: vi.fn(),
65
+ },
66
+ }));
67
+
68
+ // Now import the bridge class
69
+ import { IslandsPyodideBridge } from "../bridge";
70
+
71
+ describe("IslandsPyodideBridge", () => {
72
+ let bridge: IslandsPyodideBridge;
73
+
74
+ beforeEach(() => {
75
+ vi.clearAllMocks();
76
+ // Reset the singleton by clearing the window property
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ delete (window as any)._marimo_private_IslandsPyodideBridge;
79
+ // Access the singleton - creates a fresh instance
80
+ bridge = IslandsPyodideBridge.INSTANCE;
81
+ });
82
+
83
+ afterEach(() => {
84
+ // Clean up singleton
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ delete (window as any)._marimo_private_IslandsPyodideBridge;
87
+ });
88
+
89
+ describe("sendComponentValues", () => {
90
+ it("should include type field and token in control request", async () => {
91
+ const request = {
92
+ objectIds: ["Hbol-0"],
93
+ values: [58],
94
+ };
95
+
96
+ await bridge.sendComponentValues(request);
97
+
98
+ expect(mockBridge).toHaveBeenCalledWith({
99
+ functionName: "put_control_request",
100
+ payload: {
101
+ type: "update-ui-element",
102
+ objectIds: ["Hbol-0"],
103
+ values: [58],
104
+ token: "test-uuid-12345",
105
+ },
106
+ });
107
+ });
108
+
109
+ it("should preserve all request properties", async () => {
110
+ const request = {
111
+ objectIds: ["slider-1", "slider-2"],
112
+ values: [10, 20],
113
+ };
114
+
115
+ await bridge.sendComponentValues(request);
116
+
117
+ expect(mockBridge).toHaveBeenCalledWith({
118
+ functionName: "put_control_request",
119
+ payload: expect.objectContaining({
120
+ type: "update-ui-element",
121
+ objectIds: ["slider-1", "slider-2"],
122
+ values: [10, 20],
123
+ }),
124
+ });
125
+ });
126
+ });
127
+
128
+ describe("sendFunctionRequest", () => {
129
+ it("should include type field in control request", async () => {
130
+ const request = {
131
+ functionCallId: "call-123",
132
+ namespace: "test_namespace",
133
+ functionName: "my_function",
134
+ args: { x: 1, y: 2 },
135
+ };
136
+
137
+ await bridge.sendFunctionRequest(request);
138
+
139
+ expect(mockBridge).toHaveBeenCalledWith({
140
+ functionName: "put_control_request",
141
+ payload: {
142
+ type: "invoke-function",
143
+ functionCallId: "call-123",
144
+ namespace: "test_namespace",
145
+ functionName: "my_function",
146
+ args: { x: 1, y: 2 },
147
+ },
148
+ });
149
+ });
150
+ });
151
+
152
+ describe("sendRun", () => {
153
+ it("should include type field in control request", async () => {
154
+ const request = {
155
+ cellIds: ["cell-1", "cell-2"],
156
+ codes: ["print('hello')", "print('world')"],
157
+ };
158
+
159
+ await bridge.sendRun(request);
160
+
161
+ expect(mockBridge).toHaveBeenCalledWith({
162
+ functionName: "put_control_request",
163
+ payload: {
164
+ type: "execute-cells",
165
+ cellIds: ["cell-1", "cell-2"],
166
+ codes: ["print('hello')", "print('world')"],
167
+ },
168
+ });
169
+ });
170
+
171
+ it("should call loadPackages before putControlRequest", async () => {
172
+ const request = {
173
+ cellIds: ["cell-1"],
174
+ codes: ["import pandas"],
175
+ };
176
+
177
+ await bridge.sendRun(request);
178
+
179
+ // Verify loadPackages was called with joined codes
180
+ expect(mockLoadPackages).toHaveBeenCalledWith("import pandas");
181
+
182
+ // Verify order: loadPackages should be called before bridge
183
+ const loadPackagesCallOrder =
184
+ mockLoadPackages.mock.invocationCallOrder[0];
185
+ const bridgeCallOrder = mockBridge.mock.invocationCallOrder[0];
186
+ expect(loadPackagesCallOrder).toBeLessThan(bridgeCallOrder);
187
+ });
188
+ });
189
+
190
+ describe("sendModelValue", () => {
191
+ it("should include type field in control request", async () => {
192
+ const request = {
193
+ modelId: "widget-1",
194
+ message: {
195
+ state: { value: 42 },
196
+ bufferPaths: [],
197
+ },
198
+ };
199
+
200
+ await bridge.sendModelValue(request);
201
+
202
+ expect(mockBridge).toHaveBeenCalledWith({
203
+ functionName: "put_control_request",
204
+ payload: {
205
+ type: "update-widget-model",
206
+ modelId: "widget-1",
207
+ message: {
208
+ state: { value: 42 },
209
+ bufferPaths: [],
210
+ },
211
+ },
212
+ });
213
+ });
214
+ });
215
+
216
+ describe("control request message format", () => {
217
+ it("should always include the type field required by msgspec", async () => {
218
+ // Test all methods to ensure they include the type field
219
+ await bridge.sendComponentValues({ objectIds: [], values: [] });
220
+ await bridge.sendFunctionRequest({
221
+ functionCallId: "",
222
+ namespace: "",
223
+ functionName: "",
224
+ args: {},
225
+ });
226
+ await bridge.sendRun({ cellIds: [], codes: [] });
227
+ await bridge.sendModelValue({
228
+ modelId: "",
229
+ message: { state: {}, bufferPaths: [] },
230
+ });
231
+
232
+ // All calls should have the type field
233
+ const allCalls = mockBridge.mock.calls;
234
+ for (const call of allCalls) {
235
+ const payload = call[0].payload;
236
+ expect(payload).toHaveProperty("type");
237
+ expect(typeof payload.type).toBe("string");
238
+ }
239
+ });
240
+ });
241
+ });
@@ -6,7 +6,8 @@ import { Deferred } from "@/utils/Deferred";
6
6
  import { throwNotImplemented } from "@/utils/functions";
7
7
  import type { JsonString } from "@/utils/json/base64";
8
8
  import { Logger } from "@/utils/Logger";
9
- import type { NotificationPayload } from "../kernel/messages";
9
+ import { generateUUID } from "@/utils/uuid";
10
+ import type { CommandMessage, NotificationPayload } from "../kernel/messages";
10
11
  import { getMarimoVersion } from "../meta/globals";
11
12
  import type { EditRequests, RunRequests } from "../network/types";
12
13
  import { store } from "../state/jotai";
@@ -104,7 +105,11 @@ export class IslandsPyodideBridge implements RunRequests, EditRequests {
104
105
  sendComponentValues: RunRequests["sendComponentValues"] = async (
105
106
  request,
106
107
  ): Promise<null> => {
107
- await this.putControlRequest(request);
108
+ await this.putControlRequest({
109
+ type: "update-ui-element",
110
+ ...request,
111
+ token: generateUUID(),
112
+ });
108
113
  return null;
109
114
  };
110
115
 
@@ -117,18 +122,27 @@ export class IslandsPyodideBridge implements RunRequests, EditRequests {
117
122
  sendFunctionRequest: RunRequests["sendFunctionRequest"] = async (
118
123
  request,
119
124
  ): Promise<null> => {
120
- await this.putControlRequest(request);
125
+ await this.putControlRequest({
126
+ type: "invoke-function",
127
+ ...request,
128
+ });
121
129
  return null;
122
130
  };
123
131
 
124
132
  sendRun: EditRequests["sendRun"] = async (request): Promise<null> => {
125
133
  await this.rpc.proxy.request.loadPackages(request.codes.join("\n"));
126
- await this.putControlRequest(request);
134
+ await this.putControlRequest({
135
+ type: "execute-cells",
136
+ ...request,
137
+ });
127
138
  return null;
128
139
  };
129
140
 
130
141
  sendModelValue: RunRequests["sendModelValue"] = async (request) => {
131
- await this.putControlRequest(request);
142
+ await this.putControlRequest({
143
+ type: "update-widget-model",
144
+ ...request,
145
+ });
132
146
  return null;
133
147
  };
134
148
 
@@ -187,7 +201,9 @@ export class IslandsPyodideBridge implements RunRequests, EditRequests {
187
201
  clearCache = throwNotImplemented;
188
202
  getCacheInfo = throwNotImplemented;
189
203
 
190
- private async putControlRequest(operation: object) {
204
+ // The kernel uses msgspec to parse control requests, which requires a 'type'
205
+ // field for discriminated union deserialization.
206
+ private async putControlRequest(operation: CommandMessage) {
191
207
  await this.rpc.proxy.request.bridge({
192
208
  functionName: "put_control_request",
193
209
  payload: operation,
@@ -1,11 +1,14 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { useAtomValue } from "jotai";
4
+ import { ArrowLeftIcon } from "lucide-react";
4
5
  import { useEffect } from "react";
5
6
  import { AppContainer } from "@/components/editor/app-container";
6
7
  import { AppHeader } from "@/components/editor/header/app-header";
7
8
  import { Spinner } from "@/components/icons/spinner";
9
+ import { buttonVariants } from "@/components/ui/button";
8
10
  import { DelayMount } from "@/components/utils/delay-mount";
11
+ import { cn } from "@/utils/cn";
9
12
  import { CellsRenderer } from "../components/editor/renderers/cells-renderer";
10
13
  import { notebookIsRunningAtom, useCellActions } from "./cells/cells";
11
14
  import type { AppConfig } from "./config/config-schema";
@@ -75,15 +78,19 @@ export const RunApp: React.FC<AppProps> = ({ appConfig }) => {
75
78
  isRunning={isRunning}
76
79
  width={appConfig.width}
77
80
  >
78
- <AppHeader connection={connection} className={"sm:pt-8"}>
81
+ <AppHeader connection={connection} className="sm:pt-8">
79
82
  {galleryHref && (
80
- <div className="flex items-center px-6 pt-4">
83
+ <div className="flex items-center px-6 pt-4 sm:-mt-8">
81
84
  <a
82
85
  href={galleryHref}
83
86
  aria-label="Back to gallery"
84
- className="inline-flex items-center"
87
+ className={cn(
88
+ buttonVariants({ variant: "text", size: "sm" }),
89
+ "gap-2 px-0 text-muted-foreground hover:text-foreground",
90
+ )}
85
91
  >
86
- <img src="logo.png" alt="marimo logo" className="h-6 w-auto" />
92
+ <ArrowLeftIcon className="size-4" aria-hidden={true} />
93
+ <span>Back</span>
87
94
  </a>
88
95
  </div>
89
96
  )}
@@ -101,10 +101,17 @@ function PluginSlotInternal<T>(
101
101
  return plugin.validator.safeParse(parseDataset(hostElement));
102
102
  });
103
103
 
104
+ // Incremented on each reset to invalidate memoized function references.
105
+ // This ensures that plugin functions (e.g., search) are re-created when
106
+ // the underlying UI element instance changes (new object-id), even if
107
+ // the element's data attributes haven't changed.
108
+ const [resetNonce, setResetNonce] = useState(0);
109
+
104
110
  useImperativeHandle(ref, () => ({
105
111
  reset: () => {
106
112
  setValue(getInitialValue());
107
113
  setParsedResult(plugin.validator.safeParse(parseDataset(hostElement)));
114
+ setResetNonce((n) => n + 1);
108
115
  },
109
116
  setChildren: (children) => {
110
117
  setChildNodes(children);
@@ -224,7 +231,8 @@ function PluginSlotInternal<T>(
224
231
  }
225
232
 
226
233
  return methods;
227
- }, [plugin.functions, hostElement]);
234
+ // eslint-disable-next-line react-hooks/exhaustive-deps
235
+ }, [plugin.functions, hostElement, resetNonce]);
228
236
 
229
237
  // If we failed to parse the initial value, render an error
230
238
  if (!parsedResult.success) {
@@ -0,0 +1,164 @@
1
+ /* Copyright 2026 Marimo. All rights reserved. */
2
+
3
+ import { TooltipProvider } from "@radix-ui/react-tooltip";
4
+ import { act, render, screen, waitFor } from "@testing-library/react";
5
+ import { Provider } from "jotai";
6
+ import { beforeAll, describe, expect, it, vi } from "vitest";
7
+ import type { DownloadAsArgs } from "@/components/data-table/schemas";
8
+ import type { FieldTypesWithExternalType } from "@/components/data-table/types";
9
+ import { store } from "@/core/state/jotai";
10
+ import {
11
+ type GetDataUrl,
12
+ type GetRowIds,
13
+ LoadingDataTableComponent,
14
+ } from "../DataTablePlugin";
15
+
16
+ beforeAll(() => {
17
+ global.ResizeObserver = class ResizeObserver {
18
+ observe() {
19
+ // do nothing
20
+ }
21
+ unobserve() {
22
+ // do nothing
23
+ }
24
+ disconnect() {
25
+ // do nothing
26
+ }
27
+ };
28
+ });
29
+
30
+ describe("LoadingDataTableComponent", () => {
31
+ /**
32
+ * Regression test for https://github.com/marimo-team/marimo/issues/8023
33
+ *
34
+ * When a table is replaced via mo.output.replace() with updated data,
35
+ * but the initial page data (unsorted first page) hasn't changed,
36
+ * the useAsyncData hook's deps may all remain the same.
37
+ * Previously, the `search` function reference was memoized on
38
+ * [plugin.functions, hostElement] and wouldn't change on reset(),
39
+ * so the useAsyncData effect wouldn't re-fire.
40
+ *
41
+ * The fix adds a resetNonce to the functionMethods memo deps,
42
+ * so when the plugin is reset (table instance changes), the search
43
+ * function reference changes, triggering useAsyncData to re-fetch.
44
+ *
45
+ * This test verifies that when the search function reference changes
46
+ * (simulating reset()), the component re-fetches data even if
47
+ * props.data hasn't changed.
48
+ */
49
+ it("should refetch data when search function reference changes", async () => {
50
+ const host = document.createElement("div");
51
+ const setValue = vi.fn();
52
+
53
+ // The initial page data string - identical for both renders.
54
+ // This simulates the case where only a row on page 2 changed,
55
+ // so the first page data is the same.
56
+ const initialPageData = JSON.stringify([
57
+ { id: 1, status: "pending", value: 10 },
58
+ { id: 2, status: "pending", value: 20 },
59
+ { id: 3, status: "pending", value: 30 },
60
+ ]);
61
+
62
+ const searchResult = {
63
+ data: [
64
+ { id: 1, status: "pending", value: 10 },
65
+ { id: 2, status: "pending", value: 20 },
66
+ { id: 3, status: "pending", value: 30 },
67
+ ],
68
+ total_rows: 4,
69
+ cell_styles: null,
70
+ cell_hover_texts: null,
71
+ };
72
+
73
+ const searchFn1 = vi.fn().mockResolvedValue(searchResult);
74
+ const searchFn2 = vi.fn().mockResolvedValue(searchResult);
75
+
76
+ const fieldTypes: FieldTypesWithExternalType = [
77
+ ["id", ["integer", "integer"]],
78
+ ["status", ["string", "string"]],
79
+ ["value", ["integer", "integer"]],
80
+ ];
81
+
82
+ const commonProps = {
83
+ label: null,
84
+ totalRows: 4,
85
+ pagination: true,
86
+ pageSize: 3,
87
+ selection: "single" as const,
88
+ showDownload: false,
89
+ showFilters: false,
90
+ showColumnSummaries: false as const,
91
+ showDataTypes: false,
92
+ showPageSizeSelector: false,
93
+ showColumnExplorer: false,
94
+ showRowExplorer: false,
95
+ showChartBuilder: false,
96
+ rowHeaders: [] as FieldTypesWithExternalType,
97
+ fieldTypes,
98
+ totalColumns: 3,
99
+ maxColumns: "all" as const,
100
+ hasStableRowId: false,
101
+ lazy: false,
102
+ host,
103
+ enableSearch: true,
104
+ value: [] as (number | string | { rowId: string; columnName?: string })[],
105
+ setValue,
106
+ download_as: vi.fn() as DownloadAsArgs,
107
+ get_column_summaries: vi.fn().mockResolvedValue({
108
+ data: null,
109
+ stats: {},
110
+ bin_values: {},
111
+ value_counts: {},
112
+ show_charts: false,
113
+ }),
114
+ get_data_url: vi.fn() as GetDataUrl,
115
+ get_row_ids: vi.fn() as GetRowIds,
116
+ };
117
+
118
+ const Wrapper = ({ children }: { children: React.ReactNode }) => (
119
+ <Provider store={store}>
120
+ <TooltipProvider>{children}</TooltipProvider>
121
+ </Provider>
122
+ );
123
+
124
+ // Render with first search function
125
+ const { rerender } = render(
126
+ <Wrapper>
127
+ <LoadingDataTableComponent
128
+ {...commonProps}
129
+ data={initialPageData}
130
+ search={searchFn1}
131
+ />
132
+ </Wrapper>,
133
+ );
134
+
135
+ // Wait for the table to render with data
136
+ await waitFor(() => {
137
+ expect(screen.getAllByRole("row").length).toBeGreaterThan(1);
138
+ });
139
+
140
+ // Search was called on initial load (fire-and-forget for canShowInitialPage)
141
+ expect(searchFn1).toHaveBeenCalled();
142
+
143
+ // Now rerender with the same data but a NEW search function reference.
144
+ // This simulates what happens after reset() when resetNonce increments
145
+ // and functionMethods is recreated.
146
+ await act(async () => {
147
+ rerender(
148
+ <Wrapper>
149
+ <LoadingDataTableComponent
150
+ {...commonProps}
151
+ data={initialPageData}
152
+ search={searchFn2}
153
+ />
154
+ </Wrapper>,
155
+ );
156
+ });
157
+
158
+ // The new search function should be called because the search
159
+ // dependency changed in useAsyncData.
160
+ await waitFor(() => {
161
+ expect(searchFn2).toHaveBeenCalled();
162
+ });
163
+ });
164
+ });