mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
fix(documents): cancel a layout read in flight before flipping the switch
A first read of the vault layout that was still running when the switch was flipped landed afterwards and painted the old layout until the save answered, so the switch jumped back for a moment.
This commit is contained in:
1 parent
7525d2ed00
commit
dd76b434c4
2 files changed
+42
No files matched your search
@@ -72,6 +72,41 @@ describe("runSetDocumentsLayout", () => {
|
||||
await run;
|
||||
});
|
||||
|
||||
it("is not undone by a first read still in flight", async () => {
|
||||
const queryClient = new QueryClient();
|
||||
let answerRead: (value: DocumentsLayout) => void = () => {};
|
||||
const read = queryClient
|
||||
.fetchQuery({
|
||||
queryKey: key,
|
||||
queryFn: () =>
|
||||
new Promise<DocumentsLayout>((resolve) => {
|
||||
answerRead = resolve;
|
||||
}),
|
||||
})
|
||||
.catch(() => undefined);
|
||||
let settle: (value: DocumentsLayout) => void = () => {};
|
||||
vi.mocked(apiPut).mockReturnValue(
|
||||
new Promise<DocumentsLayout>((resolve) => {
|
||||
settle = resolve;
|
||||
}),
|
||||
);
|
||||
|
||||
const run = runSetDocumentsLayout({
|
||||
patch: { view: "list" },
|
||||
queryClient,
|
||||
t,
|
||||
});
|
||||
// The read answers with the stored layout while the save is pending.
|
||||
answerRead(STORED);
|
||||
await read;
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
expect(queryClient.getQueryData<DocumentsLayout>(key)?.view).toBe("list");
|
||||
|
||||
settle({ ...STORED, view: "list" });
|
||||
await run;
|
||||
expect(queryClient.getQueryData<DocumentsLayout>(key)?.view).toBe("list");
|
||||
});
|
||||
|
||||
it("rolls back and says so when the save fails", async () => {
|
||||
const queryClient = new QueryClient();
|
||||
queryClient.setQueryData(key, STORED);
|
||||
|
||||
@@ -40,6 +40,13 @@ export async function runSetDocumentsLayout(deps: {
|
||||
}): Promise<void> {
|
||||
const { patch, queryClient, t } = deps;
|
||||
const key = queryKeys.documentsLayout();
|
||||
// A read still in flight (the first GET) would land after the flip and
|
||||
// paint the old layout until the PUT answered. Cancel it first; only then
|
||||
// is the flip safe, because a cancelled fetch reverts the cache as it
|
||||
// settles. Without one in flight the flip stays synchronous.
|
||||
if (queryClient.isFetching({ queryKey: key }) > 0) {
|
||||
await queryClient.cancelQueries({ queryKey: key });
|
||||
}
|
||||
const previous = queryClient.getQueryData<DocumentsLayout>(key);
|
||||
queryClient.setQueryData<DocumentsLayout>(key, {
|
||||
...(previous ?? DEFAULT_DOCUMENTS_LAYOUT),
|
||||
|
||||
Reference in new issue
Block a user