Compare commits

...
Author SHA1 Message Date
kristinhe 7f2d445181 fix(web): order concurrent sedimentation reads 2026-10-18 17:46:01 +08:00
3 changed files with 50 additions and 0 deletions

No files matched your search

@@ -18,6 +18,7 @@ import * as api from "./api";
import { saveConnectionPreferences } from "./connection-preferences";
import { resetConnectionReconcile } from "./connection-reconcile";
import { queryClient, resetClient } from "./query-client";
import { commitSedimentation } from "./sedimentation-state";
const {
summary,
@@ -700,6 +701,28 @@ it("shows a paused switch immediately even when task rows still say running", as
expect(screen.queryByText("新的对话正在整理")).toBeNull();
});
it("updates an already mounted home as soon as settings commits the switch receipt", async () => {
render(
<ApplicationsHome
imports={imports}
onManage={() => {}}
onMemories={() => {}}
onSettings={() => {}}
/>,
);
expect(await screen.findAllByText("整理中")).toHaveLength(2);
act(() => {
commitSedimentation({
enabled: false,
pending_retained: true,
imports_unaffected: true,
});
});
await waitFor(() => expect(screen.getAllByText("已暂停")).toHaveLength(2));
});
it("keeps the import-in-progress empty state stable without a progress link", async () => {
summary.mockResolvedValue({
memory_count: 0,
@@ -39,3 +39,23 @@ it("keeps a newer switch receipt when an older read lands later", async () => {
expect(await olderRead).toEqual(paused);
expect(queryClient.getQueryData(["sedimentation"])).toEqual(paused);
});
it("keeps the newest read when concurrent reads finish out of order", async () => {
let finishFirst: ((value: typeof enabled) => void) | undefined;
getSedimentation
.mockImplementationOnce(
() =>
new Promise<typeof enabled>((resolve) => {
finishFirst = resolve;
}),
)
.mockResolvedValueOnce(paused);
const first = refreshSedimentation();
const second = refreshSedimentation();
expect(await second).toEqual(paused);
finishFirst?.(enabled);
expect(await first).toEqual(paused);
expect(queryClient.getQueryData(["sedimentation"])).toEqual(paused);
});
@@ -11,8 +11,12 @@ queryClient.setQueryDefaults(SEDIMENTATION_KEY, {
});
let revision = 0;
let readsStarted = 0;
let readsLanded = 0;
onClientReset(() => {
revision = 0;
readsStarted = 0;
readsLanded = 0;
});
/**
@@ -20,11 +24,14 @@ onClientReset(() => {
* newer PUT receipt committed by the settings page.
*/
export async function refreshSedimentation(): Promise<SedimentationState> {
const order = ++readsStarted;
const startedAtRevision = revision;
const next = await getSedimentation();
const current =
queryClient.getQueryData<SedimentationState>(SEDIMENTATION_KEY);
if (startedAtRevision !== revision && current) return current;
if (order < readsLanded && current) return current;
readsLanded = order;
queryClient.setQueryData(SEDIMENTATION_KEY, next);
return next;
}