返回 DeepSeek-Reasonix
fileBrowserPreviewBindings.ts
根目录 / desktop / frontend / src / lib / fileBrowserPreviewBindings.ts
1 import { useEffect, useSyncExternalStore } from "react";
2
3 import type { BrowserTabView } from "./browserHost";
4 import type { FileResourceRef } from "./fileResource";
5
6 type Binding = { ref: FileResourceRef; url: string };
7
8 const bindings = new Map<string, Binding>();
9 const listeners = new Set<() => void>();
10 let revision = 0;
11
12 const subscribe = (listener: () => void) => {
13 listeners.add(listener);
14 return () => listeners.delete(listener);
15 };
16 const snapshot = () => revision;
17
18 export function bindFileBrowserPreview(tabId: string, ref: FileResourceRef, url: string): void {
19 bindings.set(tabId, { ref, url });
20 revision += 1;
21 listeners.forEach((listener) => listener());
22 }
23
24 export function useFileBrowserPreview(tab: BrowserTabView | undefined): Binding | undefined {
25 useSyncExternalStore(subscribe, snapshot, snapshot);
26 const binding = tab ? bindings.get(tab.id) : undefined;
27 const stale = Boolean(binding && tab?.url !== binding.url);
28 useEffect(() => {
29 if (stale && tab) bindings.delete(tab.id);
30 }, [stale, tab]);
31 return stale ? undefined : binding;
32 }
33
33 lines TYPESCRIPT