fix: keep tierlist saves consistent
Build and Deploy Next Preview / build-deploy (push) Successful in 2m52s

This commit is contained in:
2026-10-10 08:10:54 +00:00 Unverified
parent c8f9352fe9
commit 26a4331a08
15 changed files with 1051 additions and 76 deletions
+103
View File
@@ -0,0 +1,103 @@
/** Keeps canonical reads current across invalidations and version switches. */
export function reconcileCanonicalStates<T extends { ref: string }>(
canonical: T[],
current: T[],
protectedRefs: Set<string>,
): T[] {
return [
...canonical.filter((entry) => !protectedRefs.has(entry.ref)),
...current.filter((entry) => protectedRefs.has(entry.ref)),
];
}
export function reconcileScopedStateWrite<T extends { ref: string }>(
current: T[],
ref: string,
saved: T[],
): T[] {
return [
...current.filter((entry) => entry.ref !== ref),
...saved.filter((entry) => entry.ref === ref),
];
}
export class TierlistCanonicalFetch<T> {
private activeVersion: string | undefined;
private disposed = false;
private readonly requests = new Map<
string,
{ generation: number; invalidated: boolean; inFlight: boolean }
>();
activate(version: string) {
this.disposed = false;
this.activeVersion = version;
}
setVersion(version: string) {
if (this.activeVersion === version) return;
this.activeVersion = version;
const request = this.requests.get(version);
if (request?.inFlight) request.invalidated = true;
}
invalidate(version: string) {
const request = this.requests.get(version);
if (request?.inFlight) request.invalidated = true;
}
fetch(
version: string,
load: () => Promise<T>,
apply: (data: T) => void,
onError: (error: unknown) => void,
onSettled: () => void = () => {},
) {
if (this.disposed || this.activeVersion !== version) return;
let request = this.requests.get(version);
if (request?.inFlight) {
request.invalidated = true;
return;
}
request ??= { generation: 0, invalidated: false, inFlight: false };
request.inFlight = true;
request.invalidated = false;
const generation = ++request.generation;
this.requests.set(version, request);
void load()
.then(
(data) => {
if (
!this.disposed &&
this.activeVersion === version &&
request?.generation === generation &&
!request.invalidated
)
apply(data);
},
(error: unknown) => {
if (!this.disposed && this.activeVersion === version) onError(error);
},
)
.finally(() => {
if (request?.generation !== generation) return;
request.inFlight = false;
if (
this.disposed ||
this.activeVersion !== version ||
!request.invalidated
) {
if (this.activeVersion === version) onSettled();
return;
}
request.invalidated = false;
this.fetch(version, load, apply, onError, onSettled);
});
}
dispose() {
this.disposed = true;
this.requests.clear();
}
}