UNPKG

3.97 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5async function delayUntil(delay = 0) {
6 return new Promise((yay) => {
7 const delayNum = 'number' === typeof (delay) ? +delay : 0;
8 if (delayNum < 1)
9 yay();
10 else
11 setTimeout(yay, delay);
12 });
13}
14
15async function globalPerformance() {
16 return ('undefined' !== typeof (window) ? window : global).performance;
17}
18
19class PollingMeasure {
20 constructor(name, duration, startTime) {
21 this.name = name;
22 this.duration = duration;
23 this.startTime = startTime;
24 this.entryType = 'polling-measure';
25 }
26 toJSON() {
27 return {
28 duration: this.duration,
29 entryType: this.entryType,
30 name: this.name,
31 startTime: this.startTime,
32 };
33 }
34}
35
36function isPromise(r) {
37 return 'function' === typeof (r.then);
38}
39class PollingObserver {
40 constructor(conditionCallback) {
41 this.conditionCallback = conditionCallback;
42 this._forceStop = false;
43 this._records = [];
44 this._isPolling = false;
45 if ('function' !== typeof (conditionCallback)) {
46 throw new TypeError(`'conditionCallback' is not defined`);
47 }
48 }
49 disconnect() {
50 this._forceStop = true;
51 if (!this._isPolling)
52 this._records = [];
53 }
54 async observe(callback, options) {
55 this._forceStop = false;
56 const { interval, timeout } = options || {};
57 const isValidInterval = 'number' === typeof (interval) && interval > 0;
58 const obsTimeout = 'number' === typeof (timeout) ? +timeout : -1;
59 const obsInterval = isValidInterval ? +interval : -1;
60 const perf = await globalPerformance();
61 const isInfinitePolling = obsTimeout < 1;
62 const records = this._records;
63 const onfinishCallback = this.onfinish;
64 const conditionCallback = this.conditionCallback;
65 let totalTime = 0;
66 let value = void 0;
67 let i = 0;
68 let status = 'finish';
69 let result = {};
70 try {
71 polling: while (true) {
72 if (this._forceStop)
73 break polling;
74 this._isPolling = true;
75 const conditionResult = conditionCallback(value, records, this);
76 const didConditionMeet = isPromise(conditionResult) ?
77 await conditionResult : conditionResult;
78 const didTimeout = isInfinitePolling ? false : totalTime >= obsTimeout;
79 if (didTimeout || didConditionMeet) {
80 status = didTimeout ? 'timeout' : status;
81 break polling;
82 }
83 const startAt = perf.now();
84 const r = callback();
85 value = isPromise(r) ? await r : r;
86 const endAt = perf.now();
87 const duration = endAt - startAt;
88 const timeLeft = isValidInterval ? obsInterval - duration : 0;
89 records.push(new PollingMeasure(`polling:${i}`, duration, startAt));
90 totalTime += (duration > obsInterval ? duration : obsInterval);
91 i += 1;
92 if (timeLeft > 0)
93 await delayUntil(timeLeft);
94 }
95 result = { status, value };
96 }
97 catch (e) {
98 result = { status: 'error', reason: e };
99 }
100 finally {
101 const recordsSlice = records.slice();
102 if (this._forceStop)
103 this._records = [];
104 this._isPolling = this._forceStop = false;
105 if ('function' === typeof (onfinishCallback)) {
106 onfinishCallback(result, recordsSlice, this);
107 }
108 }
109 }
110 takeRecords() {
111 return this._records;
112 }
113}
114
115exports.PollingObserver = PollingObserver;
116exports.default = PollingObserver;
117//# sourceMappingURL=index.js.map