Skip to content

Commit 6c4db0c

Browse files
committed
fix: include all changed states in time-travel callback, not just dirty
Previously, dirty_states only included scopes with concrete unsaved work. This meant clean->dirty AND dirty->clean transitions were processed for LAST_CHANGED_FIELD tracking, but only dirty scopes were passed to callbacks. Now: - Track scopes_with_changes separately from scopes_needing_window - Include ANY scope with parameter changes in the callback - This ensures navigation works for dirty->clean transitions too
1 parent 068b78b commit 6c4db0c

1 file changed

Lines changed: 8 additions & 5 deletions

File tree

src/objectstate/object_state.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,8 @@ def time_travel_to_snapshot(cls, snapshot_id: str) -> bool:
938938
# PHASE 3: RESTORE state for all ObjectStates in snapshot
939939
# Track which scopes need window reopening (for PHASE 4)
940940
scopes_needing_window: Set[str] = set()
941+
# Track which scopes have any parameter changes (for navigation, even if now clean)
942+
scopes_with_changes: Set[str] = set()
941943

942944
for scope_key, state_snap in snapshot.all_states.items():
943945
state = cls._states.get(scope_key)
@@ -983,6 +985,7 @@ def time_travel_to_snapshot(cls, snapshot_id: str) -> bool:
983985
)
984986
state._last_changed_field = sorted_changes[0][0]
985987
state._last_changed_paths = {item[0] for item in changed_param_keys}
988+
scopes_with_changes.add(scope_key)
986989
logger.debug(f"⏱️ LAST_CHANGED_FIELD: {scope_key} field={state._last_changed_field} total_changes={len(changed_param_keys)}")
987990
else:
988991
state._last_changed_field = None
@@ -1026,16 +1029,16 @@ def time_travel_to_snapshot(cls, snapshot_id: str) -> bool:
10261029
# PHASE 4: Fire time-travel completion callbacks
10271030
# ALWAYS fire callbacks so subscribers can update their state (e.g., PlateManager
10281031
# needs to refresh orchestrators dict even when no dirty states).
1029-
# Pass dirty_states for states with concrete unsaved work.
1032+
# Pass states_with_changes for navigation (includes clean->dirty AND dirty->clean transitions)
10301033
if cls._on_time_travel_complete_callbacks:
1031-
dirty_states = [
1034+
states_with_changes = [
10321035
(scope_key, cls._states[scope_key])
1033-
for scope_key in scopes_needing_window
1036+
for scope_key in scopes_with_changes
10341037
if scope_key in cls._states
10351038
]
1036-
logger.debug(f"⏱️ TIME_TRAVEL: Firing {len(cls._on_time_travel_complete_callbacks)} callback(s) with {len(dirty_states)} dirty state(s)")
1039+
logger.debug(f"⏱️ TIME_TRAVEL: Firing {len(cls._on_time_travel_complete_callbacks)} callback(s) with {len(states_with_changes)} changed state(s)")
10371040
for callback in cls._on_time_travel_complete_callbacks:
1038-
callback(dirty_states, snapshot.triggering_scope)
1041+
callback(states_with_changes, snapshot.triggering_scope)
10391042
finally:
10401043
cls._in_time_travel = False
10411044

0 commit comments

Comments
 (0)