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

35.48% Statements 11/31
0% Branches 0/4
23.52% Functions 4/17
36.66% Lines 11/30

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                                213x 5x       5x 3x         213x             213x                                       213x 5x 5x 5x       213x                                        
import type { TRPCQueryInput, TRPCQueryOutput } from "~app/trpc";
import type { ReceiptPageEntry } from "~app/trpc-types";
import type { ReceiptId } from "~db/ids";
 
import type { ControllerContext, ControllerWith, UpdateFn } from "../../types";
import {
	applyUpdateFnWithRevert,
	getAllInputs,
	getUpdatedData,
} from "../utils";
 
type Controller = ControllerWith<{
	procedure: ControllerContext["trpc"]["receipts"]["getPaged"];
}>;
type Input = TRPCQueryInput<"receipts.getPaged">;
 
const invalidate = ({ queryClient, procedure }: Controller) => {
	const inputs = getAllInputs<"receipts.getPaged">(
		queryClient,
		procedure.queryKey(),
	);
	return inputs.map((input) =>
		queryClient.invalidateQueries(procedure.queryFilter(input)),
	);
};
 
const updatePage =
	({ queryClient, procedure }: Controller, input: Input) =>
	(updater: UpdateFn<TRPCQueryOutput<"receipts.getPaged">>) =>
		queryClient.setQueryData(procedure.queryKey(input), (result) =>
			getUpdatedData(result, updater),
		);
 
const updatePages =
	(controller: Controller) =>
	(updater: UpdateFn<ReceiptPageEntry[], ReceiptPageEntry[], Input>) => {
		const inputs = getAllInputs<"receipts.getPaged">(
			controller.queryClient,
			controller.procedure.queryKey(),
		);
		for (const input of inputs) {
			updatePage(
				controller,
				input,
			)((page) => {
				const nextItems = updater(page.items, input);
				if (nextItems === page.items) {
					return page;
				}
				return { ...page, items: nextItems };
			});
		}
	};
 
export const getController = ({ queryClient, trpc }: ControllerContext) => {
	const controller = { queryClient, procedure: trpc.receipts.getPaged };
	return {
		invalidate: () => invalidate(controller),
	};
};
 
export const getRevertController = ({
	queryClient,
	trpc,
}: ControllerContext) => {
	const controller = { queryClient, procedure: trpc.receipts.getPaged };
	return {
		remove: (receiptId: ReceiptId) =>
			applyUpdateFnWithRevert(
				updatePages(controller),
				(items) =>
					items.some((item) => item.id === receiptId)
						? items.filter((item) => item.id !== receiptId)
						: items,
				() => (items) => {
					void invalidate(controller);
					return items;
				},
			),
	};
};