diff --git a/src/background/undo.ts b/src/background/undo.ts index ee77244..0eaf1f2 100644 --- a/src/background/undo.ts +++ b/src/background/undo.ts @@ -139,28 +139,51 @@ export function popUndoIfKind( // ---- Utilities ----------------------------------------------------------- -/** Walk all spaces to find the windowId that owns a given folderId. */ -export function findWindowIdForFolder( +const folderWindowIdCache = new WeakMap< + Awaited>, + Map +>() + +function getFolderWindowIdMap( store: Awaited>, - folderId: FolderId, -): number | undefined { - // BFS from every space root. - for (const sp of Object.values(store.spaces)) { +): Map { + let map = folderWindowIdCache.get(store) + if (!map) { + map = new Map() + const stack: { id: FolderId; windowId: number }[] = [] + + for (const sp of Object.values(store.spaces)) { + stack.push({ id: sp.rootFolderId, windowId: sp.windowId }) + } + const visited = new Set() - const queue: FolderId[] = [sp.rootFolderId] - while (queue.length) { - const id = queue.shift()! - if (visited.has(id)) continue - visited.add(id) - if (id === folderId) return sp.windowId - const f = store.folders[id] + while (stack.length) { + const curr = stack.pop()! + if (visited.has(curr.id)) continue + visited.add(curr.id) + + map.set(curr.id, curr.windowId) + + const f = store.folders[curr.id] if (!f) continue + for (const it of f.items) { - if (it.kind === 'folder') queue.push(it.folderId) + if (it.kind === 'folder') { + stack.push({ id: it.folderId, windowId: curr.windowId }) + } } } + folderWindowIdCache.set(store, map) } - return undefined + return map +} + +/** Walk all spaces to find the windowId that owns a given folderId. */ +export function findWindowIdForFolder( + store: Awaited>, + folderId: FolderId, +): number | undefined { + return getFolderWindowIdMap(store).get(folderId) } /** Walk all spaces to find the windowId that owns a given ItemRef. */