2026-04-22 05:57:06 +08:00
|
|
|
import { useMemo } from "react";
|
|
|
|
|
import type { SidebarInitialData } from "@/components/sidebar/types";
|
2026-05-14 05:52:08 +08:00
|
|
|
import { buildSidebarDataSyncKey, getSidebarDataFreshness } from "@/components/sidebar/sidebar-sync";
|
2026-04-22 05:57:06 +08:00
|
|
|
|
|
|
|
|
export type PreferredSidebarSnapshotSource = "initial" | "query" | "tree_stream";
|
|
|
|
|
|
|
|
|
|
export function usePreferredSidebarSnapshot(input: {
|
|
|
|
|
initialData: SidebarInitialData;
|
|
|
|
|
sidebarQueryData: SidebarInitialData | null;
|
|
|
|
|
treeStreamData: SidebarInitialData | null;
|
2026-04-24 06:10:18 +08:00
|
|
|
treeStreamStatus?: "idle" | "connecting" | "live" | "fallback";
|
2026-05-14 05:52:08 +08:00
|
|
|
treeStreamCursor?: string | null;
|
2026-04-22 05:57:06 +08:00
|
|
|
}) {
|
|
|
|
|
const querySyncKey = useMemo(
|
|
|
|
|
() => (input.sidebarQueryData ? buildSidebarDataSyncKey(input.sidebarQueryData) : null),
|
|
|
|
|
[input.sidebarQueryData],
|
|
|
|
|
);
|
|
|
|
|
const treeStreamSyncKey = useMemo(
|
|
|
|
|
() => (input.treeStreamData ? buildSidebarDataSyncKey(input.treeStreamData) : null),
|
|
|
|
|
[input.treeStreamData],
|
|
|
|
|
);
|
|
|
|
|
const initialSyncKey = useMemo(() => buildSidebarDataSyncKey(input.initialData), [input.initialData]);
|
2026-05-14 05:52:08 +08:00
|
|
|
const initialVersion = useMemo(() => getSidebarDataFreshness(input.initialData), [input.initialData]);
|
|
|
|
|
const queryVersion = useMemo(
|
|
|
|
|
() => (input.sidebarQueryData ? getSidebarDataFreshness(input.sidebarQueryData) : null),
|
|
|
|
|
[input.sidebarQueryData],
|
|
|
|
|
);
|
|
|
|
|
const treeStreamVersion = useMemo(
|
|
|
|
|
() => (input.treeStreamData ? getSidebarDataFreshness(input.treeStreamData) : null),
|
|
|
|
|
[input.treeStreamData],
|
|
|
|
|
);
|
2026-04-24 06:10:18 +08:00
|
|
|
const streamIsPreferred = input.treeStreamStatus !== "fallback";
|
2026-05-14 05:52:08 +08:00
|
|
|
|
|
|
|
|
const preferredVersion = Math.max(
|
|
|
|
|
initialVersion,
|
|
|
|
|
queryVersion ?? 0,
|
|
|
|
|
streamIsPreferred ? treeStreamVersion ?? 0 : 0,
|
|
|
|
|
);
|
|
|
|
|
const queryHasPreferredVersion = queryVersion != null && queryVersion >= preferredVersion;
|
|
|
|
|
const treeStreamHasPreferredVersion =
|
|
|
|
|
streamIsPreferred &&
|
|
|
|
|
input.treeStreamData != null &&
|
|
|
|
|
treeStreamVersion != null &&
|
|
|
|
|
treeStreamVersion >= preferredVersion;
|
2026-04-22 05:57:06 +08:00
|
|
|
|
|
|
|
|
const source = useMemo<PreferredSidebarSnapshotSource>(() => {
|
2026-05-14 06:51:10 +08:00
|
|
|
if (
|
|
|
|
|
queryHasPreferredVersion &&
|
|
|
|
|
(!treeStreamHasPreferredVersion || querySyncKey !== treeStreamSyncKey)
|
|
|
|
|
) {
|
|
|
|
|
return "query";
|
|
|
|
|
}
|
2026-05-14 05:52:08 +08:00
|
|
|
if (treeStreamHasPreferredVersion) {
|
2026-04-22 05:57:06 +08:00
|
|
|
return "tree_stream";
|
|
|
|
|
}
|
2026-05-14 05:52:08 +08:00
|
|
|
if (queryHasPreferredVersion) {
|
2026-04-22 05:57:06 +08:00
|
|
|
return "query";
|
|
|
|
|
}
|
|
|
|
|
return "initial";
|
|
|
|
|
}, [
|
2026-05-14 05:52:08 +08:00
|
|
|
queryHasPreferredVersion,
|
2026-05-14 06:51:10 +08:00
|
|
|
querySyncKey,
|
2026-05-14 05:52:08 +08:00
|
|
|
treeStreamHasPreferredVersion,
|
2026-05-14 06:51:10 +08:00
|
|
|
treeStreamSyncKey,
|
2026-04-22 05:57:06 +08:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
const data =
|
|
|
|
|
source === "tree_stream" && input.treeStreamData
|
|
|
|
|
? input.treeStreamData
|
|
|
|
|
: source === "query" && input.sidebarQueryData
|
|
|
|
|
? input.sidebarQueryData
|
2026-05-11 13:16:34 +08:00
|
|
|
: input.initialData;
|
2026-04-22 05:57:06 +08:00
|
|
|
const syncKey =
|
|
|
|
|
source === "tree_stream"
|
2026-04-24 06:10:18 +08:00
|
|
|
? treeStreamSyncKey ?? querySyncKey ?? initialSyncKey
|
2026-04-22 05:57:06 +08:00
|
|
|
: source === "query"
|
|
|
|
|
? querySyncKey ?? initialSyncKey
|
|
|
|
|
: initialSyncKey;
|
2026-05-14 05:52:08 +08:00
|
|
|
const version =
|
|
|
|
|
source === "tree_stream"
|
|
|
|
|
? treeStreamVersion ?? initialVersion
|
|
|
|
|
: source === "query"
|
|
|
|
|
? queryVersion ?? initialVersion
|
|
|
|
|
: initialVersion;
|
|
|
|
|
const cursor = source === "tree_stream" ? input.treeStreamCursor ?? null : null;
|
2026-04-22 05:57:06 +08:00
|
|
|
|
|
|
|
|
return useMemo(
|
|
|
|
|
() => ({
|
|
|
|
|
data,
|
|
|
|
|
source,
|
|
|
|
|
syncKey,
|
2026-05-14 05:52:08 +08:00
|
|
|
version,
|
|
|
|
|
cursor,
|
2026-04-22 05:57:06 +08:00
|
|
|
}),
|
2026-05-14 05:52:08 +08:00
|
|
|
[cursor, data, source, syncKey, version],
|
2026-04-22 05:57:06 +08:00
|
|
|
);
|
|
|
|
|
}
|