@marimo-team/frontend 0.15.4 → 0.16.0-dev96986

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/dist/assets/ConnectedDataExplorerComponent-CNLoZkWr.js +19 -0
  2. package/dist/assets/{ImageComparisonComponent-CEXMKKA4.js → ImageComparisonComponent-SX7fDaTK.js} +1 -1
  3. package/dist/assets/{VegaLite-Bt14Ds9k.js → VegaLite-MJUW3b7C.js} +6 -6
  4. package/dist/assets/_baseEach-9_logFrf.js +1 -0
  5. package/dist/assets/_baseMap-NzEbKt5c.js +1 -0
  6. package/dist/assets/_baseUniq-C5LFcyNC.js +1 -0
  7. package/dist/assets/_createAggregator-ZRm2b6Zm.js +1 -0
  8. package/dist/assets/agent-panel-BBd11wNX.js +287 -0
  9. package/dist/assets/agent-panel-D92Mfy1i.css +1 -0
  10. package/dist/assets/{any-language-editor-DiwNT6zp.js → any-language-editor-DwAaEQfS.js} +1 -1
  11. package/dist/assets/architectureDiagram-W76B3OCA-BJmVXUoW.js +36 -0
  12. package/dist/assets/{between-horizontal-start-FyewyCGn.js → between-horizontal-start-KiwU-a3C.js} +1 -1
  13. package/dist/assets/{blockDiagram-QIGZ2CNN-BrOkAf_c.js → blockDiagram-QIGZ2CNN-DzxZjE7B.js} +1 -1
  14. package/dist/assets/{c4Diagram-FPNF74CW-BHPzDxE2.js → c4Diagram-FPNF74CW-DjmldG_J.js} +5 -5
  15. package/dist/assets/channel-DHcKBVM4.js +1 -0
  16. package/dist/assets/chat-panel-DgJZr0eS.js +3 -0
  17. package/dist/assets/{chunk-4BX2VUAB-DLxaCNYh.js → chunk-4BX2VUAB-EUTQThiZ.js} +1 -1
  18. package/dist/assets/{chunk-55IACEB6-DdzvO3HR.js → chunk-55IACEB6-DZAiDJxy.js} +1 -1
  19. package/dist/assets/{chunk-FMBD7UC4-R5o-nSiG.js → chunk-FMBD7UC4-Bd0Czs-J.js} +1 -1
  20. package/dist/assets/{chunk-K7UQS3LO-DxaMrGgG.js → chunk-K7UQS3LO-DEKMIknX.js} +1 -1
  21. package/dist/assets/{chunk-QN33PNHL-DqS9-FYm.js → chunk-QN33PNHL-E0jwHU_n.js} +1 -1
  22. package/dist/assets/{chunk-QZHKN3VN-BZ-TzajS.js → chunk-QZHKN3VN-BzaIHJbq.js} +1 -1
  23. package/dist/assets/{chunk-TVAH2DTR-BsgP2dyv.js → chunk-TVAH2DTR-CZFYvqnm.js} +1 -1
  24. package/dist/assets/{chunk-TZMSLE5B-D-h3ahXI.js → chunk-TZMSLE5B-BNqnFjtv.js} +1 -1
  25. package/dist/assets/{circle-play-CQtRZ-rT.js → circle-play-D3J_mYrF.js} +1 -1
  26. package/dist/assets/classDiagram-KNZD7YFC-D-xwLnlX.js +1 -0
  27. package/dist/assets/classDiagram-v2-RKCZMP56-D-xwLnlX.js +1 -0
  28. package/dist/assets/{clear-button-BY6Z_ViL.js → clear-button-ifzRuAR3.js} +1 -1
  29. package/dist/assets/clone-CSxIll62.js +1 -0
  30. package/dist/assets/command-palette-D2fdVSET.js +1 -0
  31. package/dist/assets/common-Ku-cF_2J.js +1 -0
  32. package/dist/assets/{compile-Ct_jzdKr.js → compile-BgZlHW1c.js} +1 -1
  33. package/dist/assets/cose-bilkent-S5V4N54A-CVM83SqK.js +1 -0
  34. package/dist/assets/dagre-5GWH7T2D-ouQPkxT3.js +4 -0
  35. package/dist/assets/{data-grid-overlay-editor-BN_wulc3.js → data-grid-overlay-editor-B47j5GJJ.js} +1 -1
  36. package/dist/assets/datasources-panel-Bt41Zir-.js +1 -0
  37. package/dist/assets/{dependency-graph-panel-BOmSCZf7.js → dependency-graph-panel-CZC_B7pK.js} +4 -4
  38. package/dist/assets/diagram-N5W7TBWH-CQ817ZdR.js +24 -0
  39. package/dist/assets/diagram-QEK2KX5R-DOK_psUO.js +43 -0
  40. package/dist/assets/diagram-S2PKOQOG-CVljmOW8.js +24 -0
  41. package/dist/assets/{documentation-panel-BxjJO_Gw.js → documentation-panel-C7yIvGg1.js} +1 -1
  42. package/dist/assets/edit-page-CyTMQV2u.js +129 -0
  43. package/dist/assets/{ellipsis-vertical-UHbmjI2n.js → ellipsis-vertical-C7FjlUsY.js} +1 -1
  44. package/dist/assets/{empty-state-BIBXzY_0.js → empty-state-DIOGM_CU.js} +1 -1
  45. package/dist/assets/{erDiagram-AWTI2OKA-E84mAle_.js → erDiagram-AWTI2OKA-DYu8cEdc.js} +1 -1
  46. package/dist/assets/{error-panel-MEvQ6K7h.js → error-panel-Ddb8RkFG.js} +1 -1
  47. package/dist/assets/file-explorer-panel-Oy9DbyFP.js +1 -0
  48. package/dist/assets/{flowDiagram-PVAE7QVJ-DfbIRSAW.js → flowDiagram-PVAE7QVJ-CmvW5iTb.js} +1 -1
  49. package/dist/assets/{ganttDiagram-OWAHRB6G-DR4HZ1z_.js → ganttDiagram-OWAHRB6G-BaKQlCaT.js} +4 -4
  50. package/dist/assets/gitGraphDiagram-NY62KEGX-CWO24eP6.js +65 -0
  51. package/dist/assets/{glide-data-editor-nNmo1lPq.js → glide-data-editor-CNDLEJ9a.js} +11 -11
  52. package/dist/assets/graph-BZKTtxsc.js +1 -0
  53. package/dist/assets/home-page-Bvwppn9N.js +9 -0
  54. package/dist/assets/{index-VPWqq2Pg.js → index-0XOUPdwT.js} +1 -1
  55. package/dist/assets/{index-uacyUula.js → index-BH7f3aiU.js} +1 -1
  56. package/dist/assets/{index-Dt9UWeWn.js → index-BJVyzkx5.js} +1 -1
  57. package/dist/assets/{index-BAH034Ue.js → index-B_d_JZGI.js} +1 -1
  58. package/dist/assets/{index-CB2pnVQG.js → index-BgXbBA39.js} +1 -1
  59. package/dist/assets/{index-B8llrTSo.js → index-Brf2DwUM.js} +1 -1
  60. package/dist/assets/{index-BLu5CX6z.js → index-CXrWwFX6.js} +1 -1
  61. package/dist/assets/{index-DyLSuOH1.js → index-CZaurnA9.js} +1 -1
  62. package/dist/assets/{index-BFSnz7iM.js → index-CerjupfZ.js} +1 -1
  63. package/dist/assets/{index-B7yXbrLa.js → index-D-tZfElD.js} +1 -1
  64. package/dist/assets/{index-c6If577Q.js → index-D3PqGupX.js} +1 -1
  65. package/dist/assets/{index-CSgxTUzD.js → index-DCkzth56.js} +1 -1
  66. package/dist/assets/{index-DWOaniGT.js → index-DFrGFNW1.js} +1 -1
  67. package/dist/assets/{index-CPN7TRA1.js → index-DZhOPkOB.js} +1 -1
  68. package/dist/assets/index-DadI618h.css +1 -0
  69. package/dist/assets/{index-DqzMPAC8.js → index-DkntzpX4.js} +2 -2
  70. package/dist/assets/{index-B1_GXGaP.js → index-DmgwT3sx.js} +1 -1
  71. package/dist/assets/index-PmY0x4Zd.js +578 -0
  72. package/dist/assets/{index-Bq516OmX.js → index-WXJFkQHg.js} +1 -1
  73. package/dist/assets/{index-DSU75csX.js → index-qE8lHQ-N.js} +1 -1
  74. package/dist/assets/{index-DMomwMcN.js → index-zrSUQXha.js} +1 -1
  75. package/dist/assets/infoDiagram-STP46IZ2-CAuVVehw.js +2 -0
  76. package/dist/assets/isEmpty-D1t7Gran.js +1 -0
  77. package/dist/assets/{journeyDiagram-BIP6EPQ6-BBiFyygf.js → journeyDiagram-BIP6EPQ6-D4Rp6H_h.js} +1 -1
  78. package/dist/assets/{kanban-definition-6OIFK2YF-DhgA6Nt6.js → kanban-definition-6OIFK2YF-DFt9DftA.js} +4 -4
  79. package/dist/assets/layout-D8WXi2_g.js +1 -0
  80. package/dist/assets/linear-BwY8e5hA.js +1 -0
  81. package/dist/assets/links-4B6ldZ5P.js +7 -0
  82. package/dist/assets/{logs-panel-B9SmTZAW.js → logs-panel-Dxiyt7dO.js} +1 -1
  83. package/dist/assets/{agent-panel-DpQ6muj-.css → markdown-renderer-ClyzDMmG.css} +1 -1
  84. package/dist/assets/markdown-renderer-VDu-NBKB.js +263 -0
  85. package/dist/assets/mermaid-B-O-Puyi.js +1 -0
  86. package/dist/assets/{mermaid.core-4nVOEVX3.js → mermaid.core-BFFCqfOn.js} +41 -41
  87. package/dist/assets/min-DtVSfYKl.js +1 -0
  88. package/dist/assets/{mindmap-definition-Q6HEUPPD-CVLQNn1q.js → mindmap-definition-Q6HEUPPD-kyvIY8Dg.js} +2 -2
  89. package/dist/assets/{number-overlay-editor-CzRzXLcd.js → number-overlay-editor-GjLB2UK4.js} +1 -1
  90. package/dist/assets/outline-panel-CMJjOoN7.js +1 -0
  91. package/dist/assets/packages-panel-nfXB-bKW.js +1 -0
  92. package/dist/assets/{pieDiagram-ADFJNKIX-C5IQ5DBZ.js → pieDiagram-ADFJNKIX-D8JFQcWR.js} +3 -3
  93. package/dist/assets/{quadrantDiagram-LMRXKWRM-CFXFnQxx.js → quadrantDiagram-LMRXKWRM-Nf8GzxXG.js} +1 -1
  94. package/dist/assets/{react-plotly-mzdv02_Y.js → react-plotly-CnW9p7ZA.js} +1 -1
  95. package/dist/assets/{requirementDiagram-4UW4RH46-D9bPC89T.js → requirementDiagram-4UW4RH46-CCUxF8BZ.js} +1 -1
  96. package/dist/assets/run-page-Bl4p3AbZ.js +1 -0
  97. package/dist/assets/sankeyDiagram-GR3RE2ED-Sr8kDwP1.js +10 -0
  98. package/dist/assets/scratchpad-panel-Ja1Mu-W3.js +1 -0
  99. package/dist/assets/secrets-panel-B-3fcSyP.js +1 -0
  100. package/dist/assets/{sequenceDiagram-C3RYC4MD-6N7_hY4k.js → sequenceDiagram-C3RYC4MD-CBJ152Q3.js} +4 -4
  101. package/dist/assets/{slides-component-DMjQomc3.css → slides-component-C-LoGC1U.css} +1 -1
  102. package/dist/assets/{slides-component-EcjC8sDK.js → slides-component-DGtsVP5o.js} +1 -1
  103. package/dist/assets/snippets-panel-ClNnwKBM.js +1 -0
  104. package/dist/assets/sortBy-D47H6Vyl.js +1 -0
  105. package/dist/assets/state-B_RCHTH5.js +1 -0
  106. package/dist/assets/stateDiagram-KXAO66HF-BlBFSAZr.js +1 -0
  107. package/dist/assets/stateDiagram-v2-UMBNRL4Z-DbA-iToo.js +1 -0
  108. package/dist/assets/storage-BNcWOH3-.js +26 -0
  109. package/dist/assets/terminal-CATzv5Hd.js +10 -0
  110. package/dist/assets/time-CsYqILfB.js +1 -0
  111. package/dist/assets/{timeline-definition-XQNQX7LJ-BEaynAiY.js → timeline-definition-XQNQX7LJ-CGrhjuAs.js} +1 -1
  112. package/dist/assets/tracing-DUbJtOyq.js +2 -0
  113. package/dist/assets/{tracing-panel-BmuHLPrY.js → tracing-panel-DmzqPUtc.js} +2 -2
  114. package/dist/assets/{trash-UBqfK4mR.js → trash-rxdjLzkf.js} +1 -1
  115. package/dist/assets/{tree-XiEycetl.js → tree-C2Ul1h1C.js} +1 -1
  116. package/dist/assets/{treemap-75Q7IDZK-CnuVFbBG.js → treemap-75Q7IDZK-N9hyUpyj.js} +20 -20
  117. package/dist/assets/{ts-tags-CloPe9IY.js → ts-tags-DxCDHihD.js} +1 -1
  118. package/dist/assets/variable-panel-BbgupOdG.js +1 -0
  119. package/dist/assets/{vega-component-DsTH4tuX.js → vega-component-CR_MHOBT.js} +1 -1
  120. package/dist/assets/worker-fHbtoWvT.js +1 -0
  121. package/dist/assets/{xychartDiagram-6GGTOJPD-Dcz3O-A3.js → xychartDiagram-6GGTOJPD-jdLZsMb2.js} +1 -1
  122. package/dist/index.html +2 -2
  123. package/package.json +10 -5
  124. package/src/__tests__/mocks.ts +43 -0
  125. package/src/components/app-config/user-config-form.tsx +78 -1
  126. package/src/components/chat/acp/__tests__/__snapshots__/prompt.test.ts.snap +116 -65
  127. package/src/components/chat/acp/__tests__/atoms.test.ts +1 -1
  128. package/src/components/chat/acp/__tests__/context-utils.test.ts +222 -0
  129. package/src/components/chat/acp/__tests__/prompt.test.ts +1 -1
  130. package/src/components/chat/acp/__tests__/state.test.ts +38 -42
  131. package/src/components/chat/acp/agent-docs.tsx +33 -6
  132. package/src/components/chat/acp/agent-panel.css +0 -18
  133. package/src/components/chat/acp/agent-panel.tsx +394 -72
  134. package/src/components/chat/acp/agent-selector.tsx +7 -1
  135. package/src/components/chat/acp/blocks.tsx +40 -10
  136. package/src/components/chat/acp/common.tsx +10 -2
  137. package/src/components/chat/acp/context-utils.ts +127 -0
  138. package/src/components/chat/acp/prompt.ts +96 -53
  139. package/src/components/chat/acp/state.ts +1 -1
  140. package/src/components/chat/acp/types.ts +8 -0
  141. package/src/components/chat/chat-panel.tsx +28 -89
  142. package/src/components/chat/chat-utils.ts +127 -1
  143. package/src/components/chat/markdown-renderer.css +39 -0
  144. package/src/components/chat/markdown-renderer.tsx +12 -47
  145. package/src/components/chat/tool-call-accordion.tsx +148 -26
  146. package/src/components/data-table/SearchBar.tsx +8 -7
  147. package/src/components/data-table/__tests__/column_formatting.test.ts +50 -35
  148. package/src/components/data-table/__tests__/data-table.test.tsx +39 -1
  149. package/src/components/data-table/cell-hover-template/feature.ts +14 -0
  150. package/src/components/data-table/cell-hover-template/types.ts +11 -0
  151. package/src/components/data-table/charts/components/form-fields.tsx +41 -37
  152. package/src/components/data-table/charts/forms/common-chart.tsx +2 -2
  153. package/src/components/data-table/column-explorer-panel/column-explorer.tsx +5 -2
  154. package/src/components/data-table/column-formatting/feature.ts +62 -29
  155. package/src/components/data-table/column-formatting/types.ts +1 -0
  156. package/src/components/data-table/column-header.tsx +3 -1
  157. package/src/components/data-table/column-summary/chart-spec-model.tsx +24 -7
  158. package/src/components/data-table/column-summary/column-summary.tsx +18 -9
  159. package/src/components/data-table/columns.tsx +42 -18
  160. package/src/components/data-table/data-table.tsx +10 -2
  161. package/src/components/data-table/date-popover.tsx +85 -75
  162. package/src/components/data-table/filter-pills.tsx +14 -9
  163. package/src/components/data-table/header-items.tsx +5 -1
  164. package/src/components/data-table/pagination.tsx +20 -13
  165. package/src/components/data-table/renderers.tsx +28 -0
  166. package/src/components/data-table/row-viewer-panel/row-viewer.tsx +10 -8
  167. package/src/components/datasources/column-preview.tsx +6 -2
  168. package/src/components/datasources/datasources.tsx +8 -12
  169. package/src/components/editor/Cell.tsx +6 -0
  170. package/src/components/editor/actions/name-cell-input.tsx +6 -1
  171. package/src/components/editor/actions/useCellActionButton.tsx +3 -1
  172. package/src/components/editor/ai/__tests__/completion-utils.test.ts +178 -1
  173. package/src/components/editor/ai/add-cell-with-ai.tsx +68 -66
  174. package/src/components/editor/ai/ai-completion-editor.tsx +29 -26
  175. package/src/components/editor/ai/completion-handlers.tsx +44 -6
  176. package/src/components/editor/ai/completion-utils.ts +92 -0
  177. package/src/components/editor/ai/transport/chat-transport.tsx +39 -0
  178. package/src/components/editor/cell/CellStatus.tsx +23 -20
  179. package/src/components/editor/cell/CreateCellButton.tsx +3 -4
  180. package/src/components/editor/cell/StagedAICell.tsx +51 -0
  181. package/src/components/editor/cell/cell-actions.tsx +2 -1
  182. package/src/components/editor/cell/code/language-toggle.tsx +3 -4
  183. package/src/components/editor/chrome/wrapper/footer-items/machine-stats.tsx +39 -28
  184. package/src/components/editor/controls/notebook-menu-dropdown.tsx +4 -2
  185. package/src/components/editor/file-tree/requesting-tree.tsx +14 -8
  186. package/src/components/editor/renderers/CellArray.tsx +3 -4
  187. package/src/components/editor/renderers/slides-layout/slides-layout.tsx +3 -3
  188. package/src/components/editor/renderers/slides-layout/types.ts +1 -0
  189. package/src/components/pages/home-page.tsx +4 -1
  190. package/src/components/slides/slides-component.tsx +1 -1
  191. package/src/components/slides/slides.css +6 -0
  192. package/src/components/terminal/__tests__/state.test.ts +207 -0
  193. package/src/components/terminal/hooks.ts +41 -0
  194. package/src/components/terminal/state.ts +75 -0
  195. package/src/components/terminal/terminal.tsx +334 -13
  196. package/src/components/terminal/theme.tsx +57 -0
  197. package/src/components/tracing/tracing-spec.ts +5 -4
  198. package/src/components/ui/range-slider.tsx +4 -2
  199. package/src/components/ui/slider.tsx +3 -1
  200. package/src/components/variables/variables-table.tsx +3 -0
  201. package/src/core/MarimoApp.tsx +9 -6
  202. package/src/core/ai/__tests__/staged-cells.test.ts +356 -0
  203. package/src/core/ai/context/__tests__/registry.test.ts +6 -4
  204. package/src/core/ai/context/providers/cell-output.ts +3 -2
  205. package/src/core/ai/context/providers/error.ts +3 -1
  206. package/src/core/ai/context/providers/file.ts +7 -2
  207. package/src/core/ai/context/providers/tables.ts +3 -2
  208. package/src/core/ai/context/providers/variable.ts +6 -4
  209. package/src/core/ai/staged-cells.ts +208 -0
  210. package/src/core/cells/cells.ts +1 -1
  211. package/src/core/cells/logs.ts +1 -1
  212. package/src/core/codemirror/find-replace/search-highlight.ts +3 -1
  213. package/src/core/codemirror/language/LanguageAdapters.ts +9 -3
  214. package/src/core/codemirror/lsp/federated-lsp.ts +1 -1
  215. package/src/core/codemirror/lsp/notebook-lsp.ts +8 -2
  216. package/src/core/codemirror/readonly/__tests__/extension.test.ts +1 -1
  217. package/src/core/codemirror/rtc/loro/awareness.ts +52 -17
  218. package/src/core/codemirror/rtc/loro/sync.ts +12 -4
  219. package/src/core/config/config-schema.ts +1 -0
  220. package/src/core/config/config.ts +4 -0
  221. package/src/core/hotkeys/hotkeys.ts +8 -4
  222. package/src/core/i18n/__tests__/locale-provider.test.tsx +176 -0
  223. package/src/core/i18n/locale-provider.tsx +35 -0
  224. package/src/core/i18n/with-locale.tsx +12 -0
  225. package/src/core/islands/components/web-components.tsx +13 -10
  226. package/src/core/islands/main.ts +2 -2
  227. package/src/core/kernel/RuntimeState.ts +4 -1
  228. package/src/core/kernel/messages.ts +8 -12
  229. package/src/core/network/DeferredRequestRegistry.ts +16 -4
  230. package/src/core/runtime/runtime.ts +5 -4
  231. package/src/core/saving/__tests__/filename.test.ts +37 -0
  232. package/src/core/static/__tests__/download-html.test.ts +43 -1
  233. package/src/core/wasm/bridge.ts +5 -1
  234. package/src/core/wasm/store.ts +4 -1
  235. package/src/core/wasm/worker/message-buffer.ts +3 -2
  236. package/src/core/websocket/types.ts +22 -16
  237. package/src/core/websocket/useMarimoWebSocket.tsx +2 -2
  238. package/src/css/app/Cell.css +11 -0
  239. package/src/hooks/useFormatting.ts +97 -0
  240. package/src/hooks/useTimer.ts +8 -5
  241. package/src/plugins/core/RenderHTML.tsx +36 -2
  242. package/src/plugins/core/__test__/RenderHTML.test.ts +72 -0
  243. package/src/plugins/core/registerReactComponent.tsx +44 -10
  244. package/src/plugins/impl/DataTablePlugin.tsx +4 -0
  245. package/src/plugins/impl/FileBrowserPlugin.tsx +8 -2
  246. package/src/plugins/impl/RangeSliderPlugin.tsx +5 -3
  247. package/src/plugins/impl/SliderPlugin.tsx +3 -1
  248. package/src/plugins/impl/anywidget/model.ts +16 -5
  249. package/src/plugins/impl/data-editor/types.ts +7 -5
  250. package/src/plugins/impl/data-explorer/components/column-summary.tsx +20 -13
  251. package/src/plugins/impl/panel/utils.ts +6 -4
  252. package/src/plugins/layout/OutlinePlugin.tsx +69 -0
  253. package/src/plugins/layout/StatPlugin.tsx +4 -1
  254. package/src/plugins/plugins.ts +2 -0
  255. package/src/stories/cell.stories.tsx +1 -1
  256. package/src/stories/layout/vertical/one-column.stories.tsx +1 -1
  257. package/src/utils/__tests__/cell-urls.test.ts +29 -0
  258. package/src/utils/__tests__/dates.test.ts +45 -24
  259. package/src/utils/__tests__/filenames.test.ts +18 -0
  260. package/src/utils/__tests__/numbers.test.ts +42 -30
  261. package/src/utils/__tests__/once.test.ts +187 -0
  262. package/src/utils/__tests__/path.test.ts +38 -0
  263. package/src/utils/__tests__/urls.test.ts +56 -1
  264. package/src/utils/dates.ts +15 -10
  265. package/src/utils/edit-distance.ts +8 -6
  266. package/src/utils/errors.ts +9 -0
  267. package/src/utils/id-tree.tsx +21 -10
  268. package/src/utils/localStorage.ts +13 -4
  269. package/src/utils/numbers.ts +11 -11
  270. package/src/utils/once.ts +32 -0
  271. package/src/utils/paths.ts +4 -1
  272. package/src/utils/pluralize.ts +12 -5
  273. package/src/utils/python-poet/poet.ts +30 -15
  274. package/src/utils/time.ts +5 -1
  275. package/dist/assets/ConnectedDataExplorerComponent-Cn5-l2X1.js +0 -19
  276. package/dist/assets/_baseEach-C1FLm7WW.js +0 -1
  277. package/dist/assets/_baseMap-DBVArUYD.js +0 -1
  278. package/dist/assets/_baseUniq-Dk7ZPJ3N.js +0 -1
  279. package/dist/assets/_createAggregator-Bn38fDd3.js +0 -1
  280. package/dist/assets/agent-panel-COUYnuIK.js +0 -475
  281. package/dist/assets/architectureDiagram-W76B3OCA-DBzWQKKu.js +0 -36
  282. package/dist/assets/channel-CjhbjOv4.js +0 -1
  283. package/dist/assets/chat-panel-BPXKoTnZ.js +0 -7
  284. package/dist/assets/chat-panel-Brrs_eeH.css +0 -1
  285. package/dist/assets/classDiagram-KNZD7YFC-DHs5cFzy.js +0 -1
  286. package/dist/assets/classDiagram-v2-RKCZMP56-DHs5cFzy.js +0 -1
  287. package/dist/assets/clone-DM1YNjEn.js +0 -1
  288. package/dist/assets/command-palette-S0bzQp7v.js +0 -1
  289. package/dist/assets/common-B8U9k2Ly.js +0 -1
  290. package/dist/assets/cose-bilkent-S5V4N54A-wz1Sfx7j.js +0 -1
  291. package/dist/assets/dagre-5GWH7T2D-BfpcVBgq.js +0 -4
  292. package/dist/assets/datasources-panel-DfuURLJw.js +0 -1
  293. package/dist/assets/diagram-N5W7TBWH-Bf0oqqQh.js +0 -24
  294. package/dist/assets/diagram-QEK2KX5R-ZTc3qikh.js +0 -43
  295. package/dist/assets/diagram-S2PKOQOG-tLScBy7Z.js +0 -24
  296. package/dist/assets/edit-page-DJ8kJZ9w.js +0 -129
  297. package/dist/assets/file-explorer-panel-CzNUJ63G.js +0 -1
  298. package/dist/assets/gitGraphDiagram-NY62KEGX-C1t6QtVa.js +0 -65
  299. package/dist/assets/graph-CssCVWIq.js +0 -1
  300. package/dist/assets/home-page-9eW6qida.js +0 -9
  301. package/dist/assets/index-CknhX2Vy.css +0 -1
  302. package/dist/assets/index-DcCIe7np.js +0 -28
  303. package/dist/assets/index-OC46250R.js +0 -570
  304. package/dist/assets/infoDiagram-STP46IZ2-CwiAoz9f.js +0 -2
  305. package/dist/assets/layout-DpQrxGW-.js +0 -1
  306. package/dist/assets/linear-NsreOeBF.js +0 -1
  307. package/dist/assets/links-CbvGxbsJ.js +0 -7
  308. package/dist/assets/mermaid-DSt0r6IQ.js +0 -1
  309. package/dist/assets/min-D259kI3t.js +0 -1
  310. package/dist/assets/outline-panel-uvsS-YEQ.js +0 -1
  311. package/dist/assets/packages-panel-xMz9W2hW.js +0 -1
  312. package/dist/assets/run-page-Bb68qdhQ.js +0 -1
  313. package/dist/assets/sankeyDiagram-GR3RE2ED-BSJOau8E.js +0 -10
  314. package/dist/assets/scratchpad-panel-BF4BO-U4.js +0 -1
  315. package/dist/assets/secrets-panel-CdIX44dQ.js +0 -1
  316. package/dist/assets/snippets-panel-Dco9h0rb.js +0 -1
  317. package/dist/assets/sortBy-aLGA-PGK.js +0 -1
  318. package/dist/assets/stateDiagram-KXAO66HF-Bd68WT3b.js +0 -1
  319. package/dist/assets/stateDiagram-v2-UMBNRL4Z-BXz_GSwb.js +0 -1
  320. package/dist/assets/storage-CGlP4lCF.js +0 -26
  321. package/dist/assets/terminal-CxkHubcu.js +0 -9
  322. package/dist/assets/time-D2nr1UgQ.js +0 -1
  323. package/dist/assets/tracing-kTqHxa7q.js +0 -2
  324. package/dist/assets/variable-panel-noTnH-AQ.js +0 -1
  325. package/dist/assets/worker-X5rxzQGQ.js +0 -1
@@ -1,20 +1,26 @@
1
1
  /* Copyright 2024 Marimo. All rights reserved. */
2
2
 
3
+ import { once } from "@/utils/once";
3
4
  import { MarkdownLanguageAdapter } from "./languages/markdown";
4
5
  import { PythonLanguageAdapter } from "./languages/python";
5
6
  import { SQLLanguageAdapter } from "./languages/sql/sql";
6
7
  import type { LanguageAdapter, LanguageAdapterType } from "./types";
7
8
 
9
+ // Create cached instances
10
+ const createPythonAdapter = once(() => new PythonLanguageAdapter());
11
+ const createMarkdownAdapter = once(() => new MarkdownLanguageAdapter());
12
+ const createSqlAdapter = once(() => new SQLLanguageAdapter());
13
+
8
14
  export const LanguageAdapters: Record<LanguageAdapterType, LanguageAdapter> = {
9
15
  // Getters to prevent circular dependencies
10
16
  get python() {
11
- return new PythonLanguageAdapter();
17
+ return createPythonAdapter();
12
18
  },
13
19
  get markdown() {
14
- return new MarkdownLanguageAdapter();
20
+ return createMarkdownAdapter();
15
21
  },
16
22
  get sql() {
17
- return new SQLLanguageAdapter();
23
+ return createSqlAdapter();
18
24
  },
19
25
  };
20
26
 
@@ -4,7 +4,7 @@ import type { LanguageServerPlugin } from "@marimo-team/codemirror-languageserve
4
4
  import type * as LSP from "vscode-languageserver-protocol";
5
5
  import { Objects } from "@/utils/objects";
6
6
  import type { ILanguageServerClient } from "./types";
7
- import { getLSPDocument } from "./utils.ts";
7
+ import { getLSPDocument } from "./utils";
8
8
 
9
9
  function removeFalseyValues<T extends object>(obj: T): T {
10
10
  return Objects.filter(obj, (value) => value !== false && value !== null) as T;
@@ -18,13 +18,19 @@ import { getLSPDocument } from "./utils";
18
18
 
19
19
  class Snapshotter {
20
20
  private documentVersion = 0;
21
+ private readonly getNotebookCode: () => {
22
+ cellIds: CellId[];
23
+ codes: Record<CellId, string>;
24
+ };
21
25
 
22
26
  constructor(
23
- private readonly getNotebookCode: () => {
27
+ getNotebookCode: () => {
24
28
  cellIds: CellId[];
25
29
  codes: Record<CellId, string>;
26
30
  },
27
- ) {}
31
+ ) {
32
+ this.getNotebookCode = getNotebookCode;
33
+ }
28
34
 
29
35
  /**
30
36
  * Map from the global document version to the cell id and version.
@@ -9,7 +9,7 @@ import { connectionAtom } from "../../../network/connection";
9
9
  import { dynamicReadonly, isEditorReadonly } from "../extension";
10
10
 
11
11
  function makeStoreWithConnection(
12
- state: WebSocketState.CONNECTING | WebSocketState.OPEN,
12
+ state: typeof WebSocketState.CONNECTING | typeof WebSocketState.OPEN,
13
13
  ) {
14
14
  const store = createStore();
15
15
  store.set(connectionAtom, { state });
@@ -202,13 +202,25 @@ export const createSelectionLayer = (): Extension =>
202
202
  * Renders a blinking cursor to indicate the cursor of another user.
203
203
  */
204
204
  export class RemoteCursorMarker implements LayerMarker {
205
+ private left: number;
206
+ private top: number;
207
+ private height: number;
208
+ private name: string;
209
+ private colorClassName: string;
210
+
205
211
  constructor(
206
- private left: number,
207
- private top: number,
208
- private height: number,
209
- private name: string,
210
- private colorClassName: string,
211
- ) {}
212
+ left: number,
213
+ top: number,
214
+ height: number,
215
+ name: string,
216
+ colorClassName: string,
217
+ ) {
218
+ this.left = left;
219
+ this.top = top;
220
+ this.height = height;
221
+ this.name = name;
222
+ this.colorClassName = colorClassName;
223
+ }
212
224
 
213
225
  draw(): HTMLElement {
214
226
  const elt = document.createElement("div");
@@ -353,16 +365,30 @@ export interface CursorPosition {
353
365
 
354
366
  export class AwarenessPlugin implements PluginValue {
355
367
  sub: Subscription;
368
+ public view: EditorView;
369
+ public doc: LoroDoc;
370
+ public user: UserState;
371
+ public awareness: Awareness<AwarenessState>;
372
+ private getTextFromDoc: (doc: LoroDoc) => LoroText;
373
+ private scopeId: ScopeId;
374
+ private getUserId?: () => Uid;
356
375
 
357
376
  constructor(
358
- public view: EditorView,
359
- public doc: LoroDoc,
360
- public user: UserState,
361
- public awareness: Awareness<AwarenessState>,
362
- private getTextFromDoc: (doc: LoroDoc) => LoroText,
363
- private scopeId: ScopeId,
364
- private getUserId?: () => Uid,
377
+ view: EditorView,
378
+ doc: LoroDoc,
379
+ user: UserState,
380
+ awareness: Awareness<AwarenessState>,
381
+ getTextFromDoc: (doc: LoroDoc) => LoroText,
382
+ scopeId: ScopeId,
383
+ getUserId?: () => Uid,
365
384
  ) {
385
+ this.view = view;
386
+ this.doc = doc;
387
+ this.user = user;
388
+ this.awareness = awareness;
389
+ this.getTextFromDoc = getTextFromDoc;
390
+ this.scopeId = scopeId;
391
+ this.getUserId = getUserId;
366
392
  this.sub = this.doc.subscribe((e) => {
367
393
  if (e.by === "local") {
368
394
  // update remote cursor position
@@ -435,12 +461,21 @@ export class AwarenessPlugin implements PluginValue {
435
461
  }
436
462
  export class RemoteAwarenessPlugin implements PluginValue {
437
463
  _awarenessListener?: AwarenessListener;
464
+ public view: EditorView;
465
+ public doc: LoroDoc;
466
+ public awareness: Awareness<AwarenessState>;
467
+ private scopeId: ScopeId;
468
+
438
469
  constructor(
439
- public view: EditorView,
440
- public doc: LoroDoc,
441
- public awareness: Awareness<AwarenessState>,
442
- private scopeId: ScopeId,
470
+ view: EditorView,
471
+ doc: LoroDoc,
472
+ awareness: Awareness<AwarenessState>,
473
+ scopeId: ScopeId,
443
474
  ) {
475
+ this.view = view;
476
+ this.doc = doc;
477
+ this.awareness = awareness;
478
+ this.scopeId = scopeId;
444
479
  const listener: AwarenessListener = async (arg, origin) => {
445
480
  if (origin === "local") {
446
481
  return;
@@ -40,13 +40,21 @@ export const loroSyncAnnotation = Annotation.define();
40
40
  export class LoroSyncPluginValue implements PluginValue {
41
41
  sub?: Subscription;
42
42
  private isInitDispatch = false;
43
+ private view: EditorView;
44
+ private doc: LoroDoc;
45
+ private docPath: string[];
46
+ private getTextFromDoc: (doc: LoroDoc) => LoroText;
43
47
 
44
48
  constructor(
45
- private view: EditorView,
46
- private doc: LoroDoc,
47
- private docPath: string[],
48
- private getTextFromDoc: (doc: LoroDoc) => LoroText,
49
+ view: EditorView,
50
+ doc: LoroDoc,
51
+ docPath: string[],
52
+ getTextFromDoc: (doc: LoroDoc) => LoroText,
49
53
  ) {
54
+ this.view = view;
55
+ this.doc = doc;
56
+ this.docPath = docPath;
57
+ this.getTextFromDoc = getTextFromDoc;
50
58
  this.sub = doc.subscribe(this.onRemoteUpdate);
51
59
  Promise.resolve().then(() => {
52
60
  this.isInitDispatch = true;
@@ -144,6 +144,7 @@ export const UserConfigSchema = z
144
144
  }
145
145
  return width;
146
146
  }),
147
+ locale: z.string().nullable().optional(),
147
148
  reference_highlighting: z.boolean().default(false),
148
149
  })
149
150
  .passthrough()
@@ -82,6 +82,10 @@ export const editorFontSizeAtom = atom<number>((get) => {
82
82
  return get(resolvedMarimoConfigAtom).display.code_editor_font_size;
83
83
  });
84
84
 
85
+ export const localeAtom = atom<string | null | undefined>((get) => {
86
+ return get(resolvedMarimoConfigAtom).display.locale;
87
+ });
88
+
85
89
  export function isAiEnabled(config: UserConfig) {
86
90
  return (
87
91
  Boolean(config.ai?.models?.chat_model) ||
@@ -452,10 +452,13 @@ export class HotkeyProvider implements IHotkeyProvider {
452
452
  return new HotkeyProvider(DEFAULT_HOT_KEY, { platform });
453
453
  }
454
454
 
455
+ private hotkeys: Record<HotkeyAction, Hotkey>;
456
+
455
457
  constructor(
456
- private hotkeys: Record<HotkeyAction, Hotkey>,
458
+ hotkeys: Record<HotkeyAction, Hotkey>,
457
459
  options: HotkeyProviderOptions = {},
458
460
  ) {
461
+ this.hotkeys = hotkeys;
459
462
  this.platform = options.platform ?? resolvePlatform();
460
463
  this.mod = this.platform === "mac" ? "Cmd" : "Ctrl";
461
464
  }
@@ -503,13 +506,14 @@ export class HotkeyProvider implements IHotkeyProvider {
503
506
  }
504
507
 
505
508
  export class OverridingHotkeyProvider extends HotkeyProvider {
509
+ private readonly overrides: Partial<Record<HotkeyAction, string | undefined>>;
510
+
506
511
  constructor(
507
- private readonly overrides: Partial<
508
- Record<HotkeyAction, string | undefined>
509
- >,
512
+ overrides: Partial<Record<HotkeyAction, string | undefined>>,
510
513
  options: HotkeyProviderOptions = {},
511
514
  ) {
512
515
  super(DEFAULT_HOT_KEY, options);
516
+ this.overrides = overrides;
513
517
  }
514
518
 
515
519
  override getHotkey(action: HotkeyAction): ResolvedHotkey {
@@ -0,0 +1,176 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { cleanup, render } from "@testing-library/react";
4
+ import { createStore, Provider } from "jotai";
5
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { userConfigAtom } from "@/core/config/config";
7
+ import { parseUserConfig } from "@/core/config/config-schema";
8
+ import { LocaleProvider } from "../locale-provider";
9
+
10
+ // Mock navigator.language with a getter
11
+ let mockNavigatorLanguage: string | undefined;
12
+
13
+ Object.defineProperty(window, "navigator", {
14
+ value: {
15
+ get language() {
16
+ return mockNavigatorLanguage;
17
+ },
18
+ },
19
+ writable: true,
20
+ });
21
+
22
+ // Mock react-aria-components I18nProvider
23
+ vi.mock("react-aria-components", () => ({
24
+ I18nProvider: ({
25
+ children,
26
+ locale,
27
+ }: {
28
+ children: React.ReactNode;
29
+ locale: string;
30
+ }) => (
31
+ <div data-testid="i18n-provider" data-locale={locale}>
32
+ {children}
33
+ </div>
34
+ ),
35
+ }));
36
+
37
+ describe("LocaleProvider", () => {
38
+ beforeEach(() => {
39
+ // Reset the mock before each test
40
+ mockNavigatorLanguage = undefined;
41
+ });
42
+
43
+ afterEach(() => {
44
+ cleanup();
45
+ // Clear all mocks after each test
46
+ mockNavigatorLanguage = undefined;
47
+ vi.clearAllMocks();
48
+ });
49
+
50
+ it("should render I18nProvider without locale when locale is null", () => {
51
+ const store = createStore();
52
+ const config = parseUserConfig({ display: { locale: null } });
53
+ store.set(userConfigAtom, config);
54
+
55
+ const { getByTestId } = render(
56
+ <Provider store={store}>
57
+ <LocaleProvider>
58
+ <div>Test content</div>
59
+ </LocaleProvider>
60
+ </Provider>,
61
+ );
62
+
63
+ const i18nProvider = getByTestId("i18n-provider");
64
+ expect(i18nProvider).toBeInTheDocument();
65
+ expect(i18nProvider.dataset.locale).toBe(undefined);
66
+ expect(i18nProvider).toHaveTextContent("Test content");
67
+ });
68
+
69
+ it("should render I18nProvider without locale when locale is undefined", () => {
70
+ const store = createStore();
71
+ const config = parseUserConfig({ display: { locale: undefined } });
72
+ store.set(userConfigAtom, config);
73
+
74
+ const { getByTestId } = render(
75
+ <Provider store={store}>
76
+ <LocaleProvider>
77
+ <div>Test content</div>
78
+ </LocaleProvider>
79
+ </Provider>,
80
+ );
81
+
82
+ const i18nProvider = getByTestId("i18n-provider");
83
+ expect(i18nProvider).toBeInTheDocument();
84
+ expect(i18nProvider.dataset.locale).toBe(undefined);
85
+ expect(i18nProvider).toHaveTextContent("Test content");
86
+ });
87
+
88
+ it("should render I18nProvider with locale when locale is provided", () => {
89
+ const store = createStore();
90
+ const testLocale = "es-ES";
91
+ const config = parseUserConfig({ display: { locale: testLocale } });
92
+ store.set(userConfigAtom, config);
93
+
94
+ const { getByTestId } = render(
95
+ <Provider store={store}>
96
+ <LocaleProvider>
97
+ <div>Test content</div>
98
+ </LocaleProvider>
99
+ </Provider>,
100
+ );
101
+
102
+ const i18nProvider = getByTestId("i18n-provider");
103
+ expect(i18nProvider).toBeInTheDocument();
104
+ expect(i18nProvider.dataset.locale).toBe(testLocale);
105
+ expect(i18nProvider).toHaveTextContent("Test content");
106
+ });
107
+
108
+ it("should render I18nProvider with different locale values", () => {
109
+ const testCases = ["en-US", "fr-FR", "de-DE", "ja-JP"];
110
+
111
+ testCases.forEach((locale) => {
112
+ const store = createStore();
113
+ const config = parseUserConfig({ display: { locale } });
114
+ store.set(userConfigAtom, config);
115
+
116
+ const { getByTestId } = render(
117
+ <Provider store={store}>
118
+ <LocaleProvider>
119
+ <div>Test content for {locale}</div>
120
+ </LocaleProvider>
121
+ </Provider>,
122
+ );
123
+
124
+ const i18nProvider = getByTestId("i18n-provider");
125
+ expect(i18nProvider.dataset.locale).toBe(locale);
126
+ expect(i18nProvider).toHaveTextContent(`Test content for ${locale}`);
127
+
128
+ // Clean up after each iteration
129
+ cleanup();
130
+ });
131
+ });
132
+
133
+ it("should render children correctly", () => {
134
+ const store = createStore();
135
+ const config = parseUserConfig({ display: { locale: "en-US" } });
136
+ store.set(userConfigAtom, config);
137
+
138
+ const { getByText, getByRole } = render(
139
+ <Provider store={store}>
140
+ <LocaleProvider>
141
+ <div>
142
+ <h1>Test Heading</h1>
143
+ <p>Test paragraph</p>
144
+ <button type="button">Test Button</button>
145
+ </div>
146
+ </LocaleProvider>
147
+ </Provider>,
148
+ );
149
+
150
+ expect(getByText("Test Heading")).toBeInTheDocument();
151
+ expect(getByText("Test paragraph")).toBeInTheDocument();
152
+ expect(getByRole("button", { name: "Test Button" })).toBeInTheDocument();
153
+ });
154
+
155
+ it("should auto-detect locale when no locale is set in config", () => {
156
+ mockNavigatorLanguage = "de-DE";
157
+
158
+ const store = createStore();
159
+ const config = parseUserConfig({});
160
+ store.set(userConfigAtom, config);
161
+
162
+ const { getByTestId } = render(
163
+ <Provider store={store}>
164
+ <LocaleProvider>
165
+ <div>Test content</div>
166
+ </LocaleProvider>
167
+ </Provider>,
168
+ );
169
+
170
+ const i18nProvider = getByTestId("i18n-provider");
171
+ expect(i18nProvider).toBeInTheDocument();
172
+ // When no locale is specified in config, it should use navigator.language
173
+ expect(i18nProvider.dataset.locale).toBe("de-DE");
174
+ expect(i18nProvider).toHaveTextContent("Test content");
175
+ });
176
+ });
@@ -0,0 +1,35 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { useAtomValue } from "jotai";
4
+ import type { ReactNode } from "react";
5
+ import { I18nProvider } from "react-aria-components";
6
+ import { localeAtom } from "@/core/config/config";
7
+
8
+ interface LocaleProviderProps {
9
+ children: ReactNode;
10
+ }
11
+
12
+ export const LocaleProvider = ({ children }: LocaleProviderProps) => {
13
+ const locale = useAtomValue(localeAtom);
14
+
15
+ return <I18nProvider locale={safeLocale(locale)}>{children}</I18nProvider>;
16
+ };
17
+
18
+ function safeLocale(locale: string | null | undefined) {
19
+ if (!locale) {
20
+ return navigator.language;
21
+ }
22
+ if (isValidLocale(locale)) {
23
+ return locale;
24
+ }
25
+ return navigator.language;
26
+ }
27
+
28
+ function isValidLocale(locale: string) {
29
+ try {
30
+ new Intl.NumberFormat(locale);
31
+ return true;
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
@@ -0,0 +1,12 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { useLocale } from "react-aria";
4
+
5
+ export const WithLocale = ({
6
+ children,
7
+ }: {
8
+ children: (locale: string) => React.ReactNode;
9
+ }) => {
10
+ const { locale } = useLocale();
11
+ return children(locale);
12
+ };
@@ -7,6 +7,7 @@ import { ErrorBoundary } from "@/components/editor/boundary/ErrorBoundary";
7
7
  import { TooltipProvider } from "@/components/ui/tooltip";
8
8
  import { notebookAtom } from "@/core/cells/cells";
9
9
  import { UI_ELEMENT_REGISTRY } from "@/core/dom/uiregistry";
10
+ import { LocaleProvider } from "@/core/i18n/locale-provider";
10
11
  import { renderHTML } from "@/plugins/core/RenderHTML";
11
12
  import { invariant } from "@/utils/invariant";
12
13
  import type { CellId } from "../../cells/ids";
@@ -80,16 +81,18 @@ export class MarimoIslandElement extends HTMLElement {
80
81
  this.root?.render(
81
82
  <ErrorBoundary>
82
83
  <Provider store={store}>
83
- <TooltipProvider>
84
- <MarimoOutputWrapper
85
- cellId={this.cellId}
86
- codeCallback={codeCallback}
87
- alwaysShowRun={alwaysShowRun}
88
- >
89
- {initialHtml}
90
- </MarimoOutputWrapper>
91
- {editor}
92
- </TooltipProvider>
84
+ <LocaleProvider>
85
+ <TooltipProvider>
86
+ <MarimoOutputWrapper
87
+ cellId={this.cellId}
88
+ codeCallback={codeCallback}
89
+ alwaysShowRun={alwaysShowRun}
90
+ >
91
+ {initialHtml}
92
+ </MarimoOutputWrapper>
93
+ {editor}
94
+ </TooltipProvider>
95
+ </LocaleProvider>
93
96
  </Provider>
94
97
  </ErrorBoundary>,
95
98
  );
@@ -103,7 +103,7 @@ export async function initialize() {
103
103
  // Consume messages from the kernel
104
104
  IslandsPyodideBridge.INSTANCE.consumeMessages((message) => {
105
105
  const msg = jsonParseWithSpecialChar(message);
106
- switch (msg.op) {
106
+ switch (msg.data.op) {
107
107
  case "banner":
108
108
  case "missing-package-alert":
109
109
  case "installing-package-alert":
@@ -185,7 +185,7 @@ export async function initialize() {
185
185
  case "reconnected":
186
186
  return;
187
187
  default:
188
- logNever(msg);
188
+ logNever(msg.data);
189
189
  }
190
190
  });
191
191
 
@@ -29,8 +29,11 @@ export class RuntimeState {
29
29
  * ObjectIds of UIElements whose values need to be updated in the kernel
30
30
  */
31
31
  private _sendComponentValues: RunRequests["sendComponentValues"] | undefined;
32
+ private uiElementRegistry: UIElementRegistry;
32
33
 
33
- constructor(private uiElementRegistry: UIElementRegistry) {}
34
+ constructor(uiElementRegistry: UIElementRegistry) {
35
+ this.uiElementRegistry = uiElementRegistry;
36
+ }
34
37
 
35
38
  private get sendComponentValues(): RunRequests["sendComponentValues"] {
36
39
  if (!this._sendComponentValues) {
@@ -40,21 +40,17 @@ export type SQLTableListPreview =
40
40
  OperationMessageData<"sql-table-list-preview">;
41
41
  export type SecretKeysResult = OperationMessageData<"secret-keys-result">;
42
42
  export type StartupLogs = OperationMessageData<"startup-logs">;
43
- export type MessageOperation = schemas["KnownUnions"]["operation"];
43
+ export type CellMessage = OperationMessageData<"cell-op">;
44
+ export type Capabilities = OperationMessageData<"kernel-ready">["capabilities"];
44
45
 
45
- export type OperationMessageType = MessageOperation["op"];
46
- export type OperationMessage = {
47
- [Type in OperationMessageType]: {
48
- op: Type;
49
- data: Omit<Extract<MessageOperation, { op: Type }>, "op">;
50
- };
51
- }[OperationMessageType];
46
+ export type MessageOperationUnion = schemas["KnownUnions"]["operation"];
52
47
 
53
- export type CellMessage = OperationMessageData<"cell-op">;
48
+ export type OperationMessageType = MessageOperationUnion["op"];
49
+ export interface OperationMessage {
50
+ data: MessageOperationUnion;
51
+ }
54
52
 
55
53
  export type OperationMessageData<T extends OperationMessageType> = Omit<
56
- Extract<MessageOperation, { op: T }>,
54
+ Extract<MessageOperationUnion, { op: T }>,
57
55
  "op"
58
56
  >;
59
-
60
- export type Capabilities = OperationMessageData<"kernel-ready">["capabilities"];
@@ -18,17 +18,29 @@ export const RequestId = {
18
18
  */
19
19
  export class DeferredRequestRegistry<REQ, RES> {
20
20
  public requests = new Map<RequestId, Deferred<RES>>();
21
+ public operation: string;
22
+ private makeRequest: (id: RequestId, req: REQ) => Promise<void>;
23
+ private opts: {
24
+ /**
25
+ * Resolve existing requests with an empty response.
26
+ */
27
+ resolveExistingRequests?: () => RES;
28
+ };
21
29
 
22
30
  constructor(
23
- public operation: string,
24
- private makeRequest: (id: RequestId, req: REQ) => Promise<void>,
25
- private opts: {
31
+ operation: string,
32
+ makeRequest: (id: RequestId, req: REQ) => Promise<void>,
33
+ opts: {
26
34
  /**
27
35
  * Resolve existing requests with an empty response.
28
36
  */
29
37
  resolveExistingRequests?: () => RES;
30
38
  } = {},
31
- ) {}
39
+ ) {
40
+ this.operation = operation;
41
+ this.makeRequest = makeRequest;
42
+ this.opts = opts;
43
+ }
32
44
 
33
45
  async request(opts: REQ): Promise<RES> {
34
46
  if (this.opts.resolveExistingRequests) {
@@ -10,11 +10,12 @@ import type { RuntimeConfig } from "./types";
10
10
 
11
11
  export class RuntimeManager {
12
12
  private initialHealthyCheck = new Deferred<void>();
13
+ private config: RuntimeConfig;
14
+ private lazy: boolean;
13
15
 
14
- constructor(
15
- private config: RuntimeConfig,
16
- private lazy = false,
17
- ) {
16
+ constructor(config: RuntimeConfig, lazy = false) {
17
+ this.config = config;
18
+ this.lazy = lazy;
18
19
  // Validate the URL on construction
19
20
  try {
20
21
  new URL(this.config.url);
@@ -0,0 +1,37 @@
1
+ /* Copyright 2024 Marimo. All rights reserved. */
2
+
3
+ import { describe, expect, it } from "vitest";
4
+ import { EDGE_CASE_FILENAMES } from "../../../__tests__/mocks";
5
+ import { Paths } from "../../../utils/paths";
6
+
7
+ describe("filename handling logic", () => {
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
+ );
15
+
16
+ it("should handle full paths with unicode filenames", () => {
17
+ EDGE_CASE_FILENAMES.forEach((filename) => {
18
+ const fullPath = `/path/to/${filename}`;
19
+
20
+ const basename = Paths.basename(fullPath);
21
+ expect(basename).toBe(filename);
22
+ });
23
+ });
24
+
25
+ it("should handle document title setting with unicode", () => {
26
+ EDGE_CASE_FILENAMES.forEach((filename) => {
27
+ const originalTitle = document.title;
28
+
29
+ // In case this does any conversions, we want to simulate reading/writing the title
30
+ document.title = filename;
31
+ expect(document.title).toBe(filename);
32
+
33
+ // Restore
34
+ document.title = originalTitle;
35
+ });
36
+ });
37
+ });