Files
paseo/packages/app/src/utils/attempt-guard.ts
2026-03-21 20:22:15 +07:00

36 lines
818 B
TypeScript

export class AttemptCancelledError extends Error {
constructor(message = "Attempt cancelled") {
super(message);
this.name = "AttemptCancelledError";
}
}
/**
* Tiny helper for async lifecycles:
* - Call `next()` to start a new attempt and invalidate previous ones
* - Call `cancel()` to invalidate any in-flight attempt
* - Call `assertCurrent(id)` after awaits to enforce a single active attempt
*/
export class AttemptGuard {
private attemptId = 0;
public next(): number {
this.attemptId += 1;
return this.attemptId;
}
public cancel(): void {
this.attemptId += 1;
}
public isCurrent(id: number): boolean {
return id === this.attemptId;
}
public assertCurrent(id: number): void {
if (!this.isCurrent(id)) {
throw new AttemptCancelledError();
}
}
}