39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { mergeDeltaRows, type DeltaDeletedItem } from "@govoplan/core-webui";
|
|
|
|
export type AdminDeltaResponse = {
|
|
deleted: DeltaDeletedItem[];
|
|
watermark?: string | null;
|
|
has_more: boolean;
|
|
full: boolean;
|
|
};
|
|
|
|
export async function loadDeltaRows<TItem, TResponse extends AdminDeltaResponse>(
|
|
current: TItem[],
|
|
key: string,
|
|
getDeltaWatermark: (key: string) => string | null,
|
|
setDeltaWatermark: (key: string, watermark: string | null | undefined) => void,
|
|
fetchDelta: (since: string | null) => Promise<TResponse>,
|
|
rowsFromResponse: (response: TResponse) => TItem[],
|
|
getKey: (item: TItem) => string,
|
|
deletedResourceType: string,
|
|
sort?: (left: TItem, right: TItem) => number
|
|
): Promise<TItem[]> {
|
|
let nextWatermark = getDeltaWatermark(key);
|
|
let merged = current;
|
|
let hasMore = false;
|
|
do {
|
|
const response = await fetchDelta(nextWatermark);
|
|
const rows = rowsFromResponse(response);
|
|
const continuingFullSnapshot = response.full && nextWatermark?.startsWith("full:");
|
|
merged = response.full
|
|
? continuingFullSnapshot
|
|
? mergeDeltaRows(merged, rows, [], getKey, { deletedResourceType, sort })
|
|
: rows
|
|
: mergeDeltaRows(merged, rows, response.deleted, getKey, { deletedResourceType, sort });
|
|
nextWatermark = response.watermark ?? null;
|
|
hasMore = response.has_more;
|
|
} while (hasMore);
|
|
setDeltaWatermark(key, nextWatermark);
|
|
return merged;
|
|
}
|