mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 17:52:49 +00:00
* feat(app): show recent commit history in explorer * fix(app): keep recent commit history accurate * fix(app): include merged commits in recent history * perf(app): bound recent commit classification * fix(app): refresh recent commits on Git updates
135 lines
3.7 KiB
TypeScript
135 lines
3.7 KiB
TypeScript
import type { Query, QueryClient } from "@tanstack/react-query";
|
|
import { prPanePipelineQueryKind, prPaneTimelineQueryKind } from "./pull-request-panel/query-keys";
|
|
|
|
interface CheckoutQueryIdentity {
|
|
serverId: string;
|
|
cwd: string;
|
|
}
|
|
|
|
interface CheckoutQueryScope {
|
|
serverId: string;
|
|
cwd?: string;
|
|
}
|
|
|
|
type CheckoutQueryKey = readonly unknown[];
|
|
|
|
// A commit's file diff is immutable for a given sha+path, so every consumer
|
|
// can share the same long-lived cache policy.
|
|
export const COMMIT_FILE_DIFF_STALE_TIME = 5 * 60_000;
|
|
|
|
export function checkoutStatusQueryKey(serverId: string, cwd: string) {
|
|
return ["checkoutStatus", serverId, cwd] as const;
|
|
}
|
|
|
|
export function checkoutDiffQueryKey(
|
|
serverId: string,
|
|
cwd: string,
|
|
mode: "uncommitted" | "base",
|
|
baseRef?: string,
|
|
ignoreWhitespace?: boolean,
|
|
) {
|
|
return ["checkoutDiff", serverId, cwd, mode, baseRef ?? "", ignoreWhitespace === true] as const;
|
|
}
|
|
|
|
export function checkoutPrStatusQueryKey(serverId: string, cwd: string) {
|
|
return ["checkoutPrStatus", serverId, cwd] as const;
|
|
}
|
|
|
|
export function checkoutCommitsQueryKey(serverId: string, cwd: string) {
|
|
return ["checkoutCommits", serverId, cwd] as const;
|
|
}
|
|
|
|
export function checkoutCommitFileDiffQueryKey(
|
|
serverId: string,
|
|
cwd: string,
|
|
sha: string,
|
|
path: string,
|
|
) {
|
|
return ["checkoutCommitFileDiff", serverId, cwd, sha, path] as const;
|
|
}
|
|
|
|
export async function invalidateCheckoutGitQueriesForClient(
|
|
queryClient: QueryClient,
|
|
identity: CheckoutQueryIdentity,
|
|
) {
|
|
await Promise.all([
|
|
queryClient.invalidateQueries({
|
|
queryKey: checkoutStatusQueryKey(identity.serverId, identity.cwd),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate("checkoutDiff", identity),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate("checkoutPrStatus", identity),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
queryKey: checkoutCommitsQueryKey(identity.serverId, identity.cwd),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate(prPaneTimelineQueryKind, identity),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate(prPanePipelineQueryKind, identity),
|
|
}),
|
|
]);
|
|
}
|
|
|
|
// checkoutDiff is excluded: diff queries are subscription-fed (queryFn: skipToken) and
|
|
// receive a fresh snapshot on every resubscribe, so invalidation cannot and need not
|
|
// refetch them.
|
|
export async function invalidateCheckoutGitQueriesForServer(
|
|
queryClient: QueryClient,
|
|
serverId: string,
|
|
) {
|
|
const kinds = [
|
|
"checkoutStatus",
|
|
"checkoutPrStatus",
|
|
"checkoutCommits",
|
|
prPaneTimelineQueryKind,
|
|
prPanePipelineQueryKind,
|
|
];
|
|
await Promise.all(
|
|
kinds.map((kind) =>
|
|
queryClient.invalidateQueries({ predicate: checkoutQueryPredicate(kind, { serverId }) }),
|
|
),
|
|
);
|
|
}
|
|
|
|
export async function invalidatePrPaneTimelineForCheckout(
|
|
queryClient: QueryClient,
|
|
identity: CheckoutQueryIdentity,
|
|
) {
|
|
await Promise.all([
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate(prPaneTimelineQueryKind, identity),
|
|
}),
|
|
queryClient.invalidateQueries({
|
|
predicate: checkoutQueryPredicate(prPanePipelineQueryKind, identity),
|
|
}),
|
|
]);
|
|
}
|
|
|
|
function checkoutQueryPredicate(
|
|
queryKind: CheckoutQueryKey[0],
|
|
scope: CheckoutQueryScope,
|
|
): (query: Query) => boolean {
|
|
return (query) => {
|
|
const key = query.queryKey;
|
|
return (
|
|
isCheckoutQueryKey(key) &&
|
|
key[0] === queryKind &&
|
|
key[1] === scope.serverId &&
|
|
(scope.cwd === undefined || key[2] === scope.cwd)
|
|
);
|
|
};
|
|
}
|
|
|
|
function isCheckoutQueryKey(key: readonly unknown[]): key is CheckoutQueryKey {
|
|
return (
|
|
key.length >= 3 &&
|
|
typeof key[0] === "string" &&
|
|
typeof key[1] === "string" &&
|
|
typeof key[2] === "string"
|
|
);
|
|
}
|