@marimo-team/islands 0.22.1-dev3 → 0.22.1-dev31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedDataExplorerComponent-Dl1grr8z.js → ConnectedDataExplorerComponent-DTOsfq2x.js} +54 -54
- package/dist/_basePickBy-Sow3pJjS.js +41 -0
- package/dist/{_baseUniq-B4eL5sTC.js → _baseUniq-C87CckHL.js} +15 -54
- package/dist/{any-language-editor-CT_9yBde.js → any-language-editor-BHH_pQ6M.js} +21 -21
- package/dist/architecture-7HQA4BMR-BHdkAMvZ.js +6 -0
- package/dist/{architectureDiagram-VXUJARFQ-vxgYGIMP.js → architectureDiagram-VXUJARFQ-B3YQo9At.js} +15 -15
- package/dist/{arrays-Du-jRBAy.js → arrays-beUWo8RF.js} +1 -1
- package/dist/assets/__vite-browser-external-WSlCcXn_.js +1 -0
- package/dist/assets/{worker-D10K3OOz.js → worker-DUYMdbtA.js} +2 -2
- package/dist/{blockDiagram-VD42YOAC-C7x6YTH7.js → blockDiagram-VD42YOAC-CpQ3TKEN.js} +7 -7
- package/dist/{button-qsiIHncQ.js → button-DNlNlZY_.js} +82 -84
- package/dist/{c4Diagram-YG6GDRKO-Cx4oseGg.js → c4Diagram-YG6GDRKO-CZSU4uqU.js} +4 -4
- package/dist/{capabilities-26mwv03y.js → capabilities-Coe9eM9T.js} +2 -2
- package/dist/{channel-C_50jIAn.js → channel-X3JKk8gE.js} +1 -1
- package/dist/{chat-ui-CtqUthFR.js → chat-ui-eH46RYWT.js} +147 -146
- package/dist/{check-D_YwHEgY.js → check-CWUkiHmb.js} +1 -1
- package/dist/{chunk-4F5CHEZ2-Dvo_CFnR.js → chunk-4F5CHEZ2-D5mClyDv.js} +1 -1
- package/dist/{chunk-ABZYJK2D-D5YIs71w.js → chunk-ABZYJK2D-CZYCCtLy.js} +1 -1
- package/dist/{chunk-ATLVNIR6-CyOjzOcf.js → chunk-ATLVNIR6-DaOzLLgN.js} +1 -1
- package/dist/{chunk-B2363JML-BzZqINRO.js → chunk-B2363JML-Br0eA2T3.js} +1 -1
- package/dist/{chunk-B4BG7PRW-ZJeV3KdD.js → chunk-B4BG7PRW-4BjV11Br.js} +4 -4
- package/dist/{chunk-DI55MBZ5-Dx_wwX6l.js → chunk-DI55MBZ5-DITY3EyP.js} +4 -4
- package/dist/{chunk-EXTU4WIE-CgefpSXQ.js → chunk-EXTU4WIE-jUPSAk3i.js} +1 -1
- package/dist/{chunk-FRFDVMJY-Derq8UzY.js → chunk-FRFDVMJY-DnEvEFRR.js} +1 -1
- package/dist/{chunk-JA3XYJ7Z-CcIOIFpc.js → chunk-JA3XYJ7Z-BcPEfxk_.js} +2 -2
- package/dist/{chunk-JZLCHNYA-CgO0GG1p.js → chunk-JZLCHNYA-2bnLL3xL.js} +4 -4
- package/dist/{chunk-N4CR4FBY-2qzGzAxT.js → chunk-N4CR4FBY-CpZSuGSU.js} +5 -5
- package/dist/{chunk-PL6DKKU2-KoG71Zin.js → chunk-PL6DKKU2-DnId6G-x.js} +1 -1
- package/dist/{chunk-QN33PNHL-Dp1qBo28.js → chunk-QN33PNHL-B9p5ojHB.js} +1 -1
- package/dist/{chunk-QXUST7PY-BxmmeIwf.js → chunk-QXUST7PY-Ch6F5Obl.js} +5 -5
- package/dist/{chunk-S3R3BYOJ-D3Rys9ZW.js → chunk-S3R3BYOJ-B0UOFJwq.js} +3 -3
- package/dist/{chunk-SJTYNZTY-Co-DhKAG.js → chunk-SJTYNZTY-BsBZnJUj.js} +1 -1
- package/dist/{chunk-TCCFYFTB-BAhzIqBO.js → chunk-TCCFYFTB-Clbl-fTg.js} +8 -7
- package/dist/{chunk-TQ3KTPDO-DxYI735Z.js → chunk-TQ3KTPDO-CFkSQ30e.js} +1 -1
- package/dist/{chunk-TZMSLE5B-Dxumt0wv.js → chunk-TZMSLE5B-D45397J2.js} +1 -1
- package/dist/{chunk-UMXZTB3W-CuahpKin.js → chunk-UMXZTB3W-D-A834Bq.js} +1 -1
- package/dist/{classDiagram-v2-WZHVMYZB-CYoFMQKE.js → classDiagram-2ON5EDUG-C8-zE3Zv.js} +10 -10
- package/dist/{classDiagram-2ON5EDUG-DkOvXRlx.js → classDiagram-v2-WZHVMYZB-DrmbGANl.js} +10 -10
- package/dist/{clone-DDndUqI0.js → clone-DZFQCtFJ.js} +1 -1
- package/dist/{constants-D1Am36hX.js → constants-CvyfaCvs.js} +3 -3
- package/dist/{copy-CBo9JcJW.js → copy-B7781WJ3.js} +2 -2
- package/dist/{dagre-6UL2VRFP-BXBaU8PB.js → dagre-6UL2VRFP-OMItEBnY.js} +12 -12
- package/dist/{dagre-D3dlYz-r.js → dagre-QVd-lCXU.js} +13 -23
- package/dist/{data-grid-overlay-editor-nZux6_d2.js → data-grid-overlay-editor-lKF301ME.js} +1 -1
- package/dist/{diagram-PSM6KHXK-CJxjk4LG.js → diagram-PSM6KHXK-CkKbohWI.js} +16 -16
- package/dist/{diagram-QEK2KX5R-IMILPh_p.js → diagram-QEK2KX5R-DjUMpVcx.js} +14 -14
- package/dist/{diagram-S2PKOQOG-6O0g6Boj.js → diagram-S2PKOQOG-b-c0d-wZ.js} +14 -14
- package/dist/{dist-BkXs8bw0.js → dist--6TSlp8H.js} +1 -1
- package/dist/dist-7K5doRvB.js +6 -0
- package/dist/{dist-CQidOwep.js → dist-B43sbpd0.js} +3 -3
- package/dist/dist-B6I_A2-E.js +8 -0
- package/dist/dist-BEQsmaZY.js +5 -0
- package/dist/dist-BasY2RHp.js +8 -0
- package/dist/{dist-BemtTYzN.js → dist-Bfp1XXWt.js} +5 -5
- package/dist/{dist-v-1kgqZ3.js → dist-BjDuO5JW.js} +1 -1
- package/dist/dist-Bosc00dY.js +5 -0
- package/dist/{dist-DLNKBPsk.js → dist-BrxqmS9Q.js} +4 -4
- package/dist/{dist-DBYL08Lu.js → dist-BvhGByxL.js} +4 -4
- package/dist/{dist-CVqlhD3M.js → dist-C4bq5Ioy.js} +2 -2
- package/dist/{dist-DwmxBUOe.js → dist-CFKdzOIu.js} +2 -2
- package/dist/{dist-5nTQE2yt.js → dist-CIB8w0Fl.js} +2 -2
- package/dist/{dist-C-EcLtO9.js → dist-CNF0QBLR.js} +1 -1
- package/dist/dist-CQMZOn-_.js +8 -0
- package/dist/dist-CViQhWZ8.js +5 -0
- package/dist/{dist-Dg65j0em.js → dist-CcMfr7jD.js} +1 -1
- package/dist/{dist-C0XYIHKJ.js → dist-Ci0CXEFt.js} +1 -1
- package/dist/dist-Cz6rLfwY.js +5 -0
- package/dist/dist-D8eq8st3.js +6 -0
- package/dist/{dist-qoCY8giM.js → dist-DAfcmt-d.js} +2 -2
- package/dist/{dist-B6Op2ogv.js → dist-DD_cYHOl.js} +2 -2
- package/dist/{dist-BUSLKXcu.js → dist-DFK94vuS.js} +2 -2
- package/dist/{dist-DBXPlQ0D.js → dist-DGNtjMZu.js} +1 -1
- package/dist/{dist-C9qF7MRB.js → dist-DJ9F1eHs.js} +2 -2
- package/dist/{dist-Ci_jEudG.js → dist-DJKubHDd.js} +1 -1
- package/dist/{dist-CnFp2Kcl.js → dist-DLafRu9s.js} +2 -2
- package/dist/dist-DM1UDXdl.js +5 -0
- package/dist/dist-DNrtWPgS.js +5 -0
- package/dist/dist-D_UjpfOY.js +1381 -0
- package/dist/{dist-DmFS6KZW.js → dist-DbnBiLNH.js} +3 -3
- package/dist/{dist-BiZZAo22.js → dist-DlSUOIm9.js} +1 -1
- package/dist/{dist-DStU8He1.js → dist-Doy0mQDg.js} +2 -2
- package/dist/{dist-CxAX99oC.js → dist-DpkJHKB8.js} +2 -2
- package/dist/{dist-DjaZNkZ7.js → dist-LhQNUe5A.js} +3 -3
- package/dist/dist-V7q2qnpA.js +5 -0
- package/dist/{dist-BJ3fhRYu.js → dist-VqF3W_ue.js} +2 -2
- package/dist/dist-a5_hPgu2.js +8 -0
- package/dist/{dist-B9KLrfoh.js → dist-ej6AQKaS.js} +1 -1
- package/dist/{dist-Brb6VNc4.js → dist-m9tsXsFf.js} +2 -2
- package/dist/{dist-CBwMSFDu.js → dist-tGk0aZ--.js} +2 -2
- package/dist/dist-uVyZcV1-.js +5 -0
- package/dist/{erDiagram-Q2GNP2WA-sho7Cl9f.js → erDiagram-Q2GNP2WA-CDhLaOZ1.js} +10 -10
- package/dist/{error-banner-Bx9kIgrs.js → error-banner-Cjf0RU9I.js} +79 -79
- package/dist/{esm-CMg2ABu6.js → esm-4wmsH2lp.js} +6 -6
- package/dist/{esm-cqK9POGH.js → esm-CD1iby2n.js} +23 -23
- package/dist/{flowDiagram-NV44I4VS-C4nY4Fbz.js → flowDiagram-NV44I4VS-BDi4O4CL.js} +10 -10
- package/dist/{ganttDiagram-JELNMOA3-CtxNcCM2.js → ganttDiagram-JELNMOA3-BpZE6kVp.js} +3 -3
- package/dist/{gitGraph-G5XIXVHT-SL6TDof6.js → gitGraph-G5XIXVHT-B_c6xFJv.js} +3 -3
- package/dist/{gitGraphDiagram-V2S2FVAM-D9885mxd.js → gitGraphDiagram-V2S2FVAM-iQnXzbPM.js} +13 -13
- package/dist/{glide-data-editor-CkVEV-Gk.js → glide-data-editor-VgPtWvhu.js} +63 -63
- package/dist/{graphlib-CxWdvYQt.js → graphlib-BV1_gi0C.js} +4 -3
- package/dist/hasIn-DnfJcYpY.js +108 -0
- package/dist/{info-VBDWY6EO-6MXPTSmi.js → info-VBDWY6EO-BTyzxmhr.js} +3 -3
- package/dist/{infoDiagram-HS3SLOUP-Bw2FlRwF.js → infoDiagram-HS3SLOUP-OYrX6uO3.js} +13 -13
- package/dist/{input-BSde8uV4.js → input-CFY9gApZ.js} +5055 -5055
- package/dist/{isEmpty-BQtUinxJ.js → isEmpty-B7FX9wKt.js} +1 -1
- package/dist/{isSymbol-DFp8040B.js → isSymbol-DCbjQG_U.js} +1 -1
- package/dist/{journeyDiagram-XKPGCS4Q-BXlCEth8.js → journeyDiagram-XKPGCS4Q-ClPC94aN.js} +3 -3
- package/dist/{kanban-definition-3W4ZIXB7-CorxzSYm.js → kanban-definition-3W4ZIXB7-DHEAKdZt.js} +7 -7
- package/dist/{label-DTNqw9tv.js → label-DbZGAoCH.js} +538 -569
- package/dist/{loader-3c9hT4kT.js → loader-Bd1kgLn7.js} +19 -16
- package/dist/main.js +2602 -2594
- package/dist/{memoize-CuHciEBb.js → memoize-CSTI9eOX.js} +1 -1
- package/dist/{merge-CA_buyY3.js → merge-CVhG7q_o.js} +1 -1
- package/dist/{mermaid-CEKslOkI.js → mermaid-B2HDLx2g.js} +54 -54
- package/dist/{mermaid-parser.core-cq4YDee-.js → mermaid-parser.core-ntCgyx0x.js} +8 -8
- package/dist/min-Ds3gG0Ff.js +96 -0
- package/dist/{mindmap-definition-VGOIOE7T-DRsT8UaN.js → mindmap-definition-VGOIOE7T-CxEUZZvY.js} +9 -9
- package/dist/{now-CXAdKY5k.js → now-nrrrOr01.js} +1 -1
- package/dist/{once-CZno0h-b.js → once-C_TIu-kR.js} +1 -1
- package/dist/{packet-DYOGHKS2-Dw08gMaZ.js → packet-DYOGHKS2-BhvnpoGi.js} +3 -3
- package/dist/{pie-VRWISCQL-C5SPSvT8.js → pie-VRWISCQL-dILuA3iG.js} +3 -3
- package/dist/{pieDiagram-ADFJNKIX-DhJ1Cx2O.js → pieDiagram-ADFJNKIX-U3LrUqAS.js} +14 -14
- package/dist/{process-output-KyzWazB-.js → process-output-BbUNe4iH.js} +3181 -3204
- package/dist/{quadrantDiagram-AYHSOK5B-DXUFIWlz.js → quadrantDiagram-AYHSOK5B-BVWuq-3R.js} +2 -2
- package/dist/{radar-ZZBFDIW7-BvY0bgSg.js → radar-ZZBFDIW7-DwFrOJDj.js} +3 -3
- package/dist/range-fJeId9Ri.js +30 -0
- package/dist/{requirementDiagram-UZGBJVZJ-DO_gtQIb.js → requirementDiagram-UZGBJVZJ-D0zpQnKC.js} +9 -9
- package/dist/{sankeyDiagram-TZEHDZUN-OZzXEkuG.js → sankeyDiagram-TZEHDZUN-CExy1joT.js} +2 -2
- package/dist/{sequenceDiagram-WL72ISMW-K7nZRifV.js → sequenceDiagram-WL72ISMW-D1BJxLjH.js} +4 -4
- package/dist/{slides-component-CIcSvFh7.js → slides-component-CX2JC-Ws.js} +2 -2
- package/dist/{spec-DYaR1rJh.js → spec-CiHus5Bb.js} +3 -3
- package/dist/{stateDiagram-FKZM4ZOC-DzXJZAq7.js → stateDiagram-FKZM4ZOC-B1S8jGMn.js} +12 -12
- package/dist/{stateDiagram-v2-4FDKWEC3-BZBPUmyF.js → stateDiagram-v2-4FDKWEC3-BH5ozUbc.js} +10 -10
- package/dist/stex-CQDv3aS8.js +4 -0
- package/dist/style.css +1 -1
- package/dist/{timeline-definition-IT6M3QCI-DNoLAh-i.js → timeline-definition-IT6M3QCI-BDT9JAmn.js} +2 -2
- package/dist/{toDate-D6VXexnV.js → toDate-BzYZtEK7.js} +4 -4
- package/dist/{toNumber-xFPoy1OI.js → toNumber-55tjPCWr.js} +2 -2
- package/dist/tooltip-BXEpXV3R.js +404 -0
- package/dist/{treemap-GDKQZRPO-C5OoxpmV.js → treemap-GDKQZRPO-bx2ngsgN.js} +3 -3
- package/dist/{types-CQ-RbYxp.js → types-D_ntCXg0.js} +3 -3
- package/dist/{useAsyncData-Cd4Urlww.js → useAsyncData-rN1nzPaS.js} +2 -2
- package/dist/{useDeepCompareMemoize-X7clcrcQ.js → useDeepCompareMemoize-iM1YNTEF.js} +4 -4
- package/dist/{useIframeCapabilities-BVQrlRBd.js → useIframeCapabilities-CqhrVue6.js} +1 -1
- package/dist/{useLifecycle-Dids8BPm.js → useLifecycle-DgDTfOLZ.js} +9 -9
- package/dist/{useTheme-Dm1WaAGy.js → useTheme-MWfxn4oz.js} +4 -5
- package/dist/{vega-component-A6unyUJS.js → vega-component-CkpTXaRx.js} +23 -23
- package/dist/{xychartDiagram-PRI3JC2R-ehVeySMW.js → xychartDiagram-PRI3JC2R-CuAZiqHS.js} +5 -5
- package/dist/{Combination-B--d1_LV.js → zod-C6UGQ3fz.js} +8085 -8151
- package/package.json +8 -41
- package/src/__tests__/branded.ts +6 -0
- package/src/__tests__/main.test.tsx +12 -14
- package/src/components/ai/ai-provider-icon.tsx +3 -2
- package/src/components/app-config/user-config-form.tsx +0 -27
- package/src/components/chat/acp/agent-docs.tsx +3 -3
- package/src/components/chat/acp/agent-panel.tsx +69 -22
- package/src/components/chat/acp/agent-selector.tsx +2 -11
- package/src/components/chat/acp/state.ts +14 -2
- package/src/components/chat/chat-panel.tsx +2 -1
- package/src/components/data-table/TableBottomBar.tsx +12 -1
- package/src/components/data-table/TableTopBar.tsx +31 -35
- package/src/components/data-table/cell-selection/types.ts +3 -2
- package/src/components/data-table/charts/charts.tsx +42 -13
- package/src/components/data-table/charts/components/chart-items.tsx +1 -1
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/column-formatting/types.ts +3 -2
- package/src/components/data-table/column-header.tsx +4 -2
- package/src/components/data-table/column-wrapping/types.ts +3 -2
- package/src/components/data-table/columns.tsx +4 -1
- package/src/components/data-table/copy-column/types.ts +3 -2
- package/src/components/data-table/data-table.tsx +6 -1
- package/src/components/data-table/focus-row/types.ts +3 -2
- package/src/components/data-table/loading-table.tsx +4 -1
- package/src/components/data-table/range-focus/__tests__/atoms.test.ts +11 -11
- package/src/components/data-table/range-focus/__tests__/use-cell-range-selection.test.ts +9 -11
- package/src/components/data-table/range-focus/cell-selection-stats.tsx +3 -1
- package/src/components/data-table/row-viewer-panel/row-viewer.tsx +1 -1
- package/src/components/data-table/table-explorer-panel/table-explorer-panel.tsx +2 -2
- package/src/components/editor/__tests__/data-attributes.test.tsx +93 -94
- package/src/components/editor/actions/name-cell-input.tsx +4 -2
- package/src/components/editor/actions/useCellActionButton.tsx +4 -2
- package/src/components/editor/ai/add-cell-with-ai.tsx +2 -1
- package/src/components/editor/cell/CellStatus.tsx +4 -5
- package/src/components/editor/cell/cell-context-menu.tsx +4 -2
- package/src/components/editor/cell/code/cell-editor.tsx +2 -1
- package/src/components/editor/cell/toolbar.tsx +2 -1
- package/src/components/editor/chrome/components/contribute-snippet-button.tsx +4 -1
- package/src/components/editor/chrome/components/feedback-button.tsx +4 -1
- package/src/components/editor/chrome/panels/context-aware-panel/context-aware-panel.tsx +1 -1
- package/src/components/editor/chrome/panels/file-explorer-panel.tsx +0 -10
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +4 -1
- package/src/components/editor/chrome/wrapper/footer-items/lsp-status.tsx +2 -1
- package/src/components/editor/header/filename-input.tsx +4 -1
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +11 -12
- package/src/components/storage/__tests__/storage-snippets.test.ts +4 -6
- package/src/components/tracing/tracing.test.tsx +30 -30
- package/src/components/ui/accordion.tsx +1 -1
- package/src/components/ui/alert-dialog.tsx +1 -1
- package/src/components/ui/badge.tsx +2 -1
- package/src/components/ui/button.tsx +4 -3
- package/src/components/ui/calendar.tsx +3 -2
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/combobox.tsx +2 -1
- package/src/components/ui/command.tsx +4 -1
- package/src/components/ui/context-menu.tsx +1 -1
- package/src/components/ui/date-input.tsx +7 -6
- package/src/components/ui/date-picker.tsx +6 -4
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/draggable-popover.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +2 -1
- package/src/components/ui/field.tsx +1 -2
- package/src/components/ui/form.tsx +4 -5
- package/src/components/ui/fullscreen.tsx +4 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/navigation.tsx +1 -1
- package/src/components/ui/popover.tsx +1 -1
- package/src/components/ui/progress.tsx +4 -3
- package/src/components/ui/query-param-preserving-link.tsx +4 -2
- package/src/components/ui/radio-group.tsx +1 -1
- package/src/components/ui/range-slider.tsx +1 -1
- package/src/components/ui/scroll-area.tsx +1 -1
- package/src/components/ui/select.tsx +1 -1
- package/src/components/ui/sheet.tsx +3 -2
- package/src/components/ui/slider.tsx +1 -1
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -1
- package/src/components/ui/textarea.tsx +1 -2
- package/src/components/ui/toast.tsx +1 -1
- package/src/components/ui/toggle.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/core/ai/context/providers/cell-output.ts +1 -2
- package/src/core/ai/tools/edit-notebook-tool.ts +4 -3
- package/src/core/ai/tools/run-cells-tool.ts +4 -3
- package/src/core/cells/__tests__/add-missing-import.test.ts +23 -22
- package/src/core/cells/__tests__/apply-transaction.test.ts +12 -11
- package/src/core/cells/__tests__/cell.test.ts +14 -13
- package/src/core/cells/document-changes.ts +9 -9
- package/src/core/cells/logs.ts +1 -1
- package/src/core/codemirror/cells/__tests__/extensions.test.ts +15 -17
- package/src/core/codemirror/copilot/__tests__/transport.test.ts +128 -2
- package/src/core/codemirror/copilot/client.ts +9 -2
- package/src/core/codemirror/copilot/language-server.ts +11 -0
- package/src/core/codemirror/copilot/transport.ts +33 -8
- package/src/core/codemirror/language/languages/markdown.ts +1 -3
- package/src/core/codemirror/language/languages/python.ts +4 -0
- package/src/core/codemirror/language/languages/sql/completion-sources.tsx +4 -6
- package/src/core/codemirror/language/languages/sql/sql.ts +1 -3
- package/src/core/codemirror/language/panel/sql.tsx +4 -1
- package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +28 -42
- package/src/core/config/__tests__/config-schema.test.ts +2 -6
- package/src/core/config/config-schema.ts +0 -1
- package/src/core/config/feature-flag.tsx +0 -2
- package/src/core/datasets/data-source-connections.ts +4 -2
- package/src/core/dom/__tests__/htmlUtils.test.ts +8 -14
- package/src/core/dom/__tests__/outline.test.ts +2 -3
- package/src/core/edit-app.tsx +4 -1
- package/src/core/islands/__tests__/bridge.test.ts +20 -10
- package/src/core/islands/__tests__/parse.test.ts +8 -7
- package/src/core/network/__tests__/requests-lazy.test.ts +30 -14
- package/src/core/saving/__tests__/filename.test.ts +7 -6
- package/src/core/static/__tests__/download-html.test.ts +16 -15
- package/src/core/static/__tests__/files.test.ts +30 -28
- package/src/core/websocket/useMarimoKernelConnection.tsx +5 -11
- package/src/core/websocket/useWebSocket.tsx +3 -1
- package/src/css/app/Cell.css +25 -1
- package/src/css/globals.css +40 -14
- package/src/css/table.css +17 -0
- package/src/plugins/core/BadPlugin.tsx +7 -6
- package/src/plugins/impl/CheckboxPlugin.tsx +4 -1
- package/src/plugins/impl/DataEditorPlugin.tsx +8 -3
- package/src/plugins/impl/DataTablePlugin.tsx +5 -1
- package/src/plugins/impl/FormPlugin.tsx +1 -2
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +4 -1
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +43 -15
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +2 -11
- package/src/plugins/impl/chat/chat-ui.tsx +4 -1
- package/src/plugins/impl/data-frames/forms/__tests__/form.test.tsx +7 -9
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +12 -68
- package/src/plugins/impl/plotly/__tests__/selection.test.ts +237 -0
- package/src/plugins/impl/plotly/selection.ts +115 -0
- package/src/plugins/impl/vega/__tests__/make-selectable.test.ts +13 -14
- package/src/plugins/impl/vega/__tests__/utils.test.ts +68 -0
- package/src/plugins/impl/vega/utils.ts +14 -5
- package/src/plugins/impl/vega/vega.css +2 -1
- package/src/plugins/layout/ImageComparisonPlugin.tsx +1 -3
- package/src/plugins/stateless-plugin.ts +4 -2
- package/src/utils/__tests__/cell-urls.test.ts +24 -21
- package/src/utils/__tests__/filenames.test.ts +15 -14
- package/src/utils/__tests__/json-parser.test.ts +14 -21
- package/src/utils/__tests__/path.test.ts +34 -31
- package/src/utils/__tests__/urls.test.ts +19 -18
- package/src/utils/json/base64.ts +2 -5
- package/src/utils/time.ts +4 -2
- package/src/utils/tracer.ts +1 -0
- package/src/utils/typed.ts +2 -2
- package/dist/_basePickBy-QjOmBDRE.js +0 -110
- package/dist/_baseSet-xgn1IbGV.js +0 -27
- package/dist/architecture-7HQA4BMR-BRyVh_Za.js +0 -6
- package/dist/assets/__vite-browser-external-Us1ds95c.js +0 -1
- package/dist/dist-B0R_ZM4-.js +0 -6
- package/dist/dist-B4a9_9pj.js +0 -5
- package/dist/dist-BCSUKEwO.js +0 -5
- package/dist/dist-BONIDQq6.js +0 -5
- package/dist/dist-BYeRx2hb.js +0 -5
- package/dist/dist-D2Rk1j4R.js +0 -1381
- package/dist/dist-DZjX5TYv.js +0 -5
- package/dist/dist-Dkw9x6kc.js +0 -5
- package/dist/dist-Ds6UaXGR.js +0 -6
- package/dist/dist-KuEJ1Q53.js +0 -8
- package/dist/dist-S72WNyTZ.js +0 -5
- package/dist/dist-bTG-yssT.js +0 -5
- package/dist/dist-diF0sguc.js +0 -8
- package/dist/dist-mJ84BIgu.js +0 -8
- package/dist/dist-wSIhFWQz.js +0 -8
- package/dist/get-CqrzlV1v.js +0 -68
- package/dist/range-CYz5jI--.js +0 -17
- package/dist/stex-CZyTRGVB.js +0 -4
- package/dist/tooltip-DGHTbHl5.js +0 -404
- /package/dist/{dist-KZI_BHqV.js → dist-CxZvoNao.js} +0 -0
- /package/dist/{invariant-D4hPsZFI.js → invariant-e8eBgdux.js} +0 -0
- /package/dist/{isArrayLikeObject-C-hFPChh.js → isArrayLikeObject-LXbTYiBa.js} +0 -0
- /package/dist/{main-CvkAPtaq.js → main-XimWhSi_.js} +0 -0
- /package/dist/{purify.es-ukiMXY-F.js → purify.es-hTCfRGdl.js} +0 -0
- /package/dist/{react-dom-BKwCWYPW.js → react-dom-BSUuJjCR.js} +0 -0
- /package/dist/{stex-Ze8D4R_5.js → stex-D887Ylhf.js} +0 -0
|
@@ -38,9 +38,7 @@ export const MARKDOWN_INITIAL_HIDE_CODE = true;
|
|
|
38
38
|
/**
|
|
39
39
|
* Language adapter for Markdown.
|
|
40
40
|
*/
|
|
41
|
-
export class MarkdownLanguageAdapter
|
|
42
|
-
implements LanguageAdapter<MarkdownLanguageAdapterMetadata>
|
|
43
|
-
{
|
|
41
|
+
export class MarkdownLanguageAdapter implements LanguageAdapter<MarkdownLanguageAdapterMetadata> {
|
|
44
42
|
private parser = new MarkdownParser();
|
|
45
43
|
|
|
46
44
|
readonly type = "markdown";
|
|
@@ -45,6 +45,7 @@ import type { LanguageAdapter } from "../types";
|
|
|
45
45
|
|
|
46
46
|
const pylspClient = once((lspConfig: LSPConfig) => {
|
|
47
47
|
// Create a mutable reference for the resync callback
|
|
48
|
+
// oxlint-disable-next-line prefer-const -- reassigned after closure capture
|
|
48
49
|
let resyncCallback: (() => Promise<void>) | undefined;
|
|
49
50
|
|
|
50
51
|
const transport = createTransport("pylsp", async () => {
|
|
@@ -151,6 +152,7 @@ const pylspClient = once((lspConfig: LSPConfig) => {
|
|
|
151
152
|
});
|
|
152
153
|
|
|
153
154
|
const tyLspClient = once((_: LSPConfig) => {
|
|
155
|
+
// oxlint-disable-next-line prefer-const -- reassigned after closure capture
|
|
154
156
|
let resyncCallback: (() => Promise<void>) | undefined;
|
|
155
157
|
|
|
156
158
|
const transport = createTransport("ty", async () => {
|
|
@@ -181,6 +183,7 @@ const tyLspClient = once((_: LSPConfig) => {
|
|
|
181
183
|
|
|
182
184
|
const pyreflyClient = once(
|
|
183
185
|
(lspConfig: LSPConfig & { diagnostics: DiagnosticsConfig }) => {
|
|
186
|
+
// oxlint-disable-next-line prefer-const -- reassigned after closure capture
|
|
184
187
|
let resyncCallback: (() => Promise<void>) | undefined;
|
|
185
188
|
|
|
186
189
|
const transport = createTransport("pyrefly", async () => {
|
|
@@ -218,6 +221,7 @@ const pyreflyClient = once(
|
|
|
218
221
|
);
|
|
219
222
|
|
|
220
223
|
const pyrightClient = once((_: LSPConfig) => {
|
|
224
|
+
// oxlint-disable-next-line prefer-const -- reassigned after closure capture
|
|
221
225
|
let resyncCallback: (() => Promise<void>) | undefined;
|
|
222
226
|
|
|
223
227
|
const transport = createTransport("basedpyright", async () => {
|
|
@@ -91,13 +91,11 @@ export function customKeywordCompletionSource(): CompletionSource {
|
|
|
91
91
|
|
|
92
92
|
// e.g. lazily load keyword docs
|
|
93
93
|
const getKeywordDocs = once(async (): Promise<Record<string, unknown>> => {
|
|
94
|
-
const keywords =
|
|
95
|
-
"@marimo-team/codemirror-sql/data/common-keywords.json"
|
|
96
|
-
);
|
|
94
|
+
const keywords =
|
|
95
|
+
await import("@marimo-team/codemirror-sql/data/common-keywords.json");
|
|
97
96
|
// Include DuckDB for now, but we can remove this once we have a better way to handle dialect-specific keywords
|
|
98
|
-
const duckdbKeywords =
|
|
99
|
-
"@marimo-team/codemirror-sql/data/duckdb-keywords.json"
|
|
100
|
-
);
|
|
97
|
+
const duckdbKeywords =
|
|
98
|
+
await import("@marimo-team/codemirror-sql/data/duckdb-keywords.json");
|
|
101
99
|
return {
|
|
102
100
|
...keywords.default.keywords,
|
|
103
101
|
...duckdbKeywords.default.keywords,
|
|
@@ -77,9 +77,7 @@ function getLatestEngine(): ConnectionName {
|
|
|
77
77
|
/**
|
|
78
78
|
* Language adapter for SQL.
|
|
79
79
|
*/
|
|
80
|
-
export class SQLLanguageAdapter
|
|
81
|
-
implements LanguageAdapter<SQLLanguageAdapterMetadata>
|
|
82
|
-
{
|
|
80
|
+
export class SQLLanguageAdapter implements LanguageAdapter<SQLLanguageAdapterMetadata> {
|
|
83
81
|
private parser = new SQLParser();
|
|
84
82
|
readonly type = "sql";
|
|
85
83
|
sqlModeEnabled: boolean;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { Select as SelectPrimitive } from "radix-ui";
|
|
4
|
+
|
|
5
|
+
type SelectTriggerProps = SelectPrimitive.SelectTriggerProps;
|
|
6
|
+
|
|
4
7
|
import { useAtomValue } from "jotai";
|
|
5
8
|
import {
|
|
6
9
|
AlertCircle,
|
|
@@ -45,9 +45,8 @@ def foo(x):
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
test("should handle lambda parameters", () => {
|
|
48
|
-
expect(
|
|
49
|
-
|
|
50
|
-
).toMatchInlineSnapshot(`
|
|
48
|
+
expect(runHighlight(["a", "b"], "result = lambda a: a + b"))
|
|
49
|
+
.toMatchInlineSnapshot(`
|
|
51
50
|
"
|
|
52
51
|
result = lambda a: a + b
|
|
53
52
|
^
|
|
@@ -56,9 +55,8 @@ def foo(x):
|
|
|
56
55
|
});
|
|
57
56
|
|
|
58
57
|
test("should handle comprehension variables", () => {
|
|
59
|
-
expect(
|
|
60
|
-
|
|
61
|
-
).toMatchInlineSnapshot(`
|
|
58
|
+
expect(runHighlight(["a", "data"], "result = [a for a in data]"))
|
|
59
|
+
.toMatchInlineSnapshot(`
|
|
62
60
|
"
|
|
63
61
|
result = [a for a in data]
|
|
64
62
|
^^^^
|
|
@@ -146,9 +144,8 @@ def factorial(n):
|
|
|
146
144
|
});
|
|
147
145
|
|
|
148
146
|
test("function param vs global", () => {
|
|
149
|
-
expect(
|
|
150
|
-
|
|
151
|
-
).toMatchInlineSnapshot(`
|
|
147
|
+
expect(runHighlight(["a", "b"], "def foo(a): return a + b"))
|
|
148
|
+
.toMatchInlineSnapshot(`
|
|
152
149
|
"
|
|
153
150
|
def foo(a): return a + b
|
|
154
151
|
^
|
|
@@ -157,9 +154,8 @@ def factorial(n):
|
|
|
157
154
|
});
|
|
158
155
|
|
|
159
156
|
test("lambda param vs global", () => {
|
|
160
|
-
expect(
|
|
161
|
-
|
|
162
|
-
).toMatchInlineSnapshot(`
|
|
157
|
+
expect(runHighlight(["x", "b"], "func = lambda x: x + b"))
|
|
158
|
+
.toMatchInlineSnapshot(`
|
|
163
159
|
"
|
|
164
160
|
func = lambda x: x + b
|
|
165
161
|
^
|
|
@@ -168,9 +164,8 @@ def factorial(n):
|
|
|
168
164
|
});
|
|
169
165
|
|
|
170
166
|
test("lambda with multiple params", () => {
|
|
171
|
-
expect(
|
|
172
|
-
|
|
173
|
-
).toMatchInlineSnapshot(`
|
|
167
|
+
expect(runHighlight(["x", "y", "z"], "f = lambda x, y: x + y + z"))
|
|
168
|
+
.toMatchInlineSnapshot(`
|
|
174
169
|
"
|
|
175
170
|
f = lambda x, y: x + y + z
|
|
176
171
|
^
|
|
@@ -187,9 +182,8 @@ def factorial(n):
|
|
|
187
182
|
});
|
|
188
183
|
|
|
189
184
|
test("nested comprehension", () => {
|
|
190
|
-
expect(
|
|
191
|
-
|
|
192
|
-
).toMatchInlineSnapshot(`
|
|
185
|
+
expect(runHighlight(["a", "b"], "[(a + b) for a, b in [(1,2), (3,4)]]"))
|
|
186
|
+
.toMatchInlineSnapshot(`
|
|
193
187
|
"
|
|
194
188
|
[(a + b) for a, b in [(1,2), (3,4)]]
|
|
195
189
|
"
|
|
@@ -225,9 +219,8 @@ def factorial(n):
|
|
|
225
219
|
});
|
|
226
220
|
|
|
227
221
|
test("class body using globals", () => {
|
|
228
|
-
expect(
|
|
229
|
-
|
|
230
|
-
).toMatchInlineSnapshot(`
|
|
222
|
+
expect(runHighlight(["a", "b"], "class MyClass:\n value = a + b"))
|
|
223
|
+
.toMatchInlineSnapshot(`
|
|
231
224
|
"
|
|
232
225
|
class MyClass:
|
|
233
226
|
value = a + b
|
|
@@ -237,9 +230,8 @@ def factorial(n):
|
|
|
237
230
|
});
|
|
238
231
|
|
|
239
232
|
test("decorator using global", () => {
|
|
240
|
-
expect(
|
|
241
|
-
|
|
242
|
-
).toMatchInlineSnapshot(`
|
|
233
|
+
expect(runHighlight(["logger"], "@logger\ndef decorated(): pass"))
|
|
234
|
+
.toMatchInlineSnapshot(`
|
|
243
235
|
"
|
|
244
236
|
@logger
|
|
245
237
|
^^^^^^
|
|
@@ -317,9 +309,8 @@ ${" ".repeat(8)}
|
|
|
317
309
|
});
|
|
318
310
|
|
|
319
311
|
test("multiple assignment", () => {
|
|
320
|
-
expect(
|
|
321
|
-
|
|
322
|
-
).toMatchInlineSnapshot(`
|
|
312
|
+
expect(runHighlight(["x", "y", "z", "a"], "x = y = z + a"))
|
|
313
|
+
.toMatchInlineSnapshot(`
|
|
323
314
|
"
|
|
324
315
|
x = y = z + a
|
|
325
316
|
^ ^
|
|
@@ -353,9 +344,8 @@ ${" ".repeat(8)}
|
|
|
353
344
|
});
|
|
354
345
|
|
|
355
346
|
test("global in return", () => {
|
|
356
|
-
expect(
|
|
357
|
-
|
|
358
|
-
).toMatchInlineSnapshot(`
|
|
347
|
+
expect(runHighlight(["config"], "def get_config(): return config"))
|
|
348
|
+
.toMatchInlineSnapshot(`
|
|
359
349
|
"
|
|
360
350
|
def get_config(): return config
|
|
361
351
|
^^^^^^
|
|
@@ -410,9 +400,8 @@ class Configurable:
|
|
|
410
400
|
});
|
|
411
401
|
|
|
412
402
|
test("comprehension shadows global 2", () => {
|
|
413
|
-
expect(
|
|
414
|
-
|
|
415
|
-
).toMatchInlineSnapshot(`
|
|
403
|
+
expect(runHighlight(["i"], "squares = [i**2 for i in range(10)]"))
|
|
404
|
+
.toMatchInlineSnapshot(`
|
|
416
405
|
"
|
|
417
406
|
squares = [i**2 for i in range(10)]
|
|
418
407
|
"
|
|
@@ -420,9 +409,8 @@ class Configurable:
|
|
|
420
409
|
});
|
|
421
410
|
|
|
422
411
|
test("comprehension with global in condition", () => {
|
|
423
|
-
expect(
|
|
424
|
-
|
|
425
|
-
).toMatchInlineSnapshot(`
|
|
412
|
+
expect(runHighlight(["x", "z"], "filtered = [x for x in [] if x > z]"))
|
|
413
|
+
.toMatchInlineSnapshot(`
|
|
426
414
|
"
|
|
427
415
|
filtered = [x for x in [] if x > z]
|
|
428
416
|
^
|
|
@@ -459,9 +447,8 @@ def make_adder(x):
|
|
|
459
447
|
});
|
|
460
448
|
|
|
461
449
|
test("rebinding in list comprehension", () => {
|
|
462
|
-
expect(
|
|
463
|
-
|
|
464
|
-
).toMatchInlineSnapshot(`
|
|
450
|
+
expect(runHighlight(["x"], "rebinding = [x for x in range(5)]"))
|
|
451
|
+
.toMatchInlineSnapshot(`
|
|
465
452
|
"
|
|
466
453
|
rebinding = [x for x in range(5)]
|
|
467
454
|
"
|
|
@@ -644,9 +631,8 @@ def run(polars):
|
|
|
644
631
|
});
|
|
645
632
|
|
|
646
633
|
test("mixed comprehension and outer globals", () => {
|
|
647
|
-
expect(
|
|
648
|
-
|
|
649
|
-
).toMatchInlineSnapshot(`
|
|
634
|
+
expect(runHighlight(["y", "z"], "values = [y + z for y in range(5)]"))
|
|
635
|
+
.toMatchInlineSnapshot(`
|
|
650
636
|
"
|
|
651
637
|
values = [y + z for y in range(5)]
|
|
652
638
|
^
|
|
@@ -70,9 +70,7 @@ test("default UserConfig - empty", () => {
|
|
|
70
70
|
"reference_highlighting": true,
|
|
71
71
|
"theme": "light",
|
|
72
72
|
},
|
|
73
|
-
"experimental": {
|
|
74
|
-
"storage_inspector": true,
|
|
75
|
-
},
|
|
73
|
+
"experimental": {},
|
|
76
74
|
"formatting": {
|
|
77
75
|
"line_length": 79,
|
|
78
76
|
},
|
|
@@ -142,9 +140,7 @@ test("default UserConfig - one level", () => {
|
|
|
142
140
|
"reference_highlighting": true,
|
|
143
141
|
"theme": "light",
|
|
144
142
|
},
|
|
145
|
-
"experimental": {
|
|
146
|
-
"storage_inspector": true,
|
|
147
|
-
},
|
|
143
|
+
"experimental": {},
|
|
148
144
|
"formatting": {
|
|
149
145
|
"line_length": 79,
|
|
150
146
|
},
|
|
@@ -186,7 +186,6 @@ export const UserConfigSchema = z
|
|
|
186
186
|
.looseObject({
|
|
187
187
|
markdown: z.boolean().optional(),
|
|
188
188
|
rtc: z.boolean().optional(),
|
|
189
|
-
storage_inspector: z.boolean().prefault(true),
|
|
190
189
|
// Add new experimental features here
|
|
191
190
|
})
|
|
192
191
|
// Pass through so that we don't remove any extra keys that the user has added.
|
|
@@ -11,7 +11,6 @@ export interface ExperimentalFeatures {
|
|
|
11
11
|
rtc_v2: boolean;
|
|
12
12
|
cache_panel: boolean;
|
|
13
13
|
external_agents: boolean;
|
|
14
|
-
storage_inspector: boolean;
|
|
15
14
|
// Add new feature flags here
|
|
16
15
|
}
|
|
17
16
|
|
|
@@ -21,7 +20,6 @@ const defaultValues: ExperimentalFeatures = {
|
|
|
21
20
|
rtc_v2: false,
|
|
22
21
|
cache_panel: false,
|
|
23
22
|
external_agents: import.meta.env.DEV,
|
|
24
|
-
storage_inspector: true,
|
|
25
23
|
};
|
|
26
24
|
|
|
27
25
|
export function getFeatureFlag<T extends keyof ExperimentalFeatures>(
|
|
@@ -32,8 +32,10 @@ const initialConnections: ConnectionsMap = new Map([
|
|
|
32
32
|
]);
|
|
33
33
|
|
|
34
34
|
// Extend the backend type but override the name property with the strongly typed ConnectionName
|
|
35
|
-
export interface DataSourceConnection
|
|
36
|
-
|
|
35
|
+
export interface DataSourceConnection extends Omit<
|
|
36
|
+
DataSourceConnectionType,
|
|
37
|
+
"name"
|
|
38
|
+
> {
|
|
37
39
|
name: ConnectionName;
|
|
38
40
|
}
|
|
39
41
|
|
|
@@ -6,20 +6,14 @@ import { UIElementRegistry } from "../uiregistry";
|
|
|
6
6
|
const registry = UIElementRegistry.INSTANCE;
|
|
7
7
|
|
|
8
8
|
describe("htmlUtils", () => {
|
|
9
|
-
it.each([
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"",
|
|
18
|
-
])("can parse element.dataset.initialValue", (initialValue) => {
|
|
19
|
-
const div = document.createElement("div");
|
|
20
|
-
div.dataset.initialValue = JSON.stringify(initialValue);
|
|
21
|
-
expect(parseInitialValue(div, registry)).toEqual(initialValue);
|
|
22
|
-
});
|
|
9
|
+
it.each([false, { a: 1 }, true, 0, 1, [{ a: 1 }, { b: 2 }], "hello", ""])(
|
|
10
|
+
"can parse element.dataset.initialValue",
|
|
11
|
+
(initialValue) => {
|
|
12
|
+
const div = document.createElement("div");
|
|
13
|
+
div.dataset.initialValue = JSON.stringify(initialValue);
|
|
14
|
+
expect(parseInitialValue(div, registry)).toEqual(initialValue);
|
|
15
|
+
},
|
|
16
|
+
);
|
|
23
17
|
|
|
24
18
|
it("can parse an element with no initialValue", () => {
|
|
25
19
|
const div = document.createElement("div");
|
|
@@ -439,9 +439,8 @@ const OUTLINE_2: Outline = {
|
|
|
439
439
|
};
|
|
440
440
|
|
|
441
441
|
it("mergeOutlines", () => {
|
|
442
|
-
expect(
|
|
443
|
-
|
|
444
|
-
).toMatchInlineSnapshot(`
|
|
442
|
+
expect(mergeOutlines([OUTLINE_1, null, OUTLINE_2, null]))
|
|
443
|
+
.toMatchInlineSnapshot(`
|
|
445
444
|
{
|
|
446
445
|
"items": [
|
|
447
446
|
{
|
package/src/core/edit-app.tsx
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { usePrevious } from "@dnd-kit/utilities";
|
|
4
|
-
import {
|
|
4
|
+
import { Tooltip } from "radix-ui";
|
|
5
|
+
|
|
6
|
+
const TooltipProvider = Tooltip.Provider;
|
|
7
|
+
|
|
5
8
|
import { useAtomValue, useSetAtom } from "jotai";
|
|
6
9
|
import { useEffect } from "react";
|
|
7
10
|
import { NotStartedConnectionAlert } from "@/components/editor/alerts/connecting-alert";
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import type { components } from "@marimo-team/marimo-api";
|
|
2
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
cellId,
|
|
7
|
+
requestId,
|
|
8
|
+
uiElementId,
|
|
9
|
+
widgetModelId,
|
|
10
|
+
} from "@/__tests__/branded";
|
|
11
|
+
|
|
12
|
+
type Base64String = components["schemas"]["Base64String"];
|
|
3
13
|
|
|
4
14
|
// Mock browser APIs before any imports
|
|
5
15
|
vi.stubGlobal(
|
|
@@ -89,7 +99,7 @@ describe("IslandsPyodideBridge", () => {
|
|
|
89
99
|
describe("sendComponentValues", () => {
|
|
90
100
|
it("should include type field and token in control request", async () => {
|
|
91
101
|
const request = {
|
|
92
|
-
objectIds: ["Hbol-0"],
|
|
102
|
+
objectIds: [uiElementId("Hbol-0")],
|
|
93
103
|
values: [58],
|
|
94
104
|
};
|
|
95
105
|
|
|
@@ -108,7 +118,7 @@ describe("IslandsPyodideBridge", () => {
|
|
|
108
118
|
|
|
109
119
|
it("should preserve all request properties", async () => {
|
|
110
120
|
const request = {
|
|
111
|
-
objectIds: ["slider-1", "slider-2"],
|
|
121
|
+
objectIds: [uiElementId("slider-1"), uiElementId("slider-2")],
|
|
112
122
|
values: [10, 20],
|
|
113
123
|
};
|
|
114
124
|
|
|
@@ -128,7 +138,7 @@ describe("IslandsPyodideBridge", () => {
|
|
|
128
138
|
describe("sendFunctionRequest", () => {
|
|
129
139
|
it("should include type field in control request", async () => {
|
|
130
140
|
const request = {
|
|
131
|
-
functionCallId: "call-123",
|
|
141
|
+
functionCallId: requestId("call-123"),
|
|
132
142
|
namespace: "test_namespace",
|
|
133
143
|
functionName: "my_function",
|
|
134
144
|
args: { x: 1, y: 2 },
|
|
@@ -152,7 +162,7 @@ describe("IslandsPyodideBridge", () => {
|
|
|
152
162
|
describe("sendRun", () => {
|
|
153
163
|
it("should include type field in control request", async () => {
|
|
154
164
|
const request = {
|
|
155
|
-
cellIds: ["cell-1", "cell-2"],
|
|
165
|
+
cellIds: [cellId("cell-1"), cellId("cell-2")],
|
|
156
166
|
codes: ["print('hello')", "print('world')"],
|
|
157
167
|
};
|
|
158
168
|
|
|
@@ -170,7 +180,7 @@ describe("IslandsPyodideBridge", () => {
|
|
|
170
180
|
|
|
171
181
|
it("should call loadPackages before putControlRequest", async () => {
|
|
172
182
|
const request = {
|
|
173
|
-
cellIds: ["cell-1"],
|
|
183
|
+
cellIds: [cellId("cell-1")],
|
|
174
184
|
codes: ["import pandas"],
|
|
175
185
|
};
|
|
176
186
|
|
|
@@ -190,13 +200,13 @@ describe("IslandsPyodideBridge", () => {
|
|
|
190
200
|
describe("sendModelValue", () => {
|
|
191
201
|
it("should include type field in control request", async () => {
|
|
192
202
|
const request = {
|
|
193
|
-
modelId: "widget-1",
|
|
203
|
+
modelId: widgetModelId("widget-1"),
|
|
194
204
|
message: {
|
|
195
205
|
method: "update" as const,
|
|
196
206
|
state: { value: 42 },
|
|
197
207
|
bufferPaths: [],
|
|
198
208
|
},
|
|
199
|
-
buffers: [],
|
|
209
|
+
buffers: [] as Base64String[],
|
|
200
210
|
};
|
|
201
211
|
|
|
202
212
|
await bridge.sendModelValue(request);
|
|
@@ -222,16 +232,16 @@ describe("IslandsPyodideBridge", () => {
|
|
|
222
232
|
// Test all methods to ensure they include the type field
|
|
223
233
|
await bridge.sendComponentValues({ objectIds: [], values: [] });
|
|
224
234
|
await bridge.sendFunctionRequest({
|
|
225
|
-
functionCallId: "",
|
|
235
|
+
functionCallId: requestId(""),
|
|
226
236
|
namespace: "",
|
|
227
237
|
functionName: "",
|
|
228
238
|
args: {},
|
|
229
239
|
});
|
|
230
240
|
await bridge.sendRun({ cellIds: [], codes: [] });
|
|
231
241
|
await bridge.sendModelValue({
|
|
232
|
-
modelId: "",
|
|
242
|
+
modelId: widgetModelId(""),
|
|
233
243
|
message: { method: "update", state: {}, bufferPaths: [] },
|
|
234
|
-
buffers: [],
|
|
244
|
+
buffers: [] as Base64String[],
|
|
235
245
|
});
|
|
236
246
|
|
|
237
247
|
// All calls should have the type field
|
|
@@ -78,11 +78,12 @@ describe("parseIslandCode", () => {
|
|
|
78
78
|
|
|
79
79
|
codes = [...codes, ...codes.map(encodeURIComponent)];
|
|
80
80
|
|
|
81
|
-
it.each(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
it.each(codes)(
|
|
82
|
+
"should return the code without leading or trailing whitespace",
|
|
83
|
+
(code) => {
|
|
84
|
+
const result = parseIslandCode(code);
|
|
85
|
+
const expected = 'def __():\n print("Hello, World!")\n return';
|
|
86
|
+
expect(result).toBe(expected);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
88
89
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { cellId, requestId, uiElementId } from "@/__tests__/branded";
|
|
4
5
|
import type { RuntimeManager } from "../../runtime/runtime";
|
|
5
6
|
import { createLazyRequests } from "../requests-lazy";
|
|
6
7
|
import type { EditRequests, RunRequests } from "../types";
|
|
@@ -59,7 +60,7 @@ describe("createLazyRequests", () => {
|
|
|
59
60
|
mockGetRuntimeManager,
|
|
60
61
|
);
|
|
61
62
|
|
|
62
|
-
await lazyRequests.sendRun({ cellIds: ["cell1"], codes: ["code"] });
|
|
63
|
+
await lazyRequests.sendRun({ cellIds: [cellId("cell1")], codes: ["code"] });
|
|
63
64
|
|
|
64
65
|
expect(mockInit).toHaveBeenCalledTimes(1);
|
|
65
66
|
});
|
|
@@ -70,10 +71,13 @@ describe("createLazyRequests", () => {
|
|
|
70
71
|
mockGetRuntimeManager,
|
|
71
72
|
);
|
|
72
73
|
|
|
73
|
-
await lazyRequests.sendRun({ cellIds: ["cell1"], codes: ["code"] });
|
|
74
|
-
await lazyRequests.sendInstantiate({
|
|
74
|
+
await lazyRequests.sendRun({ cellIds: [cellId("cell1")], codes: ["code"] });
|
|
75
|
+
await lazyRequests.sendInstantiate({
|
|
76
|
+
objectIds: [uiElementId("obj1")],
|
|
77
|
+
values: [],
|
|
78
|
+
});
|
|
75
79
|
await lazyRequests.sendFunctionRequest({
|
|
76
|
-
functionCallId: "func1",
|
|
80
|
+
functionCallId: requestId("func1"),
|
|
77
81
|
functionName: "testFunc",
|
|
78
82
|
args: {},
|
|
79
83
|
namespace: "test",
|
|
@@ -89,7 +93,7 @@ describe("createLazyRequests", () => {
|
|
|
89
93
|
mockGetRuntimeManager,
|
|
90
94
|
);
|
|
91
95
|
|
|
92
|
-
await lazyRequests.sendRun({ cellIds: ["cell1"], codes: ["code"] });
|
|
96
|
+
await lazyRequests.sendRun({ cellIds: [cellId("cell1")], codes: ["code"] });
|
|
93
97
|
|
|
94
98
|
expect(waitForConnectionOpen).toHaveBeenCalled();
|
|
95
99
|
});
|
|
@@ -100,7 +104,7 @@ describe("createLazyRequests", () => {
|
|
|
100
104
|
mockGetRuntimeManager,
|
|
101
105
|
);
|
|
102
106
|
|
|
103
|
-
const args = { cellIds: ["cell1"], codes: ["code"] };
|
|
107
|
+
const args = { cellIds: [cellId("cell1")], codes: ["code"] };
|
|
104
108
|
await lazyRequests.sendRun(args);
|
|
105
109
|
|
|
106
110
|
expect(mockDelegate.sendRun).toHaveBeenCalledWith(args);
|
|
@@ -113,7 +117,7 @@ describe("createLazyRequests", () => {
|
|
|
113
117
|
);
|
|
114
118
|
|
|
115
119
|
const result = await lazyRequests.sendFunctionRequest({
|
|
116
|
-
functionCallId: "func1",
|
|
120
|
+
functionCallId: requestId("func1"),
|
|
117
121
|
functionName: "testFunc",
|
|
118
122
|
args: {},
|
|
119
123
|
namespace: "test",
|
|
@@ -143,7 +147,7 @@ describe("createLazyRequests", () => {
|
|
|
143
147
|
);
|
|
144
148
|
|
|
145
149
|
await expect(
|
|
146
|
-
lazyRequests.sendRun({ cellIds: ["cell1"], codes: ["code"] }),
|
|
150
|
+
lazyRequests.sendRun({ cellIds: [cellId("cell1")], codes: ["code"] }),
|
|
147
151
|
).rejects.toThrow("Init failed");
|
|
148
152
|
});
|
|
149
153
|
|
|
@@ -157,7 +161,7 @@ describe("createLazyRequests", () => {
|
|
|
157
161
|
);
|
|
158
162
|
|
|
159
163
|
await expect(
|
|
160
|
-
lazyRequests.sendRun({ cellIds: ["cell1"], codes: ["code"] }),
|
|
164
|
+
lazyRequests.sendRun({ cellIds: [cellId("cell1")], codes: ["code"] }),
|
|
161
165
|
).rejects.toThrow("Request failed");
|
|
162
166
|
});
|
|
163
167
|
|
|
@@ -169,7 +173,10 @@ describe("createLazyRequests", () => {
|
|
|
169
173
|
);
|
|
170
174
|
|
|
171
175
|
// First request with first runtime manager
|
|
172
|
-
await lazyRequests.sendRun({
|
|
176
|
+
await lazyRequests.sendRun({
|
|
177
|
+
cellIds: [cellId("cell1")],
|
|
178
|
+
codes: ["code"],
|
|
179
|
+
});
|
|
173
180
|
expect(mockInit).toHaveBeenCalledTimes(1);
|
|
174
181
|
|
|
175
182
|
// Create a new runtime manager
|
|
@@ -187,7 +194,10 @@ describe("createLazyRequests", () => {
|
|
|
187
194
|
);
|
|
188
195
|
|
|
189
196
|
// Second request with second runtime manager
|
|
190
|
-
await lazyRequests2.sendRun({
|
|
197
|
+
await lazyRequests2.sendRun({
|
|
198
|
+
cellIds: [cellId("cell2")],
|
|
199
|
+
codes: ["code2"],
|
|
200
|
+
});
|
|
191
201
|
|
|
192
202
|
// Both inits should have been called
|
|
193
203
|
expect(mockInit).toHaveBeenCalledTimes(1);
|
|
@@ -201,9 +211,15 @@ describe("createLazyRequests", () => {
|
|
|
201
211
|
);
|
|
202
212
|
|
|
203
213
|
// Multiple requests
|
|
204
|
-
await lazyRequests.sendRun({
|
|
205
|
-
|
|
206
|
-
|
|
214
|
+
await lazyRequests.sendRun({
|
|
215
|
+
cellIds: [cellId("cell1")],
|
|
216
|
+
codes: ["code"],
|
|
217
|
+
});
|
|
218
|
+
await lazyRequests.sendDeleteCell({ cellId: cellId("cell2") });
|
|
219
|
+
await lazyRequests.sendInstantiate({
|
|
220
|
+
objectIds: [uiElementId("obj1")],
|
|
221
|
+
values: [],
|
|
222
|
+
});
|
|
207
223
|
|
|
208
224
|
// Init should only be called once
|
|
209
225
|
expect(mockInit).toHaveBeenCalledTimes(1);
|
|
@@ -5,12 +5,13 @@ import { EDGE_CASE_FILENAMES } from "../../../__tests__/mocks";
|
|
|
5
5
|
import { Paths } from "../../../utils/paths";
|
|
6
6
|
|
|
7
7
|
describe("filename handling logic", () => {
|
|
8
|
-
it.each(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
it.each(EDGE_CASE_FILENAMES)(
|
|
9
|
+
"should extract basename correctly for document title: %s",
|
|
10
|
+
(filename) => {
|
|
11
|
+
const basename = Paths.basename(filename);
|
|
12
|
+
expect(basename).toBe(filename); // Since no path separator
|
|
13
|
+
},
|
|
14
|
+
);
|
|
14
15
|
|
|
15
16
|
it("should handle full paths with unicode filenames", () => {
|
|
16
17
|
EDGE_CASE_FILENAMES.forEach((filename) => {
|
|
@@ -44,23 +44,24 @@ describe("updateAssetUrl", () => {
|
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
describe("filename handling for downloads", () => {
|
|
47
|
-
it.each(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
it.each(EDGE_CASE_FILENAMES)(
|
|
48
|
+
"should handle edge case filenames in download operations: %s",
|
|
49
|
+
(filename) => {
|
|
50
|
+
// Test that basename extraction works correctly for downloads
|
|
51
|
+
const basename = Paths.basename(filename);
|
|
52
|
+
expect(basename).toBe(filename);
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
// Test filename conversion for HTML downloads
|
|
55
|
+
const htmlFilename = Filenames.toHTML(filename);
|
|
56
|
+
expect(htmlFilename).toMatch(/\.html$/);
|
|
57
|
+
expect(htmlFilename).toContain(Filenames.withoutExtension(filename));
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
// Ensure unicode and spaces are preserved in basename
|
|
60
|
+
const withoutExt = Filenames.withoutExtension(filename);
|
|
61
|
+
expect(withoutExt).not.toBe("");
|
|
62
|
+
expect(typeof withoutExt).toBe("string");
|
|
63
|
+
},
|
|
64
|
+
);
|
|
64
65
|
|
|
65
66
|
it("should handle blob download filename generation", () => {
|
|
66
67
|
// Mock URL.createObjectURL for blob testing
|