@marimo-team/islands 0.24.3-dev2 → 0.24.3-dev22
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.
- package/dist/{ConnectedDataExplorerComponent-qIKbwYin.js → ConnectedDataExplorerComponent-BLO7UDpo.js} +18 -18
- package/dist/{ErrorBoundary-CR-ZQN_c.js → ErrorBoundary-B7uSdDUm.js} +6 -6
- package/dist/{ImageComparisonComponent-2a9TMMm2.js → ImageComparisonComponent-RspMflu6.js} +3 -3
- package/dist/{Plot-C-9MQeGP.js → Plot-CTyjbQDT.js} +21032 -20666
- package/dist/_baseMerge-Bnytch8P.js +165 -0
- package/dist/{abnfDiagram-N423BO3Z-CQKwzX8t.js → abnfDiagram-VCTEODGH-DCb2K_RB.js} +17 -18
- package/dist/{any-language-editor-CpTnK43-.js → any-language-editor-C0dftc2Z.js} +8 -8
- package/dist/arc-7ra3iNdN.js +81 -0
- package/dist/architecture-7GRP2DOG-BWLylgiA.js +3 -0
- package/dist/{architectureDiagram-T3A2C74G-CncrDpfa.js → architectureDiagram-5GKGNRK7-Bb_n642s.js} +25 -25
- package/dist/assets/__vite-browser-external-BajL8aoc.js +1 -0
- package/dist/assets/worker-BemUy60C.js +109 -0
- package/dist/blockDiagram-I7D4REHJ-BbXEXJRu.js +1922 -0
- package/dist/{button-CKBkqR9J.js → button-DdXAm8iz.js} +5 -5
- package/dist/{c4Diagram-5PPSVZJV-DarUk3Yq.js → c4Diagram-7LVT6UL2-DcLsbQmR.js} +696 -668
- package/dist/{capabilities-CMBBJTcc.js → capabilities-B3ce_GNu.js} +1 -1
- package/dist/{channel-CyiYUzJv.js → channel-B5XnTarr.js} +1 -1
- package/dist/chat-ui-Cn1TFk66.js +5835 -0
- package/dist/{check-CHig47QV.js → check-mcQyZmFG.js} +1 -1
- package/dist/{chunk-2Q5K7J3B-BMuJl2jB.js → chunk-2Q5K7J3B-BMkUkeuy.js} +2 -2
- package/dist/chunk-4HAMMTFA-D2qv8E0X.js +4188 -0
- package/dist/{chunk-5VM5RSS4-Bcq0ftdy.js → chunk-5VM5RSS4-DKsmPCL6.js} +2 -2
- package/dist/{chunk-NSK5VX7P-CDTMcJB0.js → chunk-75Z2AOVW-5_HsvXwr.js} +23 -23
- package/dist/{chunk-I66GZJ75-BqyTCAPf.js → chunk-DU6HZSFF-BUgAHvnM.js} +21 -4
- package/dist/{chunk-2GRJ4B5K-DgO8Qudq.js → chunk-F27PBJKO-DHmYWZXr.js} +4 -4
- package/dist/{chunk-KEIR6QF5-C4KX3XYh.js → chunk-FOHPRMQF-BpYR8RqP.js} +4 -4
- package/dist/{chunk-WRU74C26-BpWsbiDK.js → chunk-GMAD6QVW-Czynz8aA.js} +486 -258
- package/dist/chunk-GVQU2GXP-yQEdulRS.js +37 -0
- package/dist/{chunk-5RXB4S5H-tLNUVDdO.js → chunk-IMKFNOWR-Du9BN2Ul.js} +11 -11
- package/dist/{chunk-JWPE2WC7-BJwjGUnF.js → chunk-JWPE2WC7-DJvv1t8U.js} +2 -2
- package/dist/chunk-L3NEJ4N5-DwRWnDDK.js +245 -0
- package/dist/{chunk-7Z6QIM7H-Dc18hFxH.js → chunk-OSK3NFVY-BBKU_Ign.js} +222 -144
- package/dist/{chunk-W5SLKNZC-DLnvpEtV.js → chunk-P2QGCYS3-C0iGU29N.js} +20 -20
- package/dist/{chunk-KBJHAD2P-BuqWqkcW.js → chunk-POPQ4Y6H-BCbS3Ozc.js} +4 -4
- package/dist/{chunk-4I5QYGJK-DpytHuZQ.js → chunk-PWAF6VOD-CTFCL0jI.js} +4 -4
- package/dist/{chunk-JQJVKLGR-CgqCwe8E.js → chunk-SHT3W25Y-tUelricH.js} +109 -63
- package/dist/{chunk-6Q2QTUOP-DmTcEBMn.js → chunk-SVP7TREG-DK3egkfQ.js} +5 -5
- package/dist/{chunk-GF5L2VYU-B0wgCQgS.js → chunk-TICWLB2K-DRANTdnp.js} +13 -13
- package/dist/{chunk-XXDRQBXY-D73H4IN0.js → chunk-XXDRQBXY-Dnl5VBqG.js} +3 -3
- package/dist/{chunk-Y2CYZVJY-DoegUj_e.js → chunk-Y2CYZVJY-DKKS1VyV.js} +1 -1
- package/dist/{chunk-5FQGJX7Z-B85XCPv6.js → chunk-YOKDWASO-DrWbKnxA.js} +6925 -5460
- package/dist/classDiagram-ZZMXUADV-7wCSVH7o.js +30 -0
- package/dist/classDiagram-v2-VYDZK3BY-QwnvcnhB.js +30 -0
- package/dist/{common-C4UahYwr.js → common-DIyUaEO6.js} +7398 -6912
- package/dist/{compiler-runtime-CAH9RLw2.js → compiler-runtime-Cj8ZWiNS.js} +2 -2
- package/dist/{copy-CD7S58CY.js → copy-C0N4m1lm.js} +4 -4
- package/dist/{cose-bilkent-JH36ORCC-FUWHkXFX.js → cose-bilkent-JH36ORCC-_LyRKVqm.js} +2 -2
- package/dist/cubic-OaEBhQPK.js +1404 -0
- package/dist/cynefin-OW5HDTMX-obq-i80l.js +3 -0
- package/dist/{cynefinDiagram-MW4NZA55-BXSFK93J.js → cynefinDiagram-5FMLGOSQ-CB7O4IZB.js} +10 -10
- package/dist/{dagre-CGyalH38.js → dagre-DfYd3btw.js} +678 -537
- package/dist/dagre-GXQ25YYZ-C-a95ISW.js +425 -0
- package/dist/{data-grid-overlay-editor-DZM4BAaI.js → data-grid-overlay-editor-C5eUZVTo.js} +8 -9
- package/dist/{data-grid-types-BnZwWG8z.js → data-grid-types-BucVmDDp.js} +1 -1
- package/dist/{defaultLocale-DKaU_opG.js → defaultLocale-JI_lnoCe.js} +1 -1
- package/dist/{diagram-7IWD3JNH-BjfzDNvj.js → diagram-S7CK7UJ4-BsKLYQaH.js} +40 -39
- package/dist/{diagram-UB23O5K3-DDg-7wLA.js → diagram-UQ7AKVKN-ppYdvuTN.js} +10 -10
- package/dist/{diagram-B4RE2ZJO-CKccR9eE.js → diagram-VSXAHHWV-BKpmG23x.js} +10 -10
- package/dist/{diagram-Q27KOJAE-Zhz01ss7.js → diagram-VX7I27RA-CAMK2l0E.js} +21 -21
- package/dist/{diagram-LBJQPF4R-CJ-bOruh.js → diagram-Z3DM3KII-CxQ7MggT.js} +10 -10
- package/dist/{dist-dAqZAPcF.js → dist-1HDa70oE.js} +3 -3
- package/dist/{dist-3_o3T78I.js → dist-6ChWbo8z.js} +13 -13
- package/dist/{dist-Re9sOPOx.js → dist-9x1ZRe-e.js} +2 -2
- package/dist/{dist-DEeLqRlU.js → dist-B1vYLK28.js} +1 -1
- package/dist/{dist-C5Bn52W4.js → dist-B8D7McG3.js} +3 -3
- package/dist/{dist-_XvgytiS.js → dist-BHCHt1NI.js} +1 -1
- package/dist/{dist-CRjAdnqF.js → dist-BRxfaJgs.js} +3 -3
- package/dist/{dist-Byj2bV8o.js → dist-BVGtK7Ht.js} +1 -1
- package/dist/{dist-BIN5LKyE.js → dist-BaHjhkpZ.js} +2 -2
- package/dist/{dist-DVFbIwc5.js → dist-BtKIs9N-.js} +1 -1
- package/dist/{dist-BrQGcfQ9.js → dist-C2KzV-vf.js} +2 -2
- package/dist/{dist-DJFiGP2k.js → dist-C2wDlYdD.js} +2 -2
- package/dist/{dist-BVRM2y1P.js → dist-C8xMLVYi.js} +2 -2
- package/dist/dist-CMh_W4y4.js +538 -0
- package/dist/{dist-BzN60Z2s.js → dist-CPGxfVGX.js} +1 -1
- package/dist/{dist-C7v-9nUK.js → dist-Cm3iAFMD.js} +3 -3
- package/dist/{dist-CGAxEiaM.js → dist-Cs2FijYk.js} +2 -2
- package/dist/{dist-hXd65f0_.js → dist-D1PpnuZB.js} +1 -1
- package/dist/{dist-VdvbxG72.js → dist-DHOTQar0.js} +1 -1
- package/dist/{dist-DcgzXCfy.js → dist-DPcEtqmG.js} +2 -2
- package/dist/{dist-D4Z_qdP4.js → dist-Df0wKI0F.js} +1 -1
- package/dist/{dist-qhLI-SHd.js → dist-DszxuxS1.js} +2 -2
- package/dist/{dist-BEmkrGoQ.js → dist-Kxgjxakw.js} +1 -1
- package/dist/{dist-BbSMhhD2.js → dist-KzZ7WELx.js} +2 -2
- package/dist/{dist-jWUab2d1.js → dist-lA1Cttkb.js} +1 -1
- package/dist/{dropdown-menu-DhCfcscX.js → dropdown-menu-C73aTomr.js} +184 -184
- package/dist/{ebnfDiagram-BXEA7PRR-Dm75pCAS.js → ebnfDiagram-PWID7BFC-DzybELvk.js} +17 -18
- package/dist/{erDiagram-JOGREHBK-rVDG3VSQ.js → erDiagram-RLTQ6QDP-BVxV97ld.js} +1037 -798
- package/dist/{error-banner-WDhUzJyg.js → error-banner-hCaH06e3.js} +207 -207
- package/dist/{esm-CR1nhb1c.js → esm-BElI3qKH.js} +22 -22
- package/dist/{esm-C1d0g6Bv.js → esm-G4Fhsgng.js} +51 -37
- package/dist/{esm-CesmlDrs.js → esm-blALgIVy.js} +332 -319
- package/dist/eventmodeling-NTZA5JFV-D7nP7Uyu.js +3 -0
- package/dist/{extends-BPB6_lTK.js → extends-Do6pRuJa.js} +8 -8
- package/dist/flowDiagram-HODETNUW-BKvXsWYX.js +16 -0
- package/dist/{formats-CJMVUfb3.js → formats-vDAoRpYs.js} +8 -8
- package/dist/{ganttDiagram-PKOTCBZU-9D-LXF6P.js → ganttDiagram-EL5Y4UJY-DbzEBLbl.js} +15 -15
- package/dist/gitGraph-4MIJSDKK-Dy9uQXGh.js +3 -0
- package/dist/{gitGraphDiagram-DS77QQ5N-BfpsXTLf.js → gitGraphDiagram-WWUBYQGX-BMf0iKi1.js} +10 -10
- package/dist/{glide-data-editor-sPZ8fUFn.js → glide-data-editor-Bcy8iaZa.js} +2785 -2562
- package/dist/{glide-utils-NShAPPtn.js → glide-utils-BMnFm0vZ.js} +4 -4
- package/dist/highlighted-body-KPVGNVTW-Ad3MKZ18.js +38 -0
- package/dist/{html-to-image-BTYnN4ev.js → html-to-image-CSU-_5BI.js} +5716 -5451
- package/dist/info-A6RAGUB7-DKoayiHY.js +3 -0
- package/dist/{infoDiagram-6WML65LV-DqCTXHVy.js → infoDiagram-27XIBGKW-B_ucqo-U.js} +7 -7
- package/dist/{ishikawaDiagram-WSZJBQD7-BCUYmZ1v.js → ishikawaDiagram-5VMMS53U-BZFx9b-o.js} +8 -8
- package/dist/{journeyDiagram-NVQOT4AX-BXB6M4zN.js → journeyDiagram-3NMN7TZE-D2LcKDUO.js} +8 -8
- package/dist/{jsx-runtime-CpoKNRgu.js → jsx-runtime-DgDPJV9S.js} +1 -1
- package/dist/{kanban-definition-27J2QSJJ-CGRhrDUX.js → kanban-definition-UXKFOSKX-BpIfcu3G.js} +29 -29
- package/dist/katex-DFBiSucW.js +21840 -0
- package/dist/{label-lwzzBHUW.js → label-e37ixur5.js} +6 -6
- package/dist/{linear-D5r_1YqD.js → linear-Cnaq3Tfb.js} +4 -4
- package/dist/{loader-VZ__bv4g.js → loader-D2W4oM-3.js} +15 -15
- package/dist/main.js +7018 -12382
- package/dist/mermaid-B1Jb9HfY.js +3084 -0
- package/dist/mermaid-HWGCJPDP-DYCzSILp.js +2 -0
- package/dist/mermaid-parser.core-DxuSfYwJ.js +638 -0
- package/dist/{mhchem-BjwrxcV-.js → mhchem-DWCF06w9.js} +1 -1
- package/dist/{micromark-factory-space-DruVGzeG.js → micromark-factory-space-DGxAzmw8.js} +2 -2
- package/dist/{mindmap-definition-FAOFIHXS-C9gRhzZq.js → mindmap-definition-YA3MSWOX-CmpAfv8K.js} +17 -17
- package/dist/{node-sql-parser-DesT1xNw.js → node-sql-parser-BiZOJ-FS.js} +0 -3
- package/dist/{number-overlay-editor-De2CabLL.js → number-overlay-editor-CFofZaOi.js} +5 -5
- package/dist/packet-AYTQ26CC-Yw7ajchJ.js +3 -0
- package/dist/{pegDiagram-VL7TDLO6-Df9IUjMD.js → pegDiagram-XKGWAZYB-DO-0Q8SE.js} +19 -20
- package/dist/{pick-SnHlmIBN.js → pick-B7vX8zxG.js} +1 -1
- package/dist/pie-WAS4IAKB-BKdKOAkL.js +3 -0
- package/dist/{pieDiagram-7S7Q4E2Y-BmRzQ8ZP.js → pieDiagram-E7YTZNPT-B1MbuA_g.js} +29 -31
- package/dist/{process-output-CsALk6tp.js → process-output-B6HE2ojm.js} +4 -4
- package/dist/purify.es-DgKyQviY.js +805 -0
- package/dist/{quadrantDiagram-CIZ2JOQS-wFBvWcxS.js → quadrantDiagram-AXDQQJYC-DftINo6g.js} +5 -5
- package/dist/radar-RG4KPBEZ-ScR_D_Ts.js +3 -0
- package/dist/railroad-74A4TZTK-DQvPSdo5.js +3 -0
- package/dist/railroad-abnf-HS5TGJTU-CsJQG2O8.js +3 -0
- package/dist/railroad-ebnf-LZEXJU2U-BgEobkSn.js +3 -0
- package/dist/railroad-peg-WCYAUIDC-DjLAjofI.js +3 -0
- package/dist/{railroadDiagram-AXF67PYL-DxbIatiN.js → railroadDiagram-O6MQD6OU-DPVOQUXC.js} +17 -18
- package/dist/{react-dom-C94wmq5w.js → react-dom-BUgJ-ab_.js} +3 -3
- package/dist/{react-DMWcHin-.js → react-ofJbxM4x.js} +2 -2
- package/dist/{react-vega-DSD5aT7_.js → react-vega-5AcMW8gG.js} +10012 -9369
- package/dist/{requirementDiagram-LRYGKXZP-X_x-Y713.js → requirementDiagram-BXWQKSXE-CC7wZ-tM.js} +20 -19
- package/dist/{reveal-component-ChYEzi00.js → reveal-component-GEGc56E6.js} +1171 -1105
- package/dist/{sankeyDiagram-W5VNT64P-BYJALbbm.js → sankeyDiagram-P5KCCOFB-CDKR5TJH.js} +4 -4
- package/dist/schemas-BDZr-nP0.js +5727 -0
- package/dist/{select-3qHpFKF9.js → select-UMOSCa3W.js} +246 -246
- package/dist/{sequenceDiagram-SI44F4Z6-BiPBe3Sv.js → sequenceDiagram-WJ2MYXX4-DomSyoJI.js} +11 -11
- package/dist/{sizeCapture-X5ZJPWSS-BKLDeh5H.js → sizeCapture-INFHLROL-Dx5SpkQF.js} +2 -2
- package/dist/{spec-CutWdqo3.js → spec-g740fOWu.js} +4 -4
- package/dist/{src-C31ngt98.js → src-CA_m4ONl.js} +298 -303
- package/dist/{stateDiagram-OKZ733FA-B7QyNBxH.js → stateDiagram-D77RDMKH-SQLLjdtF.js} +19 -20
- package/dist/stateDiagram-v2-MP3YSRHH-Dup4KkIr.js +30 -0
- package/dist/style.css +2 -2
- package/dist/{swimlanes-SLNWSIFB-B4f8VP3b.js → swimlanes-42K2YHIH-ZXbhyGv6.js} +1501 -1591
- package/dist/swimlanesDiagram-VR7AAH4N-CluwxV0g.js +30 -0
- package/dist/{swiper-component-C90YjhaV.js → swiper-component-IOUowglM.js} +39 -26
- package/dist/{time-aWGfjN8x.js → time-BieKwdYS.js} +42 -42
- package/dist/{timeline-definition-Z64GVDOM-Dacq_5lr.js → timeline-definition-24CTP7MA-B8i6B9RR.js} +7 -7
- package/dist/{toDate-D-Rx3ux5.js → toDate-C3JOXlJT.js} +10 -9
- package/dist/{tooltip-Dt77sBeT.js → tooltip-CdE8k0pS.js} +42 -42
- package/dist/treeView-Q6P3EWNA-DuRV97YF.js +3 -0
- package/dist/treemap-WGGIJYW6-AsLq-uwC.js +3 -0
- package/dist/{use-vega-container-remeasure-DUW4tRxq.js → use-vega-container-remeasure-4DwJbPWu.js} +2 -2
- package/dist/{useAsyncData-CH6-CgJF.js → useAsyncData-C0f7qnnN.js} +3 -3
- package/dist/{useDateFormatter-Cp9Jdxls.js → useDateFormatter-BKpQHt-W.js} +8 -8
- package/dist/{useDeepCompareMemoize-JC87C_jO.js → useDeepCompareMemoize-QCa0HbWB.js} +2 -2
- package/dist/{useIframeCapabilities-De3C-9b4.js → useIframeCapabilities-CVtNkI3Y.js} +2 -2
- package/dist/{useLifecycle-B4RGlyf0.js → useLifecycle-BGRBkTFT.js} +6 -6
- package/dist/useTheme-iQ0VoptU.js +904 -0
- package/dist/{vega-component-D-IXRnlx.js → vega-component-DRI4BDLQ.js} +15 -15
- package/dist/{vega-embed-container-TJ5z5dZw.js → vega-embed-container-CbnTccZi.js} +6 -6
- package/dist/vega-loader.browser-D95WfUcj.js +1139 -0
- package/dist/{vennDiagram-T6HMQDX7-D-Rcq3Iu.js → vennDiagram-4TSXK5OY-CS7lHhxI.js} +9 -9
- package/dist/wardley-WFR3VGLG-Na-tFhQJ.js +3 -0
- package/dist/{wardleyDiagram-T6FBY63Y-Z-Og7_Wd.js → wardleyDiagram-VM6X3IG4-BSm-L8JI.js} +10 -10
- package/dist/{xychartDiagram-ELKLHX3M-BDJ2dITA.js → xychartDiagram-S5SC5T6Z-8fKCJGrJ.js} +248 -139
- package/package.json +52 -52
- package/src/__mocks__/requests.ts +7 -2
- package/src/__tests__/__snapshots__/CellStatus.test.tsx.snap +12 -12
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
- package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
- package/src/components/datasources/components.tsx +4 -2
- package/src/components/editor/chrome/components/feedback-button.tsx +10 -9
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +143 -0
- package/src/components/editor/chrome/panels/packages-panel.tsx +145 -51
- package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
- package/src/components/editor/code/readonly-diff.tsx +1 -1
- package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
- package/src/components/editor/file-tree/tree-actions.tsx +11 -14
- package/src/components/editor/output/Outputs.css +1 -0
- package/src/components/editor/package-alert.tsx +25 -1
- package/src/components/home/components.tsx +17 -0
- package/src/components/pages/gallery-page.tsx +2 -4
- package/src/components/pages/home-page.tsx +2 -4
- package/src/components/terminal/terminal.tsx +4 -4
- package/src/components/tracing/tracing-spec.ts +1 -1
- package/src/components/ui/table.tsx +1 -1
- package/src/core/cells/pending-delete-service.ts +12 -16
- package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
- package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
- package/src/core/codemirror/rtc/extension.ts +5 -2
- package/src/core/datasets/__tests__/data-source.test.ts +2 -0
- package/src/core/datasets/data-source-connections.ts +15 -10
- package/src/core/islands/__tests__/parse.test.ts +140 -7
- package/src/core/islands/parse.ts +20 -0
- package/src/core/packages/__tests__/useInstallPackage.test.tsx +47 -1
- package/src/core/packages/toast-components.tsx +26 -0
- package/src/core/packages/useInstallPackage.ts +7 -2
- package/src/core/runtime/__tests__/runtime.test.ts +11 -0
- package/src/core/runtime/runtime.ts +7 -2
- package/src/core/wasm/bridge.ts +1 -0
- package/src/core/websocket/transports/transport.ts +1 -1
- package/src/core/websocket/transports/ws.ts +1 -1
- package/src/css/app/Cell.css +2 -0
- package/src/plugins/core/RenderHTML.tsx +22 -2
- package/src/plugins/core/__test__/RenderHTML.test.ts +187 -0
- package/src/plugins/layout/AccordionPlugin.tsx +7 -2
- package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
- package/dist/_baseMerge-Dv8bBloN.js +0 -73
- package/dist/_initCloneObject---vediN2.js +0 -95
- package/dist/arc-DOVLrCPd.js +0 -82
- package/dist/architecture-TIHT7OUA-MiJpPpQW.js +0 -3
- package/dist/array-CApNbSU9.js +0 -6
- package/dist/assets/__vite-browser-external-BdKGjRZ4.js +0 -1
- package/dist/assets/worker-DlIBfp9S.js +0 -98
- package/dist/blockDiagram-VBNYF7ZC-Bc--I65C.js +0 -3158
- package/dist/chat-ui-DttQ-5Ut.js +0 -8455
- package/dist/chunk-3NCLNEKW-BIp_lB_4.js +0 -14
- package/dist/chunk-5FCAYU7R-C_HO9A1J.js +0 -23
- package/dist/chunk-5HE753X5-Bixm_MV-.js +0 -38
- package/dist/chunk-5JV3BV7I-CH5J3iZY.js +0 -54
- package/dist/chunk-5TONJI2A-DG6gDiSS.js +0 -62
- package/dist/chunk-7BUUIJ7U-5afmIPeo.js +0 -82
- package/dist/chunk-BIQX33UG-7TMBUf89.js +0 -23
- package/dist/chunk-CQNSW5MT-Cnqqsxt-.js +0 -38
- package/dist/chunk-CYSBUYHQ-BAbymFHR.js +0 -23
- package/dist/chunk-EMLP6XTP-Bsz-QL77.js +0 -23
- package/dist/chunk-J7OUQ5F2-CM_meqZH.js +0 -57
- package/dist/chunk-JG7HCLWE-DUnCDgPk.js +0 -62
- package/dist/chunk-MOZMSUNE-BG6IHvzT.js +0 -35
- package/dist/chunk-OSBZ3O6U-CYwj_bvR.js +0 -23
- package/dist/chunk-QBLGF6JB-B4vJ4j8J.js +0 -23
- package/dist/chunk-QR6OTTB3-D4wH2ldi.js +0 -3738
- package/dist/chunk-R7FJI6CG-Blf8FcmZ.js +0 -64
- package/dist/chunk-RYQCIY6F-BWbIlBIH.js +0 -241
- package/dist/chunk-U6XO7XAA-COw445DS.js +0 -63
- package/dist/chunk-UBXNYLIW-BHigVU4H.js +0 -32
- package/dist/chunk-YOTPTUD7-Dn044Q_d.js +0 -30
- package/dist/chunk-ZIRB5QZD-BR4TMfOa.js +0 -1153
- package/dist/classDiagram-JCYQIIEL-DmXSLxe_.js +0 -30
- package/dist/classDiagram-v2-OCEON4UE-CooqVexA.js +0 -30
- package/dist/click-outside-container-D_URcm3D.js +0 -167
- package/dist/code-block-37QAKDTI-CQrzBOr-.js +0 -107
- package/dist/cynefin-VYW2F7L2-CeHAxOEX.js +0 -3
- package/dist/dagre-VZM6K2ZE-CJggWPTJ.js +0 -328
- package/dist/dist-ABQjhuek.js +0 -64
- package/dist/dist-CO5R6VMi.js +0 -538
- package/dist/eventmodeling-45OFAUF4-B_lWZ-Pd.js +0 -3
- package/dist/flowDiagram-UKHOOZJN-g1AmrZzM.js +0 -17
- package/dist/gitGraph-TEB2WS4Q-Dj-eXUph.js +0 -3
- package/dist/info-DKCQHKI2-Bhb-pe2e.js +0 -3
- package/dist/line-CuKjIQa1.js +0 -34
- package/dist/map-BJpOfPlL.js +0 -149
- package/dist/math-BXtKgYah.js +0 -10
- package/dist/mermaid-4DMBBIKO-Ddp9TgNp.js +0 -2
- package/dist/mermaid-BsHdQeQf.js +0 -1173
- package/dist/mermaid-parser.core-Din9FvSi.js +0 -99
- package/dist/packet-7NZHBO7P-fbkIIyKE.js +0 -3
- package/dist/path-BNHuHZP8.js +0 -87
- package/dist/pie-RZYD4A2V-CLRIsxY1.js +0 -3
- package/dist/purify.es-CB-YO1Hn.js +0 -774
- package/dist/radar-I7S5WNFK-BGzCbgXu.js +0 -3
- package/dist/railroad-3IZDKUUU-CvQIIcuU.js +0 -3
- package/dist/railroad-abnf-AHOZXSZD-CMwtlNtu.js +0 -3
- package/dist/railroad-ebnf-EBAXGLYW-n1QUOAsh.js +0 -3
- package/dist/railroad-peg-LSFZ7HO6-PjnrpmCs.js +0 -3
- package/dist/schemas-DzK6U94N.js +0 -6057
- package/dist/stateDiagram-v2-UEYNNEHI-BTRUs8Il.js +0 -30
- package/dist/step-CKczO72Q.js +0 -670
- package/dist/swimlanesDiagram-ULZ7WXOC-NBmgBl9G.js +0 -31
- package/dist/timer-DpDyj9G0.js +0 -596
- package/dist/treeView-QDETBFTQ-DU8LwHuf.js +0 -3
- package/dist/treemap-6X3UGDF4-DUk4-k_O.js +0 -3
- package/dist/useTheme-CVJ0UOf2.js +0 -841
- package/dist/vega-loader.browser-DEggZzni.js +0 -1083
- package/dist/wardley-OPB4EBWU-Db-AaGas.js +0 -3
|
@@ -22,9 +22,13 @@ import { Tooltip } from "@/components/ui/tooltip";
|
|
|
22
22
|
import { toast } from "@/components/ui/use-toast";
|
|
23
23
|
import { useResolvedMarimoConfig } from "@/core/config/config";
|
|
24
24
|
import { useRequestClient } from "@/core/network/requests";
|
|
25
|
-
import type {
|
|
25
|
+
import type {
|
|
26
|
+
DependencyTreeNode,
|
|
27
|
+
DependencyTreeResponse,
|
|
28
|
+
} from "@/core/network/types";
|
|
26
29
|
import { stripPackageManagerPrefix } from "@/core/packages/package-input-utils";
|
|
27
30
|
import {
|
|
31
|
+
showPackageRestartToast,
|
|
28
32
|
showRemovePackageToast,
|
|
29
33
|
showUpgradePackageToast,
|
|
30
34
|
} from "@/core/packages/toast-components";
|
|
@@ -39,6 +43,7 @@ import { PanelEmptyState } from "./empty-state";
|
|
|
39
43
|
import { PACKAGES_INPUT_ID, packagesToInstallAtom } from "./packages-utils";
|
|
40
44
|
|
|
41
45
|
type ViewMode = "tree" | "list";
|
|
46
|
+
type PackageInstallationContext = DependencyTreeResponse["context"];
|
|
42
47
|
|
|
43
48
|
const PackageActionButton: React.FC<{
|
|
44
49
|
onClick: () => void;
|
|
@@ -77,12 +82,22 @@ const PackagesPanel: React.FC = () => {
|
|
|
77
82
|
refetch,
|
|
78
83
|
isPending,
|
|
79
84
|
} = useAsyncData(async () => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
// A sandbox's list and tree both inspect the same environment. Wait for
|
|
86
|
+
// the context before issuing the list request so sandboxes do that work
|
|
87
|
+
// only once; non-sandbox managers still need both views.
|
|
88
|
+
const dependencyTreeResponse = await getDependencyTree();
|
|
89
|
+
if (dependencyTreeResponse.context.kind === "sandbox") {
|
|
90
|
+
return {
|
|
91
|
+
list: [],
|
|
92
|
+
context: dependencyTreeResponse.context,
|
|
93
|
+
tree: dependencyTreeResponse.tree,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const listPackagesResponse = await getPackageList();
|
|
84
98
|
return {
|
|
85
99
|
list: listPackagesResponse.packages,
|
|
100
|
+
context: dependencyTreeResponse.context,
|
|
86
101
|
tree: dependencyTreeResponse.tree,
|
|
87
102
|
};
|
|
88
103
|
}, [packageManager]);
|
|
@@ -97,48 +112,66 @@ const PackagesPanel: React.FC = () => {
|
|
|
97
112
|
}
|
|
98
113
|
|
|
99
114
|
const isTreeSupported = dependencies.tree != null;
|
|
100
|
-
const viewMode = resolveViewMode(userViewMode, isTreeSupported);
|
|
101
115
|
const name = dependencies.tree?.name;
|
|
102
116
|
const version = dependencies?.tree?.version;
|
|
103
|
-
const
|
|
117
|
+
const sandboxBackend =
|
|
118
|
+
dependencies.context.kind === "sandbox"
|
|
119
|
+
? dependencies.context.backend
|
|
120
|
+
: null;
|
|
121
|
+
const isSandbox = sandboxBackend !== null;
|
|
122
|
+
const viewMode = isSandbox
|
|
123
|
+
? "tree"
|
|
124
|
+
: resolveViewMode(userViewMode, isTreeSupported);
|
|
125
|
+
const scopeLabel = sandboxBackend
|
|
126
|
+
? `${sandboxBackend} sandbox`
|
|
127
|
+
: name && name !== "<root>"
|
|
128
|
+
? "project"
|
|
129
|
+
: "environment";
|
|
130
|
+
const scopeTitle = sandboxBackend
|
|
131
|
+
? `Dependencies are managed by the ${sandboxBackend} sandbox selected when marimo started.`
|
|
132
|
+
: scopeLabel;
|
|
104
133
|
|
|
105
134
|
return (
|
|
106
135
|
<div className="flex-1 flex flex-col overflow-hidden">
|
|
107
|
-
<InstallPackageForm
|
|
108
|
-
{isTreeSupported && (
|
|
136
|
+
<InstallPackageForm context={dependencies.context} onSuccess={refetch} />
|
|
137
|
+
{(isTreeSupported || isSandbox) && (
|
|
109
138
|
<div className="flex items-center justify-between px-2 py-1 border-b">
|
|
110
|
-
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
139
|
+
{isTreeSupported && !isSandbox ? (
|
|
140
|
+
<div className="flex gap-1">
|
|
141
|
+
<button
|
|
142
|
+
type="button"
|
|
143
|
+
className={cn(
|
|
144
|
+
"px-2 py-1 text-xs rounded",
|
|
145
|
+
viewMode === "list"
|
|
146
|
+
? "bg-accent text-accent-foreground"
|
|
147
|
+
: "text-muted-foreground hover:text-foreground",
|
|
148
|
+
)}
|
|
149
|
+
onClick={() => setUserViewMode("list")}
|
|
150
|
+
>
|
|
151
|
+
List
|
|
152
|
+
</button>
|
|
153
|
+
<button
|
|
154
|
+
type="button"
|
|
155
|
+
className={cn(
|
|
156
|
+
"px-2 py-1 text-xs rounded",
|
|
157
|
+
viewMode === "tree"
|
|
158
|
+
? "bg-accent text-accent-foreground"
|
|
159
|
+
: "text-muted-foreground hover:text-foreground",
|
|
160
|
+
)}
|
|
161
|
+
onClick={() => setUserViewMode("tree")}
|
|
162
|
+
>
|
|
163
|
+
Tree
|
|
164
|
+
</button>
|
|
165
|
+
</div>
|
|
166
|
+
) : (
|
|
167
|
+
<div />
|
|
168
|
+
)}
|
|
136
169
|
<div className="flex items-center gap-2">
|
|
137
170
|
<div
|
|
138
171
|
className="items-center border px-2 py-0.5 text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground rounded-sm text-ellipsis block overflow-hidden max-w-fit font-medium"
|
|
139
|
-
title={
|
|
172
|
+
title={scopeTitle}
|
|
140
173
|
>
|
|
141
|
-
{
|
|
174
|
+
{scopeLabel}
|
|
142
175
|
</div>
|
|
143
176
|
{name && !isSandbox && (
|
|
144
177
|
<span className="text-xs text-muted-foreground">
|
|
@@ -155,6 +188,7 @@ const PackagesPanel: React.FC = () => {
|
|
|
155
188
|
<DependencyTree
|
|
156
189
|
tree={dependencies.tree}
|
|
157
190
|
error={error}
|
|
191
|
+
sandboxBackend={sandboxBackend}
|
|
158
192
|
onSuccess={refetch}
|
|
159
193
|
/>
|
|
160
194
|
)}
|
|
@@ -165,11 +199,13 @@ const PackagesPanel: React.FC = () => {
|
|
|
165
199
|
export default PackagesPanel;
|
|
166
200
|
|
|
167
201
|
const InstallPackageForm: React.FC<{
|
|
168
|
-
|
|
202
|
+
context: PackageInstallationContext;
|
|
169
203
|
onSuccess: () => void;
|
|
170
|
-
}> = ({ onSuccess,
|
|
204
|
+
}> = ({ onSuccess, context }) => {
|
|
171
205
|
const [input, setInput] = React.useState("");
|
|
172
206
|
const { handleClick: openSettings } = useOpenSettingsToTab();
|
|
207
|
+
const isSandbox = context.kind === "sandbox";
|
|
208
|
+
const packageManager = isSandbox ? context.backend : context.name;
|
|
173
209
|
|
|
174
210
|
// Get the packages to install from the atom
|
|
175
211
|
const packagesToInstall = useAtomValue(packagesToInstallAtom);
|
|
@@ -201,7 +237,11 @@ const InstallPackageForm: React.FC<{
|
|
|
201
237
|
return (
|
|
202
238
|
<div className="flex items-center w-full border-b">
|
|
203
239
|
<SearchInput
|
|
204
|
-
placeholder={
|
|
240
|
+
placeholder={
|
|
241
|
+
isSandbox
|
|
242
|
+
? `Add packages to ${packageManager} sandbox...`
|
|
243
|
+
: `Install packages with ${packageManager}...`
|
|
244
|
+
}
|
|
205
245
|
id={PACKAGES_INPUT_ID}
|
|
206
246
|
icon={
|
|
207
247
|
loading ? (
|
|
@@ -209,12 +249,23 @@ const InstallPackageForm: React.FC<{
|
|
|
209
249
|
size="small"
|
|
210
250
|
className="mr-2 h-4 w-4 shrink-0 opacity-50"
|
|
211
251
|
/>
|
|
252
|
+
) : isSandbox ? (
|
|
253
|
+
<BoxIcon
|
|
254
|
+
aria-hidden="true"
|
|
255
|
+
className="mr-2 h-4 w-4 shrink-0 opacity-50"
|
|
256
|
+
/>
|
|
212
257
|
) : (
|
|
213
|
-
<Tooltip
|
|
214
|
-
|
|
258
|
+
<Tooltip
|
|
259
|
+
content={`Change package manager (currently ${packageManager})`}
|
|
260
|
+
>
|
|
261
|
+
<button
|
|
262
|
+
type="button"
|
|
263
|
+
aria-label="Change package manager"
|
|
215
264
|
onClick={() => openSettings("packageManagementAndData")}
|
|
216
|
-
className="
|
|
217
|
-
|
|
265
|
+
className="pointer-events-auto mr-2 rounded-sm opacity-50 hover:opacity-80 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring"
|
|
266
|
+
>
|
|
267
|
+
<BoxIcon aria-hidden="true" className="h-4 w-4 shrink-0" />
|
|
268
|
+
</button>
|
|
218
269
|
</Tooltip>
|
|
219
270
|
)
|
|
220
271
|
}
|
|
@@ -234,9 +285,21 @@ const InstallPackageForm: React.FC<{
|
|
|
234
285
|
align="start"
|
|
235
286
|
content={
|
|
236
287
|
<div className="text-sm flex flex-col w-full max-w-[360px]">
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
288
|
+
{isSandbox ? (
|
|
289
|
+
<span>
|
|
290
|
+
Packages are recorded in this notebook's inline metadata
|
|
291
|
+
and synchronized with its {packageManager} sandbox. To switch
|
|
292
|
+
backends, restart marimo with a different --sandbox option.
|
|
293
|
+
</span>
|
|
294
|
+
) : (
|
|
295
|
+
<span>
|
|
296
|
+
Packages are installed using {packageManager}, selected in your
|
|
297
|
+
user configuration.
|
|
298
|
+
</span>
|
|
299
|
+
)}
|
|
300
|
+
<span className="mt-2">
|
|
301
|
+
You can install packages with various formats:
|
|
302
|
+
</span>
|
|
240
303
|
<div className="flex flex-col gap-2 mt-2">
|
|
241
304
|
<div>
|
|
242
305
|
<span className="font-bold tracking-wide">Package name:</span> A
|
|
@@ -379,7 +442,9 @@ const UpgradeButton: React.FC<{
|
|
|
379
442
|
upgrade: true,
|
|
380
443
|
group,
|
|
381
444
|
});
|
|
382
|
-
if (response.
|
|
445
|
+
if (response.restartRequired) {
|
|
446
|
+
showPackageRestartToast();
|
|
447
|
+
} else if (response.success) {
|
|
383
448
|
onSuccess();
|
|
384
449
|
showUpgradePackageToast(packageName);
|
|
385
450
|
} else {
|
|
@@ -413,7 +478,9 @@ const RemoveButton: React.FC<{
|
|
|
413
478
|
package: packageName,
|
|
414
479
|
group,
|
|
415
480
|
});
|
|
416
|
-
if (response.
|
|
481
|
+
if (response.restartRequired) {
|
|
482
|
+
showPackageRestartToast();
|
|
483
|
+
} else if (response.success) {
|
|
417
484
|
onSuccess();
|
|
418
485
|
showRemovePackageToast(packageName);
|
|
419
486
|
} else {
|
|
@@ -434,8 +501,9 @@ const RemoveButton: React.FC<{
|
|
|
434
501
|
const DependencyTree: React.FC<{
|
|
435
502
|
tree: DependencyTreeNode | null;
|
|
436
503
|
error?: Error | null;
|
|
504
|
+
sandboxBackend: "uv" | "pixi" | null;
|
|
437
505
|
onSuccess: () => void;
|
|
438
|
-
}> = ({ tree, error, onSuccess }) => {
|
|
506
|
+
}> = ({ tree, error, sandboxBackend, onSuccess }) => {
|
|
439
507
|
const [expandedNodes, setExpandedNodes] = React.useState<Set<string>>(
|
|
440
508
|
new Set(),
|
|
441
509
|
);
|
|
@@ -450,10 +518,25 @@ const DependencyTree: React.FC<{
|
|
|
450
518
|
}
|
|
451
519
|
|
|
452
520
|
if (!tree) {
|
|
453
|
-
return
|
|
521
|
+
return (
|
|
522
|
+
<PanelEmptyState
|
|
523
|
+
title="Dependency tree unavailable"
|
|
524
|
+
description="The sandbox did not return a dependency tree."
|
|
525
|
+
icon={<BoxIcon />}
|
|
526
|
+
/>
|
|
527
|
+
);
|
|
454
528
|
}
|
|
455
529
|
|
|
456
530
|
if (tree.dependencies.length === 0) {
|
|
531
|
+
if (sandboxBackend === "pixi") {
|
|
532
|
+
return (
|
|
533
|
+
<PanelEmptyState
|
|
534
|
+
title="No PyPI dependencies"
|
|
535
|
+
description="Conda dependencies are not shown in this panel."
|
|
536
|
+
icon={<BoxIcon />}
|
|
537
|
+
/>
|
|
538
|
+
);
|
|
539
|
+
}
|
|
457
540
|
return (
|
|
458
541
|
<PanelEmptyState
|
|
459
542
|
title="No dependencies"
|
|
@@ -575,6 +658,17 @@ const DependencyTreeNode: React.FC<{
|
|
|
575
658
|
{/* Tags */}
|
|
576
659
|
<div className="flex items-center gap-1 ml-2">
|
|
577
660
|
{node.tags.map((tag, index) => {
|
|
661
|
+
if (tag.kind === "dedupe") {
|
|
662
|
+
return (
|
|
663
|
+
<div
|
|
664
|
+
key={index}
|
|
665
|
+
className="items-center border px-2 py-0.5 text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 text-muted-foreground rounded-sm text-ellipsis block overflow-hidden max-w-fit font-medium"
|
|
666
|
+
title="Package tree already displayed"
|
|
667
|
+
>
|
|
668
|
+
already in tree
|
|
669
|
+
</div>
|
|
670
|
+
);
|
|
671
|
+
}
|
|
578
672
|
if (tag.kind === "cycle") {
|
|
579
673
|
return (
|
|
580
674
|
<div
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { render, screen } from "@testing-library/react";
|
|
4
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { ReadonlyDiff } from "../readonly-diff";
|
|
6
|
+
|
|
7
|
+
const mocks = vi.hoisted(() => ({
|
|
8
|
+
mergeView: vi.fn(),
|
|
9
|
+
useTheme: vi.fn(),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
vi.mock("@codemirror/merge", () => ({
|
|
13
|
+
unifiedMergeView: mocks.mergeView,
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
vi.mock("@uiw/react-codemirror", () => ({
|
|
17
|
+
default: ({ theme, value }: { theme: string; value: string }) => (
|
|
18
|
+
<div data-testid="code-mirror" data-theme={theme} data-value={value} />
|
|
19
|
+
),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
vi.mock("@/theme/useTheme", () => ({
|
|
23
|
+
useTheme: mocks.useTheme,
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
describe("ReadonlyDiff", () => {
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
mocks.mergeView.mockReset();
|
|
29
|
+
mocks.mergeView.mockReturnValue([]);
|
|
30
|
+
mocks.useTheme.mockReturnValue({ theme: "light" });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("updates modified code without rebuilding the diff extensions", () => {
|
|
34
|
+
const { rerender } = render(
|
|
35
|
+
<ReadonlyDiff original="before" modified="first revision" />,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
expect(screen.getByTestId("code-mirror")).toHaveAttribute(
|
|
39
|
+
"data-value",
|
|
40
|
+
"first revision",
|
|
41
|
+
);
|
|
42
|
+
expect(mocks.mergeView).toHaveBeenCalledTimes(1);
|
|
43
|
+
|
|
44
|
+
rerender(<ReadonlyDiff original="before" modified="second revision" />);
|
|
45
|
+
|
|
46
|
+
expect(screen.getByTestId("code-mirror")).toHaveAttribute(
|
|
47
|
+
"data-value",
|
|
48
|
+
"second revision",
|
|
49
|
+
);
|
|
50
|
+
expect(mocks.mergeView).toHaveBeenCalledTimes(1);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("rebuilds diff extensions when the original code changes", () => {
|
|
54
|
+
const { rerender } = render(
|
|
55
|
+
<ReadonlyDiff original="before" modified="after" />,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
rerender(<ReadonlyDiff original="earlier" modified="after" />);
|
|
59
|
+
|
|
60
|
+
expect(mocks.mergeView).toHaveBeenCalledTimes(2);
|
|
61
|
+
expect(mocks.mergeView).toHaveBeenLastCalledWith(
|
|
62
|
+
expect.objectContaining({ original: "earlier" }),
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { act, fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import type React from "react";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { RefreshIconButton } from "../tree-actions";
|
|
7
|
+
|
|
8
|
+
vi.mock("@/components/ui/tooltip", () => ({
|
|
9
|
+
Tooltip: ({ children }: { children: React.ReactNode }) => children,
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
describe("RefreshIconButton", () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.useFakeTimers();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
vi.useRealTimers();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("spins for at least 500ms after a refresh completes", async () => {
|
|
22
|
+
const onClick = vi.fn().mockResolvedValue(undefined);
|
|
23
|
+
const { container } = render(<RefreshIconButton onClick={onClick} />);
|
|
24
|
+
|
|
25
|
+
fireEvent.click(screen.getByRole("button"));
|
|
26
|
+
|
|
27
|
+
expect(onClick).toHaveBeenCalledOnce();
|
|
28
|
+
expect(container.querySelector("svg")).toHaveClass("animate-[spin_0.5s]");
|
|
29
|
+
|
|
30
|
+
await act(async () => {
|
|
31
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(container.querySelector("svg")).not.toHaveClass(
|
|
35
|
+
"animate-[spin_0.5s]",
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("uses the latest refresh callback after a rerender", async () => {
|
|
40
|
+
const initialOnClick = vi.fn().mockResolvedValue(undefined);
|
|
41
|
+
const updatedOnClick = vi.fn().mockResolvedValue(undefined);
|
|
42
|
+
const { rerender } = render(<RefreshIconButton onClick={initialOnClick} />);
|
|
43
|
+
|
|
44
|
+
rerender(<RefreshIconButton onClick={updatedOnClick} />);
|
|
45
|
+
fireEvent.click(screen.getByRole("button"));
|
|
46
|
+
|
|
47
|
+
expect(initialOnClick).not.toHaveBeenCalled();
|
|
48
|
+
expect(updatedOnClick).toHaveBeenCalledOnce();
|
|
49
|
+
|
|
50
|
+
await act(async () => {
|
|
51
|
+
await vi.advanceTimersByTimeAsync(500);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
MoreVerticalIcon,
|
|
8
8
|
RefreshCwIcon,
|
|
9
9
|
} from "lucide-react";
|
|
10
|
-
import React, {
|
|
10
|
+
import React, { useState } from "react";
|
|
11
11
|
import { Button, type ButtonProps } from "@/components/ui/button";
|
|
12
12
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
13
13
|
import { cn } from "@/utils/cn";
|
|
@@ -41,19 +41,16 @@ export const RefreshIconButton: React.FC<{
|
|
|
41
41
|
}> = ({ onClick, tooltip = "Refresh", className, iconClassName }) => {
|
|
42
42
|
const [isSpinning, setIsSpinning] = useState(false);
|
|
43
43
|
|
|
44
|
-
const handleClick =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
},
|
|
55
|
-
[onClick],
|
|
56
|
-
);
|
|
44
|
+
const handleClick = async (e: React.MouseEvent) => {
|
|
45
|
+
setIsSpinning(true);
|
|
46
|
+
// Artificially spin for 500ms to show the user that the button is working.
|
|
47
|
+
const minDelay = new Promise<void>((r) => setTimeout(r, 500));
|
|
48
|
+
try {
|
|
49
|
+
await Promise.all([onClick(e), minDelay]);
|
|
50
|
+
} finally {
|
|
51
|
+
setIsSpinning(false);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
57
54
|
|
|
58
55
|
const button = (
|
|
59
56
|
<Button
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
PackageCheckIcon,
|
|
11
11
|
PackageXIcon,
|
|
12
12
|
PlusIcon,
|
|
13
|
+
RotateCwIcon,
|
|
13
14
|
XIcon,
|
|
14
15
|
} from "lucide-react";
|
|
15
16
|
import type React from "react";
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
import { useResolvedMarimoConfig } from "@/core/config/config";
|
|
33
34
|
import type { PackageInstallationStatus } from "@/core/kernel/messages";
|
|
34
35
|
import { useRequestClient } from "@/core/network/requests";
|
|
36
|
+
import { RESTART_REQUIRED_DESCRIPTION } from "@/core/packages/toast-components";
|
|
35
37
|
import { isWasm } from "@/core/wasm/utils";
|
|
36
38
|
import { usePackageMetadata } from "@/hooks/usePackageMetadata";
|
|
37
39
|
import { Banner } from "@/plugins/impl/common/error-banner";
|
|
@@ -55,6 +57,12 @@ import {
|
|
|
55
57
|
import { ExternalLink } from "../ui/links";
|
|
56
58
|
import { NativeSelect } from "../ui/native-select";
|
|
57
59
|
import { Tooltip } from "../ui/tooltip";
|
|
60
|
+
import { useRestartKernel } from "./actions/useRestartKernel";
|
|
61
|
+
|
|
62
|
+
const RestartKernelButton = () => {
|
|
63
|
+
const restartKernel = useRestartKernel();
|
|
64
|
+
return <Button onClick={restartKernel}>Restart Kernel</Button>;
|
|
65
|
+
};
|
|
58
66
|
|
|
59
67
|
function parsePackageSpecifier(spec: string): {
|
|
60
68
|
name: string;
|
|
@@ -251,6 +259,10 @@ export const PackageAlert: React.FC = () => {
|
|
|
251
259
|
)}
|
|
252
260
|
>
|
|
253
261
|
<p>{description}</p>
|
|
262
|
+
{status !== "installing" &&
|
|
263
|
+
Object.values(packageAlert.packages).includes(
|
|
264
|
+
"restart-required",
|
|
265
|
+
) && <RestartKernelButton />}
|
|
254
266
|
<ul className="list-disc ml-2 mt-1">
|
|
255
267
|
{Object.entries(packageAlert.packages).map(([pkg, st], index) => (
|
|
256
268
|
<li
|
|
@@ -290,7 +302,9 @@ function getInstallationStatusElements(packages: PackageInstallationStatus) {
|
|
|
290
302
|
? "installing"
|
|
291
303
|
: statuses.has("failed")
|
|
292
304
|
? "failed"
|
|
293
|
-
: "
|
|
305
|
+
: statuses.has("restart-required")
|
|
306
|
+
? "restart-required"
|
|
307
|
+
: "installed";
|
|
294
308
|
|
|
295
309
|
if (status === "installing") {
|
|
296
310
|
return {
|
|
@@ -300,6 +314,14 @@ function getInstallationStatusElements(packages: PackageInstallationStatus) {
|
|
|
300
314
|
description: "Installing packages:",
|
|
301
315
|
};
|
|
302
316
|
}
|
|
317
|
+
if (status === "restart-required") {
|
|
318
|
+
return {
|
|
319
|
+
status,
|
|
320
|
+
title: "Changes saved — restart required",
|
|
321
|
+
titleIcon: <RotateCwIcon className="w-5 h-5 inline-block mr-2" />,
|
|
322
|
+
description: RESTART_REQUIRED_DESCRIPTION,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
303
325
|
if (status === "installed") {
|
|
304
326
|
return {
|
|
305
327
|
status: "installed",
|
|
@@ -330,6 +352,8 @@ const ProgressIcon = ({
|
|
|
330
352
|
return <CheckIcon size="1rem" />;
|
|
331
353
|
case "failed":
|
|
332
354
|
return <XIcon size="1rem" />;
|
|
355
|
+
case "restart-required":
|
|
356
|
+
return <RotateCwIcon size="1rem" />;
|
|
333
357
|
default:
|
|
334
358
|
logNever(status);
|
|
335
359
|
return null;
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
import { Constants } from "@/core/constants";
|
|
32
32
|
import { useRequestClient } from "@/core/network/requests";
|
|
33
33
|
import type { TutorialId } from "@/core/network/types";
|
|
34
|
+
import { Banner } from "@/plugins/impl/common/error-banner";
|
|
34
35
|
import { openNotebook } from "@/utils/links";
|
|
35
36
|
import { Objects } from "@/utils/objects";
|
|
36
37
|
import { MarimoPlusIcon } from "../icons/marimo-icons";
|
|
@@ -186,6 +187,22 @@ export const ResourceLinks: React.FC = () => {
|
|
|
186
187
|
);
|
|
187
188
|
};
|
|
188
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Shown when the workspace scan stopped early, so the file list the user is
|
|
192
|
+
* looking at is missing files and folders.
|
|
193
|
+
*/
|
|
194
|
+
export const TruncatedWorkspaceBanner: React.FC<{
|
|
195
|
+
fileCount: number | undefined;
|
|
196
|
+
}> = ({ fileCount }) => {
|
|
197
|
+
return (
|
|
198
|
+
<Banner kind="warn" className="rounded p-4">
|
|
199
|
+
Showing {fileCount} files. Some files and folders were skipped because
|
|
200
|
+
your workspace is large or deeply nested. Start marimo from a subfolder to
|
|
201
|
+
see them.
|
|
202
|
+
</Banner>
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
|
|
189
206
|
export const Header: React.FC<{
|
|
190
207
|
Icon: React.FC<React.SVGProps<SVGSVGElement>>;
|
|
191
208
|
control?: React.ReactNode;
|
|
@@ -4,6 +4,7 @@ import { SearchIcon } from "lucide-react";
|
|
|
4
4
|
import type React from "react";
|
|
5
5
|
import { Suspense, useMemo, useState } from "react";
|
|
6
6
|
import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary";
|
|
7
|
+
import { TruncatedWorkspaceBanner } from "@/components/home/components";
|
|
7
8
|
import { Spinner } from "@/components/icons/spinner";
|
|
8
9
|
import { Card, CardContent } from "@/components/ui/card";
|
|
9
10
|
import { Input } from "@/components/ui/input";
|
|
@@ -119,10 +120,7 @@ const GalleryPage: React.FC = () => {
|
|
|
119
120
|
<ErrorBoundary>
|
|
120
121
|
<div className="flex flex-col gap-2">
|
|
121
122
|
{workspace.hasMore && (
|
|
122
|
-
<
|
|
123
|
-
Showing first {workspace.fileCount} files. Your workspace has
|
|
124
|
-
more files.
|
|
125
|
-
</Banner>
|
|
123
|
+
<TruncatedWorkspaceBanner fileCount={workspace.fileCount} />
|
|
126
124
|
)}
|
|
127
125
|
{formattedFiles.length > SEARCH_THRESHOLD && (
|
|
128
126
|
<Input
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
Header,
|
|
68
68
|
OpenTutorialDropDown,
|
|
69
69
|
ResourceLinks,
|
|
70
|
+
TruncatedWorkspaceBanner,
|
|
70
71
|
} from "../home/components";
|
|
71
72
|
import {
|
|
72
73
|
expandedFoldersAtom,
|
|
@@ -196,10 +197,7 @@ const WorkspaceNotebooks: React.FC<{ onRefreshRecents: () => void }> = ({
|
|
|
196
197
|
<WorkspaceContext value={workspaceContextValue}>
|
|
197
198
|
<div className="flex flex-col gap-2">
|
|
198
199
|
{workspace.hasMore && (
|
|
199
|
-
<
|
|
200
|
-
Showing first {workspace.fileCount} files. Your workspace has more
|
|
201
|
-
files.
|
|
202
|
-
</Banner>
|
|
200
|
+
<TruncatedWorkspaceBanner fileCount={workspace.fileCount} />
|
|
203
201
|
)}
|
|
204
202
|
<Header
|
|
205
203
|
Icon={BookTextIcon}
|
|
@@ -254,7 +254,9 @@ const TerminalComponent: React.FC<TerminalComponentProps> = ({
|
|
|
254
254
|
try {
|
|
255
255
|
await waitForConnectionOpen();
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
// Size the PTY before the shell draws its first prompt.
|
|
258
|
+
fitAddon.fit();
|
|
259
|
+
const socket = new WebSocket(runtimeManager.getTerminalWsURL(terminal));
|
|
258
260
|
const attachAddon = new AttachAddon(socket);
|
|
259
261
|
terminal.loadAddon(attachAddon);
|
|
260
262
|
wsRef.current = socket;
|
|
@@ -270,9 +272,7 @@ const TerminalComponent: React.FC<TerminalComponentProps> = ({
|
|
|
270
272
|
|
|
271
273
|
const handleOpen = () => {
|
|
272
274
|
updateReadyState();
|
|
273
|
-
//
|
|
274
|
-
// before the WS was OPEN, dropping the resize message and leaving
|
|
275
|
-
// the PTY at its default 0x0 winsize.
|
|
275
|
+
// The container may have resized while the connection was opening.
|
|
276
276
|
fitAddon.fit();
|
|
277
277
|
if (terminal.cols > 0 && terminal.rows > 0) {
|
|
278
278
|
socket.send(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import type { TopLevelSpec } from "vega-lite";
|
|
4
|
-
import type { TimeUnit } from "vega-
|
|
4
|
+
import type { TimeUnit } from "vega-lite/types_unstable/timeunit.js";
|
|
5
5
|
import type { CellId } from "@/core/cells/ids";
|
|
6
6
|
import type { CellRun } from "@/core/cells/runs";
|
|
7
7
|
import type { ResolvedTheme } from "@/theme/useTheme";
|