@marimo-team/frontend 0.25.3-dev48 → 0.25.3-dev51

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 (106) hide show
  1. package/dist/assets/{CellStatus-BpOBz-8m.js → CellStatus-RQxLjC9P.js} +1 -1
  2. package/dist/assets/{ErrorBoundary-DmXl4Nre.js → ErrorBoundary-DzEMMFh0.js} +2 -2
  3. package/dist/assets/{JsonOutput-53CM4rZw.js → JsonOutput-9IONH7hu.js} +5 -5
  4. package/dist/assets/MarimoErrorOutput-BT8Qy5wh.js +10 -0
  5. package/dist/assets/{RenderHTML-BFaztTR0.js → RenderHTML-PyMU3fBB.js} +1 -1
  6. package/dist/assets/{RunButton-B44xE_d5.js → RunButton-2p2uCp9U.js} +1 -1
  7. package/dist/assets/{add-cell-with-ai-DQlEdS75.js → add-cell-with-ai-CEQ8jvcR.js} +5 -5
  8. package/dist/assets/{add-connection-dialog-CWLLVKju.js → add-connection-dialog-D9fnw-j0.js} +1 -1
  9. package/dist/assets/{agent-panel-Dvr9HVds.js → agent-panel-DkTYXm6j.js} +1 -1
  10. package/dist/assets/{ai-model-dropdown-F3mm17Wa.js → ai-model-dropdown-Cv9fEAp9.js} +3 -3
  11. package/dist/assets/{app-config-button-D0uDs5nC.js → app-config-button-BZzwY1BU.js} +1 -1
  12. package/dist/assets/{blob-BSfsdCNF.js → blob-DmUUV8Xf.js} +1 -1
  13. package/dist/assets/{cell-editor-B9xsMBv-.js → cell-editor-C6xeN3x0.js} +8 -8
  14. package/dist/assets/cell-link-BNDZZ97N.js +1 -0
  15. package/dist/assets/cells-0e2dpq3z.js +220 -0
  16. package/dist/assets/{chat-display-C3__xzM4.js → chat-display-D6TNcsmz.js} +1 -1
  17. package/dist/assets/{chat-panel-CffQmmt6.js → chat-panel-CN45Q9wF.js} +2 -2
  18. package/dist/assets/{chat-ui-TDKs3kxj.js → chat-ui-BGl1jPPe.js} +1 -1
  19. package/dist/assets/code-visibility-CV3S4xuf.js +1 -0
  20. package/dist/assets/{column-preview-8r_KX_X9.js → column-preview-D7sTOokc.js} +1 -1
  21. package/dist/assets/{command-palette-CymnpCiy.js → command-palette-CP5KmR-S.js} +1 -1
  22. package/dist/assets/{common-BcEY1yDS.js → common-GvwCMUGF.js} +1 -1
  23. package/dist/assets/{components-lkCfd2vy.js → components-nnFZuekV.js} +1 -1
  24. package/dist/assets/{config-DXjnAwtL.js → config-CjQ4WJnJ.js} +1 -1
  25. package/dist/assets/config-DzdxZb17.js +1 -0
  26. package/dist/assets/{datasource-dKk3JHSQ.js → datasource-BpMPWJoj.js} +1 -1
  27. package/dist/assets/{dependency-graph-panel-BaisS9Zt.js → dependency-graph-panel-lyJ3aygI.js} +1 -1
  28. package/dist/assets/{documentation-panel-CpSUoM8r.js → documentation-panel-CTUWNQQy.js} +1 -1
  29. package/dist/assets/{download-RV4i1fWI.js → download-Csw35OD4.js} +1 -1
  30. package/dist/assets/{edit-page-CWjREE5g.js → edit-page-Dwf3-IB6.js} +6 -6
  31. package/dist/assets/{error-entries-CJS0gOId.js → error-entries-D3H6JH3A.js} +1 -1
  32. package/dist/assets/{error-panel-BxCKpZtN.js → error-panel-CgpCPUEO.js} +1 -1
  33. package/dist/assets/feedback-button-B8idT199.js +1 -0
  34. package/dist/assets/{feedback-button-DYjae3_b.js → feedback-button-BEBY1q2a.js} +2 -2
  35. package/dist/assets/{file-explorer-panel-DRj-91dB.js → file-explorer-panel-MnNgzxxE.js} +1 -1
  36. package/dist/assets/{file-name-input-BpfSzvEB.js → file-name-input-DrtIQ1VP.js} +1 -1
  37. package/dist/assets/{floating-outline-CrWdiNQ2.js → floating-outline-Dtc8YhnE.js} +1 -1
  38. package/dist/assets/{gallery-page-W_b-XWq6.js → gallery-page-DL4SSfun.js} +1 -1
  39. package/dist/assets/{glide-data-editor-C_bIL30J.js → glide-data-editor-BTlU9F_s.js} +1 -1
  40. package/dist/assets/{home-page-D1teQDdF.js → home-page-BOmrrw3X.js} +1 -1
  41. package/dist/assets/hooks-DRNEKPFW.js +1 -0
  42. package/dist/assets/{index-yFM8bRve.js → index-BdCbOYjS.js} +9 -9
  43. package/dist/assets/{layout-BDFQESY4.js → layout-DY2TXsTM.js} +5 -5
  44. package/dist/assets/{logs-panel-DVSgfMgv.js → logs-panel-9f0amGf0.js} +1 -1
  45. package/dist/assets/{markdown-renderer-DX2O5YiE.js → markdown-renderer-BRDCZeXA.js} +1 -1
  46. package/dist/assets/{name-cell-input-DL1i8Mj0.js → name-cell-input-13mN6CiO.js} +1 -1
  47. package/dist/assets/{outline-panel-DPKPT2eg.js → outline-panel-DxC82nfD.js} +1 -1
  48. package/dist/assets/{packages-panel-CZZwD9YV.js → packages-panel-Bi_mcFbl.js} +1 -1
  49. package/dist/assets/{panel-accordion-state-C7vvsYz1.js → panel-accordion-state-D_2i5aDC.js} +1 -1
  50. package/dist/assets/panels-C-ygF1Rv.js +107 -0
  51. package/dist/assets/{process-output-BKhybJBb.js → process-output-DlZH3EId.js} +1 -1
  52. package/dist/assets/{readonly-code-display-9QrSm_7D.js → readonly-code-display-C8kpTYRT.js} +1 -1
  53. package/dist/assets/{readonly-python-code-BLotL3XP.js → readonly-python-code-XeDpkiXX.js} +1 -1
  54. package/dist/assets/{reveal-component-DaU9bJyq.js → reveal-component-DgYlZOla.js} +3 -3
  55. package/dist/assets/run-page-C_A8W1eR.js +1 -0
  56. package/dist/assets/{runtime-details-state-B25uM-Ps.js → runtime-details-state-BeyT-Z-4.js} +1 -1
  57. package/dist/assets/{scratchpad-panel-DVHXbcng.js → scratchpad-panel-Fb-8g4-S.js} +1 -1
  58. package/dist/assets/session-panel-Cl85FUT5.js +1 -0
  59. package/dist/assets/{snippets-panel-IxIxfxNc.js → snippets-panel-1hl_ey1w.js} +1 -1
  60. package/dist/assets/state-CbjD81T1.js +3 -0
  61. package/dist/assets/{state-CVgqwwCU.js → state-ClkxCKxQ.js} +1 -1
  62. package/dist/assets/{terminal-CjvCrRrA.js → terminal-D__Z_QZ0.js} +3 -3
  63. package/dist/assets/{tracing-V5zejPsw.js → tracing-DcFczEy0.js} +1 -1
  64. package/dist/assets/{tracing-panel-DLS3iwK6.js → tracing-panel-EWvfWPFQ.js} +2 -2
  65. package/dist/assets/{tree-actions-Be_mzC1C.js → tree-actions-Dof5VISm.js} +1 -1
  66. package/dist/assets/{useAddCell-DK79W1vA.js → useAddCell-CqnFgwhm.js} +1 -1
  67. package/dist/assets/{useBoolean-DGV7FfNx.js → useBoolean-CMgj9hnq.js} +1 -1
  68. package/dist/assets/{useCellActionButton-Cw9Ob12j.js → useCellActionButton--Sq8PDBs.js} +1 -1
  69. package/dist/assets/{useDeleteCell-BNqX6PPu.js → useDeleteCell-DNTqIwU8.js} +1 -1
  70. package/dist/assets/{useDependencyPanelTab-GnTnqKJo.js → useDependencyPanelTab-C4_EiuVH.js} +1 -1
  71. package/dist/assets/{useInstallPackage-CVItDn1e.js → useInstallPackage-DDjpV5RE.js} +1 -1
  72. package/dist/assets/useNotebookActions-C00MOhyT.js +1 -0
  73. package/dist/assets/{useRunCells-DP09DHT6.js → useRunCells-DqLsZnRn.js} +1 -1
  74. package/dist/assets/{useSplitCell-IfumZ4sm.js → useSplitCell-Daxc689Z.js} +1 -1
  75. package/dist/assets/vega-component-D7JFthDD.js +1 -0
  76. package/dist/index.html +30 -30
  77. package/package.json +1 -1
  78. package/src/__tests__/mount.test.ts +0 -20
  79. package/src/components/editor/chrome/wrapper/__tests__/attachment-status.test.tsx +2 -2
  80. package/src/components/editor/errors/__tests__/send-error-report-button.test.tsx +2 -2
  81. package/src/core/host/__tests__/notebook-client.test.ts +66 -3
  82. package/src/core/host/events.ts +1 -10
  83. package/src/core/host/notebook-client.ts +11 -18
  84. package/src/core/runtime/__tests__/runtime.test.ts +2 -53
  85. package/src/core/runtime/runtime.ts +1 -14
  86. package/src/core/runtime/types.ts +0 -2
  87. package/src/core/websocket/__tests__/useNotebookClient.hook.test.tsx +2 -23
  88. package/src/core/websocket/__tests__/useNotebookSession.hook.test.tsx +17 -25
  89. package/src/core/websocket/transports/__tests__/sse.test.ts +17 -0
  90. package/src/core/websocket/transports/sse.ts +14 -2
  91. package/src/core/websocket/useNotebookClient.ts +1 -11
  92. package/src/core/websocket/useNotebookSession.tsx +1 -6
  93. package/src/mount.tsx +0 -4
  94. package/dist/assets/MarimoErrorOutput-DVjK8RgY.js +0 -10
  95. package/dist/assets/cell-link-DFPHORAO.js +0 -1
  96. package/dist/assets/cells-BdgzY0of.js +0 -220
  97. package/dist/assets/code-visibility-Cs-Vv3jV.js +0 -1
  98. package/dist/assets/config-BwHT0yGp.js +0 -104
  99. package/dist/assets/feedback-button-BLvwvndE.js +0 -1
  100. package/dist/assets/hooks-CXfUfh2H.js +0 -1
  101. package/dist/assets/panels-Ky-lM0iL.js +0 -4
  102. package/dist/assets/run-page-5-VklWLa.js +0 -1
  103. package/dist/assets/session-panel-CPVhiI4m.js +0 -1
  104. package/dist/assets/state-D7Y-ORmT.js +0 -3
  105. package/dist/assets/useNotebookActions-CqqHJtAd.js +0 -1
  106. package/dist/assets/vega-component-CMn031HF.js +0 -1
package/dist/index.html CHANGED
@@ -66,27 +66,27 @@
66
66
  <marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
67
67
  <!-- /TODO -->
68
68
  <title>{{ title }}</title>
69
- <script type="module" crossorigin src="./assets/index-yFM8bRve.js"></script>
69
+ <script type="module" crossorigin src="./assets/index-BdCbOYjS.js"></script>
70
70
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-B0Z9INg1.js">
71
71
  <link rel="modulepreload" crossorigin href="./assets/react-DVplv7_D.js">
72
72
  <link rel="modulepreload" crossorigin href="./assets/compiler-runtime-BrajqUja.js">
73
73
  <link rel="modulepreload" crossorigin href="./assets/useEvent-Dfcbgjhg.js">
74
74
  <link rel="modulepreload" crossorigin href="./assets/react-dom-_LrxgvjW.js">
75
75
  <link rel="modulepreload" crossorigin href="./assets/schemas-ChRqMOTL.js">
76
- <link rel="modulepreload" crossorigin href="./assets/objects-rLPlQ3X_.js">
77
- <link rel="modulepreload" crossorigin href="./assets/useEventListener-CjDeLqFC.js">
78
- <link rel="modulepreload" crossorigin href="./assets/invariant-Ci2dTZ72.js">
79
- <link rel="modulepreload" crossorigin href="./assets/utils-B4K466FK.js">
80
- <link rel="modulepreload" crossorigin href="./assets/session-B8Y-GJnS.js">
81
- <link rel="modulepreload" crossorigin href="./assets/Deferred-CrTnjj37.js">
82
- <link rel="modulepreload" crossorigin href="./assets/config-BwHT0yGp.js">
83
76
  <link rel="modulepreload" crossorigin href="./assets/isObject-BCaOs5rp.js">
84
77
  <link rel="modulepreload" crossorigin href="./assets/isSymbol-oX0TOjjx.js">
85
78
  <link rel="modulepreload" crossorigin href="./assets/now-Cmx0b_zA.js">
86
79
  <link rel="modulepreload" crossorigin href="./assets/debounce-aFmHgJZY.js">
87
80
  <link rel="modulepreload" crossorigin href="./assets/isArrayLikeObject-DnwgSs_Z.js">
88
81
  <link rel="modulepreload" crossorigin href="./assets/_baseMerge-CQpUq7ep.js">
82
+ <link rel="modulepreload" crossorigin href="./assets/objects-rLPlQ3X_.js">
83
+ <link rel="modulepreload" crossorigin href="./assets/useEventListener-CjDeLqFC.js">
84
+ <link rel="modulepreload" crossorigin href="./assets/invariant-Ci2dTZ72.js">
89
85
  <link rel="modulepreload" crossorigin href="./assets/config-DGX7JYor.js">
86
+ <link rel="modulepreload" crossorigin href="./assets/utils-B4K466FK.js">
87
+ <link rel="modulepreload" crossorigin href="./assets/session-B8Y-GJnS.js">
88
+ <link rel="modulepreload" crossorigin href="./assets/Deferred-CrTnjj37.js">
89
+ <link rel="modulepreload" crossorigin href="./assets/config-DzdxZb17.js">
90
90
  <link rel="modulepreload" crossorigin href="./assets/clsx-DB0hHKMi.js">
91
91
  <link rel="modulepreload" crossorigin href="./assets/cn-ldLVeaqm.js">
92
92
  <link rel="modulepreload" crossorigin href="./assets/jsx-runtime-B74pBk57.js">
@@ -139,7 +139,7 @@
139
139
  <link rel="modulepreload" crossorigin href="./assets/useTheme-DLtPc-39.js">
140
140
  <link rel="modulepreload" crossorigin href="./assets/useAsyncData-DhhdOGGd.js">
141
141
  <link rel="modulepreload" crossorigin href="./assets/purify.es--06brOip.js">
142
- <link rel="modulepreload" crossorigin href="./assets/cells-BdgzY0of.js">
142
+ <link rel="modulepreload" crossorigin href="./assets/cells-0e2dpq3z.js">
143
143
  <link rel="modulepreload" crossorigin href="./assets/coerce-DWjFeXOY.js">
144
144
  <link rel="modulepreload" crossorigin href="./assets/get-DjNf4SIX.js">
145
145
  <link rel="modulepreload" crossorigin href="./assets/_hasPath-BmRQipI0.js">
@@ -147,47 +147,47 @@
147
147
  <link rel="modulepreload" crossorigin href="./assets/_baseSet-Bpdo9AvU.js">
148
148
  <link rel="modulepreload" crossorigin href="./assets/pick-DKIID_Mo.js">
149
149
  <link rel="modulepreload" crossorigin href="./assets/errors-CNsgAw6m.js">
150
- <link rel="modulepreload" crossorigin href="./assets/config-DXjnAwtL.js">
150
+ <link rel="modulepreload" crossorigin href="./assets/config-CjQ4WJnJ.js">
151
151
  <link rel="modulepreload" crossorigin href="./assets/state-C0irhlOZ.js">
152
152
  <link rel="modulepreload" crossorigin href="./assets/state-DaWgt-rn.js">
153
153
  <link rel="modulepreload" crossorigin href="./assets/LazyAnyLanguageCodeMirror-BPYE76jR.js">
154
154
  <link rel="modulepreload" crossorigin href="./assets/copy-KlhazlhB.js">
155
155
  <link rel="modulepreload" crossorigin href="./assets/micromark-factory-space-D9Dr-k4J.js">
156
156
  <link rel="modulepreload" crossorigin href="./assets/chunk-YOKDWASO-BIpRENEC.js">
157
- <link rel="modulepreload" crossorigin href="./assets/markdown-renderer-DX2O5YiE.js">
157
+ <link rel="modulepreload" crossorigin href="./assets/markdown-renderer-BRDCZeXA.js">
158
158
  <link rel="modulepreload" crossorigin href="./assets/copy-Djr5m5ac.js">
159
159
  <link rel="modulepreload" crossorigin href="./assets/copy-icon-8-a5vovc.js">
160
- <link rel="modulepreload" crossorigin href="./assets/useRunCells-DP09DHT6.js">
161
- <link rel="modulepreload" crossorigin href="./assets/RenderHTML-BFaztTR0.js">
162
- <link rel="modulepreload" crossorigin href="./assets/blob-BSfsdCNF.js">
160
+ <link rel="modulepreload" crossorigin href="./assets/useRunCells-DqLsZnRn.js">
161
+ <link rel="modulepreload" crossorigin href="./assets/RenderHTML-PyMU3fBB.js">
162
+ <link rel="modulepreload" crossorigin href="./assets/blob-DmUUV8Xf.js">
163
163
  <link rel="modulepreload" crossorigin href="./assets/kbd-pdKBv96t.js">
164
- <link rel="modulepreload" crossorigin href="./assets/useInstallPackage-CVItDn1e.js">
164
+ <link rel="modulepreload" crossorigin href="./assets/useInstallPackage-DDjpV5RE.js">
165
165
  <link rel="modulepreload" crossorigin href="./assets/share-BZW3tzEX.js">
166
166
  <link rel="modulepreload" crossorigin href="./assets/events-CbeVJ6OD.js">
167
- <link rel="modulepreload" crossorigin href="./assets/state-D7Y-ORmT.js">
168
- <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-DmXl4Nre.js">
167
+ <link rel="modulepreload" crossorigin href="./assets/state-CbjD81T1.js">
168
+ <link rel="modulepreload" crossorigin href="./assets/ErrorBoundary-DzEMMFh0.js">
169
169
  <link rel="modulepreload" crossorigin href="./assets/chevron-right-eAtVhbNZ.js">
170
170
  <link rel="modulepreload" crossorigin href="./assets/dropdown-menu-DS6umAnH.js">
171
171
  <link rel="modulepreload" crossorigin href="./assets/html-to-image-D_0rd3_B.js">
172
- <link rel="modulepreload" crossorigin href="./assets/download-RV4i1fWI.js">
172
+ <link rel="modulepreload" crossorigin href="./assets/download-Csw35OD4.js">
173
173
  <link rel="modulepreload" crossorigin href="./assets/switch-1h011wlH.js">
174
174
  <link rel="modulepreload" crossorigin href="./assets/tabs-CY8E4r9U.js">
175
175
  <link rel="modulepreload" crossorigin href="./assets/table-DG7Ap4H4.js">
176
176
  <link rel="modulepreload" crossorigin href="./assets/eye-off-CxVozGAC.js">
177
177
  <link rel="modulepreload" crossorigin href="./assets/refresh-cw-Qw1f8Jhy.js">
178
- <link rel="modulepreload" crossorigin href="./assets/tree-actions-Be_mzC1C.js">
178
+ <link rel="modulepreload" crossorigin href="./assets/tree-actions-Dof5VISm.js">
179
179
  <link rel="modulepreload" crossorigin href="./assets/ellipsis-63DyBLHQ.js">
180
180
  <link rel="modulepreload" crossorigin href="./assets/external-link-UrX9KO36.js">
181
181
  <link rel="modulepreload" crossorigin href="./assets/spinner-DyNE-o8o.js">
182
182
  <link rel="modulepreload" crossorigin href="./assets/message-circle-C3rKm8_a.js">
183
183
  <link rel="modulepreload" crossorigin href="./assets/hat-glasses-C8RhSVii.js">
184
184
  <link rel="modulepreload" crossorigin href="./assets/package-GSoSTiIK.js">
185
- <link rel="modulepreload" crossorigin href="./assets/datasource-dKk3JHSQ.js">
186
- <link rel="modulepreload" crossorigin href="./assets/error-entries-CJS0gOId.js">
185
+ <link rel="modulepreload" crossorigin href="./assets/datasource-BpMPWJoj.js">
186
+ <link rel="modulepreload" crossorigin href="./assets/error-entries-D3H6JH3A.js">
187
187
  <link rel="modulepreload" crossorigin href="./assets/alert-DTaqCu_d.js">
188
- <link rel="modulepreload" crossorigin href="./assets/state-CVgqwwCU.js">
189
- <link rel="modulepreload" crossorigin href="./assets/cell-link-DFPHORAO.js">
190
- <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-DVjK8RgY.js">
188
+ <link rel="modulepreload" crossorigin href="./assets/state-ClkxCKxQ.js">
189
+ <link rel="modulepreload" crossorigin href="./assets/cell-link-BNDZZ97N.js">
190
+ <link rel="modulepreload" crossorigin href="./assets/MarimoErrorOutput-BT8Qy5wh.js">
191
191
  <link rel="modulepreload" crossorigin href="./assets/useDateFormatter-DA-62E-Y.js">
192
192
  <link rel="modulepreload" crossorigin href="./assets/en-US-Buu61juQ.js">
193
193
  <link rel="modulepreload" crossorigin href="./assets/isValid-q_Ad80ug.js">
@@ -206,13 +206,13 @@
206
206
  <link rel="modulepreload" crossorigin href="./assets/formats-zylfwejq.js">
207
207
  <link rel="modulepreload" crossorigin href="./assets/table-vrvqpuKJ.js">
208
208
  <link rel="modulepreload" crossorigin href="./assets/react-resizable-panels.browser.esm-Dbe0MrFr.js">
209
- <link rel="modulepreload" crossorigin href="./assets/JsonOutput-53CM4rZw.js">
209
+ <link rel="modulepreload" crossorigin href="./assets/JsonOutput-9IONH7hu.js">
210
210
  <link rel="modulepreload" crossorigin href="./assets/chart-no-axes-column-C4_v6fQW.js">
211
211
  <link rel="modulepreload" crossorigin href="./assets/square-function-_W_Lo0P4.js">
212
212
  <link rel="modulepreload" crossorigin href="./assets/spec-uCpVvaAR.js">
213
213
  <link rel="modulepreload" crossorigin href="./assets/semaphore-BjoL5P0h.js">
214
214
  <link rel="modulepreload" crossorigin href="./assets/fileToBase64-BgBraYAr.js">
215
- <link rel="modulepreload" crossorigin href="./assets/useBoolean-DGV7FfNx.js">
215
+ <link rel="modulepreload" crossorigin href="./assets/useBoolean-CMgj9hnq.js">
216
216
  <link rel="modulepreload" crossorigin href="./assets/code-xml-SQaZqvcO.js">
217
217
  <link rel="modulepreload" crossorigin href="./assets/file-headphone-Dl35U6h3.js">
218
218
  <link rel="modulepreload" crossorigin href="./assets/file-BPBVl9pl.js">
@@ -220,11 +220,11 @@
220
220
  <link rel="modulepreload" crossorigin href="./assets/file-icons-CdJgUy-I.js">
221
221
  <link rel="modulepreload" crossorigin href="./assets/globe-UdPdIbF7.js">
222
222
  <link rel="modulepreload" crossorigin href="./assets/esm-CI_o7NhW.js">
223
- <link rel="modulepreload" crossorigin href="./assets/useAddCell-DK79W1vA.js">
224
- <link rel="modulepreload" crossorigin href="./assets/readonly-python-code-BLotL3XP.js">
223
+ <link rel="modulepreload" crossorigin href="./assets/useAddCell-CqnFgwhm.js">
224
+ <link rel="modulepreload" crossorigin href="./assets/readonly-python-code-XeDpkiXX.js">
225
225
  <link rel="modulepreload" crossorigin href="./assets/data-grid-types-DgHVN_Zz.js">
226
226
  <link rel="modulepreload" crossorigin href="./assets/glide-utils-HFqhvWHI.js">
227
- <link rel="modulepreload" crossorigin href="./assets/column-preview-8r_KX_X9.js">
227
+ <link rel="modulepreload" crossorigin href="./assets/column-preview-D7sTOokc.js">
228
228
  <link rel="modulepreload" crossorigin href="./assets/square-BPmgQFnh.js">
229
229
  <link rel="modulepreload" crossorigin href="./assets/triangle-alert-DmIqR8sY.js">
230
230
  <link rel="modulepreload" crossorigin href="./assets/prop-types-Djf4O40e.js">
@@ -236,7 +236,7 @@
236
236
  <link rel="modulepreload" crossorigin href="./assets/icons-CiZ_8zS-.js">
237
237
  <link rel="modulepreload" crossorigin href="./assets/useDeepCompareMemoize-DFIVN9dn.js">
238
238
  <link rel="modulepreload" crossorigin href="./assets/pathUtils-DPmlLd-r.js">
239
- <link rel="modulepreload" crossorigin href="./assets/floating-outline-CrWdiNQ2.js">
239
+ <link rel="modulepreload" crossorigin href="./assets/floating-outline-Dtc8YhnE.js">
240
240
  <link rel="stylesheet" crossorigin href="./assets/cells-0PFKL3SH.css">
241
241
  <link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DjIHoF9Z.css">
242
242
  <link rel="stylesheet" crossorigin href="./assets/JsonOutput-B0GmlMnR.css">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/frontend",
3
- "version": "0.25.3-dev48",
3
+ "version": "0.25.3-dev51",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -6,7 +6,6 @@ import { initialLayoutState, layoutStateAtom } from "@/core/layout/state";
6
6
  import { kioskModeAtom } from "@/core/mode";
7
7
  import { connectionAtom } from "@/core/network/connection";
8
8
  import { store } from "@/core/state/jotai";
9
- import { runtimeConfigAtom } from "@/core/runtime/config";
10
9
  import { isStaticNotebook } from "@/core/static/static-state";
11
10
  import { ConnectionState } from "@/core/websocket/types";
12
11
  import { pairConfigAtom } from "@/core/config/pair";
@@ -102,25 +101,6 @@ describe("mount", () => {
102
101
  });
103
102
 
104
103
  describe("connection state initialization", () => {
105
- it("passes the host notebook identity to the local runtime", () => {
106
- mount({ ...baseOptions, notebookId: "nb_local" }, mockElement);
107
- expect(store.get(runtimeConfigAtom).notebookId).toBe("nb_local");
108
- });
109
-
110
- it("uses a remote runtime's own notebook identity", () => {
111
- mount(
112
- {
113
- ...baseOptions,
114
- notebookId: "nb_local",
115
- runtimeConfig: [
116
- { url: "https://remote.example", notebookId: "nb_remote" },
117
- ],
118
- },
119
- mockElement,
120
- );
121
- expect(store.get(runtimeConfigAtom).notebookId).toBe("nb_remote");
122
- });
123
-
124
104
  it("should set connection to CONNECTING when runtimeConfig has lazy=false", () => {
125
105
  mount(
126
106
  {
@@ -16,6 +16,7 @@ import { TooltipProvider } from "@/components/ui/tooltip";
16
16
  import { toast } from "@/components/ui/use-toast";
17
17
  import type { Attachment } from "@/core/attachments/state";
18
18
  import { pairConfigAtom } from "@/core/config/pair";
19
+ import { createNotebookClient } from "@/core/host/notebook-client";
19
20
  import {
20
21
  type StableSessionId,
21
22
  stableSessionIdAtom,
@@ -45,10 +46,9 @@ function renderStatus(attachments: Attachment[] = [AGENT], preview = true) {
45
46
  store.set(connectionAtom, { state: ConnectionState.OPEN });
46
47
  store.set(pairConfigAtom, { ...PAIR_CONFIG, hostEnabled: preview });
47
48
  store.set(notebookClientAtom, {
49
+ ...createNotebookClient(store).client,
48
50
  connectionAtom: atom({ state: ConnectionState.OPEN }),
49
- documentAtom: atom(null),
50
51
  attachmentsAtom,
51
- reconnect: async () => undefined,
52
52
  });
53
53
  store.set(attachmentsAtom, attachments);
54
54
  store.set(stableSessionIdAtom, "stable/test" as StableSessionId);
@@ -25,6 +25,7 @@ import {
25
25
  } from "@/core/cells/error-report";
26
26
  import { pairConfigAtom } from "@/core/config/pair";
27
27
  import { notebookStateFromSession } from "@/core/cells/session";
28
+ import { createNotebookClient } from "@/core/host/notebook-client";
28
29
  import type { MarimoError, OutputMessage } from "@/core/kernel/messages";
29
30
  import {
30
31
  type StableSessionId,
@@ -97,10 +98,9 @@ function renderButton({
97
98
  store.set(connectionAtom, { state: ConnectionState.OPEN });
98
99
  store.set(pairConfigAtom, { ...PAIR_CONFIG, hostEnabled: preview });
99
100
  store.set(notebookClientAtom, {
101
+ ...createNotebookClient(store).client,
100
102
  connectionAtom: atom({ state: ConnectionState.OPEN }),
101
- documentAtom: atom(null),
102
103
  attachmentsAtom,
103
- reconnect: async () => undefined,
104
104
  });
105
105
  store.set(attachmentsAtom, attachments);
106
106
  store.set(stableSessionIdAtom, stableId);
@@ -49,12 +49,10 @@ function setup(url: () => string = () => "ws://localhost/ws") {
49
49
  return transport;
50
50
  },
51
51
  url,
52
- messageFormat: "host",
53
52
  signal,
54
53
  waitUntilReady: () => healthy.promise,
55
54
  checkHealth,
56
55
  onNotification: (notification) => onNotification({ data: notification }),
57
- onMessageError: vi.fn(),
58
56
  decodeJson: jsonParseWithSpecialChar,
59
57
  classifyClose: classifyCloseEvent,
60
58
  });
@@ -76,6 +74,71 @@ function setup(url: () => string = () => "ws://localhost/ws") {
76
74
  }
77
75
 
78
76
  describe("NotebookClient lifetime", () => {
77
+ it("exposes identity and capabilities only after the notebook is ready", async () => {
78
+ const { connect, healthy, events, receive, client, store } = setup();
79
+ const lifetime = new AbortController();
80
+ connect(lifetime.signal);
81
+ healthy.resolve();
82
+ await healthy.promise;
83
+ events.dispatchEvent(new Event("open"));
84
+ const notebook = {
85
+ id: "nb/with space",
86
+ project_id: "p1",
87
+ path: null,
88
+ name: "Notebook",
89
+ operations: ["notebook.edit"],
90
+ updated_at: null,
91
+ };
92
+ receive({ event: "notebook", data: { notebook } });
93
+ expect(store.get(client.notebookAtom)).toBeNull();
94
+ receive({ event: "ready", id: "1", data: {} });
95
+ expect(store.get(client.notebookAtom)).toEqual(notebook);
96
+ receive({
97
+ event: "notebook",
98
+ id: "2",
99
+ data: { notebook: { ...notebook, operations: [] } },
100
+ });
101
+ expect(store.get(client.notebookAtom)?.operations).toEqual([]);
102
+ receive({ event: "notebook.removed", id: "3", data: { id: notebook.id } });
103
+ expect(store.get(client.notebookAtom)).toBeNull();
104
+ lifetime.abort();
105
+ });
106
+
107
+ it("rebuilds the replica after a reconnect reset selects a new notebook", async () => {
108
+ const notebookId = "n2";
109
+ const { connect, events, healthy, urls, receive, client, store } = setup(
110
+ () => "ws://localhost/ws?session_id=visitor",
111
+ );
112
+ const lifetime = new AbortController();
113
+ connect(lifetime.signal);
114
+ healthy.resolve();
115
+ await healthy.promise;
116
+ events.dispatchEvent(new Event("open"));
117
+ fixtureMessages("notebook-events.sse").forEach(receive);
118
+ expect(store.get(client.documentAtom)?.revision.notebook_id).toBe("n1");
119
+
120
+ events.dispatchEvent(new CloseEvent("close"));
121
+ expect(urls.at(-1)?.searchParams.get("cursor")).toBe("97");
122
+ expect(store.get(client.documentAtom)?.revision.notebook_id).toBe("n1");
123
+ expect(store.get(client.notebookAtom)).toBeNull();
124
+ events.dispatchEvent(new Event("open"));
125
+ receive({ event: "reset", data: {} });
126
+ expect(store.get(client.documentAtom)).toBeNull();
127
+ for (const event of fixtureMessages("notebook-events.sse")) {
128
+ receive(
129
+ JSON.parse(
130
+ JSON.stringify(event).replaceAll('"n1"', JSON.stringify(notebookId)),
131
+ ),
132
+ );
133
+ }
134
+ expect(store.get(client.documentAtom)?.revision.notebook_id).toBe(
135
+ notebookId,
136
+ );
137
+ expect(store.get(client.connectionAtom).state).toBe(ConnectionState.OPEN);
138
+ expect(store.get(client.notebookAtom)?.id).toBe(notebookId);
139
+ lifetime.abort();
140
+ });
141
+
79
142
  it.each(["{broken", JSON.stringify({ event: "ready", data: {} })])(
80
143
  "stops consuming a malformed host stream: %s",
81
144
  (data) => {
@@ -423,7 +486,7 @@ describe("NotebookClient attachments", () => {
423
486
  },
424
487
  );
425
488
 
426
- it("keeps legacy sessions empty", async () => {
489
+ it("keeps host resources empty for notification-only WASM connections", async () => {
427
490
  const { client, store, receive, lifetime } = await open();
428
491
  receive({ data: { op: "kernel-ready" } });
429
492
  receive({ data: { op: "reconnected" } });
@@ -10,15 +10,6 @@ import * as Protocol from "@marimo-team/client/protocol";
10
10
  * and cursor so clients can skip them without losing their place in the stream.
11
11
  */
12
12
 
13
- /** Event kinds requested by the client; removals and controls are implicit. */
14
- export const NOTEBOOK_EVENT_TYPES = [
15
- "notebook",
16
- "document",
17
- "cell",
18
- "attachment",
19
- "marimo",
20
- ] as const satisfies readonly (Protocol.ObjectType | "marimo")[];
21
-
22
13
  const envelope = z.object({
23
14
  event: z.string().min(1),
24
15
  data: z.unknown(),
@@ -54,7 +45,7 @@ export type NotebookEvent =
54
45
  const sessionEnvelope = z.object({ data: z.unknown() });
55
46
 
56
47
  /**
57
- * Decode a host event or a legacy `{ data: notification }` session message.
48
+ * Decode a host event or an in-process WASM `{ data: notification }` message.
58
49
  *
59
50
  * Throws if the envelope or a known event is malformed. Native notification
60
51
  * payloads are passed through for the session handler to interpret.
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  import { Logger } from "@/utils/Logger";
4
- import type { Attachment } from "@marimo-team/client/protocol";
4
+ import type { Attachment, NotebookOutput } from "@marimo-team/client/protocol";
5
5
  import { createReducer } from "@marimo-team/client/reducer";
6
6
  import { type Atom, atom, type createStore } from "jotai/vanilla";
7
7
  import {
@@ -27,6 +27,8 @@ const UNCURSORED = new Set<NotebookEvent["event"]>([
27
27
  export interface NotebookClient {
28
28
  /** Client connection status, independent of application session readiness. */
29
29
  readonly connectionAtom: Atom<ConnectionStatus>;
30
+ /** Identity and capabilities, available while the stream is connected and ready. */
31
+ readonly notebookAtom: Atom<NotebookOutput | null>;
30
32
  /**
31
33
  * The most recently confirmed document.
32
34
  *
@@ -47,8 +49,6 @@ export interface NotebookConnection {
47
49
  createTransport: (url: () => string) => NotebookTransport;
48
50
  /** The current stream URL, including authentication and subscription options. */
49
51
  url: () => string;
50
- /** Host events require an intact stream; legacy notifications are independent. */
51
- messageFormat: "host" | "session";
52
52
  /** Abort to close the transport and clear the client's state. */
53
53
  signal: AbortSignal;
54
54
  /** Wait until the host can accept the initial connection. */
@@ -59,8 +59,6 @@ export interface NotebookConnection {
59
59
  decodeJson: (message: string) => unknown;
60
60
  /** Handle a native marimo notification. Its payload has not been validated. */
61
61
  onNotification: (notification: unknown) => void;
62
- /** Report a malformed message without coupling the client to editor UI. */
63
- onMessageError: (error: unknown) => void;
64
62
  /** Choose the connection status and retry policy after the transport closes. */
65
63
  classifyClose: (event: CloseEvent) => CloseDecision;
66
64
  }
@@ -75,6 +73,11 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
75
73
  const streamAtom = atom(reducer.initial);
76
74
  // A resumed stream is live, but presence waits for this connection's ready.
77
75
  const readyAtom = atom(false);
76
+ const notebookAtom = atom((get) =>
77
+ get(readyAtom) && get(connectionAtom).state === ConnectionState.OPEN
78
+ ? get(streamAtom).notebook
79
+ : null,
80
+ );
78
81
  const documentAtom = atom(
79
82
  (get) => get(streamAtom).resources.document.current,
80
83
  );
@@ -86,6 +89,7 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
86
89
  let reconnect: (() => Promise<void>) | undefined;
87
90
  const client: NotebookClient = {
88
91
  connectionAtom,
92
+ notebookAtom,
89
93
  documentAtom,
90
94
  attachmentsAtom,
91
95
  reconnect: async () => reconnect?.(),
@@ -94,12 +98,10 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
94
98
  function connect({
95
99
  createTransport,
96
100
  url,
97
- messageFormat,
98
101
  signal,
99
102
  waitUntilReady,
100
103
  checkHealth,
101
104
  onNotification,
102
- onMessageError,
103
105
  decodeJson,
104
106
  classifyClose,
105
107
  }: NotebookConnection) {
@@ -113,9 +115,6 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
113
115
  // The id of the last live event. Null before `ready` and after `reset`.
114
116
  let cursor: string | null = null;
115
117
  const transport = createTransport(() => {
116
- if (messageFormat === "session") {
117
- return url();
118
- }
119
118
  const next = new URL(url());
120
119
  next.searchParams.delete("cursor");
121
120
  if (signal.aborted) {
@@ -131,11 +130,9 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
131
130
  // A live stream keeps its state and resumes from the cursor. An
132
131
  // incomplete snapshot starts over.
133
132
  const state =
134
- key !== streamKey
133
+ key !== streamKey || current.phase === "snapshot"
135
134
  ? reducer.initial
136
- : current.phase === "snapshot"
137
- ? { ...reducer.initial, notebookId: current.notebookId }
138
- : current;
135
+ : current;
139
136
  if (state.phase === "snapshot") {
140
137
  cursor = null;
141
138
  }
@@ -226,10 +223,6 @@ export function createNotebookClient(store: ReturnType<typeof createStore>) {
226
223
  }
227
224
  } catch (error) {
228
225
  Logger.error("Failed to decode notebook message", error);
229
- if (messageFormat === "session") {
230
- onMessageError(error);
231
- return;
232
- }
233
226
  store.set(streamAtom, reducer.initial);
234
227
  cursor = null;
235
228
  terminal = true;
@@ -2,11 +2,7 @@
2
2
 
3
3
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
4
  import { Mocks } from "@/__mocks__/common";
5
- import {
6
- generateSessionId,
7
- isSessionId,
8
- type SessionId,
9
- } from "@/core/kernel/session";
5
+ import type { SessionId } from "@/core/kernel/session";
10
6
  import { Logger } from "@/utils/Logger";
11
7
  import { RuntimeManager } from "../runtime";
12
8
  import type { RuntimeConfig } from "../types";
@@ -56,38 +52,6 @@ describe("RuntimeManager", () => {
56
52
  });
57
53
 
58
54
  describe("getWsURL", () => {
59
- it("uses host notebook events with the existing session and auth parameters", () => {
60
- const original = window.location.href;
61
- window.history.replaceState({}, "", "/?types=run");
62
- try {
63
- const runtime = new RuntimeManager({
64
- ...mockConfig,
65
- url: "https://example.com/nested?file=notebook.py",
66
- notebookId: "nb_123",
67
- });
68
- const sessionId = "s_123456";
69
- if (!isSessionId(sessionId)) {
70
- throw new Error("Invalid test session ID");
71
- }
72
- const url = runtime.getWsURL(sessionId);
73
- expect({
74
- endpoint: `${url.origin}${url.pathname}`,
75
- params: Object.fromEntries(url.searchParams),
76
- }).toEqual({
77
- endpoint:
78
- "wss://example.com/nested/api/marimo/v1/notebooks/nb_123/events/ws",
79
- params: {
80
- file: "notebook.py",
81
- types: "notebook,document,cell,attachment,marimo",
82
- session_id: sessionId,
83
- access_token: "test-token",
84
- },
85
- });
86
- } finally {
87
- window.history.replaceState({}, "", original);
88
- }
89
- });
90
-
91
55
  it("should return WebSocket URL with session ID for https", () => {
92
56
  const runtime = new RuntimeManager(mockConfig);
93
57
  const sessionId = "1234" as SessionId;
@@ -257,21 +221,6 @@ describe("RuntimeManager", () => {
257
221
  });
258
222
 
259
223
  describe("getSseURL", () => {
260
- it.each([undefined, "nb_123"])(
261
- "uses the legacy session stream when notebookId is %s",
262
- (notebookId) => {
263
- const runtime = new RuntimeManager({
264
- ...mockConfig,
265
- url: "https://example.com/nested?file=notebook.py",
266
- notebookId,
267
- });
268
- const sessionId = generateSessionId();
269
- expect(runtime.getSseURL(sessionId).toString()).toBe(
270
- `https://example.com/nested/sse?file=notebook.py&session_id=${sessionId}`,
271
- );
272
- },
273
- );
274
-
275
224
  it("should never put the auth token in the URL, even cross-origin", () => {
276
225
  // SSE requests can send headers, so auth travels in the
277
226
  // Authorization header; a token in the URL would leak into
@@ -781,7 +730,7 @@ describe("RuntimeManager", () => {
781
730
  );
782
731
  });
783
732
 
784
- it("should throw when creating WebSocket URLs from blob URLs", () => {
733
+ it("warns when creating WebSocket URLs from blob URLs", () => {
785
734
  const runtime = new RuntimeManager({
786
735
  url: "blob:https://example.com/12345678-1234-1234-1234-123456789abc",
787
736
  lazy: true,
@@ -3,7 +3,6 @@
3
3
  import { Deferred } from "@/utils/Deferred";
4
4
  import { Logger } from "@/utils/Logger";
5
5
  import { KnownQueryParams } from "../constants";
6
- import { NOTEBOOK_EVENT_TYPES } from "../host/events";
7
6
  import { isIslands } from "../islands/utils";
8
7
  import { getSessionId, type SessionId } from "../kernel/session";
9
8
  import { isStaticNotebook } from "../static/static-state";
@@ -155,17 +154,7 @@ export class RuntimeManager {
155
154
  */
156
155
  public getWsURL(sessionId: SessionId): URL {
157
156
  const searchParams = this.getSessionSearchParams(sessionId);
158
- // TODO(MO-8039): Rediscover hosts and resolve notebooks on reconnect.
159
- const notebookId = this.config.notebookId;
160
- const path = notebookId
161
- ? `/api/marimo/v1/notebooks/${encodeURIComponent(notebookId)}/events/ws`
162
- : "/ws";
163
- const url = this.formatWsURL(path, searchParams);
164
- if (notebookId) {
165
- // TODO(MO-8034): Separate host options from notebook query params.
166
- url.searchParams.set("types", NOTEBOOK_EVENT_TYPES.join(","));
167
- }
168
- return url;
157
+ return this.formatWsURL("/ws", searchParams);
169
158
  }
170
159
 
171
160
  /**
@@ -175,8 +164,6 @@ export class RuntimeManager {
175
164
  * (see `headers()`) instead of the URL.
176
165
  */
177
166
  public getSseURL(sessionId: SessionId): URL {
178
- // TODO: Migrate editor SSE to the host event stream. Until then, host
179
- // state such as attachments is unavailable on this legacy connection.
180
167
  const url = this.formatHttpURL({
181
168
  path: "/sse",
182
169
  searchParams: this.getSessionSearchParams(sessionId),
@@ -1,8 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
 
3
3
  export interface RuntimeConfig {
4
- /** The host notebook for WebSocket events. SSE uses the legacy session stream. */
5
- readonly notebookId?: string;
6
4
  /**
7
5
  * The URL of the runtime server.
8
6
  */
@@ -15,11 +15,12 @@ import { notebookClientAtom } from "../state";
15
15
 
16
16
  vi.mock("../transports/create", () => ({ createConnectionTransport: vi.fn() }));
17
17
 
18
- function makeTransport() {
18
+ function makeTransport(url?: () => string) {
19
19
  const events = new EventTarget();
20
20
  const transport: IConnectionTransport = {
21
21
  readyState: WebSocket.CLOSED,
22
22
  reconnect: vi.fn(() => {
23
+ url?.();
23
24
  transport.readyState = WebSocket.OPEN;
24
25
  events.dispatchEvent(new Event("open"));
25
26
  }),
@@ -52,16 +53,13 @@ function makeTransport() {
52
53
  function setup(strict = false) {
53
54
  const store = createStore();
54
55
  const options = {
55
- sessionId: "first",
56
56
  static: false,
57
57
  transportType: "websocket" as const,
58
- messageFormat: "host" as const,
59
58
  url: () => "ws://localhost/ws",
60
59
  headers: () => ({}),
61
60
  waitUntilReady: async () => undefined,
62
61
  checkHealth: async () => true,
63
62
  onNotification: vi.fn(),
64
- onMessageError: vi.fn(),
65
63
  };
66
64
  const wrapper = ({ children }: PropsWithChildren) => (
67
65
  <Provider store={store}>{children}</Provider>
@@ -121,25 +119,6 @@ describe("useNotebookClient", () => {
121
119
  unmount();
122
120
  });
123
121
 
124
- it("replaces the transport when session identity changes and ignores old messages", async () => {
125
- const first = makeTransport();
126
- const second = makeTransport();
127
- vi.mocked(createConnectionTransport)
128
- .mockReturnValueOnce(first.transport)
129
- .mockReturnValueOnce(second.transport);
130
- const { rerender, options, unmount } = setup();
131
- await act(async () => Promise.resolve());
132
- rerender({ ...options, sessionId: "second" });
133
- await act(async () => Promise.resolve());
134
- expect(first.transport.close).toHaveBeenCalledOnce();
135
- act(() => {
136
- first.notify();
137
- second.notify();
138
- });
139
- expect(options.onNotification).toHaveBeenCalledOnce();
140
- unmount();
141
- });
142
-
143
122
  it("cleans up every transport under Strict Mode and only connects the active lifetime", async () => {
144
123
  const transports: ReturnType<typeof makeTransport>[] = [];
145
124
  vi.mocked(createConnectionTransport).mockImplementation(() => {