@marimo-team/frontend 0.23.12-dev8 → 0.23.12

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 (317) hide show
  1. package/dist/assets/{CellStatus-6opTJjMX.js → CellStatus-xkT4Dvj4.js} +1 -1
  2. package/dist/assets/{ConnectedDataExplorerComponent-i1kaFF7n.js → ConnectedDataExplorerComponent-swQQzg5v.js} +1 -1
  3. package/dist/assets/{DeferredRequestRegistry-RuL7NV1n.js → DeferredRequestRegistry-EP9ZArpv.js} +1 -1
  4. package/dist/assets/{ImperativeModal-B62Q6S9l.js → ImperativeModal-MQnbMIO2.js} +1 -1
  5. package/dist/assets/JsonOutput-FFLZqPUK.js +53 -0
  6. package/dist/assets/{LazyAnyLanguageCodeMirror-CsAMDSIw.js → LazyAnyLanguageCodeMirror-CUQODgGJ.js} +2 -2
  7. package/dist/assets/{MarimoErrorOutput-dYrcxVwq.js → MarimoErrorOutput-BQt_FXJL.js} +1 -1
  8. package/dist/assets/{RSPContexts-VzcTZjG1.js → RSPContexts-CXueMbRb.js} +1 -1
  9. package/dist/assets/{RenderHTML-ohul2q99.js → RenderHTML-Cq4mwWYz.js} +1 -1
  10. package/dist/assets/{RunButton-BMpP08P_.js → RunButton-DdQ4s_KP.js} +1 -1
  11. package/dist/assets/{add-cell-with-ai-5tJjrFh0.js → add-cell-with-ai-wdY7HT-D.js} +26 -26
  12. package/dist/assets/{add-connection-dialog-pVExi7gB.js → add-connection-dialog-C41ThK2T.js} +3 -3
  13. package/dist/assets/{agent-panel-By97CFFK.js → agent-panel-q5ey8yNH.js} +1 -1
  14. package/dist/assets/{ai-model-dropdown-Dvmxl0HU.js → ai-model-dropdown-DQb_CyMN.js} +4 -4
  15. package/dist/assets/{any-language-editor-F2HBwXr3.js → any-language-editor-ChWsxHdv.js} +1 -1
  16. package/dist/assets/{app-config-button-BB5z7_FE.js → app-config-button-8FXNdkBs.js} +1 -1
  17. package/dist/assets/{architectureDiagram-VXUJARFQ-DkQVwQl-.js → architectureDiagram-VXUJARFQ-BTCyBm7a.js} +1 -1
  18. package/dist/assets/{blockDiagram-VD42YOAC-CACq6Mqn.js → blockDiagram-VD42YOAC-mvbUAzY4.js} +1 -1
  19. package/dist/assets/{c4Diagram-YG6GDRKO-COoIP9fI.js → c4Diagram-YG6GDRKO-qKF4yNR5.js} +1 -1
  20. package/dist/assets/{cache-panel-BlIrcwlT.js → cache-panel-Ds3GhmDF.js} +1 -1
  21. package/dist/assets/{cell-editor-DQKaGrC9.js → cell-editor-CFq9iL3S.js} +1 -1
  22. package/dist/assets/{cell-link-DBKqdVgo.js → cell-link-DgWTiCtG.js} +1 -1
  23. package/dist/assets/{cells-DiASVTIh.js → cells-06TDmJ8V.js} +50 -50
  24. package/dist/assets/channel-Bvgym58O.js +1 -0
  25. package/dist/assets/{chat-display-D8X6vz7W.js → chat-display-DO7nc_uY.js} +1 -1
  26. package/dist/assets/{chat-panel-B9l3ukjX.js → chat-panel-DmUkj42a.js} +1 -1
  27. package/dist/assets/{chat-ui-BwH7dd6n.js → chat-ui-Bf7t-NAW.js} +1 -1
  28. package/dist/assets/{chunk-55IACEB6-Cr4aqhf3.js → chunk-55IACEB6-BZgGh8Op.js} +1 -1
  29. package/dist/assets/{chunk-5FQGJX7Z-DTLanAkx.js → chunk-5FQGJX7Z-C6VN0dQj.js} +3 -3
  30. package/dist/assets/{chunk-ABZYJK2D-BWwBJaW4.js → chunk-ABZYJK2D-DntHwfwl.js} +1 -1
  31. package/dist/assets/{chunk-ATLVNIR6-ZywQjHDL.js → chunk-ATLVNIR6-CZy1WXhH.js} +1 -1
  32. package/dist/assets/{chunk-B4BG7PRW-Q6rM60b0.js → chunk-B4BG7PRW-CifnFMMD.js} +1 -1
  33. package/dist/assets/{chunk-DI55MBZ5-DkUFRB44.js → chunk-DI55MBZ5-BKMnvFi2.js} +1 -1
  34. package/dist/assets/{chunk-EXTU4WIE-A9IRvoap.js → chunk-EXTU4WIE-CYseDwky.js} +1 -1
  35. package/dist/assets/{chunk-JA3XYJ7Z-BC57JRLK.js → chunk-JA3XYJ7Z-Bj396ovX.js} +1 -1
  36. package/dist/assets/{chunk-JZLCHNYA-CmPEo2OR.js → chunk-JZLCHNYA-QttzWzFq.js} +1 -1
  37. package/dist/assets/{chunk-N4CR4FBY-qcFzulsJ.js → chunk-N4CR4FBY-DgrFkHXi.js} +2 -2
  38. package/dist/assets/{chunk-QN33PNHL-CfKFSQ8y.js → chunk-QN33PNHL-shgGaZ1X.js} +1 -1
  39. package/dist/assets/{chunk-QXUST7PY-DiH4MyLq.js → chunk-QXUST7PY-EJQ74OiC.js} +1 -1
  40. package/dist/assets/{chunk-S3R3BYOJ-C7n0Esov.js → chunk-S3R3BYOJ-DHLCcICg.js} +1 -1
  41. package/dist/assets/{chunk-TZMSLE5B-Yl1gB5ep.js → chunk-TZMSLE5B-BgJLE0Za.js} +1 -1
  42. package/dist/assets/classDiagram-2ON5EDUG-DrqS8d9F.js +1 -0
  43. package/dist/assets/classDiagram-v2-WZHVMYZB-DchP-T46.js +1 -0
  44. package/dist/assets/{code-block-37QAKDTI-BJ9X4ytb.js → code-block-37QAKDTI--cy-8SOv.js} +1 -1
  45. package/dist/assets/{column-preview-B3CdpsbL.js → column-preview-oHsVFerC.js} +1 -1
  46. package/dist/assets/{command-DRHbYHUP.js → command-CsbsBLBw.js} +1 -1
  47. package/dist/assets/{command-palette-D2BHtSuk.js → command-palette-Bvl7fQ8h.js} +1 -1
  48. package/dist/assets/{common-CvUUt55g.js → common-cKvfH0fD.js} +1 -1
  49. package/dist/assets/{components-CimBDpZ8.js → components-BhmX9dcm.js} +1 -1
  50. package/dist/assets/{config-3clPIEB9.js → config-BE150fVL.js} +1 -1
  51. package/dist/assets/{context-C2Ie4tn_.js → context-DE_5rdOV.js} +1 -1
  52. package/dist/assets/{copy-icon-EHMT-qlr.js → copy-icon-BCIGtBo0.js} +1 -1
  53. package/dist/assets/{cose-bilkent-S5V4N54A-CQqSLzd1.js → cose-bilkent-S5V4N54A-DhxFsKpJ.js} +1 -1
  54. package/dist/assets/{dagre-6UL2VRFP-C8k8cWk0.js → dagre-6UL2VRFP-B6hk_Bns.js} +1 -1
  55. package/dist/assets/{data-grid-overlay-editor-BrFXEIvf.js → data-grid-overlay-editor-CTUPMnar.js} +1 -1
  56. package/dist/assets/{datasource-Da-qoi34.js → datasource-mVfTJz3V.js} +1 -1
  57. package/dist/assets/{dates-D8uxHHPL.js → dates-CnrjjcMO.js} +1 -1
  58. package/dist/assets/{dependency-graph-panel-CMjZH8W-.js → dependency-graph-panel-D9C_hBQw.js} +1 -1
  59. package/dist/assets/{diagram-PSM6KHXK-CyHuNpNq.js → diagram-PSM6KHXK-mo2Enmtf.js} +1 -1
  60. package/dist/assets/{diagram-QEK2KX5R-XfuQrtcF.js → diagram-QEK2KX5R-BmkxV10c.js} +1 -1
  61. package/dist/assets/{diagram-S2PKOQOG-bJWzui-7.js → diagram-S2PKOQOG-FgQ9g-FW.js} +1 -1
  62. package/dist/assets/dist-B1NchzZ7.js +1 -0
  63. package/dist/assets/{dist-CyK0ePPW.js → dist-B3BjoKW1.js} +1 -1
  64. package/dist/assets/dist-Bc19bAck.js +1 -0
  65. package/dist/assets/{dist-D-2yWcX9.js → dist-Bj9Iedc0.js} +1 -1
  66. package/dist/assets/{dist-BHCGBHnf.js → dist-BygSqKXd.js} +1 -1
  67. package/dist/assets/{dist-77VmTZjj.js → dist-CBFremCY.js} +1 -1
  68. package/dist/assets/dist-CGfx7GOn.js +1 -0
  69. package/dist/assets/{dist-CABwQOV5.js → dist-CKZJyGZk.js} +1 -1
  70. package/dist/assets/{dist-CIQQgRzz.js → dist-CKjd2mnC.js} +1 -1
  71. package/dist/assets/dist-CKlHe_tO.js +1 -0
  72. package/dist/assets/{dist-C4-ruy-b.js → dist-CPAr7_4H.js} +1 -1
  73. package/dist/assets/{dist-FYUcqnI2.js → dist-CmjkyMZS.js} +1 -1
  74. package/dist/assets/{dist-sJHUucQ8.js → dist-Cq98Ix9k.js} +1 -1
  75. package/dist/assets/{dist-XexmIjM8.js → dist-CwSi3e6S.js} +1 -1
  76. package/dist/assets/{dist-Cqrb9QGk.js → dist-D6TmDEVn.js} +1 -1
  77. package/dist/assets/{dist-DblYTes5.js → dist-DHMtQYxT.js} +1 -1
  78. package/dist/assets/{dist-BP6Oj7vU.js → dist-DU6-XN1L.js} +1 -1
  79. package/dist/assets/{dist-CruUwJkI.js → dist-DZJfnBKu.js} +1 -1
  80. package/dist/assets/dist-D_FHXQyQ.js +1 -0
  81. package/dist/assets/{dist-CKVgRUgH.js → dist-Ds-fJX2L.js} +1 -1
  82. package/dist/assets/{dist-DyuwOQr-.js → dist-d_9Qt_7_.js} +1 -1
  83. package/dist/assets/dist-znptp4sC.js +1 -0
  84. package/dist/assets/{documentation-panel-BS_uG8hW.js → documentation-panel-C0uXzYri.js} +1 -1
  85. package/dist/assets/{download-CdS_EveB.js → download-VxqV5OSK.js} +1 -1
  86. package/dist/assets/{edit-page-DanoliKk.js → edit-page-CInfJ1ps.js} +6 -6
  87. package/dist/assets/{erDiagram-Q2GNP2WA-Db-GMQLy.js → erDiagram-Q2GNP2WA-DZx9RiLu.js} +1 -1
  88. package/dist/assets/{error-banner-BSQVN46J.js → error-banner-C4DZksWV.js} +1 -1
  89. package/dist/assets/{error-panel-Csh1BgrG.js → error-panel-D2WmJDnT.js} +1 -1
  90. package/dist/assets/{es-EItoYvXh.js → es-Cy7KBUrF.js} +1 -1
  91. package/dist/assets/{esm-DwJBDgEq.js → esm-BqXnk7X6.js} +1 -1
  92. package/dist/assets/{esm-X3Tr2pur.js → esm-DSv-aO_T.js} +1 -1
  93. package/dist/assets/{field-DlNY-dDH.js → field-CA9HCE2Y.js} +1 -1
  94. package/dist/assets/{file-explorer-panel--h0xwnRB.js → file-explorer-panel-nn5I1oLj.js} +3 -3
  95. package/dist/assets/{file-icons-D6BjDFSV.js → file-icons-BeJWUbBH.js} +1 -1
  96. package/dist/assets/{file-name-input-CsUxNFtr.js → file-name-input-Slq_KVFS.js} +1 -1
  97. package/dist/assets/{fileToBase64-BSOFR3RV.js → fileToBase64-Doh9J-g6.js} +1 -1
  98. package/dist/assets/{floating-outline-D2cwxR8Z.js → floating-outline-3UBj62S1.js} +1 -1
  99. package/dist/assets/{flowDiagram-NV44I4VS-DSxxTDOm.js → flowDiagram-NV44I4VS-BaCfA1PD.js} +1 -1
  100. package/dist/assets/{focus-BvvRVcVF.js → focus-DqhVePQT.js} +1 -1
  101. package/dist/assets/{form-CO925gWV.js → form-pEJO4Mq_.js} +1 -1
  102. package/dist/assets/{formats-ZGU43GQU.js → formats-Dkhsq416.js} +1 -1
  103. package/dist/assets/{formatting-DhA_x3cD.js → formatting-Bjzx5J8_.js} +1 -1
  104. package/dist/assets/{gallery-page-CNPcxPCI.js → gallery-page-Cwx-CV9Q.js} +1 -1
  105. package/dist/assets/{ganttDiagram-JELNMOA3-Boeh8Xec.js → ganttDiagram-JELNMOA3-D76yMCwq.js} +1 -1
  106. package/dist/assets/{gitGraphDiagram-V2S2FVAM-Ww-CAbr5.js → gitGraphDiagram-V2S2FVAM-xaQk-fkD.js} +1 -1
  107. package/dist/assets/github-BQ8If5nZ.js +1 -0
  108. package/dist/assets/{glide-data-editor-Bmm8OMxa.js → glide-data-editor-DtDJGBDZ.js} +4 -4
  109. package/dist/assets/{globals-Bx8Km3LH.js → globals-BDWM3c_z.js} +1 -1
  110. package/dist/assets/home-page-CFgoMQu4.js +4 -0
  111. package/dist/assets/{hooks-7dyPrQQS.js → hooks-NssnE3R8.js} +1 -1
  112. package/dist/assets/{html-to-image-BWhkUSek.js → html-to-image-CbQeOjEJ.js} +1 -1
  113. package/dist/assets/index-BjsskD4V.js +38 -0
  114. package/dist/assets/{index-Bj8QWDiJ.css → index-CaelsqOA.css} +1 -1
  115. package/dist/assets/{infoDiagram-HS3SLOUP-emf5Oa26.js → infoDiagram-HS3SLOUP-CaCHYq-C.js} +1 -1
  116. package/dist/assets/{input-DB2LiTiQ.js → input-b2KTOk0X.js} +1 -1
  117. package/dist/assets/{journeyDiagram-XKPGCS4Q-BM5cpMVY.js → journeyDiagram-XKPGCS4Q-9j5RE995.js} +1 -1
  118. package/dist/assets/{kanban-definition-3W4ZIXB7-BAIfwDqR.js → kanban-definition-3W4ZIXB7-KTZNPjVQ.js} +1 -1
  119. package/dist/assets/{kiosk-mode-D0mAc3Fr.js → kiosk-mode-CyYnV3_y.js} +1 -1
  120. package/dist/assets/{layout-C0MKkswN.js → layout-ChW1-odP.js} +4 -4
  121. package/dist/assets/{linear-BWkmpE3J.js → linear-BWk6x-Bf.js} +1 -1
  122. package/dist/assets/{links-BN8FYTyp.js → links-BL4SaTJe.js} +1 -1
  123. package/dist/assets/{logs-panel-BaGDTq_5.js → logs-panel-CiP_30S4.js} +1 -1
  124. package/dist/assets/{markdown-renderer-CyLjgnQY.js → markdown-renderer-C1yypOYF.js} +3 -3
  125. package/dist/assets/{mermaid-4DMBBIKO-DX6ZCeSi.js → mermaid-4DMBBIKO-1vt0_Bql.js} +1 -1
  126. package/dist/assets/{mermaid-yhDJCmk2.js → mermaid-BC06IzvM.js} +3 -3
  127. package/dist/assets/{mermaid-parser.core-CEw6EtVC.js → mermaid-parser.core-UC5-TA69.js} +1 -1
  128. package/dist/assets/{mindmap-definition-VGOIOE7T-DAiNJDIe.js → mindmap-definition-VGOIOE7T-DwhzT05K.js} +1 -1
  129. package/dist/assets/{name-cell-input-DBkW5PZU.js → name-cell-input-CIkFEB6-.js} +1 -1
  130. package/dist/assets/{number-overlay-editor-4rrKClOH.js → number-overlay-editor-DU72uJyj.js} +1 -1
  131. package/dist/assets/{outline-panel-xLeB4sTR.js → outline-panel-BfysapqU.js} +1 -1
  132. package/dist/assets/{packages-panel-BbWGOWIZ.js → packages-panel-BYm2thcs.js} +1 -1
  133. package/dist/assets/{pair-with-agent-modal-Q9Od23Rh.js → pair-with-agent-modal-BONZmBdh.js} +1 -1
  134. package/dist/assets/{panels-id0eyz64.js → panels-hLpsLawB.js} +1 -1
  135. package/dist/assets/{pathUtils-BXCjaLHB.js → pathUtils-ANiMIEDI.js} +1 -1
  136. package/dist/assets/{pieDiagram-ADFJNKIX-KdHVGtb7.js → pieDiagram-ADFJNKIX-Ddohs4pt.js} +1 -1
  137. package/dist/assets/{precisionRound-BOmLQIKI.js → precisionRound-CCOoIlcP.js} +1 -1
  138. package/dist/assets/{process-output-BcuY_Us9.js → process-output-BIlXY0iE.js} +1 -1
  139. package/dist/assets/{quadrantDiagram-AYHSOK5B-B9NNSzQG.js → quadrantDiagram-AYHSOK5B-DXHmstFN.js} +1 -1
  140. package/dist/assets/{radio-group-XouISBp9.js → radio-group-BaOG2bSA.js} +1 -1
  141. package/dist/assets/react-vega-DrvGjEhj.js +1 -0
  142. package/dist/assets/{react-vega-BfOzG-mm.js → react-vega-IsGFjh4e.js} +1 -1
  143. package/dist/assets/{readonly-python-code-BK3Xk2qY.js → readonly-python-code-CNyK8G1T.js} +1 -1
  144. package/dist/assets/{renderShortcut-LpVarhnQ.js → renderShortcut-CKbqJyj4.js} +1 -1
  145. package/dist/assets/{request-registry-K6vbazWs.js → request-registry-unC7eRnq.js} +1 -1
  146. package/dist/assets/{requirementDiagram-UZGBJVZJ-B5pxFnOe.js → requirementDiagram-UZGBJVZJ-FZxRqc8c.js} +1 -1
  147. package/dist/assets/{reveal-component-Do91RUH9.js → reveal-component-D0boNLsp.js} +1 -1
  148. package/dist/assets/{run-page-CYnMjVum.js → run-page-B0OR2l0l.js} +1 -1
  149. package/dist/assets/{sankeyDiagram-TZEHDZUN-w55_GOPb.js → sankeyDiagram-TZEHDZUN-BVzsFJnF.js} +1 -1
  150. package/dist/assets/{scratchpad-panel-DH3KlUbZ.js → scratchpad-panel-Di7uCP6T.js} +1 -1
  151. package/dist/assets/{secrets-panel-CgahHnqr.js → secrets-panel-BUtOtnIM.js} +1 -1
  152. package/dist/assets/{sequenceDiagram-WL72ISMW-CW_L_PJr.js → sequenceDiagram-WL72ISMW-DdzNFBtb.js} +1 -1
  153. package/dist/assets/{session-panel-BJP2lKfE.js → session-panel-D6GA7GoC.js} +1 -1
  154. package/dist/assets/{share-DQjChRJG.js → share-vrPro738.js} +1 -1
  155. package/dist/assets/{snippets-panel-DKenTNmv.js → snippets-panel-DV2ir7q8.js} +1 -1
  156. package/dist/assets/{spec-CDgWI0fT.js → spec-BzxoPflZ.js} +1 -1
  157. package/dist/assets/{src-CvyFXpBy.js → src-CyeQdfB6.js} +1 -1
  158. package/dist/assets/{state-DwAS0kE4.js → state-B3ypjIx-.js} +1 -1
  159. package/dist/assets/state-DD6m9X2h.js +3 -0
  160. package/dist/assets/{state-DjrxAf9W.js → state-RnIztwr-.js} +1 -1
  161. package/dist/assets/{state-MC8-jN2e.js → state-WA3j91X9.js} +1 -1
  162. package/dist/assets/{stateDiagram-FKZM4ZOC-BOX6WbbZ.js → stateDiagram-FKZM4ZOC-DCOZ5EVk.js} +1 -1
  163. package/dist/assets/stateDiagram-v2-4FDKWEC3-D_uhE9WV.js +1 -0
  164. package/dist/assets/stex-CruVQx-P.js +1 -0
  165. package/dist/assets/{swiper-component-BwPCQTdo.js → swiper-component-B3QJ6Yx5.js} +1 -1
  166. package/dist/assets/{switch-DvDNxcZP.js → switch-DHhZkGEv.js} +1 -1
  167. package/dist/assets/{terminal-BXH7Uaqi.js → terminal-C0JxB62q.js} +1 -1
  168. package/dist/assets/{textarea-BBpaAGpK.js → textarea-BM7hAwR3.js} +1 -1
  169. package/dist/assets/{time-SPyfucy1.js → time-BsAzPDU3.js} +1 -1
  170. package/dist/assets/{timeline-definition-IT6M3QCI-Lad2-H_k.js → timeline-definition-IT6M3QCI-BJT2fHGH.js} +1 -1
  171. package/dist/assets/{tracing-Bz68-Fa1.js → tracing-DwjgsPkU.js} +1 -1
  172. package/dist/assets/tracing-panel-BS9eUNK_.js +2 -0
  173. package/dist/assets/{tree-actions-C729o8TG.js → tree-actions-lVyJAYy7.js} +1 -1
  174. package/dist/assets/{useBoolean-BMzj74q1.js → useBoolean-48bgGoSa.js} +1 -1
  175. package/dist/assets/{useCellActionButton-VGB6-gGh.js → useCellActionButton-B88iHApv.js} +1 -1
  176. package/dist/assets/{useDateFormatter-CAlTJ8HV.js → useDateFormatter-CANi6nSX.js} +1 -1
  177. package/dist/assets/{useDeleteCell-D_p8uMly.js → useDeleteCell-CXc93le9.js} +1 -1
  178. package/dist/assets/{useDependencyPanelTab-v8fQPE_U.js → useDependencyPanelTab-9Vnr8-OR.js} +1 -1
  179. package/dist/assets/{useInstallPackage-C1Dd0aIZ.js → useInstallPackage-DEHK-C20.js} +1 -1
  180. package/dist/assets/{useNotebookActions-Hdu82BAI.js → useNotebookActions-DSfevQ7S.js} +1 -1
  181. package/dist/assets/{useNumberFormatter-CuxZh3Bq.js → useNumberFormatter-DCM-63YT.js} +1 -1
  182. package/dist/assets/{usePress-BSFUeqnS.js → usePress-mjvipKvz.js} +1 -1
  183. package/dist/assets/{useRunCells-DXtOL4UR.js → useRunCells-DNaOKKqW.js} +1 -1
  184. package/dist/assets/{useSplitCell-CzaZEqwj.js → useSplitCell-IsXuVcLF.js} +1 -1
  185. package/dist/assets/{utils-DPvpQ891.js → utils-BIlJBJIu.js} +1 -1
  186. package/dist/assets/{vega-component-Ch7x9hsC.js → vega-component-wGZOy7qv.js} +1 -1
  187. package/dist/assets/{vega-loader.browser-CZV6_g2i.js → vega-loader.browser-BJ9oKrvH.js} +1 -1
  188. package/dist/assets/{write-secret-modal-K2n79wHj.js → write-secret-modal-qfcjtCvk.js} +1 -1
  189. package/dist/assets/{xychartDiagram-PRI3JC2R-f8MNNXWc.js → xychartDiagram-PRI3JC2R-BtC1koqJ.js} +1 -1
  190. package/dist/assets/youtube-NfBeYlaL.js +1 -0
  191. package/dist/index.html +112 -112
  192. package/package.json +1 -1
  193. package/src/components/data-table/TableBottomBar.tsx +4 -1
  194. package/src/components/data-table/data-table.tsx +26 -17
  195. package/src/components/data-table/utils.ts +1 -4
  196. package/src/components/editor/actions/useNotebookActions.tsx +4 -4
  197. package/src/components/editor/ai/__tests__/completion-utils.test.ts +48 -2
  198. package/src/components/editor/ai/completion-utils.ts +54 -36
  199. package/src/components/editor/app-container.tsx +3 -1
  200. package/src/components/editor/output/ImageOutput.tsx +12 -3
  201. package/src/components/editor/renderers/vertical-layout/vertical-layout-wrapper.tsx +2 -2
  202. package/src/components/home/components.tsx +4 -4
  203. package/src/components/icons/github.tsx +21 -0
  204. package/src/components/icons/youtube.tsx +21 -0
  205. package/src/components/storage/components.tsx +3 -7
  206. package/src/core/codemirror/go-to-definition/__tests__/commands.test.ts +67 -0
  207. package/src/core/codemirror/go-to-definition/__tests__/utils.test.ts +47 -0
  208. package/src/core/codemirror/go-to-definition/commands.ts +47 -30
  209. package/src/core/codemirror/go-to-definition/utils.ts +0 -1
  210. package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +54 -0
  211. package/src/core/codemirror/reactive-references/analyzer.ts +44 -35
  212. package/src/core/islands/__tests__/bridge.test.ts +25 -0
  213. package/src/core/islands/__tests__/parse.test.ts +585 -1
  214. package/src/core/islands/__tests__/test-utils.tsx +10 -1
  215. package/src/core/islands/bridge.ts +6 -1
  216. package/src/core/islands/constants.ts +2 -0
  217. package/src/core/islands/parse.ts +290 -13
  218. package/src/plugins/impl/DataTablePlugin.tsx +20 -1
  219. package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +141 -1
  220. package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +54 -4
  221. package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +104 -1
  222. package/src/plugins/impl/anywidget/__tests__/model.test.ts +19 -0
  223. package/src/plugins/impl/anywidget/model.ts +15 -0
  224. package/src/utils/__tests__/records.test.ts +27 -0
  225. package/src/utils/records.ts +12 -0
  226. package/dist/assets/JsonOutput-CWVuEz6C.js +0 -53
  227. package/dist/assets/channel-CpOVhGq6.js +0 -1
  228. package/dist/assets/classDiagram-2ON5EDUG-Bxr8oM_y.js +0 -1
  229. package/dist/assets/classDiagram-v2-WZHVMYZB-CY-gITpZ.js +0 -1
  230. package/dist/assets/dist-Bm-o3knM.js +0 -1
  231. package/dist/assets/dist-C0zWDt4u.js +0 -1
  232. package/dist/assets/dist-C2qq2Q11.js +0 -1
  233. package/dist/assets/dist-CI-LXQQ2.js +0 -1
  234. package/dist/assets/dist-DThLGT6I.js +0 -1
  235. package/dist/assets/dist-VVk6z_gh.js +0 -1
  236. package/dist/assets/github-CyzgLJDA.js +0 -1
  237. package/dist/assets/home-page-CPt4LGp0.js +0 -4
  238. package/dist/assets/index-CG1hyPot.js +0 -38
  239. package/dist/assets/react-vega-4x9RLMqT.js +0 -1
  240. package/dist/assets/state-Cy10NkuA.js +0 -3
  241. package/dist/assets/stateDiagram-v2-4FDKWEC3-JHjNwkbq.js +0 -1
  242. package/dist/assets/stex-BBWVYm-R.js +0 -1
  243. package/dist/assets/tracing-panel-BfgGYFNi.js +0 -2
  244. package/dist/assets/youtube-BEAtppjN.js +0 -1
  245. /package/dist/assets/{Deferred-BMfCOLaw.js → Deferred-CfyqLOPG.js} +0 -0
  246. /package/dist/assets/{SSRProvider-DX2edArU.js → SSRProvider-DrpctNAg.js} +0 -0
  247. /package/dist/assets/{alert-1y_DnRWn.js → alert-Bjh7v4lb.js} +0 -0
  248. /package/dist/assets/{azure-DBVzcmvx.js → azure-B42ls0Ui.js} +0 -0
  249. /package/dist/assets/{badge-6yGCqY1Z.js → badge-CFAaMy0O.js} +0 -0
  250. /package/dist/assets/{blob-BiK5xmlC.js → blob-dGUJ3Bw8.js} +0 -0
  251. /package/dist/assets/{bundle.esm-D544r2Sr.js → bundle.esm-BULc9l6b.js} +0 -0
  252. /package/dist/assets/{card-s1ZaQ9ub.js → card-DrIItWkf.js} +0 -0
  253. /package/dist/assets/{copy-D8MtpXgN.js → copy-CyasABTK.js} +0 -0
  254. /package/dist/assets/{defaultLocale-DK1MWd7f.js → defaultLocale-CGfP-Ye3.js} +0 -0
  255. /package/dist/assets/{defaultLocale-OkOxlkkM.js → defaultLocale-CuYNS33t.js} +0 -0
  256. /package/dist/assets/{dialog-DkJmIrsG.js → dialog-Dr_Y1zNi.js} +0 -0
  257. /package/dist/assets/{dist-UghNT0W0.js → dist-BM-OLiKa.js} +0 -0
  258. /package/dist/assets/{dist-ZjSH4Z6x.js → dist-BZhJ1bTM.js} +0 -0
  259. /package/dist/assets/{dist-CNKFZCiw.js → dist-D-o1OXc9.js} +0 -0
  260. /package/dist/assets/{dist-BtrqKtvn.js → dist-DnIl7RU-.js} +0 -0
  261. /package/dist/assets/{emotion-is-prop-valid.esm-CK2zY6a8.js → emotion-is-prop-valid.esm-DiQGBfwj.js} +0 -0
  262. /package/dist/assets/{empty-state-QmmE2oN4.js → empty-state-vKu4k0Y4.js} +0 -0
  263. /package/dist/assets/{en-US-BXNio91F.js → en-US-DZwIjHwu.js} +0 -0
  264. /package/dist/assets/{errors-9jMmWHd9.js → errors-48KFPvCp.js} +0 -0
  265. /package/dist/assets/{events-XR_LpvHc.js → events-BRbNg7Li.js} +0 -0
  266. /package/dist/assets/{extends-CeSFM22p.js → extends-2LbFKIQQ.js} +0 -0
  267. /package/dist/assets/{house-DHu4JLi3.js → house-DkdBWh44.js} +0 -0
  268. /package/dist/assets/{icons-avFV3lBF.js → icons-D3YFXNmD.js} +0 -0
  269. /package/dist/assets/{image-BzUcK6ho.js → image-jhXeQEgs.js} +0 -0
  270. /package/dist/assets/{isValid-DKyiOp4U.js → isValid-Cgon0fXK.js} +0 -0
  271. /package/dist/assets/{kbd-UVzWBHfi.js → kbd-BCXa3Ocm.js} +0 -0
  272. /package/dist/assets/{link-e5mRDDOC.js → link-My4Pey3q.js} +0 -0
  273. /package/dist/assets/{links-CCkJpphF.js → links-DK7te6sJ.js} +0 -0
  274. /package/dist/assets/{message-circle-RkIzfQEi.js → message-circle-D_YIPPZo.js} +0 -0
  275. /package/dist/assets/{micromark-factory-space-BUQpMdx2.js → micromark-factory-space-P--XWZhg.js} +0 -0
  276. /package/dist/assets/{multi-icon-CTvmuLdL.js → multi-icon-CGXdgpE4.js} +0 -0
  277. /package/dist/assets/{numbers-_ry1Nlla.js → numbers-BKZTJMZ6.js} +0 -0
  278. /package/dist/assets/{objectWithoutPropertiesLoose-BkUn3I0-.js → objectWithoutPropertiesLoose-Msf1n32r.js} +0 -0
  279. /package/dist/assets/{ordinal-Cn9sg_-a.js → ordinal-CIZb_ice.js} +0 -0
  280. /package/dist/assets/{package-BTIV9-Dk.js → package-BoMcg6sy.js} +0 -0
  281. /package/dist/assets/{panel-context-DC1vAeB3.js → panel-context-RKllh8pM.js} +0 -0
  282. /package/dist/assets/{paths-DhuNSnZ_.js → paths-kNeJ8nbe.js} +0 -0
  283. /package/dist/assets/{plus-ZXRHY1up.js → plus-CExKUszm.js} +0 -0
  284. /package/dist/assets/{preload-helper-BW0IMuFq.js → preload-helper-y72bE5iF.js} +0 -0
  285. /package/dist/assets/{prop-types-B6Y2e__V.js → prop-types-D_pYuT11.js} +0 -0
  286. /package/dist/assets/{purify.es-DfJp_of2.js → purify.es-DdxMtdqK.js} +0 -0
  287. /package/dist/assets/{range-DNqFcYmr.js → range-ClqUI25v.js} +0 -0
  288. /package/dist/assets/{react-icons.esm-DCqqMD4w.js → react-icons.esm-C2u-_EAQ.js} +0 -0
  289. /package/dist/assets/{react-resizable-panels.browser.esm-Ce2ksurd.js → react-resizable-panels.browser.esm-CgWOEYeG.js} +0 -0
  290. /package/dist/assets/{refresh-ccw-Bee7JLOl.js → refresh-ccw-CUkO1Vlo.js} +0 -0
  291. /package/dist/assets/{refresh-cw-C9FftltI.js → refresh-cw-DcEasnos.js} +0 -0
  292. /package/dist/assets/{requests-DqJEWJ-Q.js → requests-Bm3bohzL.js} +0 -0
  293. /package/dist/assets/{rotate-ccw-ZsOWbQCw.js → rotate-ccw-CBXqO1Fd.js} +0 -0
  294. /package/dist/assets/{save-BNNMzGly.js → save-CGxzAyve.js} +0 -0
  295. /package/dist/assets/{semaphore-X3ApuO41.js → semaphore-FlZezxaf.js} +0 -0
  296. /package/dist/assets/{session-CsT5Gg9j.js → session-B6_8umQX.js} +0 -0
  297. /package/dist/assets/{settings-1WkYMLdR.js → settings-Cn43l_vx.js} +0 -0
  298. /package/dist/assets/{sparkles-COaEc8Qn.js → sparkles-DctOjjEz.js} +0 -0
  299. /package/dist/assets/{spinner-BbI9qk88.js → spinner-DTBVbtl-.js} +0 -0
  300. /package/dist/assets/{square-35tXIgiR.js → square-DPWHdF_-.js} +0 -0
  301. /package/dist/assets/{square-function-Dx0pKHko.js → square-function-CPbVtjKW.js} +0 -0
  302. /package/dist/assets/{stex-0ac7Aukl.js → stex-C6JeW1YI.js} +0 -0
  303. /package/dist/assets/{table-CnW850Wt.js → table-Fk_msRcD.js} +0 -0
  304. /package/dist/assets/{timer-B6DpdVnC.js → timer-BgiWPhV9.js} +0 -0
  305. /package/dist/assets/{trash-2-CqTUwVuU.js → trash-2-CjPoUZCP.js} +0 -0
  306. /package/dist/assets/{trash-BW_KaFjz.js → trash-Icq8_IVf.js} +0 -0
  307. /package/dist/assets/{triangle-alert-D8Ft17xk.js → triangle-alert-CV7pqa1o.js} +0 -0
  308. /package/dist/assets/{types-BnrgJ4Gh.js → types-xF5uWODg.js} +0 -0
  309. /package/dist/assets/{use-toast-kCNiuc-_.js → use-toast-BH8bU9Xf.js} +0 -0
  310. /package/dist/assets/{useAsyncData-DAQcLiyE.js → useAsyncData-CT1LpOBD.js} +0 -0
  311. /package/dist/assets/{useDebounce-CpLI2dsc.js → useDebounce-BlBSYv0n.js} +0 -0
  312. /package/dist/assets/{useDeepCompareMemoize-CWcgQCbT.js → useDeepCompareMemoize-zUHU--0D.js} +0 -0
  313. /package/dist/assets/{useHotkey-CJo8iX8v.js → useHotkey-C-blZ3Z8.js} +0 -0
  314. /package/dist/assets/{useIframeCapabilities-B0dNZiKK.js → useIframeCapabilities-DuGyzPVb.js} +0 -0
  315. /package/dist/assets/{useTheme-D_ZbTTJw.js → useTheme-CWoNQwFz.js} +0 -0
  316. /package/dist/assets/{uuid-ClFZlR7U.js → uuid-BukULOeS.js} +0 -0
  317. /package/dist/assets/{workflow-f8flhcJ1.js → workflow-ClrYl5m7.js} +0 -0
@@ -1,9 +1,12 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
- import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import { readFileSync } from "node:fs";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
4
  import {
4
5
  ISLAND_DATA_ATTRIBUTES,
5
6
  ISLAND_TAG_NAMES,
7
+ ISLANDS_JSON_SCRIPT_TYPE,
6
8
  } from "@/core/islands/constants";
9
+ import { Logger } from "@/utils/Logger";
7
10
  import {
8
11
  createMarimoFile,
9
12
  extractIslandCodeFromEmbed,
@@ -15,6 +18,43 @@ import {
15
18
  } from "../parse";
16
19
  import { createMockIslandElement, createMockIslands } from "./test-utils.tsx";
17
20
 
21
+ function createPayloadCell(
22
+ overrides: Partial<{
23
+ cellId: string;
24
+ code: string;
25
+ outputHtml: string;
26
+ outputMimetype: string;
27
+ reactive: boolean;
28
+ displayCode: boolean;
29
+ displayOutput: boolean;
30
+ }> = {},
31
+ ) {
32
+ return {
33
+ cellId: "cell-1",
34
+ code: 'print("payload")',
35
+ outputHtml: "<div>payload</div>",
36
+ outputMimetype: "text/html",
37
+ reactive: true,
38
+ displayCode: false,
39
+ displayOutput: true,
40
+ ...overrides,
41
+ };
42
+ }
43
+
44
+ function appendPayload(
45
+ root: HTMLElement,
46
+ payload: {
47
+ schemaVersion: number;
48
+ appId: string;
49
+ cells: ReturnType<typeof createPayloadCell>[];
50
+ },
51
+ ) {
52
+ const script = document.createElement("script");
53
+ script.type = ISLANDS_JSON_SCRIPT_TYPE;
54
+ script.textContent = JSON.stringify(payload);
55
+ root.appendChild(script);
56
+ }
57
+
18
58
  describe("createMarimoFile", () => {
19
59
  it("should return a string", () => {
20
60
  const app = {
@@ -90,6 +130,27 @@ describe("createMarimoFile", () => {
90
130
  `);
91
131
  });
92
132
 
133
+ it("should create disabled marimo cells", () => {
134
+ const app = {
135
+ cells: [{ code: "x = 0", disabled: true }, { code: "x = 1" }],
136
+ };
137
+
138
+ const result = createMarimoFile(app);
139
+
140
+ expect(result).toMatchInlineSnapshot(`
141
+ "import marimo
142
+ app = marimo.App()
143
+ @app.cell(disabled=True)
144
+ def __():
145
+ pass
146
+ return
147
+ @app.cell
148
+ def __():
149
+ x = 1
150
+ return"
151
+ `);
152
+ });
153
+
93
154
  it("should properly indent multi-line code", () => {
94
155
  const app = {
95
156
  cells: [{ code: "if True:\n print('hello')\n print('world')" }],
@@ -459,6 +520,7 @@ describe("parseMarimoIslandApps", () => {
459
520
 
460
521
  afterEach(() => {
461
522
  document.body.removeChild(container);
523
+ vi.restoreAllMocks();
462
524
  });
463
525
 
464
526
  it("should parse islands from document", () => {
@@ -528,4 +590,526 @@ describe("parseMarimoIslandApps", () => {
528
590
  ]
529
591
  `);
530
592
  });
593
+
594
+ it("should use supported JSON payload data for matched islands", () => {
595
+ const island = createMockIslandElement({
596
+ appId: "app1",
597
+ cellId: "cell-1",
598
+ code: 'print("dom")',
599
+ innerHTML: "<div>dom</div>",
600
+ });
601
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
602
+ container.appendChild(island);
603
+ appendPayload(container, {
604
+ schemaVersion: 1,
605
+ appId: "app1",
606
+ cells: [createPayloadCell()],
607
+ });
608
+
609
+ const result = parseMarimoIslandApps(container);
610
+
611
+ expect(result).toEqual([
612
+ {
613
+ id: "app1",
614
+ payloadBacked: true,
615
+ cells: [
616
+ {
617
+ cellId: "cell-1",
618
+ code: 'print("payload")',
619
+ idx: 0,
620
+ output: "<div>payload</div>",
621
+ },
622
+ ],
623
+ },
624
+ ]);
625
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0");
626
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull();
627
+ expect(extractIslandCodeFromEmbed(island)).toBe('print("payload")');
628
+ expect(island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)?.innerHTML).toBe(
629
+ "<div>payload</div>",
630
+ );
631
+ });
632
+
633
+ it("should parse Python-generated island payload snapshots", () => {
634
+ const html = readFileSync(
635
+ new URL(
636
+ "../../../../../tests/_islands/snapshots/html-payload.txt",
637
+ import.meta.url,
638
+ ).pathname.replace(/^\/@fs/, ""),
639
+ "utf8",
640
+ );
641
+ container.innerHTML = html;
642
+
643
+ const result = parseMarimoIslandApps(container);
644
+ const islands = container.querySelectorAll<HTMLElement>(
645
+ ISLAND_TAG_NAMES.ISLAND,
646
+ );
647
+
648
+ expect(result).toEqual([
649
+ {
650
+ id: "main",
651
+ payloadBacked: true,
652
+ cells: [
653
+ {
654
+ cellId: "Hbol",
655
+ code: "import marimo as mo",
656
+ idx: 0,
657
+ output: "",
658
+ },
659
+ {
660
+ cellId: "MJUe",
661
+ code: "mo.md('Hello, HTML!')",
662
+ idx: 1,
663
+ output: "",
664
+ },
665
+ ],
666
+ },
667
+ ]);
668
+ expect(islands[0].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBeNull();
669
+ expect(islands[1].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0");
670
+ expect(islands[2].getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
671
+ });
672
+
673
+ it("should fall back to DOM islands for unsupported payload versions", () => {
674
+ const island = createMockIslandElement({
675
+ appId: "app1",
676
+ cellId: "cell-1",
677
+ code: 'print("dom")',
678
+ innerHTML: "<div>dom</div>",
679
+ });
680
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
681
+ container.appendChild(island);
682
+ appendPayload(container, {
683
+ schemaVersion: 2,
684
+ appId: "app1",
685
+ cells: [createPayloadCell()],
686
+ });
687
+
688
+ const result = parseMarimoIslandApps(container);
689
+
690
+ expect(result).toEqual([
691
+ {
692
+ id: "app1",
693
+ cells: [
694
+ {
695
+ code: 'print("dom")',
696
+ idx: 0,
697
+ output: "<div>dom</div>",
698
+ },
699
+ ],
700
+ },
701
+ ]);
702
+ });
703
+
704
+ it("should ignore payload scripts rendered inside island output", () => {
705
+ const nestedPayload = {
706
+ schemaVersion: 1,
707
+ appId: "app1",
708
+ cells: [
709
+ createPayloadCell({
710
+ code: "payload_code_should_not_run = True",
711
+ outputHtml: "<div>payload</div>",
712
+ }),
713
+ ],
714
+ };
715
+ const island = createMockIslandElement({
716
+ appId: "app1",
717
+ cellId: "cell-1",
718
+ code: 'print("dom")',
719
+ innerHTML: `<div>dom</div><script type="${ISLANDS_JSON_SCRIPT_TYPE}">${JSON.stringify(nestedPayload)}</script>`,
720
+ });
721
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
722
+ container.appendChild(island);
723
+
724
+ const result = parseMarimoIslandApps(container);
725
+
726
+ expect(result).toEqual([
727
+ {
728
+ id: "app1",
729
+ cells: [
730
+ {
731
+ code: 'print("dom")',
732
+ idx: 0,
733
+ output: island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)
734
+ ?.innerHTML,
735
+ },
736
+ ],
737
+ },
738
+ ]);
739
+ });
740
+
741
+ it("should use payload order for runtime cell indices", () => {
742
+ const second = createMockIslandElement({
743
+ appId: "app1",
744
+ cellId: "cell-2",
745
+ code: "second_dom = True",
746
+ innerHTML: "<div>second dom</div>",
747
+ });
748
+ const first = createMockIslandElement({
749
+ appId: "app1",
750
+ cellId: "cell-1",
751
+ code: "first_dom = True",
752
+ innerHTML: "<div>first dom</div>",
753
+ });
754
+ for (const island of [second, first]) {
755
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
756
+ container.appendChild(island);
757
+ }
758
+ appendPayload(container, {
759
+ schemaVersion: 1,
760
+ appId: "app1",
761
+ cells: [
762
+ createPayloadCell({
763
+ cellId: "cell-1",
764
+ code: "first_payload = True",
765
+ outputHtml: "<div>first payload</div>",
766
+ }),
767
+ createPayloadCell({
768
+ cellId: "cell-2",
769
+ code: "second_payload = True",
770
+ outputHtml: "<div>second payload</div>",
771
+ }),
772
+ ],
773
+ });
774
+
775
+ const result = parseMarimoIslandApps(container);
776
+
777
+ expect(result[0].cells.map((cell) => cell.code)).toEqual([
778
+ "first_payload = True",
779
+ "second_payload = True",
780
+ ]);
781
+ expect(first.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0");
782
+ expect(second.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
783
+ });
784
+
785
+ it("should include payload-only runtime cells", () => {
786
+ const island = createMockIslandElement({
787
+ appId: "app1",
788
+ cellId: "cell-2",
789
+ code: "value",
790
+ innerHTML: "<div>value</div>",
791
+ });
792
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
793
+ container.appendChild(island);
794
+ appendPayload(container, {
795
+ schemaVersion: 1,
796
+ appId: "app1",
797
+ cells: [
798
+ createPayloadCell({
799
+ cellId: "cell-1",
800
+ code: "import marimo as mo",
801
+ outputHtml: "",
802
+ }),
803
+ createPayloadCell({
804
+ cellId: "cell-2",
805
+ code: "mo.md('visible')",
806
+ outputHtml: "<div>visible</div>",
807
+ }),
808
+ ],
809
+ });
810
+
811
+ const result = parseMarimoIslandApps(container);
812
+
813
+ expect(result[0].cells.map((cell) => cell.code)).toEqual([
814
+ "import marimo as mo",
815
+ "mo.md('visible')",
816
+ ]);
817
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
818
+ });
819
+
820
+ it("should bind payload-backed islands by runtime index after static cells", () => {
821
+ const island = createMockIslandElement({
822
+ appId: "app1",
823
+ cellId: "cell-2",
824
+ code: "visible_dom = True",
825
+ innerHTML: "<div>visible dom</div>",
826
+ });
827
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
828
+ container.appendChild(island);
829
+ appendPayload(container, {
830
+ schemaVersion: 1,
831
+ appId: "app1",
832
+ cells: [
833
+ createPayloadCell({
834
+ cellId: "cell-1",
835
+ code: "",
836
+ outputHtml: "<div>static</div>",
837
+ reactive: false,
838
+ }),
839
+ createPayloadCell({
840
+ cellId: "cell-2",
841
+ code: "visible_payload = True",
842
+ outputHtml: "<div>visible payload</div>",
843
+ }),
844
+ ],
845
+ });
846
+
847
+ const result = parseMarimoIslandApps(container);
848
+
849
+ expect(result[0].cells).toEqual([
850
+ {
851
+ cellId: "cell-1",
852
+ code: "",
853
+ disabled: true,
854
+ idx: 0,
855
+ output: "<div>static</div>",
856
+ },
857
+ {
858
+ cellId: "cell-2",
859
+ code: "visible_payload = True",
860
+ idx: 1,
861
+ output: "<div>visible payload</div>",
862
+ },
863
+ ]);
864
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
865
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull();
866
+ });
867
+
868
+ it("should fall back to DOM when no payload cell matches an island", () => {
869
+ const island = createMockIslandElement({
870
+ appId: "app1",
871
+ cellId: "dom-only",
872
+ code: "dom_only = True",
873
+ innerHTML: "<div>dom only</div>",
874
+ });
875
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
876
+ island.removeAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX);
877
+ container.appendChild(island);
878
+ appendPayload(container, {
879
+ schemaVersion: 1,
880
+ appId: "app1",
881
+ cells: [
882
+ createPayloadCell({
883
+ cellId: "payload-only",
884
+ code: "payload_only = True",
885
+ outputHtml: "<div>payload only</div>",
886
+ }),
887
+ ],
888
+ });
889
+
890
+ const result = parseMarimoIslandApps(container);
891
+
892
+ expect(result).toEqual([
893
+ {
894
+ id: "app1",
895
+ cells: [
896
+ {
897
+ code: "dom_only = True",
898
+ idx: 0,
899
+ output: "<div>dom only</div>",
900
+ },
901
+ ],
902
+ },
903
+ ]);
904
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0");
905
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBe(
906
+ "dom-only",
907
+ );
908
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE)).toBe("true");
909
+ });
910
+
911
+ it("should ignore payloads without matching islands", () => {
912
+ const warn = vi.spyOn(Logger, "warn").mockImplementation(() => undefined);
913
+ appendPayload(container, {
914
+ schemaVersion: 1,
915
+ appId: "app1",
916
+ cells: [createPayloadCell()],
917
+ });
918
+
919
+ const result = parseMarimoIslandApps(container);
920
+
921
+ expect(result).toEqual([]);
922
+ expect(warn).toHaveBeenCalledWith("No embedded marimo apps found.");
923
+ });
924
+
925
+ it("should still parse DOM-only apps when another app has payload", () => {
926
+ const payloadIsland = createMockIslandElement({
927
+ appId: "app1",
928
+ cellId: "cell-1",
929
+ code: "payload_dom = True",
930
+ innerHTML: "<div>payload dom</div>",
931
+ });
932
+ const domIsland = createMockIslandElement({
933
+ appId: "app2",
934
+ code: "dom_app = True",
935
+ innerHTML: "<div>dom app</div>",
936
+ });
937
+ for (const island of [payloadIsland, domIsland]) {
938
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
939
+ container.appendChild(island);
940
+ }
941
+ appendPayload(container, {
942
+ schemaVersion: 1,
943
+ appId: "app1",
944
+ cells: [createPayloadCell()],
945
+ });
946
+
947
+ const result = parseMarimoIslandApps(container);
948
+
949
+ expect(result.map((app) => app.id)).toEqual(["app1", "app2"]);
950
+ expect(result[0].cells[0].code).toBe('print("payload")');
951
+ expect(result[1].cells[0].code).toBe("dom_app = True");
952
+ });
953
+
954
+ it("should materialize non-reactive payload islands without runtime cells", () => {
955
+ const island = createMockIslandElement({
956
+ appId: "app1",
957
+ cellId: "cell-1",
958
+ code: "static_dom = True",
959
+ innerHTML: "<div>static dom</div>",
960
+ });
961
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "false");
962
+ island.removeAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX);
963
+ container.appendChild(island);
964
+ appendPayload(container, {
965
+ schemaVersion: 1,
966
+ appId: "app1",
967
+ cells: [
968
+ createPayloadCell({
969
+ code: "",
970
+ outputHtml: "<div>static payload</div>",
971
+ reactive: false,
972
+ }),
973
+ ],
974
+ });
975
+
976
+ const result = parseMarimoIslandApps(container);
977
+
978
+ expect(result).toEqual([]);
979
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBeNull();
980
+ expect(island.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID)).toBeNull();
981
+ expect(island.querySelector(ISLAND_TAG_NAMES.CELL_OUTPUT)?.innerHTML).toBe(
982
+ "<div>static payload</div>",
983
+ );
984
+ });
985
+
986
+ it("should keep non-reactive display code out of runtime cells", () => {
987
+ const staticIsland = createMockIslandElement({
988
+ appId: "app1",
989
+ cellId: "cell-1",
990
+ code: "x = 0",
991
+ innerHTML: "<div>static</div>",
992
+ });
993
+ const reactiveIsland = createMockIslandElement({
994
+ appId: "app1",
995
+ cellId: "cell-2",
996
+ code: "y = 1",
997
+ innerHTML: "<div>reactive</div>",
998
+ });
999
+ staticIsland.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "false");
1000
+ reactiveIsland.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
1001
+ container.append(staticIsland, reactiveIsland);
1002
+ appendPayload(container, {
1003
+ schemaVersion: 1,
1004
+ appId: "app1",
1005
+ cells: [
1006
+ createPayloadCell({
1007
+ cellId: "cell-1",
1008
+ code: "x = 0",
1009
+ outputHtml: "<div>static payload</div>",
1010
+ reactive: false,
1011
+ displayCode: true,
1012
+ }),
1013
+ createPayloadCell({
1014
+ cellId: "cell-2",
1015
+ code: "y = 1",
1016
+ outputHtml: "<div>reactive payload</div>",
1017
+ }),
1018
+ ],
1019
+ });
1020
+
1021
+ const result = parseMarimoIslandApps(container);
1022
+ const file = createMarimoFile(result[0]);
1023
+
1024
+ expect(result[0].cells).toEqual([
1025
+ {
1026
+ cellId: "cell-1",
1027
+ code: "",
1028
+ disabled: true,
1029
+ idx: 0,
1030
+ output: "<div>static payload</div>",
1031
+ },
1032
+ {
1033
+ cellId: "cell-2",
1034
+ code: "y = 1",
1035
+ idx: 1,
1036
+ output: "<div>reactive payload</div>",
1037
+ },
1038
+ ]);
1039
+ expect(file).not.toContain("x = 0");
1040
+ expect(file).toContain("@app.cell(disabled=True)\ndef __():\n pass");
1041
+ expect(reactiveIsland.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe(
1042
+ "1",
1043
+ );
1044
+ });
1045
+
1046
+ it("should update editor initial values from payload code", () => {
1047
+ const island = createMockIslandElement({
1048
+ appId: "app1",
1049
+ cellId: "cell-1",
1050
+ code: 'print("dom")',
1051
+ innerHTML: "<div>dom</div>",
1052
+ });
1053
+ island.insertAdjacentHTML(
1054
+ "beforeend",
1055
+ '<div data-marimo-element><marimo-code-editor data-initial-value="\\"print(\\\\\\"dom\\\\\\")\\""></marimo-code-editor></div>',
1056
+ );
1057
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
1058
+ container.appendChild(island);
1059
+ appendPayload(container, {
1060
+ schemaVersion: 1,
1061
+ appId: "app1",
1062
+ cells: [createPayloadCell()],
1063
+ });
1064
+
1065
+ parseMarimoIslandApps(container);
1066
+
1067
+ expect(
1068
+ island
1069
+ .querySelector(ISLAND_TAG_NAMES.CODE_EDITOR)
1070
+ ?.getAttribute("data-initial-value"),
1071
+ ).toBe(JSON.stringify('print("payload")'));
1072
+ });
1073
+
1074
+ it("should match duplicate cell ids by occurrence", () => {
1075
+ const first = createMockIslandElement({
1076
+ appId: "app1",
1077
+ cellId: "cell-1",
1078
+ code: "dom_first = True",
1079
+ innerHTML: "<div>dom first</div>",
1080
+ });
1081
+ const second = createMockIslandElement({
1082
+ appId: "app1",
1083
+ cellId: "cell-1",
1084
+ code: "dom_second = True",
1085
+ innerHTML: "<div>dom second</div>",
1086
+ });
1087
+ for (const island of [first, second]) {
1088
+ island.setAttribute(ISLAND_DATA_ATTRIBUTES.REACTIVE, "true");
1089
+ container.appendChild(island);
1090
+ }
1091
+ appendPayload(container, {
1092
+ schemaVersion: 1,
1093
+ appId: "app1",
1094
+ cells: [
1095
+ createPayloadCell({
1096
+ code: "payload_first = True",
1097
+ outputHtml: "<div>payload first</div>",
1098
+ }),
1099
+ createPayloadCell({
1100
+ code: "payload_second = True",
1101
+ outputHtml: "<div>payload second</div>",
1102
+ }),
1103
+ ],
1104
+ });
1105
+
1106
+ const result = parseMarimoIslandApps(container);
1107
+
1108
+ expect(result[0].cells.map((cell) => cell.code)).toEqual([
1109
+ "payload_first = True",
1110
+ "payload_second = True",
1111
+ ]);
1112
+ expect(first.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("0");
1113
+ expect(second.getAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX)).toBe("1");
1114
+ });
531
1115
  });
@@ -23,12 +23,14 @@ import type { WorkerFactory } from "@/core/islands/worker-factory";
23
23
  export function createMockIslandElement(options: {
24
24
  appId?: string;
25
25
  cellIdx?: string;
26
+ cellId?: string;
26
27
  code?: string;
27
28
  innerHTML?: string;
28
29
  }): HTMLElement {
29
30
  const {
30
31
  appId = "test-app",
31
32
  cellIdx = "0",
33
+ cellId,
32
34
  code = "import marimo as mo",
33
35
  innerHTML = "",
34
36
  } = options;
@@ -36,6 +38,9 @@ export function createMockIslandElement(options: {
36
38
  const element = document.createElement(ISLAND_TAG_NAMES.ISLAND);
37
39
  element.setAttribute(ISLAND_DATA_ATTRIBUTES.APP_ID, appId);
38
40
  element.setAttribute(ISLAND_DATA_ATTRIBUTES.CELL_IDX, cellIdx);
41
+ if (cellId) {
42
+ element.setAttribute(ISLAND_DATA_ATTRIBUTES.CELL_ID, cellId);
43
+ }
39
44
 
40
45
  if (code) {
41
46
  const codeElement = document.createElement(ISLAND_TAG_NAMES.CELL_CODE);
@@ -146,6 +151,7 @@ export async function waitForNoError<T>(
146
151
 
147
152
  export interface IslandSpec {
148
153
  appId?: string;
154
+ cellId?: string;
149
155
  reactive?: boolean;
150
156
  code?: string;
151
157
  output?: string;
@@ -160,6 +166,9 @@ export function buildIslandHTML(islands: IslandSpec[]): string {
160
166
  return islands
161
167
  .map((spec) => {
162
168
  const appId = spec.appId ?? "test-app";
169
+ const cellId = spec.cellId
170
+ ? ` ${ISLAND_DATA_ATTRIBUTES.CELL_ID}="${spec.cellId}"`
171
+ : "";
163
172
  const reactive = spec.reactive ?? true;
164
173
  const output = spec.output ?? "<div>output</div>";
165
174
  const code = spec.code ?? 'print("hello")';
@@ -169,7 +178,7 @@ export function buildIslandHTML(islands: IslandSpec[]): string {
169
178
  : "";
170
179
  const outputTag = `<${ISLAND_TAG_NAMES.CELL_OUTPUT}>${output}</${ISLAND_TAG_NAMES.CELL_OUTPUT}>`;
171
180
 
172
- return `<${ISLAND_TAG_NAMES.ISLAND} ${ISLAND_DATA_ATTRIBUTES.APP_ID}="${appId}" ${ISLAND_DATA_ATTRIBUTES.REACTIVE}="${reactive}">${outputTag}${codeTag}</${ISLAND_TAG_NAMES.ISLAND}>`;
181
+ return `<${ISLAND_TAG_NAMES.ISLAND} ${ISLAND_DATA_ATTRIBUTES.APP_ID}="${appId}"${cellId} ${ISLAND_DATA_ATTRIBUTES.REACTIVE}="${reactive}">${outputTag}${codeTag}</${ISLAND_TAG_NAMES.ISLAND}>`;
173
182
  })
174
183
  .join("\n");
175
184
  }
@@ -124,8 +124,13 @@ export class IslandsPyodideBridge implements RunRequests, EditRequests {
124
124
  `Starting sessions for ${apps.length} app(s):`,
125
125
  apps.map((a) => `${a.id} (${a.cells.length} cells)`),
126
126
  );
127
+ // Payload-backed apps already carry the exact runtime cells and order. The
128
+ // full-notebook export context may describe a different source and would
129
+ // override the payload contract for single-app pages.
127
130
  const exportContext =
128
- apps.length === 1 ? getMarimoExportContext() : undefined;
131
+ apps.length === 1 && !apps[0]?.payloadBacked
132
+ ? getMarimoExportContext()
133
+ : undefined;
129
134
  const notebookCode = exportContext?.notebookCode;
130
135
  for (const app of apps) {
131
136
  const file = notebookCode || createMarimoFile(app);
@@ -10,6 +10,8 @@ export const ISLAND_TAG_NAMES = {
10
10
  CODE_EDITOR: "marimo-code-editor",
11
11
  } as const;
12
12
 
13
+ export const ISLANDS_JSON_SCRIPT_TYPE = "application/vnd.marimo.islands+json";
14
+
13
15
  /**
14
16
  * Data attributes for islands
15
17
  */