UNPKG

nodemod

Version:

A collection of node modules for The Really Project

84 lines 3.19 kB
import { delayUntil } from '../delay-until/index'; import { PollingMeasure } from './polling-measure'; function isPromise(r) { return 'function' === typeof (r.then); } const perf = globalThis.performance; export class PollingObserver { conditionCallback; onfinish; _forceStop = false; _records = []; _isPolling = false; constructor(conditionCallback) { this.conditionCallback = conditionCallback; if ('function' !== typeof (conditionCallback)) { throw new TypeError(`'conditionCallback' is not defined`); } } disconnect() { this._forceStop = true; if (!this._isPolling) this._records = []; } async observe(callback, options) { this._forceStop = false; const { interval, timeout } = options || {}; const isValidInterval = 'number' === typeof (interval) && interval > 0; const obsTimeout = 'number' === typeof (timeout) ? +timeout : -1; const obsInterval = isValidInterval ? +interval : 100; const isInfinitePolling = obsTimeout < 1; const records = this._records; const onfinishCallback = this.onfinish; const conditionCallback = this.conditionCallback; const loop = true; let totalTime = 0; let value = void 0; let i = 0; let status = 'finish'; let result = {}; try { polling: while (loop) { if (this._forceStop) break polling; this._isPolling = true; const conditionResult = conditionCallback(value, records, this); const didConditionMeet = isPromise(conditionResult) ? await conditionResult : conditionResult; const didTimeout = isInfinitePolling ? false : totalTime >= obsTimeout; if (didTimeout || didConditionMeet) { status = didTimeout ? 'timeout' : status; break polling; } const startAt = perf.now(); const r = callback(); value = isPromise(r) ? await r : r; const endAt = perf.now(); const duration = endAt - startAt; const timeLeft = isValidInterval ? obsInterval - duration : 0; records.push(new PollingMeasure(`polling:${i}`, duration, startAt)); totalTime += (duration > obsInterval ? duration : obsInterval); i += 1; if (timeLeft > 0) await delayUntil(timeLeft); } result = { status, value }; } catch (e) { result = { status: 'error', reason: e }; } finally { const recordsSlice = records.slice(); if (this._forceStop) this._records = []; this._isPolling = this._forceStop = false; if ('function' === typeof (onfinishCallback)) { onfinishCallback(result, recordsSlice, this); } } } takeRecords() { return this._records; } } //# sourceMappingURL=polling-observer.js.map