| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import {
- MAX_POLL_TIME_MS,
- POLL_INTERVAL_MS,
- STABLE_POLLS_THRESHOLD,
- } from '../config';
- export interface PollOptions {
- pollInterval?: number;
- maxPollTime?: number;
- stableThreshold?: number;
- signal?: AbortSignal;
- }
- export interface PollResult<T> {
- success: boolean;
- data?: T;
- timedOut?: boolean;
- aborted?: boolean;
- }
- /**
- * Generic polling utility that waits for a condition to be met.
- * Returns when the condition is satisfied or timeout/abort occurs.
- */
- export async function pollUntilStable<T>(
- fetchFn: () => Promise<T>,
- isStable: (current: T, previous: T | null, stableCount: number) => boolean,
- opts: PollOptions = {},
- ): Promise<PollResult<T>> {
- const pollInterval = opts.pollInterval ?? POLL_INTERVAL_MS;
- const maxPollTime = opts.maxPollTime ?? MAX_POLL_TIME_MS;
- const stableThreshold = opts.stableThreshold ?? STABLE_POLLS_THRESHOLD;
- const pollStart = Date.now();
- let previousData: T | null = null;
- let stablePolls = 0;
- while (Date.now() - pollStart < maxPollTime) {
- if (opts.signal?.aborted) {
- return { success: false, aborted: true };
- }
- await new Promise((r) => setTimeout(r, pollInterval));
- const currentData = await fetchFn();
- if (isStable(currentData, previousData, stablePolls)) {
- stablePolls++;
- if (stablePolls >= stableThreshold) {
- return { success: true, data: currentData };
- }
- } else {
- stablePolls = 0;
- }
- previousData = currentData;
- }
- return { success: false, timedOut: true, data: previousData ?? undefined };
- }
- /**
- * Simple delay utility
- */
- export function delay(ms: number): Promise<void> {
- return new Promise((r) => setTimeout(r, ms));
- }
|