Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 4x 4x 60x 60x 60x 375x 375x 375x 375x 375x 58x 317x 259x 317x 317x 58x 58x 58x 58x 58x 375x 375x 58x 58x 58x 58x 116x 116x 116x 116x 116x 116x 116x 60x | type Callback<T> = () => PromiseLike<T> interface Event<T> { getPromise?: Callback<T> resolve: (result: T | PromiseLike<T>) => void reject: (...args: unknown[]) => void number: number } export class LimiterError extends Error {} export function createLimiter<T = void>( interval: number, noLimitCount: number ) { let currentNumber = 0 let lastCompletedNumber = 0 let events: number[] = [] let timeout: number | undefined let lastEvent: Event<T> | undefined function limited(getPromise?: Callback<T>): PromiseLike<T> { return new Promise<T>((resolve, reject) => { currentNumber += 1 const event: Event<T> = { getPromise, resolve, reject, number: currentNumber, } removeOldEvents() if (events.length < noLimitCount) { execute(event) } else { if (lastEvent !== undefined) { lastEvent.reject(new LimiterError("rate limit exceeded")) } lastEvent = event if (timeout === undefined) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore timeout = setTimeout(() => { timeoutAction() }, interval) } } }) } function stop() { if (timeout !== undefined) { clearTimeout(timeout) } timeout = undefined } function removeOldEvents() { const t = new Date().getTime() - interval * noLimitCount events = events.filter(v => v >= t) } function timeoutAction() { if (lastEvent !== undefined) { execute(lastEvent) lastEvent = undefined stop() } } async function execute(event: Event<T>) { events.push(new Date().getTime()) if (event.getPromise !== undefined) { try { const result = await event.getPromise() if (event.number > lastCompletedNumber) { lastCompletedNumber = event.number event.resolve(result) } else E{ event.reject(new LimiterError("Got newer event")) } } catch (e) { event.reject(e) } } else E{ // @ts-expect-error no result given event.resolve() } } return { limited, } } |