seyfert/src/api/bucket.ts
David 017ccfc3bf
fix: github actions (#210)
* fix: github actions

* fix: pnpm version

* fix: github actions checkout

* fix: brackets in failure function

* fix: github actions

* fix: github actions

* fix: github actions

* fix: github actions

* fix: github actions

* fix: github actions

* fix: github actions

* fix: github actions

* chore: apply formatting

* fix: github actions

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-14 14:23:58 -04:00

79 lines
1.7 KiB
TypeScript

export class Bucket {
remaining: number;
reset = 0;
resetAfter = 0;
queue: {
next: (cb: () => void, resolve: (data: any) => void, reject: (err: unknown) => void) => any;
resolve: (data: any) => void;
reject: (err: unknown) => void;
}[] = [];
processing?: NodeJS.Timeout | boolean;
processingResetAfter?: NodeJS.Timeout | boolean;
last?: number;
constructor(public limit: number) {
this.remaining = this.limit;
}
process(override = false) {
if (!this.queue.length) {
if (this.processing) {
clearTimeout(this.processing as NodeJS.Timeout);
this.processing = false;
}
return;
}
if (this.processing && !override) {
return;
}
const now = Date.now();
if (!this.reset || this.reset < now) {
this.reset = now;
this.remaining = this.limit;
}
this.last = now;
if (this.remaining <= 0) {
this.processing = setTimeout(
() => {
this.processing = false;
this.process(true);
},
this.resetAfter ? 0.5 : Math.max(0, (this.reset || 0) - now) + 1,
);
return;
}
--this.remaining;
this.processing = true;
const shift = this.queue.shift()!;
shift.next(
() => {
if (this.queue.length > 0) {
this.process(true);
} else {
this.processing = false;
}
},
shift.resolve,
shift.reject,
);
}
push(func: this['queue'][number], unshift?: boolean) {
if (unshift) {
this.queue.unshift(func);
} else {
this.queue.push(func);
}
this.process();
}
triggerResetAfter() {
if (!this.processingResetAfter && this.resetAfter) {
this.processingResetAfter = setTimeout(() => {
this.remaining++;
this.processingResetAfter = undefined;
}, this.resetAfter * 1.5);
}
}
}