- switch main document flow toward leptos tiptap island host and generated runtime assets - align page aggregate loading, page head single-source updates, and AI tool result recovery - add tests and smoke scripts for title sync, AI route recovery, and editor host cutover
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { useMemo } from "react";
|
|
import type { SidebarInitialData } from "@/components/sidebar/types";
|
|
import {
|
|
buildSidebarDataSyncKey,
|
|
getSidebarDataFreshness,
|
|
} from "@/components/sidebar/sidebar-sync";
|
|
|
|
export type PreferredSidebarSnapshotSource = "initial" | "query" | "tree_stream";
|
|
|
|
export function usePreferredSidebarSnapshot(input: {
|
|
initialData: SidebarInitialData;
|
|
sidebarQueryData: SidebarInitialData | null;
|
|
treeStreamData: SidebarInitialData | null;
|
|
}) {
|
|
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]);
|
|
const queryFreshness = useMemo(
|
|
() => (input.sidebarQueryData ? getSidebarDataFreshness(input.sidebarQueryData) : Number.NEGATIVE_INFINITY),
|
|
[input.sidebarQueryData],
|
|
);
|
|
const treeStreamFreshness = useMemo(
|
|
() => (input.treeStreamData ? getSidebarDataFreshness(input.treeStreamData) : Number.NEGATIVE_INFINITY),
|
|
[input.treeStreamData],
|
|
);
|
|
|
|
const source = useMemo<PreferredSidebarSnapshotSource>(() => {
|
|
if (input.treeStreamData && input.sidebarQueryData) {
|
|
if (treeStreamSyncKey === querySyncKey) {
|
|
return "tree_stream";
|
|
}
|
|
return queryFreshness > treeStreamFreshness ? "query" : "tree_stream";
|
|
}
|
|
if (input.treeStreamData) {
|
|
return "tree_stream";
|
|
}
|
|
if (input.sidebarQueryData) {
|
|
return "query";
|
|
}
|
|
return "initial";
|
|
}, [
|
|
input.sidebarQueryData,
|
|
input.treeStreamData,
|
|
queryFreshness,
|
|
querySyncKey,
|
|
treeStreamFreshness,
|
|
treeStreamSyncKey,
|
|
]);
|
|
|
|
const data =
|
|
source === "tree_stream" && input.treeStreamData
|
|
? input.treeStreamData
|
|
: source === "query" && input.sidebarQueryData
|
|
? input.sidebarQueryData
|
|
: input.treeStreamData ?? input.sidebarQueryData ?? input.initialData;
|
|
const syncKey =
|
|
source === "tree_stream"
|
|
? treeStreamSyncKey ?? initialSyncKey
|
|
: source === "query"
|
|
? querySyncKey ?? initialSyncKey
|
|
: initialSyncKey;
|
|
|
|
return useMemo(
|
|
() => ({
|
|
data,
|
|
source,
|
|
syncKey,
|
|
}),
|
|
[data, source, syncKey],
|
|
);
|
|
}
|