Skip to content

Commit e550919

Browse files
authored
Autosave only during code-mode (#9453)
1 parent 8e7d778 commit e550919

6 files changed

Lines changed: 29 additions & 11 deletions

File tree

marimo/_code_mode/_context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1587,7 +1587,7 @@ async def _apply_ops(
15871587
internal_ops=ops,
15881588
)
15891589
if doc_ops:
1590-
tx = Transaction(changes=tuple(doc_ops), source="kernel")
1590+
tx = Transaction(changes=tuple(doc_ops), source="code-mode")
15911591
# Apply to local snapshot so _cell_label can read names.
15921592
self._document.apply(tx)
15931593
self.notify(

marimo/_messaging/notebook/changes.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
from __future__ import annotations
55

6+
from typing import Literal
7+
68
import msgspec
79

810
from marimo._ast.cell import CellConfig
@@ -96,6 +98,8 @@ class SetConfig(msgspec.Struct, frozen=True, tag="set-config", rename="camel"):
9698
# Transaction
9799
# ------------------------------------------------------------------
98100

101+
TransactionSource = Literal["frontend", "kernel", "code-mode", "file-watch"]
102+
99103

100104
class Transaction(msgspec.Struct, frozen=True, rename="camel"):
101105
"""An atomic batch of changes applied to a NotebookDocument.
@@ -106,5 +110,5 @@ class Transaction(msgspec.Struct, frozen=True, rename="camel"):
106110
"""
107111

108112
changes: tuple[DocumentChange, ...]
109-
source: str
113+
source: TransactionSource
110114
version: int | None = None

marimo/_session/extensions/extensions.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from marimo import _loggers
2020
from marimo._cli.print import red
21+
from marimo._messaging.notebook.changes import TransactionSource
2122
from marimo._messaging.notebook.document import NotebookCell
2223
from marimo._messaging.notification import (
2324
AlertNotification,
@@ -260,7 +261,7 @@ def _on_kernel_message(self, session: Session, msg: KernelMessage) -> None:
260261
consider a middleware chain instead of inline dispatch.
261262
"""
262263
notif: KernelMessage | NotificationMessage = msg
263-
kernel_transaction_applied = False
264+
applied_source: TransactionSource | None = None
264265

265266
name = try_deserialize_kernel_notification_name(msg)
266267
if name == NotebookDocumentTransactionNotification.name:
@@ -273,24 +274,31 @@ def _on_kernel_message(self, session: Session, msg: KernelMessage) -> None:
273274
notif = NotebookDocumentTransactionNotification(
274275
transaction=applied
275276
)
276-
kernel_transaction_applied = applied.source == "kernel"
277+
applied_source = applied.source
277278
except Exception:
278279
LOGGER.warning(
279280
"Failed to decode/apply kernel document transaction"
280281
)
281282

282283
session.notify(notif, from_consumer_id=None)
283284

284-
if kernel_transaction_applied:
285-
self._maybe_autosave(session)
285+
if applied_source is not None:
286+
self._maybe_autosave(session, applied_source)
286287

287-
def _maybe_autosave(self, session: Session) -> None:
288-
"""Best-effort persistence of kernel-driven mutations to disk.
288+
def _maybe_autosave(
289+
self, session: Session, source: TransactionSource
290+
) -> None:
291+
"""Best-effort persistence of code-mode mutations to disk.
289292
293+
Only ``source="code-mode"`` transactions persist; ``"kernel"``
294+
bookkeeping (e.g. instantiation cell-order broadcasts) is skipped
295+
so opening or running a notebook never rewrites it on disk.
290296
Skipped in run mode and for unnamed notebooks. Failures surface as
291297
an ``AlertNotification`` toast; they never raise out of the
292298
interceptor.
293299
"""
300+
if source != "code-mode":
301+
return
294302
if self.kernel_manager.mode != SessionMode.EDIT:
295303
return
296304

packages/openapi/api.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5053,7 +5053,11 @@ components:
50535053
propertyName: type
50545054
type: array
50555055
source:
5056-
type: string
5056+
enum:
5057+
- code-mode
5058+
- file-watch
5059+
- frontend
5060+
- kernel
50575061
version:
50585062
anyOf:
50595063
- type: integer

packages/openapi/src/api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6431,7 +6431,8 @@ export interface components {
64316431
| components["schemas"]["SetName"]
64326432
| components["schemas"]["SetConfig"]
64336433
)[];
6434-
source: string;
6434+
/** @enum {unknown} */
6435+
source: "code-mode" | "file-watch" | "frontend" | "kernel";
64356436
/** @default null */
64366437
version?: number | null;
64376438
};

tests/_session/extensions/test_notification_listener_autosave.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
SetConfig,
1919
SetName,
2020
Transaction,
21+
TransactionSource,
2122
)
2223
from marimo._messaging.notebook.document import NotebookCell, NotebookDocument
2324
from marimo._messaging.notification import (
@@ -71,7 +72,7 @@ def _document_from(app_file_manager: AppFileManager) -> NotebookDocument:
7172

7273

7374
def _serialize_tx(
74-
*changes: DocumentChange, source: str = "kernel"
75+
*changes: DocumentChange, source: TransactionSource = "code-mode"
7576
) -> KernelMessage:
7677
return serialize_kernel_message(
7778
NotebookDocumentTransactionNotification(

0 commit comments

Comments
 (0)