From 3c3c99f521993985a424e0ea7079ce110cb0af61 Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Tue, 31 Mar 2026 11:39:50 +0200 Subject: [PATCH] Fix stale timelineStore.activeDocumentId when switching between loaded documents switchToDocument called loadDocument which returned early when a document was already in memory, skipping loadTimeline and leaving timelineStore.activeDocumentId pointing to the previous document. Store operations like duplicateStateAsChild then looked up state IDs in the wrong document's timeline, causing "state not found". Fix by adding setActiveDocument to TimelineActions and calling it from switchToDocument so both stores always stay in sync on tab switch. Co-Authored-By: Claude Sonnet 4.6 --- src/stores/timelineStore.ts | 4 ++++ src/stores/workspaceStore.test.ts | 1 + src/stores/workspaceStore.ts | 5 +++++ src/types/timeline.ts | 3 +++ 4 files changed, 13 insertions(+) diff --git a/src/stores/timelineStore.ts b/src/stores/timelineStore.ts index 8c4c857..ea79824 100644 --- a/src/stores/timelineStore.ts +++ b/src/stores/timelineStore.ts @@ -111,6 +111,10 @@ export const useTimelineStore = create( console.log(`Timeline initialized for document ${documentId}`); }, + setActiveDocument: (documentId: string) => { + set({ activeDocumentId: documentId }); + }, + loadTimeline: (documentId: string, timeline: Timeline) => { set((state) => { const newTimelines = new Map(state.timelines); diff --git a/src/stores/workspaceStore.test.ts b/src/stores/workspaceStore.test.ts index e133a6b..dde5e87 100644 --- a/src/stores/workspaceStore.test.ts +++ b/src/stores/workspaceStore.test.ts @@ -25,6 +25,7 @@ vi.mock("./timelineStore", () => ({ getState: () => ({ timelines: new Map(), loadTimeline: vi.fn(), + setActiveDocument: vi.fn(), clearTimeline: vi.fn(), }), }, diff --git a/src/stores/workspaceStore.ts b/src/stores/workspaceStore.ts index 1679816..bd45926 100644 --- a/src/stores/workspaceStore.ts +++ b/src/stores/workspaceStore.ts @@ -600,6 +600,11 @@ export const useWorkspaceStore = create((set, get) activeDocumentId: documentId, }; }); + + // Always sync timelineStore.activeDocumentId — loadDocument returns early + // when the document is already in memory, so loadTimeline is never called + // and timelineStore.activeDocumentId would remain stale. + useTimelineStore.getState().setActiveDocument(documentId); }); }, diff --git a/src/types/timeline.ts b/src/types/timeline.ts index 8d83034..85e63f4 100644 --- a/src/types/timeline.ts +++ b/src/types/timeline.ts @@ -66,6 +66,9 @@ export interface TimelineActions { // Load timeline from document loadTimeline: (documentId: string, timeline: Timeline) => void; + // Set active document without reloading timeline data (for switching between already-loaded documents) + setActiveDocument: (documentId: string) => void; + // Create new state createState: (label: string, description?: string, cloneFromCurrent?: boolean) => StateId;