@marimo-team/islands 0.25.1-dev4 → 0.25.1-dev40
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-KVhjDMSe.js → ConnectedDataExplorerComponent-CwMXfDQR.js} +3 -3
- package/dist/{ErrorBoundary-pV36lYEK.js → ErrorBoundary-CAJO-M56.js} +1 -1
- package/dist/{ImageComparisonComponent-Dlm5aWnH.js → ImageComparisonComponent-Cpfz30OZ.js} +51 -52
- package/dist/{abnfDiagram-VCTEODGH-CpN0FRda.js → abnfDiagram-VCTEODGH-AFhOQTt8.js} +3 -3
- package/dist/{architectureDiagram-5GKGNRK7-DDyj5SRB.js → architectureDiagram-5GKGNRK7-BngksAAQ.js} +5 -5
- package/dist/{blockDiagram-I7D4REHJ-BbXEXJRu.js → blockDiagram-I7D4REHJ-CvBmppdy.js} +9 -9
- package/dist/{c4Diagram-7LVT6UL2-DcLsbQmR.js → c4Diagram-7LVT6UL2-EceL4_jH.js} +7 -7
- package/dist/{cells-B5-y5EY3.js → cells-Cv93oav_.js} +3 -3
- package/dist/{channel-B5XnTarr.js → channel-z7HZXHwv.js} +1 -1
- package/dist/{chat-ui-HJZsTl7o.js → chat-ui-DLSF8a04.js} +4 -4
- package/dist/{chunk-4HAMMTFA-D2qv8E0X.js → chunk-4HAMMTFA-BPTTOOC5.js} +5 -5
- package/dist/{chunk-75Z2AOVW-5_HsvXwr.js → chunk-75Z2AOVW-C4AOleKf.js} +1 -1
- package/dist/{chunk-DU6HZSFF-BUgAHvnM.js → chunk-DU6HZSFF-1TwWR6gh.js} +1 -1
- package/dist/{chunk-F27PBJKO-DHmYWZXr.js → chunk-F27PBJKO-DMI1PBe4.js} +1 -1
- package/dist/{chunk-GMAD6QVW-Czynz8aA.js → chunk-GMAD6QVW-vStrMz2P.js} +3 -3
- package/dist/{chunk-GVQU2GXP-yQEdulRS.js → chunk-GVQU2GXP-2HwWgs4u.js} +2 -2
- package/dist/{chunk-IMKFNOWR-BfwTebD0.js → chunk-IMKFNOWR-UOVZuZVn.js} +5 -5
- package/dist/{chunk-L3NEJ4N5-DwRWnDDK.js → chunk-L3NEJ4N5-RhC7i0I2.js} +5 -5
- package/dist/{chunk-OSK3NFVY-BBKU_Ign.js → chunk-OSK3NFVY-CZV09N-U.js} +6 -6
- package/dist/{chunk-P2QGCYS3-C0iGU29N.js → chunk-P2QGCYS3-0TAWai9C.js} +1 -1
- package/dist/{chunk-POPQ4Y6H-BCbS3Ozc.js → chunk-POPQ4Y6H-Cc3_56GX.js} +1 -1
- package/dist/{chunk-PWAF6VOD-CTFCL0jI.js → chunk-PWAF6VOD-lNxB9k8z.js} +1 -1
- package/dist/{chunk-SHT3W25Y-BspJEJ5H.js → chunk-SHT3W25Y-CrEPyWy1.js} +7 -7
- package/dist/{chunk-SVP7TREG-DX3rFNTe.js → chunk-SVP7TREG-uIyyySp6.js} +2 -2
- package/dist/{chunk-TICWLB2K-fVF7Uujg.js → chunk-TICWLB2K-DdXM3eg6.js} +5 -5
- package/dist/classDiagram-ZZMXUADV-BiATbBE4.js +30 -0
- package/dist/classDiagram-v2-VYDZK3BY-JnH97GYw.js +30 -0
- package/dist/{code-visibility-CgZS2a3W.js → code-visibility-XU9RAJNV.js} +2 -2
- package/dist/{common-DnMDPPaW.js → common-C0fbrgB8.js} +13 -13
- package/dist/{cynefinDiagram-5FMLGOSQ-CFQrqzSX.js → cynefinDiagram-5FMLGOSQ-zknaAsGy.js} +3 -3
- package/dist/{dagre-GXQ25YYZ-xHNAUTyG.js → dagre-GXQ25YYZ-BhMOoMGJ.js} +10 -10
- package/dist/{data-grid-overlay-editor-hHYgD_Sm.js → data-grid-overlay-editor-BnhbJgoq.js} +1 -1
- package/dist/{diagram-S7CK7UJ4-Bt1rPbAx.js → diagram-S7CK7UJ4-V5-Z-EDY.js} +4 -4
- package/dist/{diagram-UQ7AKVKN-D1sq5FoZ.js → diagram-UQ7AKVKN-qw8AjDal.js} +3 -3
- package/dist/{diagram-VSXAHHWV-BKpmG23x.js → diagram-VSXAHHWV-CR7BJygZ.js} +2 -2
- package/dist/{diagram-VX7I27RA-BMwGFVD6.js → diagram-VX7I27RA-DfuqFb1E.js} +5 -5
- package/dist/{diagram-Z3DM3KII--KLDR9Pl.js → diagram-Z3DM3KII-DpWwlYZB.js} +3 -3
- package/dist/{dist-BaHjhkpZ.js → dist-CcyKTBTF.js} +1 -1
- package/dist/{ebnfDiagram-PWID7BFC-WnG4cvSQ.js → ebnfDiagram-PWID7BFC-C20OnNMZ.js} +3 -3
- package/dist/{erDiagram-RLTQ6QDP-DhzKiYHc.js → erDiagram-RLTQ6QDP-DBXLWO9v.js} +12 -12
- package/dist/{error-entries-Bkbpx0T0.js → error-entries-DLl0XqoW.js} +1 -1
- package/dist/{feedback-button-CvKssdG_.js → feedback-button-B0QSkbSp.js} +4 -4
- package/dist/flowDiagram-HODETNUW-DL52nMkt.js +16 -0
- package/dist/{formats-C8rLgZT9.js → formats-Cl_67ghI.js} +1 -1
- package/dist/{ganttDiagram-EL5Y4UJY-DbzEBLbl.js → ganttDiagram-EL5Y4UJY-cRRaDt88.js} +2 -2
- package/dist/{gitGraphDiagram-WWUBYQGX-BMf0iKi1.js → gitGraphDiagram-WWUBYQGX-Pox5k9-Y.js} +2 -2
- package/dist/{glide-data-editor-Ohetlgag.js → glide-data-editor-ymIQdwrb.js} +3 -3
- package/dist/{globals-CPNNcOJI.js → globals-B0S3-e_D.js} +1 -1
- package/dist/{html-to-image-BAgJOlSW.js → html-to-image-CGVgroef.js} +2 -2
- package/dist/{infoDiagram-27XIBGKW-BagtCX_5.js → infoDiagram-27XIBGKW-ntpxMfrq.js} +2 -2
- package/dist/{ishikawaDiagram-5VMMS53U-DByDehYy.js → ishikawaDiagram-5VMMS53U-BllIlHE5.js} +3 -3
- package/dist/{journeyDiagram-3NMN7TZE-D2LcKDUO.js → journeyDiagram-3NMN7TZE-EPJDPlt0.js} +2 -2
- package/dist/{kanban-definition-UXKFOSKX-BxwkbBI_.js → kanban-definition-UXKFOSKX-GYtNMjtS.js} +9 -9
- package/dist/{katex-C6D4cX_N.js → katex-BNCmKUol.js} +983 -1120
- package/dist/{loader-D2W4oM-3.js → loader-DEZSzvma.js} +253 -248
- package/dist/main.js +72 -69
- package/dist/{mermaid-DPNuhemn.js → mermaid-Dnzoxjt1.js} +49 -49
- package/dist/{mhchem-DWCF06w9.js → mhchem-BEc7A1or.js} +1 -1
- package/dist/{mindmap-definition-YA3MSWOX-Cgvojw3y.js → mindmap-definition-YA3MSWOX-Cth76xgH.js} +11 -11
- package/dist/{number-overlay-editor-CHWg5gGO.js → number-overlay-editor-DB3HJDI1.js} +1 -1
- package/dist/{pegDiagram-XKGWAZYB-DahHhYyN.js → pegDiagram-XKGWAZYB-Cu4uOXii.js} +3 -3
- package/dist/{pieDiagram-E7YTZNPT-CCtX0oCK.js → pieDiagram-E7YTZNPT-Bh3eDa9s.js} +3 -3
- package/dist/{process-output-zDX4jbhd.js → process-output-CGfg-JmZ.js} +2 -2
- package/dist/{quadrantDiagram-AXDQQJYC-DftINo6g.js → quadrantDiagram-AXDQQJYC--kqzFC3w.js} +1 -1
- package/dist/{railroadDiagram-O6MQD6OU-Du5NsPUb.js → railroadDiagram-O6MQD6OU-DG-M6Rnc.js} +3 -3
- package/dist/{react-vega-5AcMW8gG.js → react-vega-ewj7q_U5.js} +1 -1
- package/dist/{requirementDiagram-BXWQKSXE-0pmmxL6_.js → requirementDiagram-BXWQKSXE-DCwsThh0.js} +11 -11
- package/dist/{reveal-component-BujcZI2B.js → reveal-component-CfTzIkA2.js} +3 -3
- package/dist/{sankeyDiagram-P5KCCOFB-CDKR5TJH.js → sankeyDiagram-P5KCCOFB-BdzhT0BM.js} +1 -1
- package/dist/{sequenceDiagram-WJ2MYXX4-DB-ChWwU.js → sequenceDiagram-WJ2MYXX4-CbXB1_PU.js} +4 -4
- package/dist/{stateDiagram-D77RDMKH-orN6AwMx.js → stateDiagram-D77RDMKH-A-Zf3Sb2.js} +13 -13
- package/dist/stateDiagram-v2-MP3YSRHH-D9YMnUGx.js +30 -0
- package/dist/style.css +1 -1
- package/dist/{swimlanes-42K2YHIH-BkSDcqDT.js → swimlanes-42K2YHIH-B_pMf0J4.js} +10 -10
- package/dist/swimlanesDiagram-VR7AAH4N-Ctgy-yGP.js +30 -0
- package/dist/{timeline-definition-24CTP7MA-BuqJUIRZ.js → timeline-definition-24CTP7MA-DTXFjTTM.js} +3 -3
- package/dist/{vega-component-CNf5gcrm.js → vega-component-tFOzgarw.js} +4 -4
- package/dist/{vega-embed-container-CbnTccZi.js → vega-embed-container-sSR5hAsy.js} +2 -2
- package/dist/{vega-loader.browser-D95WfUcj.js → vega-loader.browser-DNST6uVf.js} +2 -2
- package/dist/{vennDiagram-4TSXK5OY-CTUlJ2PK.js → vennDiagram-4TSXK5OY-BPHjZo0R.js} +3 -3
- package/dist/{wardleyDiagram-VM6X3IG4-3evLUb0M.js → wardleyDiagram-VM6X3IG4-6fTLYBuD.js} +3 -3
- package/dist/{xychartDiagram-S5SC5T6Z-DL2E3K8-.js → xychartDiagram-S5SC5T6Z-BYjwjrzE.js} +5 -5
- package/package.json +1 -2
- package/src/__mocks__/common.ts +3 -3
- package/src/__tests__/CellStatus.test.tsx +1 -1
- package/src/__tests__/setup.ts +7 -7
- package/src/components/app-config/ai-config.tsx +2 -0
- package/src/components/app-config/optional-features.tsx +1 -1
- package/src/components/chat/chat-panel.tsx +19 -8
- package/src/components/data-table/charts/__tests__/chart-panel.test.tsx +286 -0
- package/src/components/data-table/charts/charts.tsx +26 -13
- package/src/components/data-table/column-summary/chart-spec-model.tsx +4 -4
- package/src/components/dependency-graph/elements.ts +2 -2
- package/src/components/editor/__tests__/package-alert.test.tsx +140 -0
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +107 -0
- package/src/components/editor/actions/pair-with-agent.tsx +119 -0
- package/src/components/editor/actions/useNotebookActions.tsx +2 -1
- package/src/components/editor/ai/add-cell-with-ai.tsx +2 -0
- package/src/components/editor/ai/staged-cell-submission.ts +2 -2
- package/src/components/editor/ai/transport/chat-transport.tsx +1 -1
- package/src/components/editor/chrome/components/contribute-snippet-button.tsx +6 -1
- package/src/components/editor/connections/database/as-code.ts +44 -44
- package/src/components/editor/connections/storage/as-code.ts +3 -3
- package/src/components/editor/file-tree/requesting-tree.tsx +16 -13
- package/src/components/editor/navigation/clipboard.ts +2 -2
- package/src/components/editor/notebook-cell.tsx +2 -2
- package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
- package/src/components/editor/output/VideoOutput.tsx +1 -1
- package/src/components/editor/output/ansi-reduce.ts +21 -17
- package/src/components/editor/output/console/ConsoleOutput.tsx +3 -3
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +59 -0
- package/src/components/editor/output/console/text-rendering.tsx +3 -1
- package/src/components/editor/package-alert.tsx +20 -7
- package/src/components/home/components.tsx +1 -0
- package/src/components/pages/run-page.tsx +1 -0
- package/src/components/slides/__tests__/minimap-actions.test.tsx +7 -7
- package/src/components/slides/__tests__/minimap.test.ts +12 -12
- package/src/components/slides/__tests__/slide-scroll-hint.test.tsx +8 -8
- package/src/components/static-html/share-modal.tsx +2 -1
- package/src/components/static-html/static-banner.tsx +2 -2
- package/src/components/ui/links.tsx +6 -1
- package/src/components/ui/typography.tsx +16 -8
- package/src/core/ai/context/__tests__/registry.test.ts +31 -28
- package/src/core/ai/context/providers/cell-output.ts +8 -8
- package/src/core/ai/context/providers/datasource.ts +10 -7
- package/src/core/ai/context/providers/error.ts +7 -7
- package/src/core/ai/context/providers/file.ts +8 -8
- package/src/core/ai/context/providers/tables.ts +7 -7
- package/src/core/ai/context/providers/variable.ts +7 -7
- package/src/core/ai/context/registry.ts +18 -18
- package/src/core/ai/ids/ids.ts +5 -5
- package/src/core/ai/model-registry.ts +12 -9
- package/src/core/ai/staged-cells.ts +6 -6
- package/src/core/ai/tools/base.ts +6 -6
- package/src/core/ai/tools/edit-notebook-tool.ts +6 -6
- package/src/core/ai/tools/registry.ts +4 -4
- package/src/core/ai/tools/run-cells-tool.ts +7 -7
- package/src/core/ai/tools/sample-tool.ts +6 -6
- package/src/core/cells/__tests__/cells.test.ts +27 -0
- package/src/core/cells/cells.ts +2 -1
- package/src/core/codemirror/cells/debugger-decorations.ts +13 -7
- package/src/core/codemirror/cells/line-timing-decorations.ts +9 -9
- package/src/core/codemirror/cells/traceback-decorations.ts +7 -4
- package/src/core/codemirror/code-lens/extension.ts +13 -13
- package/src/core/codemirror/copilot/__tests__/language-server.test.ts +6 -6
- package/src/core/codemirror/copilot/__tests__/transport.test.ts +12 -12
- package/src/core/codemirror/copilot/language-server.ts +13 -13
- package/src/core/codemirror/copilot/transport.ts +1 -1
- package/src/core/codemirror/find-replace/search-highlight.ts +5 -5
- package/src/core/codemirror/go-to-definition/underline.ts +3 -3
- package/src/core/codemirror/keymaps/vim.ts +3 -3
- package/src/core/codemirror/language/languages/markdown.ts +8 -8
- package/src/core/codemirror/language/languages/python.ts +7 -7
- package/src/core/codemirror/language/languages/sql/completion-builder.ts +5 -5
- package/src/core/codemirror/language/languages/sql/completion-store.ts +4 -4
- package/src/core/codemirror/language/languages/sql/sql.ts +21 -21
- package/src/core/codemirror/lsp/__tests__/transports.test.ts +10 -10
- package/src/core/codemirror/lsp/federated-lsp.ts +29 -27
- package/src/core/codemirror/lsp/notebook-lsp.ts +21 -21
- package/src/core/codemirror/misc/__tests__/dnd.test.ts +10 -10
- package/src/core/codemirror/misc/__tests__/paste.test.ts +7 -4
- package/src/core/codemirror/reactive-references/extension.ts +3 -3
- package/src/core/codemirror/rtc/loro/awareness.ts +12 -12
- package/src/core/codemirror/rtc/loro/sync.ts +5 -5
- package/src/core/codemirror/vim/cursor-visibility.ts +3 -3
- package/src/core/dom/ui-element.ts +5 -5
- package/src/core/dom/uiregistry.ts +10 -10
- package/src/core/hotkeys/hotkeys.ts +9 -9
- package/src/core/islands/__tests__/bridge.test.ts +4 -4
- package/src/core/islands/__tests__/test-utils.tsx +4 -4
- package/src/core/islands/bridge.ts +85 -82
- package/src/core/islands/components/web-components.tsx +7 -7
- package/src/core/islands/worker/__tests__/controller.test.ts +1 -1
- package/src/core/islands/worker/controller.ts +6 -3
- package/src/core/islands/worker-factory.ts +2 -2
- package/src/core/kernel/RuntimeState.ts +4 -4
- package/src/core/lsp/__tests__/transport.test.ts +19 -19
- package/src/core/lsp/transport.ts +5 -5
- package/src/core/network/CachingRequestRegistry.ts +2 -2
- package/src/core/network/DeferredRequestRegistry.ts +4 -4
- package/src/core/runtime/runtime.ts +25 -20
- package/src/core/static/virtual-file-tracker.ts +5 -5
- package/src/core/wasm/__tests__/bridge.test.ts +2 -2
- package/src/core/wasm/bridge.ts +130 -126
- package/src/core/wasm/router.ts +5 -5
- package/src/core/wasm/store.ts +4 -4
- package/src/core/wasm/worker/bootstrap.ts +8 -5
- package/src/core/wasm/worker/message-buffer.ts +3 -3
- package/src/core/websocket/transports/__tests__/ws.test.ts +8 -8
- package/src/core/websocket/transports/basic.ts +15 -8
- package/src/core/websocket/transports/sse.ts +7 -7
- package/src/core/websocket/transports/transport.ts +3 -3
- package/src/core/websocket/transports/ws.ts +9 -7
- package/src/css/globals.css +18 -21
- package/src/css/katex.min.css +260 -241
- package/src/hooks/__tests__/useOverflowDetection.test.tsx +5 -5
- package/src/hooks/__tests__/useResizeObserver.test.tsx +12 -12
- package/src/plugins/core/registerReactComponent.tsx +5 -5
- package/src/plugins/core/sidebar-element.tsx +2 -2
- package/src/plugins/impl/ButtonPlugin.tsx +3 -3
- package/src/plugins/impl/CheckboxPlugin.tsx +3 -3
- package/src/plugins/impl/CodeEditorPlugin.tsx +3 -3
- package/src/plugins/impl/DatePickerPlugin.tsx +3 -3
- package/src/plugins/impl/DateRangePlugin.tsx +3 -3
- package/src/plugins/impl/DateTimePickerPlugin.tsx +3 -3
- package/src/plugins/impl/DictPlugin.tsx +3 -3
- package/src/plugins/impl/DropdownPlugin.tsx +3 -3
- package/src/plugins/impl/FileUploadPlugin.tsx +3 -3
- package/src/plugins/impl/MatrixPlugin.tsx +4 -4
- package/src/plugins/impl/MicrophonePlugin.tsx +3 -3
- package/src/plugins/impl/MultiselectPlugin.tsx +3 -3
- package/src/plugins/impl/NumberPlugin.tsx +3 -3
- package/src/plugins/impl/RadioPlugin.tsx +9 -5
- package/src/plugins/impl/RangeSliderPlugin.tsx +3 -3
- package/src/plugins/impl/RefreshPlugin.tsx +3 -3
- package/src/plugins/impl/SliderPlugin.tsx +3 -3
- package/src/plugins/impl/SwitchPlugin.tsx +3 -3
- package/src/plugins/impl/TabsPlugin.tsx +3 -3
- package/src/plugins/impl/TextAreaPlugin.tsx +3 -3
- package/src/plugins/impl/TextInputPlugin.tsx +3 -3
- package/src/plugins/impl/__tests__/MatrixPlugin.test.tsx +2 -2
- package/src/plugins/impl/anywidget/model.ts +10 -10
- package/src/plugins/impl/anywidget/registry.ts +12 -9
- package/src/plugins/impl/anywidget/runtime.ts +11 -9
- package/src/plugins/impl/anywidget/widget-binding.ts +6 -6
- package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +7 -6
- package/src/plugins/impl/matplotlib/MatplotlibPlugin.tsx +3 -3
- package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +2 -2
- package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +2 -2
- package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +10 -10
- package/src/plugins/impl/panel/utils.ts +5 -5
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +3 -3
- package/src/plugins/impl/vega/VegaPlugin.tsx +3 -3
- package/src/plugins/impl/vega/__tests__/use-vega-container-remeasure.test.ts +7 -7
- package/src/plugins/impl/vega/__tests__/utils.test.ts +16 -1
- package/src/plugins/impl/vega/__tests__/vega.test.ts +37 -0
- package/src/plugins/impl/vega/loader.ts +23 -1
- package/src/plugins/impl/vega/utils.ts +5 -4
- package/src/plugins/layout/AccordionPlugin.tsx +3 -3
- package/src/plugins/layout/CalloutPlugin.tsx +3 -3
- package/src/plugins/layout/ImageComparisonPlugin.tsx +5 -3
- package/src/plugins/layout/JsonOutputPlugin.tsx +3 -3
- package/src/plugins/layout/MimeRenderPlugin.tsx +3 -3
- package/src/plugins/layout/NavigationMenuPlugin.tsx +3 -3
- package/src/plugins/layout/OutlinePlugin.tsx +3 -3
- package/src/plugins/layout/ProgressPlugin.tsx +3 -3
- package/src/plugins/layout/RoutesPlugin.tsx +6 -8
- package/src/plugins/layout/StatPlugin.tsx +3 -3
- package/src/plugins/layout/TexPlugin.tsx +3 -3
- package/src/plugins/layout/carousel/CarouselPlugin.tsx +4 -4
- package/src/plugins/layout/mermaid/MermaidPlugin.tsx +3 -3
- package/src/utils/Deferred.ts +6 -6
- package/src/utils/async-capture-tracker.ts +10 -7
- package/src/utils/errors.ts +5 -5
- package/src/utils/id-tree.tsx +83 -80
- package/src/utils/lru.ts +1 -1
- package/src/utils/multi-map.ts +14 -12
- package/src/utils/paths.ts +6 -6
- package/src/utils/pluralize.ts +3 -3
- package/src/utils/progress.ts +6 -6
- package/src/utils/python-poet/poet.ts +14 -14
- package/src/utils/routes.ts +4 -2
- package/src/utils/semaphore.ts +6 -6
- package/src/utils/storage/storage.ts +6 -6
- package/src/utils/storage/typed.ts +16 -12
- package/src/utils/time.ts +9 -9
- package/src/utils/timed-cache.ts +4 -4
- package/src/utils/tracer.ts +9 -6
- package/dist/classDiagram-ZZMXUADV-Fe-V14Sc.js +0 -30
- package/dist/classDiagram-v2-VYDZK3BY-xTDg7lOs.js +0 -30
- package/dist/flowDiagram-HODETNUW-6dMdB8pR.js +0 -16
- package/dist/katex-DFBiSucW.js +0 -21840
- package/dist/stateDiagram-v2-MP3YSRHH-o05_rJN8.js +0 -30
- package/dist/swimlanesDiagram-VR7AAH4N-D_nFQfRc.js +0 -30
|
@@ -64,11 +64,11 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
64
64
|
* (`widget_manager.get_model`). Assigned by the registry module at
|
|
65
65
|
* import time to avoid an import cycle.
|
|
66
66
|
*/
|
|
67
|
-
static _modelManager: {
|
|
67
|
+
public static _modelManager: {
|
|
68
68
|
getModel(model_id: WidgetModelId): Promise<Model<any>>;
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
constructor(data: T, comm: MarimoComm<T>, signal?: AbortSignal) {
|
|
71
|
+
public constructor(data: T, comm: MarimoComm<T>, signal?: AbortSignal) {
|
|
72
72
|
this.#data = data;
|
|
73
73
|
this.#comm = comm;
|
|
74
74
|
this.#dirtyFields = new Set();
|
|
@@ -84,7 +84,7 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
84
84
|
* Internal marimo API - not part of AnyWidget AFM.
|
|
85
85
|
* Access via getMarimoInternal().
|
|
86
86
|
*/
|
|
87
|
-
[marimoSymbol]: MarimoInternalApi<T> = {
|
|
87
|
+
public [marimoSymbol]: MarimoInternalApi<T> = {
|
|
88
88
|
updateAndEmitDiffs: (value: T) => this.#updateAndEmitDiffs(value),
|
|
89
89
|
emitCustomMessage: (
|
|
90
90
|
message: CustomMessage,
|
|
@@ -92,7 +92,7 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
92
92
|
) => this.#emitCustomMessage(message, buffers),
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
-
off(eventName?: string | null, callback?: EventHandler | null): void {
|
|
95
|
+
public off(eventName?: string | null, callback?: EventHandler | null): void {
|
|
96
96
|
if (!eventName) {
|
|
97
97
|
this.#listeners = {};
|
|
98
98
|
return;
|
|
@@ -106,7 +106,7 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
106
106
|
this.#listeners[eventName]?.delete(callback);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
send(
|
|
109
|
+
public send(
|
|
110
110
|
content: any,
|
|
111
111
|
callbacks?: any,
|
|
112
112
|
buffers?: ArrayBuffer[] | ArrayBufferView[],
|
|
@@ -121,7 +121,7 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
121
121
|
.then(() => callbacks?.());
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
widget_manager = {
|
|
124
|
+
public widget_manager = {
|
|
125
125
|
async get_model<TT extends ModelState>(
|
|
126
126
|
model_id: WidgetModelId,
|
|
127
127
|
): Promise<AnyModel<TT>> {
|
|
@@ -135,18 +135,18 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
135
135
|
},
|
|
136
136
|
};
|
|
137
137
|
|
|
138
|
-
get<K extends keyof T>(key: K): T[K] {
|
|
138
|
+
public get<K extends keyof T>(key: K): T[K] {
|
|
139
139
|
return this.#data[key];
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
set<K extends keyof T>(key: K, value: T[K]): void {
|
|
142
|
+
public set<K extends keyof T>(key: K, value: T[K]): void {
|
|
143
143
|
this.#data = { ...this.#data, [key]: value };
|
|
144
144
|
this.#dirtyFields.add(key);
|
|
145
145
|
this.#emit(`change:${key as K & string}`, value);
|
|
146
146
|
this.#emitAnyChange();
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
save_changes(): void {
|
|
149
|
+
public save_changes(): void {
|
|
150
150
|
if (this.#dirtyFields.size === 0) {
|
|
151
151
|
return;
|
|
152
152
|
}
|
|
@@ -169,7 +169,7 @@ export class Model<T extends ModelState> implements AnyModel<T> {
|
|
|
169
169
|
* `addEventListener({ signal })`) and is what `modelProxy` uses to
|
|
170
170
|
* scope listeners to view / binding lifetimes.
|
|
171
171
|
*/
|
|
172
|
-
on(
|
|
172
|
+
public on(
|
|
173
173
|
eventName: string,
|
|
174
174
|
callback: EventHandler,
|
|
175
175
|
options?: { signal?: AbortSignal },
|
|
@@ -41,7 +41,10 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
41
41
|
#timeout: number;
|
|
42
42
|
#isEditMode: () => boolean;
|
|
43
43
|
|
|
44
|
-
constructor(
|
|
44
|
+
public constructor(
|
|
45
|
+
timeout = 10_000,
|
|
46
|
+
isEditMode: () => boolean = defaultIsEditMode,
|
|
47
|
+
) {
|
|
45
48
|
this.#timeout = timeout;
|
|
46
49
|
this.#isEditMode = isEditMode;
|
|
47
50
|
}
|
|
@@ -71,7 +74,7 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
71
74
|
* hasn't arrived yet. Rejects after the registry timeout so a ref to
|
|
72
75
|
* a model that never opens fails loudly instead of hanging.
|
|
73
76
|
*/
|
|
74
|
-
getModel(key: WidgetModelId): Promise<Model<ModelState>> {
|
|
77
|
+
public getModel(key: WidgetModelId): Promise<Model<ModelState>> {
|
|
75
78
|
return this.#getOrCreateRuntime(key).getModel();
|
|
76
79
|
}
|
|
77
80
|
|
|
@@ -79,7 +82,7 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
79
82
|
* Get a model synchronously if it exists and has been resolved.
|
|
80
83
|
* Returns undefined if the model doesn't exist or is still pending.
|
|
81
84
|
*/
|
|
82
|
-
getModelSync(key: WidgetModelId): Model<ModelState> | undefined {
|
|
85
|
+
public getModelSync(key: WidgetModelId): Model<ModelState> | undefined {
|
|
83
86
|
return this.#runtimes.get(key)?.getModelSync();
|
|
84
87
|
}
|
|
85
88
|
|
|
@@ -87,14 +90,14 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
87
90
|
* Create a model with a managed lifecycle signal.
|
|
88
91
|
* The signal is aborted when the entry is deleted.
|
|
89
92
|
*/
|
|
90
|
-
createModel(
|
|
93
|
+
public createModel(
|
|
91
94
|
key: WidgetModelId,
|
|
92
95
|
factory: (signal: AbortSignal) => Model<ModelState>,
|
|
93
96
|
): void {
|
|
94
97
|
this.#getOrCreateRuntime(key).createModel(factory);
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
setModel(key: WidgetModelId, model: Model<ModelState>): void {
|
|
100
|
+
public setModel(key: WidgetModelId, model: Model<ModelState>): void {
|
|
98
101
|
this.#getOrCreateRuntime(key).setModel(model);
|
|
99
102
|
}
|
|
100
103
|
|
|
@@ -105,15 +108,15 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
105
108
|
* Specs only come from kernel-authored notifications; model state
|
|
106
109
|
* must never be treated as code (it is client-writable).
|
|
107
110
|
*/
|
|
108
|
-
setSpec(key: WidgetModelId, spec: EsmSpec): void {
|
|
111
|
+
public setSpec(key: WidgetModelId, spec: EsmSpec): void {
|
|
109
112
|
this.#getOrCreateRuntime(key).setSpec(spec);
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
getWidget<T = unknown>(key: WidgetModelId) {
|
|
115
|
+
public getWidget<T = unknown>(key: WidgetModelId) {
|
|
113
116
|
return this.#getOrCreateRuntime(key).getWidget<T>();
|
|
114
117
|
}
|
|
115
118
|
|
|
116
|
-
createView(options: {
|
|
119
|
+
public createView(options: {
|
|
117
120
|
modelId: WidgetModelId;
|
|
118
121
|
el: HTMLElement;
|
|
119
122
|
signal: AbortSignal;
|
|
@@ -125,7 +128,7 @@ export class WidgetRegistry implements WidgetResolver {
|
|
|
125
128
|
* Tear down everything known about `key`: the model's lifecycle
|
|
126
129
|
* signal and the current generation.
|
|
127
130
|
*/
|
|
128
|
-
delete(key: WidgetModelId): void {
|
|
131
|
+
public delete(key: WidgetModelId): void {
|
|
129
132
|
const runtime = this.#runtimes.get(key);
|
|
130
133
|
if (!runtime) {
|
|
131
134
|
return;
|
|
@@ -60,7 +60,7 @@ export class WidgetRuntime {
|
|
|
60
60
|
#generationCleanup = Promise.resolve();
|
|
61
61
|
#css = "";
|
|
62
62
|
|
|
63
|
-
constructor(key: WidgetModelId, options: WidgetRuntimeOptions) {
|
|
63
|
+
public constructor(key: WidgetModelId, options: WidgetRuntimeOptions) {
|
|
64
64
|
this.#key = key;
|
|
65
65
|
this.#timeout = options.timeout;
|
|
66
66
|
this.#isEditMode = options.isEditMode;
|
|
@@ -68,7 +68,7 @@ export class WidgetRuntime {
|
|
|
68
68
|
this.#onModelTimeout = options.onModelTimeout;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
getModel(): Promise<Model<ModelState>> {
|
|
71
|
+
public getModel(): Promise<Model<ModelState>> {
|
|
72
72
|
if (this.#model.status === "pending" && !this.#modelTimeout) {
|
|
73
73
|
this.#modelTimeout = setTimeout(() => {
|
|
74
74
|
if (this.#model.status === "pending") {
|
|
@@ -83,18 +83,20 @@ export class WidgetRuntime {
|
|
|
83
83
|
return this.#model.promise;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
getModelSync(): Model<ModelState> | undefined {
|
|
86
|
+
public getModelSync(): Model<ModelState> | undefined {
|
|
87
87
|
return this.#model.status === "resolved" ? this.#model.value : undefined;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
createModel(
|
|
90
|
+
public createModel(
|
|
91
|
+
factory: (signal: AbortSignal) => Model<ModelState>,
|
|
92
|
+
): void {
|
|
91
93
|
if (this.#model.status !== "pending") {
|
|
92
94
|
return;
|
|
93
95
|
}
|
|
94
96
|
this.#resolveModel(factory(this.#controller.signal));
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
setModel(model: Model<ModelState>): void {
|
|
99
|
+
public setModel(model: Model<ModelState>): void {
|
|
98
100
|
if (this.#model.status !== "pending") {
|
|
99
101
|
return;
|
|
100
102
|
}
|
|
@@ -121,7 +123,7 @@ export class WidgetRuntime {
|
|
|
121
123
|
);
|
|
122
124
|
}
|
|
123
125
|
|
|
124
|
-
setSpec(spec: EsmSpec): void {
|
|
126
|
+
public setSpec(spec: EsmSpec): void {
|
|
125
127
|
if (!this.#esmSpec) {
|
|
126
128
|
this.#esmSpec = spec;
|
|
127
129
|
return;
|
|
@@ -138,7 +140,7 @@ export class WidgetRuntime {
|
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
async getWidget<T = unknown>(): Promise<ResolvedWidget<T>> {
|
|
143
|
+
public async getWidget<T = unknown>(): Promise<ResolvedWidget<T>> {
|
|
142
144
|
const binding = await this.#getCurrentBinding();
|
|
143
145
|
return {
|
|
144
146
|
exports: binding.exports as T,
|
|
@@ -151,7 +153,7 @@ export class WidgetRuntime {
|
|
|
151
153
|
};
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
async createView(options: {
|
|
156
|
+
public async createView(options: {
|
|
155
157
|
el: HTMLElement;
|
|
156
158
|
signal: AbortSignal;
|
|
157
159
|
}): Promise<void> {
|
|
@@ -341,7 +343,7 @@ export class WidgetRuntime {
|
|
|
341
343
|
view.signal.addEventListener("abort", release, { once: true });
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
dispose(): void {
|
|
346
|
+
public dispose(): void {
|
|
345
347
|
if (this.#controller.signal.aborted) {
|
|
346
348
|
return;
|
|
347
349
|
}
|
|
@@ -59,7 +59,7 @@ class WidgetDefRegistry {
|
|
|
59
59
|
* `kernelAuthored: true` only for URLs from an `EsmSpec`; it widens
|
|
60
60
|
* the import gate to remote and data URLs.
|
|
61
61
|
*/
|
|
62
|
-
getModule(options: {
|
|
62
|
+
public getModule(options: {
|
|
63
63
|
jsUrl: string;
|
|
64
64
|
jsHash: string;
|
|
65
65
|
kernelAuthored?: boolean;
|
|
@@ -80,7 +80,7 @@ class WidgetDefRegistry {
|
|
|
80
80
|
return promise;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
invalidate(jsHash: string): void {
|
|
83
|
+
public invalidate(jsHash: string): void {
|
|
84
84
|
this.#cache.delete(jsHash);
|
|
85
85
|
}
|
|
86
86
|
|
|
@@ -180,7 +180,7 @@ export class WidgetBinding<T extends ModelState = ModelState> {
|
|
|
180
180
|
* `controller`'s signal. Aborting the controller mid-initialize
|
|
181
181
|
* still runs any legacy cleanup callback, and `create` rejects.
|
|
182
182
|
*/
|
|
183
|
-
static async create<T extends ModelState>({
|
|
183
|
+
public static async create<T extends ModelState>({
|
|
184
184
|
widgetDef,
|
|
185
185
|
model,
|
|
186
186
|
createHost,
|
|
@@ -261,7 +261,7 @@ export class WidgetBinding<T extends ModelState = ModelState> {
|
|
|
261
261
|
* The object returned from `initialize`, or `undefined` if it
|
|
262
262
|
* returned a cleanup function or nothing.
|
|
263
263
|
*/
|
|
264
|
-
get exports(): unknown {
|
|
264
|
+
public get exports(): unknown {
|
|
265
265
|
return this.#exports;
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -273,7 +273,7 @@ export class WidgetBinding<T extends ModelState = ModelState> {
|
|
|
273
273
|
* `render` reads current state via `model.get`; change listeners
|
|
274
274
|
* observe only subsequent changes, matching Jupyter semantics.
|
|
275
275
|
*/
|
|
276
|
-
async createView(
|
|
276
|
+
public async createView(
|
|
277
277
|
target: { el: HTMLElement },
|
|
278
278
|
options: { signal: AbortSignal },
|
|
279
279
|
): Promise<void> {
|
|
@@ -346,7 +346,7 @@ export class WidgetBinding<T extends ModelState = ModelState> {
|
|
|
346
346
|
* Destroy this generation, running initialize/render cleanups and
|
|
347
347
|
* clearing listeners registered through its model proxies.
|
|
348
348
|
*/
|
|
349
|
-
async destroy(): Promise<void> {
|
|
349
|
+
public async destroy(): Promise<void> {
|
|
350
350
|
Logger.debug("[WidgetBinding] Destroying binding generation");
|
|
351
351
|
this.#controller.abort();
|
|
352
352
|
await Promise.allSettled(this.#viewTasks);
|
|
@@ -19,7 +19,7 @@ function truncateSrc(src: string): string {
|
|
|
19
19
|
return src.length > MAX_LENGTH ? `${src.slice(0, MAX_LENGTH)}…` : src;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const ImageComparisonContent: React.FC<ImageComparisonData> = ({
|
|
23
23
|
beforeSrc,
|
|
24
24
|
afterSrc,
|
|
25
25
|
value,
|
|
@@ -31,12 +31,8 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
|
|
|
31
31
|
() => new Set(),
|
|
32
32
|
);
|
|
33
33
|
|
|
34
|
-
React.useEffect(() => {
|
|
35
|
-
setFailedSrcs(new Set());
|
|
36
|
-
}, [beforeSrc, afterSrc]);
|
|
37
|
-
|
|
38
34
|
const handleError = React.useCallback((src: string) => {
|
|
39
|
-
setFailedSrcs((
|
|
35
|
+
setFailedSrcs((previous) => new Set(previous).add(src));
|
|
40
36
|
}, []);
|
|
41
37
|
|
|
42
38
|
const containerStyle: React.CSSProperties = {
|
|
@@ -106,4 +102,9 @@ const ImageComparisonComponent: React.FC<ImageComparisonData> = ({
|
|
|
106
102
|
);
|
|
107
103
|
};
|
|
108
104
|
|
|
105
|
+
const ImageComparisonComponent: React.FC<ImageComparisonData> = (props) => {
|
|
106
|
+
const sourceKey = JSON.stringify([props.beforeSrc, props.afterSrc]);
|
|
107
|
+
return <ImageComparisonContent key={sourceKey} {...props} />;
|
|
108
|
+
};
|
|
109
|
+
|
|
109
110
|
export default ImageComparisonComponent;
|
|
@@ -11,9 +11,9 @@ import {
|
|
|
11
11
|
} from "./matplotlib-renderer";
|
|
12
12
|
|
|
13
13
|
export class MatplotlibPlugin implements IPlugin<T, Data> {
|
|
14
|
-
tagName = "marimo-matplotlib";
|
|
14
|
+
public tagName = "marimo-matplotlib";
|
|
15
15
|
|
|
16
|
-
validator = z.object({
|
|
16
|
+
public validator = z.object({
|
|
17
17
|
chartBase64: z.string(),
|
|
18
18
|
xBounds: z.tuple([z.number(), z.number()]),
|
|
19
19
|
yBounds: z.tuple([z.number(), z.number()]),
|
|
@@ -28,7 +28,7 @@ export class MatplotlibPlugin implements IPlugin<T, Data> {
|
|
|
28
28
|
yScale: z.enum(["linear", "log"]).default("linear"),
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
-
render(props: IPluginProps<T, Data>): JSX.Element {
|
|
31
|
+
public render(props: IPluginProps<T, Data>): JSX.Element {
|
|
32
32
|
return (
|
|
33
33
|
<MatplotlibComponent
|
|
34
34
|
{...props.data}
|
|
@@ -228,8 +228,8 @@ function stubSyncImage() {
|
|
|
228
228
|
vi.stubGlobal(
|
|
229
229
|
"Image",
|
|
230
230
|
class {
|
|
231
|
-
onload: (() => void) | null = null;
|
|
232
|
-
set src(_value: string) {
|
|
231
|
+
public onload: (() => void) | null = null;
|
|
232
|
+
public set src(_value: string) {
|
|
233
233
|
this.onload?.();
|
|
234
234
|
}
|
|
235
235
|
},
|
|
@@ -284,7 +284,7 @@ export class MatplotlibRenderer {
|
|
|
284
284
|
/** The devicePixelRatio the canvas buffer was last sized with. */
|
|
285
285
|
#backingDpr = 1;
|
|
286
286
|
|
|
287
|
-
constructor(
|
|
287
|
+
public constructor(
|
|
288
288
|
container: HTMLDivElement,
|
|
289
289
|
options: { state: MatplotlibState; signal: AbortSignal },
|
|
290
290
|
) {
|
|
@@ -396,7 +396,7 @@ export class MatplotlibRenderer {
|
|
|
396
396
|
mq.addEventListener("change", onChange, { once: true, signal });
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
-
update(state: MatplotlibState): void {
|
|
399
|
+
public update(state: MatplotlibState): void {
|
|
400
400
|
const prev = this.#state;
|
|
401
401
|
this.#state = state;
|
|
402
402
|
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
* - onopen / onmessage / onclose callbacks
|
|
11
11
|
*/
|
|
12
12
|
export class MplCommWebSocket {
|
|
13
|
-
readyState: number = WebSocket.OPEN;
|
|
13
|
+
public readyState: number = WebSocket.OPEN;
|
|
14
14
|
private sendFn: (msg: unknown) => void;
|
|
15
15
|
|
|
16
|
-
onopen: (() => void) | null = null;
|
|
17
|
-
onmessage: ((evt: MessageEvent) => void) | null = null;
|
|
18
|
-
onclose: (() => void) | null = null;
|
|
16
|
+
public onopen: (() => void) | null = null;
|
|
17
|
+
public onmessage: ((evt: MessageEvent) => void) | null = null;
|
|
18
|
+
public onclose: (() => void) | null = null;
|
|
19
19
|
|
|
20
|
-
constructor(sendFn: (msg: unknown) => void) {
|
|
20
|
+
public constructor(sendFn: (msg: unknown) => void) {
|
|
21
21
|
this.sendFn = sendFn;
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -27,7 +27,7 @@ export class MplCommWebSocket {
|
|
|
27
27
|
* socket instance stays bound to mpl.js (which wires `onopen`/`onmessage`
|
|
28
28
|
* onto it at construction); only the comm behind it changes.
|
|
29
29
|
*/
|
|
30
|
-
setSendHandler(sendFn: (msg: unknown) => void): void {
|
|
30
|
+
public setSendHandler(sendFn: (msg: unknown) => void): void {
|
|
31
31
|
this.sendFn = sendFn;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -35,14 +35,14 @@ export class MplCommWebSocket {
|
|
|
35
35
|
* Called by mpl.js to send a message to the backend.
|
|
36
36
|
* mpl.js always sends JSON strings.
|
|
37
37
|
*/
|
|
38
|
-
send(data: string): void {
|
|
38
|
+
public send(data: string): void {
|
|
39
39
|
this.sendFn(JSON.parse(data));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Called when the backend pushes a JSON message via the model custom event.
|
|
44
44
|
*/
|
|
45
|
-
receiveJson(data: unknown): void {
|
|
45
|
+
public receiveJson(data: unknown): void {
|
|
46
46
|
this.onmessage?.(
|
|
47
47
|
new MessageEvent("message", { data: JSON.stringify(data) }),
|
|
48
48
|
);
|
|
@@ -51,7 +51,7 @@ export class MplCommWebSocket {
|
|
|
51
51
|
/**
|
|
52
52
|
* Called when the backend pushes binary data (PNG render) via model custom event.
|
|
53
53
|
*/
|
|
54
|
-
receiveBinary(buffer: DataView): void {
|
|
54
|
+
public receiveBinary(buffer: DataView): void {
|
|
55
55
|
const ab = buffer.buffer.slice(
|
|
56
56
|
buffer.byteOffset,
|
|
57
57
|
buffer.byteOffset + buffer.byteLength,
|
|
@@ -60,7 +60,7 @@ export class MplCommWebSocket {
|
|
|
60
60
|
this.onmessage?.(new MessageEvent("message", { data: blob }));
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
close(): void {
|
|
63
|
+
public close(): void {
|
|
64
64
|
this.readyState = WebSocket.CLOSED;
|
|
65
65
|
this.onclose?.();
|
|
66
66
|
}
|
|
@@ -60,12 +60,12 @@ export class EventBuffer<T> {
|
|
|
60
60
|
private processEvents: () => void;
|
|
61
61
|
private blockDuration: number;
|
|
62
62
|
|
|
63
|
-
constructor(processEvents: () => void, blockDuration = 200) {
|
|
63
|
+
public constructor(processEvents: () => void, blockDuration = 200) {
|
|
64
64
|
this.processEvents = processEvents;
|
|
65
65
|
this.blockDuration = blockDuration;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
add(event: T) {
|
|
68
|
+
public add(event: T) {
|
|
69
69
|
this.buffer.push(event);
|
|
70
70
|
this.flush();
|
|
71
71
|
}
|
|
@@ -90,15 +90,15 @@ export class EventBuffer<T> {
|
|
|
90
90
|
}, this.blockDuration);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
size() {
|
|
93
|
+
public size() {
|
|
94
94
|
return this.buffer.length;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
clear() {
|
|
97
|
+
public clear() {
|
|
98
98
|
this.buffer = [];
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
getAndClear() {
|
|
101
|
+
public getAndClear() {
|
|
102
102
|
const events = this.buffer;
|
|
103
103
|
this.buffer = [];
|
|
104
104
|
return events;
|
|
@@ -55,9 +55,9 @@ type T =
|
|
|
55
55
|
| undefined;
|
|
56
56
|
|
|
57
57
|
export class PlotlyPlugin implements IPlugin<T, Data> {
|
|
58
|
-
tagName = "marimo-plotly";
|
|
58
|
+
public tagName = "marimo-plotly";
|
|
59
59
|
|
|
60
|
-
validator = z.object({
|
|
60
|
+
public validator = z.object({
|
|
61
61
|
figure: z
|
|
62
62
|
.object({})
|
|
63
63
|
.passthrough()
|
|
@@ -65,7 +65,7 @@ export class PlotlyPlugin implements IPlugin<T, Data> {
|
|
|
65
65
|
config: z.object({}).passthrough(),
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
render(props: IPluginProps<T, Data>): JSX.Element {
|
|
68
|
+
public render(props: IPluginProps<T, Data>): JSX.Element {
|
|
69
69
|
return (
|
|
70
70
|
<PlotlyComponent
|
|
71
71
|
{...props.data}
|
|
@@ -12,9 +12,9 @@ import React, { type JSX } from "react";
|
|
|
12
12
|
const LazyVegaComponent = React.lazy(() => import("./vega-component"));
|
|
13
13
|
|
|
14
14
|
export class VegaPlugin implements IPlugin<VegaComponentState, Data> {
|
|
15
|
-
tagName = "marimo-vega";
|
|
15
|
+
public tagName = "marimo-vega";
|
|
16
16
|
|
|
17
|
-
validator = z.object({
|
|
17
|
+
public validator = z.object({
|
|
18
18
|
spec: z
|
|
19
19
|
.object({})
|
|
20
20
|
.passthrough()
|
|
@@ -26,7 +26,7 @@ export class VegaPlugin implements IPlugin<VegaComponentState, Data> {
|
|
|
26
26
|
embedOptions: z.object({}).passthrough().default({}),
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
render(props: IPluginProps<VegaComponentState, Data>): JSX.Element {
|
|
29
|
+
public render(props: IPluginProps<VegaComponentState, Data>): JSX.Element {
|
|
30
30
|
return (
|
|
31
31
|
<LazyVegaComponent
|
|
32
32
|
value={props.value}
|
|
@@ -10,27 +10,27 @@ describe("useVegaContainerRemeasure", () => {
|
|
|
10
10
|
let OriginalResizeObserver: typeof ResizeObserver;
|
|
11
11
|
|
|
12
12
|
class FakeResizeObserver {
|
|
13
|
-
callback: ResizeObserverCallback;
|
|
14
|
-
el: Element | null = null;
|
|
13
|
+
public callback: ResizeObserverCallback;
|
|
14
|
+
public el: Element | null = null;
|
|
15
15
|
|
|
16
|
-
constructor(callback: ResizeObserverCallback) {
|
|
16
|
+
public constructor(callback: ResizeObserverCallback) {
|
|
17
17
|
this.callback = callback;
|
|
18
18
|
observers.push(this);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
observe(el: Element) {
|
|
21
|
+
public observe(el: Element) {
|
|
22
22
|
this.el = el;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
disconnect() {
|
|
25
|
+
public disconnect() {
|
|
26
26
|
this.el = null;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
unobserve() {
|
|
29
|
+
public unobserve() {
|
|
30
30
|
this.el = null;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
trigger(width: number) {
|
|
33
|
+
public trigger(width: number) {
|
|
34
34
|
this.callback(
|
|
35
35
|
[
|
|
36
36
|
{
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { describe, expect, it } from "vitest";
|
|
4
|
-
import { getContainerWidth } from "../utils";
|
|
4
|
+
import { getContainerWidth, getVegaFieldTypes } from "../utils";
|
|
5
|
+
|
|
6
|
+
describe("getVegaFieldTypes", () => {
|
|
7
|
+
it("preserves date strings unless the caller requests date parsing", () => {
|
|
8
|
+
expect(getVegaFieldTypes({ day: "date", timestamp: "datetime" })).toEqual({
|
|
9
|
+
day: "string",
|
|
10
|
+
timestamp: "date",
|
|
11
|
+
});
|
|
12
|
+
expect(
|
|
13
|
+
getVegaFieldTypes(
|
|
14
|
+
{ day: "date", timestamp: "datetime" },
|
|
15
|
+
{ parseDates: true },
|
|
16
|
+
),
|
|
17
|
+
).toEqual({ day: "date", timestamp: "date" });
|
|
18
|
+
});
|
|
19
|
+
});
|
|
5
20
|
|
|
6
21
|
describe("getContainerWidth", () => {
|
|
7
22
|
it('should return "container" when spec width is "container"', () => {
|
|
@@ -13,6 +13,43 @@ const { ZERO_WIDTH_SPACE, replacePeriodsInColumnNames, uniquifyColumnNames } =
|
|
|
13
13
|
exportedForTesting;
|
|
14
14
|
|
|
15
15
|
describe("vega loader", () => {
|
|
16
|
+
it("parses infinities only in explicitly numeric CSV fields", async () => {
|
|
17
|
+
vi.spyOn(vegaLoader, "load").mockResolvedValue(
|
|
18
|
+
"value,label,id\ninf,inf,1\n-inf,-inf,2\n+inf,+inf,3\n2.5,002.5,4\n,,5\nNaN,NaN,6\n",
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const data = await vegaLoadData("chart.csv", {
|
|
22
|
+
type: "csv",
|
|
23
|
+
parse: { value: "number", label: "string", id: "integer" },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(data).toEqual([
|
|
27
|
+
{ value: Infinity, label: "inf", id: 1 },
|
|
28
|
+
{ value: -Infinity, label: "-inf", id: 2 },
|
|
29
|
+
{ value: Infinity, label: "+inf", id: 3 },
|
|
30
|
+
{ value: 2.5, label: "002.5", id: 4 },
|
|
31
|
+
{ value: null, label: null, id: 5 },
|
|
32
|
+
{ value: Number.NaN, label: "NaN", id: 6 },
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("preserves the table's large integer and infinity handling", async () => {
|
|
37
|
+
vi.spyOn(vegaLoader, "load").mockResolvedValue(
|
|
38
|
+
"id,value\n9007199254740993,inf\n9007199254740995,-inf\n",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const data = await vegaLoadData(
|
|
42
|
+
"table.csv",
|
|
43
|
+
{ type: "csv", parse: { id: "integer", value: "number" } },
|
|
44
|
+
{ handleBigIntAndNumberLike: true },
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
expect(data).toEqual([
|
|
48
|
+
{ id: BigInt("9007199254740993"), value: "inf" },
|
|
49
|
+
{ id: BigInt("9007199254740995"), value: "-inf" },
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
|
|
16
53
|
it("should parse csv data with dates", async () => {
|
|
17
54
|
const csvData = `
|
|
18
55
|
active,username,id
|
|
@@ -16,6 +16,26 @@ const previousNumberParser = typeParsers.number;
|
|
|
16
16
|
const previousDateParser = typeParsers.date;
|
|
17
17
|
const previousBooleanParser = typeParsers.boolean;
|
|
18
18
|
|
|
19
|
+
const NUMBER_MIDDLEWARE: Middleware = () => {
|
|
20
|
+
const parseNumber = (value: string) => {
|
|
21
|
+
if (value === "inf" || value === "+inf") {
|
|
22
|
+
return Number.POSITIVE_INFINITY;
|
|
23
|
+
}
|
|
24
|
+
if (value === "-inf") {
|
|
25
|
+
return Number.NEGATIVE_INFINITY;
|
|
26
|
+
}
|
|
27
|
+
return previousNumberParser(value);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
typeParsers.integer = parseNumber;
|
|
31
|
+
typeParsers.number = parseNumber;
|
|
32
|
+
|
|
33
|
+
return () => {
|
|
34
|
+
typeParsers.integer = previousIntegerParser;
|
|
35
|
+
typeParsers.number = previousNumberParser;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
|
|
19
39
|
const BIG_INT_MIDDLEWARE: Middleware = () => {
|
|
20
40
|
// Custom parser to:
|
|
21
41
|
// - handle BigInt
|
|
@@ -159,6 +179,8 @@ export async function vegaLoadData<T = object>(
|
|
|
159
179
|
const middleware: Middleware[] = [DATE_MIDDLEWARE];
|
|
160
180
|
if (handleBigIntAndNumberLike) {
|
|
161
181
|
middleware.push(BIG_INT_MIDDLEWARE);
|
|
182
|
+
} else {
|
|
183
|
+
middleware.push(NUMBER_MIDDLEWARE);
|
|
162
184
|
}
|
|
163
185
|
|
|
164
186
|
let unsubscribes: Unsubscribe[] = [];
|
|
@@ -216,7 +238,7 @@ export async function vegaLoadData<T = object>(
|
|
|
216
238
|
|
|
217
239
|
// Apply middleware
|
|
218
240
|
unsubscribes = middleware.map((m) => m());
|
|
219
|
-
//
|
|
241
|
+
// CSV defaults to inference when no explicit column types are available.
|
|
220
242
|
const results = isCsv
|
|
221
243
|
? // csv -> json
|
|
222
244
|
read(csvOrJsonData, {
|