All files / packages/mutations/src/cache/debts get-peers-paged.ts

90% Statements 36/40
50% Branches 5/10
100% Functions 16/16
89.47% Lines 34/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103                            205x 1x 1x 1x       205x 8x 8x       8x 1x       1x 1x 1x   1x         205x         44x     8x   1x       2x         1x     1x       205x 12x 12x   11x 11x     11x       1x             205x       33x 33x   33x 33x     33x 33x        
import type { TRPCQueryInput, TRPCQueryOutput } from "~app/trpc";
import type { PeerId } from "~db/ids";
 
import type { ControllerContext, ControllerWith, UpdateFn } from "../../types";
import { applyWithRevert, getAllInputs, getUpdatedData } from "../utils";
 
type Controller = ControllerWith<{
	procedure: ControllerContext["trpc"]["debts"]["getPeersPaged"];
}>;
 
type Input = TRPCQueryInput<"debts.getPeersPaged">;
type Output = TRPCQueryOutput<"debts.getPeersPaged">;
 
const updatePage =
	({ queryClient, procedure }: Controller, input: Input) =>
	(updater: UpdateFn<Output>) =>
		queryClient.setQueryData(procedure.queryKey(input), (result) =>
			getUpdatedData(result, updater),
		);
 
const updatePages =
	(controller: Controller) =>
	(updater: UpdateFn<PeerId[], PeerId[], Input>) => {
		const inputs = getAllInputs<"debts.getPeersPaged">(
			controller.queryClient,
			controller.procedure.queryKey(),
		);
		for (const input of inputs) {
			updatePage(
				controller,
				input,
			)((page) => {
				const nextItems = updater(page.items, input);
				Eif (nextItems === page.items) {
					return page;
				}
				return { ...page, items: nextItems };
			});
		}
	};
 
const updatePeer = (
	{ queryClient, procedure }: Controller,
	allDebts: TRPCQueryOutput<"debts.getAllPeer"> | undefined,
	peerId: PeerId,
) => {
	Iif (!allDebts) {
		return;
	}
	return updatePages({ queryClient, procedure })((peerIds, input) => {
		// List with "showResolved" show every peer anyway
		Iif (input.filters?.showResolved) {
			return peerIds;
		}
		// If peer will have no debts - we should update all pages
		Iif (allDebts.items.every((debt) => debt.sum === 0)) {
			void queryClient.invalidateQueries(procedure.queryFilter(input));
		}
		// If peer will have debts and they're not on the page - they might be next time
		// We should invalidate query to probably add them in the list
		Iif (!peerIds.includes(peerId)) {
			void queryClient.invalidateQueries(procedure.queryFilter(input));
		}
		return peerIds;
	});
};
 
export const getController = ({ queryClient, trpc }: ControllerContext) => {
	const controller = { queryClient, procedure: trpc.debts.getPeersPaged };
	return {
		update: (peerId: PeerId) => {
			setTimeout(() => {
				const allDebts = queryClient.getQueryData(
					trpc.debts.getAllPeer.queryKey({ peerId }),
				);
				updatePeer(controller, allDebts, peerId);
			}, 0);
		},
		invalidate: () => {
			void queryClient.invalidateQueries(
				trpc.debts.getPeersPaged.queryFilter(),
			);
		},
	};
};
 
export const getRevertController = ({
	queryClient,
	trpc,
}: ControllerContext) => {
	const controller = { queryClient, procedure: trpc.debts.getPeersPaged };
	return {
		update: async (peerId: PeerId) => {
			await Promise.resolve();
			const allDebts = queryClient.getQueryData(
				trpc.debts.getAllPeer.queryKey({ peerId }),
			);
			const updatePeerBinded = () => updatePeer(controller, allDebts, peerId);
			return applyWithRevert(updatePeerBinded, updatePeerBinded);
		},
	};
};