nodemod
Version:
A collection of node modules for The Really Project
84 lines • 3.19 kB
JavaScript
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