@marimo-team/frontend 0.24.3-dev40 → 0.24.3-dev41

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 (96) hide show
  1. package/dist/assets/{ConnectedDataExplorerComponent-CD3m13JH.js → ConnectedDataExplorerComponent-B44a8v96.js} +1 -1
  2. package/dist/assets/{ErrorBoundary-BA_T1McN.js → ErrorBoundary-DvitwHZ-.js} +2 -2
  3. package/dist/assets/{LazyAnyLanguageCodeMirror-C9EGRgI3.js → LazyAnyLanguageCodeMirror-nYkCzYUn.js} +2 -2
  4. package/dist/assets/{RunButton-7xbGmbVZ.js → RunButton-Diz6c9QL.js} +2 -2
  5. package/dist/assets/{abnfDiagram-VCTEODGH-Cc6OUOjQ.js → abnfDiagram-VCTEODGH-Ccyp0xSu.js} +1 -1
  6. package/dist/assets/{add-cell-with-ai-DUqh2oJw.js → add-cell-with-ai-CO9r1aeU.js} +1 -1
  7. package/dist/assets/{agent-panel-f0L3fZhF.js → agent-panel-BdmlpLAM.js} +1 -1
  8. package/dist/assets/{ai-model-dropdown-8G3RZw6w.js → ai-model-dropdown-DssbNRjD.js} +1 -1
  9. package/dist/assets/{any-language-editor-BUGcoAsy.js → any-language-editor-BSgo2DDX.js} +1 -1
  10. package/dist/assets/{app-config-button-Vtv3-4qO.js → app-config-button-D59ABmDW.js} +1 -1
  11. package/dist/assets/{architectureDiagram-5GKGNRK7-KCzfyuLz.js → architectureDiagram-5GKGNRK7-BEm-4n9c.js} +1 -1
  12. package/dist/assets/{blockDiagram-I7D4REHJ-Bh4a9Uit.js → blockDiagram-I7D4REHJ-BUrZSq9L.js} +1 -1
  13. package/dist/assets/{cache-panel-B4KmMDKe.js → cache-panel-B_iCype9.js} +1 -1
  14. package/dist/assets/{chat-display-BuvLDWsS.js → chat-display-Bm59UeMA.js} +1 -1
  15. package/dist/assets/{chat-panel-Ca_yEWgH.js → chat-panel-dNw4kuh0.js} +1 -1
  16. package/dist/assets/{chat-ui-LpqYylmY.js → chat-ui-CGCvNIwk.js} +1 -1
  17. package/dist/assets/{chunk-IMKFNOWR-BOe730m-.js → chunk-IMKFNOWR-R18opolo.js} +1 -1
  18. package/dist/assets/{chunk-SHT3W25Y-CnkGlGWz.js → chunk-SHT3W25Y-Uvq3PjtN.js} +1 -1
  19. package/dist/assets/{chunk-SVP7TREG-CJoSyWpF.js → chunk-SVP7TREG-Bj3YdeMC.js} +1 -1
  20. package/dist/assets/{chunk-TICWLB2K-i8qWzFVS.js → chunk-TICWLB2K-CVMtVrv_.js} +1 -1
  21. package/dist/assets/{classDiagram-ZZMXUADV-CJeFRXIv.js → classDiagram-ZZMXUADV-CJOLUhac.js} +1 -1
  22. package/dist/assets/{classDiagram-v2-VYDZK3BY-CJeFRXIv.js → classDiagram-v2-VYDZK3BY-CJOLUhac.js} +1 -1
  23. package/dist/assets/{code-visibility-B1uPwsV_.js → code-visibility-DNaloa5q.js} +1 -1
  24. package/dist/assets/{command-palette-3VHI_Zn-.js → command-palette-DhDquLDU.js} +1 -1
  25. package/dist/assets/{common-CkW66XKl.js → common-B8WjZmP1.js} +1 -1
  26. package/dist/assets/{components-CgLXIuIx.js → components-Ci2Qhpib.js} +1 -1
  27. package/dist/assets/{components-S8HMrIzn.js → components-DyEnpbnR.js} +1 -1
  28. package/dist/assets/{cynefinDiagram-5FMLGOSQ-CtaDnIMu.js → cynefinDiagram-5FMLGOSQ-CfhLsOyb.js} +1 -1
  29. package/dist/assets/{dagre-NrXVevn8.js → dagre-DY-YgOgc.js} +1 -1
  30. package/dist/assets/{dagre-GXQ25YYZ-c1VYIziP.js → dagre-GXQ25YYZ-1qhLpHHT.js} +1 -1
  31. package/dist/assets/{data-grid-overlay-editor-DSRW7Kut.js → data-grid-overlay-editor-BEB8m-Yc.js} +1 -1
  32. package/dist/assets/{dependency-graph-panel-B551oMpv.js → dependency-graph-panel-C2jGGxQW.js} +1 -1
  33. package/dist/assets/{diagram-S7CK7UJ4-DqOZpUvg.js → diagram-S7CK7UJ4-DowwJiYY.js} +1 -1
  34. package/dist/assets/{diagram-UQ7AKVKN-C5FLa5BP.js → diagram-UQ7AKVKN-D06Wmt-y.js} +1 -1
  35. package/dist/assets/{diagram-VX7I27RA-C11x_qxv.js → diagram-VX7I27RA-B9VQfjm3.js} +1 -1
  36. package/dist/assets/{diagram-Z3DM3KII-DTmHJEdb.js → diagram-Z3DM3KII-Cce4PKo9.js} +1 -1
  37. package/dist/assets/{documentation-panel-DZyABx3u.js → documentation-panel-Ca0yv6lR.js} +1 -1
  38. package/dist/assets/{ebnfDiagram-PWID7BFC-BERjo-QO.js → ebnfDiagram-PWID7BFC-DFadkxGy.js} +1 -1
  39. package/dist/assets/{edit-page-YjV5QuiF.js → edit-page-B0N4habE.js} +4 -4
  40. package/dist/assets/{erDiagram-RLTQ6QDP-CLaxJ9Nx.js → erDiagram-RLTQ6QDP-fYNCJUQY.js} +1 -1
  41. package/dist/assets/{error-panel-CYAgqocU.js → error-panel-lRme3YhX.js} +1 -1
  42. package/dist/assets/{feedback-button-BryDuCda.js → feedback-button-Cs8LDR5v.js} +1 -1
  43. package/dist/assets/{file-explorer-panel-C2BHQXnG.js → file-explorer-panel-Ds51K7-z.js} +1 -1
  44. package/dist/assets/{file-name-input-DFamvCEI.js → file-name-input-egYaX4eq.js} +1 -1
  45. package/dist/assets/{flowDiagram-HODETNUW-BIo2cMfZ.js → flowDiagram-HODETNUW-D5rn3RBz.js} +1 -1
  46. package/dist/assets/{gallery-page-6FjNLb2K.js → gallery-page-BOCnxP0Z.js} +1 -1
  47. package/dist/assets/{glide-data-editor-B7hTvwxl.js → glide-data-editor-BmLVbdtO.js} +4 -4
  48. package/dist/assets/{graphlib-DRqVESqZ.js → graphlib-DVwyptW9.js} +1 -1
  49. package/dist/assets/has-Dif16NS7.js +1 -0
  50. package/dist/assets/{home-page-DoM0lylR.js → home-page-XXqGXvf8.js} +1 -1
  51. package/dist/assets/{index-DUgerA4i.js → index-CERjop6F.js} +8 -8
  52. package/dist/assets/{infoDiagram-27XIBGKW-BjPzhD7z.js → infoDiagram-27XIBGKW-CY92q4XM.js} +1 -1
  53. package/dist/assets/{ishikawaDiagram-5VMMS53U-BsgWAUan.js → ishikawaDiagram-5VMMS53U-BN-OOAXD.js} +1 -1
  54. package/dist/assets/{kanban-definition-UXKFOSKX-BbFz76xc.js → kanban-definition-UXKFOSKX-Ci1h7Uqf.js} +1 -1
  55. package/dist/assets/{logs-panel-w5wJQQQl.js → logs-panel-6lVYXxhD.js} +1 -1
  56. package/dist/assets/{mermaid-Rq-qrJX-.js → mermaid-gFMN3MOE.js} +4 -4
  57. package/dist/assets/{mindmap-definition-YA3MSWOX-FLyXxd_r.js → mindmap-definition-YA3MSWOX-J38EDFhm.js} +1 -1
  58. package/dist/assets/{number-overlay-editor-D_DRYHem.js → number-overlay-editor-C0W4FOYL.js} +1 -1
  59. package/dist/assets/{outline-panel-2qHnFwb2.js → outline-panel-BbCEGCyr.js} +1 -1
  60. package/dist/assets/{packages-panel-1kXiKe65.js → packages-panel-DCR6XXnI.js} +1 -1
  61. package/dist/assets/{panels-Dtl3yI4T.js → panels-cRByVYYw.js} +6 -6
  62. package/dist/assets/{pegDiagram-XKGWAZYB-iq1r0G9S.js → pegDiagram-XKGWAZYB-COjth72j.js} +1 -1
  63. package/dist/assets/{pieDiagram-E7YTZNPT-72uzmec3.js → pieDiagram-E7YTZNPT-D7vYb7jN.js} +1 -1
  64. package/dist/assets/{process-output-B5FF-e40.js → process-output-DVBUvtzt.js} +1 -1
  65. package/dist/assets/{railroadDiagram-O6MQD6OU-BSZOMALK.js → railroadDiagram-O6MQD6OU-BTQ_y6-z.js} +1 -1
  66. package/dist/assets/{requirementDiagram-BXWQKSXE-BYOHjVDS.js → requirementDiagram-BXWQKSXE-CsB_QLVl.js} +1 -1
  67. package/dist/assets/{reveal-component-ChlwzPFi.js → reveal-component-Cx_-1zzD.js} +1 -1
  68. package/dist/assets/{run-page-DOESWIjk.js → run-page-BiJRXnCs.js} +1 -1
  69. package/dist/assets/{scratchpad-panel-CtYWu9UC.js → scratchpad-panel-BJXPUrVc.js} +1 -1
  70. package/dist/assets/{secrets-panel-CEdCTqEt.js → secrets-panel-BBjIT14I.js} +1 -1
  71. package/dist/assets/{sequenceDiagram-WJ2MYXX4-B2eZmj6C.js → sequenceDiagram-WJ2MYXX4-CUu54Fl8.js} +1 -1
  72. package/dist/assets/{session-panel-CdwTrjft.js → session-panel-DquHPGWI.js} +1 -1
  73. package/dist/assets/{snippets-panel-DSOmTAOj.js → snippets-panel-DM1np-Xn.js} +1 -1
  74. package/dist/assets/{stateDiagram-D77RDMKH-Dxjzxwy_.js → stateDiagram-D77RDMKH-CncNvrvk.js} +1 -1
  75. package/dist/assets/{stateDiagram-v2-MP3YSRHH-DiVxo_WD.js → stateDiagram-v2-MP3YSRHH-DTlqbhRA.js} +1 -1
  76. package/dist/assets/{swimlanes-42K2YHIH-Cu1H_MsS.js → swimlanes-42K2YHIH-DyZtSkGs.js} +1 -1
  77. package/dist/assets/{swimlanesDiagram-VR7AAH4N-CverMF1d.js → swimlanesDiagram-VR7AAH4N-BQd9GBpR.js} +1 -1
  78. package/dist/assets/{swiper-component-Dsu9hhfr.js → swiper-component--Yi8If6u.js} +1 -1
  79. package/dist/assets/{terminal-CY2G-VQ_.js → terminal-CdSnhsaL.js} +1 -1
  80. package/dist/assets/{timeline-definition-24CTP7MA-BTVwucN-.js → timeline-definition-24CTP7MA-CboXm-4q.js} +1 -1
  81. package/dist/assets/{tracing-8vY9-6Pe.js → tracing-D-8eZbW6.js} +1 -1
  82. package/dist/assets/{tracing-panel-ChY6mG0b.js → tracing-panel-BwCn7s5a.js} +2 -2
  83. package/dist/assets/{useCellActionButton-D9N-pQkE.js → useCellActionButton-BY7U2uOH.js} +1 -1
  84. package/dist/assets/{vega-component-CcwbASQP.js → vega-component-D476jsjJ.js} +1 -1
  85. package/dist/assets/{vega-embed-container-BAidu_l4.js → vega-embed-container-DJZHfFPC.js} +1 -1
  86. package/dist/assets/{vennDiagram-4TSXK5OY-_-2BMmjK.js → vennDiagram-4TSXK5OY-Q29zguI0.js} +1 -1
  87. package/dist/assets/{wardleyDiagram-VM6X3IG4-BewFANz3.js → wardleyDiagram-VM6X3IG4-0u8FNe0j.js} +1 -1
  88. package/dist/assets/{xychartDiagram-S5SC5T6Z-CIsN_xdf.js → xychartDiagram-S5SC5T6Z-BhTJ8ewD.js} +1 -1
  89. package/dist/index.html +3 -3
  90. package/package.json +1 -1
  91. package/src/components/editor/__tests__/dynamic-favicon.test.tsx +36 -2
  92. package/src/components/editor/cell/code/__tests__/rtc-editor-config.test.ts +50 -0
  93. package/src/components/editor/cell/code/cell-editor.tsx +41 -42
  94. package/src/components/editor/dynamic-favicon.tsx +17 -10
  95. package/src/plugins/impl/data-editor/__tests__/glide-data-editor.test.tsx +23 -18
  96. package/dist/assets/has-Cv16T6xA.js +0 -1
@@ -1,6 +1,6 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { historyField } from "@codemirror/commands";
3
- import { EditorState, StateEffect } from "@codemirror/state";
3
+ import { EditorState, type Extension, StateEffect } from "@codemirror/state";
4
4
  import { EditorView, ViewPlugin } from "@codemirror/view";
5
5
  import { useIntersectionObserver } from "@uidotdev/usehooks";
6
6
  import { useAtom, useAtomValue } from "jotai";
@@ -95,6 +95,21 @@ export interface CellEditorProps
95
95
  tooltipParentSelector?: string;
96
96
  }
97
97
 
98
+ export function composeRtcEditorConfig(
99
+ code: string,
100
+ extensions: Extension[],
101
+ rtc: ReturnType<typeof realTimeCollaboration> | undefined,
102
+ ): { code: string; extensions: Extension[] } {
103
+ if (!rtc) {
104
+ return { code, extensions };
105
+ }
106
+
107
+ return {
108
+ code: rtc.code,
109
+ extensions: [...extensions, rtc.extension],
110
+ };
111
+ }
112
+
98
113
  const CellEditorInternal = ({
99
114
  theme,
100
115
  showPlaceholder,
@@ -343,27 +358,31 @@ const CellEditorInternal = ({
343
358
  ]);
344
359
 
345
360
  const rtcEnabled = isRtcEnabled() && canUseRtc(cellId);
346
- const handleInitializeEditor = useEvent(() => {
347
- // If rtc is enabled, use collaborative editing
348
- if (rtcEnabled) {
349
- const rtc = realTimeCollaboration(
350
- cellId,
351
- (code) => {
352
- // It's not really a formatting change,
353
- // but this means it won't be marked as stale
354
- cellActions.updateCellCode({ cellId, code, formattingChange: true });
355
- },
356
- code,
357
- );
358
- extensions.push(rtc.extension);
359
- code = rtc.code;
361
+ const createEditorConfig = (initialCode?: string) => {
362
+ if (!rtcEnabled) {
363
+ return composeRtcEditorConfig(code, extensions, undefined);
360
364
  }
361
365
 
366
+ const rtc = realTimeCollaboration(
367
+ cellId,
368
+ (code) => {
369
+ // It's not really a formatting change,
370
+ // but this means it won't be marked as stale
371
+ cellActions.updateCellCode({ cellId, code, formattingChange: true });
372
+ },
373
+ initialCode,
374
+ );
375
+ return composeRtcEditorConfig(code, extensions, rtc);
376
+ };
377
+
378
+ const handleInitializeEditor = useEvent(() => {
379
+ const editorConfig = createEditorConfig(code);
380
+
362
381
  // Create a new editor
363
382
  const ev = new EditorView({
364
383
  state: EditorState.create({
365
- doc: code,
366
- extensions: extensions,
384
+ doc: editorConfig.code,
385
+ extensions: editorConfig.extensions,
367
386
  }),
368
387
  });
369
388
  setEditorView(ev);
@@ -377,19 +396,11 @@ const CellEditorInternal = ({
377
396
 
378
397
  const handleReconfigureEditor = useEvent(() => {
379
398
  invariant(editorViewRef.current !== null, "Editor view is not initialized");
380
- // If rtc is enabled, use collaborative editing
381
- if (rtcEnabled) {
382
- const rtc = realTimeCollaboration(cellId, (code) => {
383
- // It's not really a formatting change,
384
- // but this means it won't be marked as stale
385
- cellActions.updateCellCode({ cellId, code, formattingChange: true });
386
- });
387
- extensions.push(rtc.extension);
388
- }
399
+ const editorConfig = createEditorConfig();
389
400
 
390
401
  editorViewRef.current.dispatch({
391
402
  effects: [
392
- StateEffect.reconfigure.of([extensions]),
403
+ StateEffect.reconfigure.of([editorConfig.extensions]),
393
404
  reconfigureLanguageEffect(editorViewRef.current, {
394
405
  completionConfig: userConfig.completion,
395
406
  hotkeysProvider: new OverridingHotkeyProvider(
@@ -406,26 +417,14 @@ const CellEditorInternal = ({
406
417
 
407
418
  const handleDeserializeEditor = useEvent(() => {
408
419
  invariant(serializedEditorState, "Editor view is not initialized");
409
- if (rtcEnabled) {
410
- const rtc = realTimeCollaboration(
411
- cellId,
412
- (code) => {
413
- // It's not really a formatting change,
414
- // but this means it won't be marked as stale
415
- cellActions.updateCellCode({ cellId, code, formattingChange: true });
416
- },
417
- code,
418
- );
419
- extensions.push(rtc.extension);
420
- code = rtc.code;
421
- }
420
+ const editorConfig = createEditorConfig(code);
422
421
 
423
422
  const ev = new EditorView({
424
423
  state: EditorState.fromJSON(
425
424
  serializedEditorState,
426
425
  {
427
- doc: code,
428
- extensions: extensions,
426
+ doc: editorConfig.code,
427
+ extensions: editorConfig.extensions,
429
428
  },
430
429
  { history: historyField },
431
430
  ),
@@ -22,6 +22,19 @@ async function getFaviconUrl(key: FaviconKey): Promise<string> {
22
22
  return FAVICON_PATHS[key];
23
23
  }
24
24
 
25
+ function getOrCreateFavicon(): HTMLLinkElement {
26
+ const existingFavicon =
27
+ document.querySelector<HTMLLinkElement>("link[rel~='icon']");
28
+ if (existingFavicon) {
29
+ return existingFavicon;
30
+ }
31
+
32
+ const favicon = document.createElement("link");
33
+ favicon.rel = "icon";
34
+ document.head.append(favicon);
35
+ return favicon;
36
+ }
37
+
25
38
  interface Props {
26
39
  isRunning: boolean;
27
40
  }
@@ -64,16 +77,9 @@ export const DynamicFavicon = (props: Props) => {
64
77
  const { isRunning } = props;
65
78
  const errors = useCellErrors();
66
79
 
67
- let favicon: HTMLLinkElement | null =
68
- document.querySelector("link[rel~='icon']");
69
-
70
- if (!favicon) {
71
- favicon = document.createElement("link");
72
- favicon.rel = "icon";
73
- document.getElementsByTagName("head")[0].append(favicon);
74
- }
75
-
76
80
  useEffect(() => {
81
+ const favicon = getOrCreateFavicon();
82
+
77
83
  // No change on startup (autorun enabled or not)
78
84
  // Treat the default marimo favicon as "idle"
79
85
  if (!isRunning && favicon.href.includes("favicon")) {
@@ -105,7 +111,7 @@ export const DynamicFavicon = (props: Props) => {
105
111
  };
106
112
 
107
113
  updateFavicon();
108
- }, [isRunning, errors, favicon]);
114
+ }, [isRunning, errors]);
109
115
 
110
116
  // Send user notification when run has completed
111
117
  const prevRunning = usePrevious(isRunning) ?? isRunning;
@@ -118,6 +124,7 @@ export const DynamicFavicon = (props: Props) => {
118
124
  // When notebook comes back in focus, reset favicon
119
125
  useEventListener(window, "focus", async (_) => {
120
126
  if (!isRunning) {
127
+ const favicon = getOrCreateFavicon();
121
128
  favicon.href = await getFaviconUrl("idle");
122
129
  }
123
130
  });
@@ -6,31 +6,36 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
6
6
  import { TooltipProvider } from "@/components/ui/tooltip";
7
7
  import { GlideDataEditor } from "../glide-data-editor";
8
8
 
9
- const capturedDataEditor = vi.hoisted(() => ({
10
- ref: undefined as React.RefObject<HTMLElement> | undefined,
11
- onCellEdited: undefined as
12
- | ((cell: [number, number], value: { data: unknown }) => void)
13
- | undefined,
14
- onRowAppended: undefined as (() => void) | undefined,
15
- }));
9
+ interface MockDataEditorProps {
10
+ portalElementRef?: React.RefObject<HTMLElement>;
11
+ onCellEdited?: (cell: [number, number], value: { data: unknown }) => void;
12
+ onRowAppended?: () => void;
13
+ }
14
+
15
+ const captureDataEditorProps = vi.hoisted(() =>
16
+ vi.fn<(props: MockDataEditorProps) => void>(),
17
+ );
18
+
19
+ const capturedDataEditor = {
20
+ get ref() {
21
+ return captureDataEditorProps.mock.lastCall?.[0].portalElementRef;
22
+ },
23
+ get onCellEdited() {
24
+ return captureDataEditorProps.mock.lastCall?.[0].onCellEdited;
25
+ },
26
+ get onRowAppended() {
27
+ return captureDataEditorProps.mock.lastCall?.[0].onRowAppended;
28
+ },
29
+ };
16
30
 
17
31
  vi.mock("@glideapps/glide-data-grid", async () => {
18
32
  const React = await import("react");
19
33
  return {
20
34
  default: React.forwardRef(function MockDataEditor(
21
- props: {
22
- portalElementRef?: React.RefObject<HTMLElement>;
23
- onCellEdited?: (
24
- cell: [number, number],
25
- value: { data: unknown },
26
- ) => void;
27
- onRowAppended?: () => void;
28
- },
35
+ props: MockDataEditorProps,
29
36
  _ref: React.Ref<HTMLDivElement>,
30
37
  ) {
31
- capturedDataEditor.ref = props.portalElementRef;
32
- capturedDataEditor.onCellEdited = props.onCellEdited;
33
- capturedDataEditor.onRowAppended = props.onRowAppended;
38
+ captureDataEditorProps(props);
34
39
  return <div data-testid="mock-data-editor" />;
35
40
  }),
36
41
  CompactSelection: {
@@ -1 +0,0 @@
1
- import{Ga as e}from"./index-DUgerA4i.js";var t=Object.prototype.hasOwnProperty;function n(e,n){return e!=null&&t.call(e,n)}function r(t,r){return t!=null&&e(t,r,n)}export{r as t};