@oscarpalmer/timer 0.37.0 → 0.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -13
- package/dist/constants.js +11 -13
- package/dist/delay.js +3 -3
- package/dist/get.js +2 -2
- package/dist/global.js +4 -4
- package/dist/index.js +4 -4
- package/dist/repeat.js +2 -2
- package/dist/timer.full.js +434 -449
- package/dist/wait.js +2 -2
- package/dist/when.js +11 -8
- package/dist/work.js +5 -5
- package/package.json +17 -20
- package/src/constants.ts +20 -14
- package/src/delay.ts +6 -7
- package/src/get.ts +3 -5
- package/src/global.ts +4 -9
- package/src/is.ts +8 -0
- package/src/models.ts +35 -40
- package/src/repeat.ts +6 -6
- package/src/timer.ts +4 -17
- package/src/wait.ts +2 -2
- package/src/when.ts +35 -31
- package/src/work.ts +17 -32
- package/types/constants.d.ts +12 -12
- package/types/delay.d.ts +3 -1
- package/types/is.d.ts +8 -0
- package/types/repeat.d.ts +3 -0
- package/types/when.d.ts +15 -1
- package/dist/constants.cjs +0 -53
- package/dist/delay.cjs +0 -15
- package/dist/get.cjs +0 -17
- package/dist/global.cjs +0 -15
- package/dist/index.cjs +0 -14
- package/dist/is.cjs +0 -20
- package/dist/models.cjs +0 -7
- package/dist/repeat.cjs +0 -18
- package/dist/rolldown_runtime.cjs +0 -21
- package/dist/timer.cjs +0 -68
- package/dist/wait.cjs +0 -18
- package/dist/when.cjs +0 -96
- package/dist/work.cjs +0 -82
package/dist/timer.full.js
CHANGED
|
@@ -1,83 +1,66 @@
|
|
|
1
1
|
function calculate$1() {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.slice(2, -2)
|
|
14
|
-
.reduce((first, second) => first + second, 0) /
|
|
15
|
-
(values.length - 4);
|
|
16
|
-
resolve(median);
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
requestAnimationFrame(step);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
requestAnimationFrame(step);
|
|
23
|
-
});
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
const values = [];
|
|
4
|
+
let last;
|
|
5
|
+
function step(now) {
|
|
6
|
+
if (last != null) values.push(now - last);
|
|
7
|
+
last = now;
|
|
8
|
+
if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
|
|
9
|
+
else requestAnimationFrame(step);
|
|
10
|
+
}
|
|
11
|
+
requestAnimationFrame(step);
|
|
12
|
+
});
|
|
24
13
|
}
|
|
25
|
-
//
|
|
26
|
-
const defaultTimeout = 30_000;
|
|
27
14
|
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
15
|
+
* Buffer value to use when evaluating if a specific time is within a certain range
|
|
16
|
+
*/
|
|
17
|
+
const BUFFER_INTERVAL = 5;
|
|
18
|
+
const DEFAULT_TIMEOUT = 3e4;
|
|
31
19
|
/**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
20
|
+
* Message to show when a when-timer is destroyed
|
|
21
|
+
*/
|
|
22
|
+
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
35
23
|
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
24
|
+
* Message to show when a when-timer is started
|
|
25
|
+
*/
|
|
26
|
+
const MESSAGE_STARTED = "Timer has already been started";
|
|
39
27
|
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
28
|
+
* A set of all active timers
|
|
29
|
+
*/
|
|
30
|
+
const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
|
|
43
31
|
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const TYPE_REPEAT =
|
|
48
|
-
const TYPE_WAIT =
|
|
49
|
-
const TYPE_WHEN =
|
|
50
|
-
const WORK_CONTINUE =
|
|
51
|
-
const WORK_PAUSE =
|
|
52
|
-
const WORK_RESTART =
|
|
53
|
-
const WORK_START =
|
|
54
|
-
const WORK_STOP =
|
|
55
|
-
//
|
|
32
|
+
* A set of timers that were paused due to the document being hidden
|
|
33
|
+
*/
|
|
34
|
+
const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
|
|
35
|
+
const TYPE_REPEAT = "repeat";
|
|
36
|
+
const TYPE_WAIT = "wait";
|
|
37
|
+
const TYPE_WHEN = "when";
|
|
38
|
+
const WORK_CONTINUE = "continue";
|
|
39
|
+
const WORK_PAUSE = "pause";
|
|
40
|
+
const WORK_RESTART = "restart";
|
|
41
|
+
const WORK_START = "start";
|
|
42
|
+
const WORK_STOP = "stop";
|
|
56
43
|
/**
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let
|
|
60
|
-
calculate$1().then(value => {
|
|
61
|
-
|
|
44
|
+
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
45
|
+
*/
|
|
46
|
+
let MILLISECONDS = 1e3 / 60;
|
|
47
|
+
calculate$1().then((value) => {
|
|
48
|
+
MILLISECONDS = value;
|
|
62
49
|
});
|
|
63
50
|
|
|
64
|
-
if (globalThis._oscarpalmer_timers == null) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return globalThis._oscarpalmer_timer_debug ? [...activeTimers] : [];
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
51
|
+
if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
52
|
+
return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
|
|
53
|
+
} });
|
|
71
54
|
/* istanbul ignore next */
|
|
72
|
-
document.addEventListener(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
document.addEventListener("visibilitychange", () => {
|
|
56
|
+
const from = document.hidden ? TIMERS_ACTIVE : TIMERS_HIDDEN;
|
|
57
|
+
const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
58
|
+
const to = document.hidden ? TIMERS_HIDDEN : TIMERS_ACTIVE;
|
|
59
|
+
for (const timer of from) {
|
|
60
|
+
timer[method]();
|
|
61
|
+
to.add(timer);
|
|
62
|
+
}
|
|
63
|
+
from.clear();
|
|
81
64
|
});
|
|
82
65
|
|
|
83
66
|
function calculate() {
|
|
@@ -87,446 +70,448 @@ function calculate() {
|
|
|
87
70
|
function step(now) {
|
|
88
71
|
if (last != null) values.push(now - last);
|
|
89
72
|
last = now;
|
|
90
|
-
if (values.length >=
|
|
91
|
-
|
|
92
|
-
resolve(median);
|
|
93
|
-
} else requestAnimationFrame(step);
|
|
73
|
+
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM));
|
|
74
|
+
else requestAnimationFrame(step);
|
|
94
75
|
}
|
|
95
76
|
requestAnimationFrame(step);
|
|
96
77
|
});
|
|
97
78
|
}
|
|
98
79
|
function noop() {}
|
|
80
|
+
var CALCULATION_TOTAL = 10;
|
|
81
|
+
var CALCULATION_TRIM = 4;
|
|
82
|
+
let milliseconds = 1e3 / 60;
|
|
99
83
|
calculate().then((value) => {
|
|
84
|
+
milliseconds = value;
|
|
100
85
|
});
|
|
101
86
|
|
|
87
|
+
var TYPED_ARRAYS = new Set([
|
|
88
|
+
Int8Array,
|
|
89
|
+
Uint8Array,
|
|
90
|
+
Uint8ClampedArray,
|
|
91
|
+
Int16Array,
|
|
92
|
+
Uint16Array,
|
|
93
|
+
Int32Array,
|
|
94
|
+
Uint32Array,
|
|
95
|
+
Float32Array,
|
|
96
|
+
Float64Array,
|
|
97
|
+
BigInt64Array,
|
|
98
|
+
BigUint64Array
|
|
99
|
+
]);
|
|
100
|
+
|
|
102
101
|
function getCallback(value) {
|
|
103
|
-
|
|
102
|
+
return typeof value === "function" ? value : noop;
|
|
104
103
|
}
|
|
105
104
|
function getValidTimeout(value) {
|
|
106
|
-
|
|
105
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
107
106
|
}
|
|
108
107
|
function getValidNumber(value, defaultValue) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
? value
|
|
112
|
-
: actualDefault;
|
|
108
|
+
const actualDefault = defaultValue ?? 0;
|
|
109
|
+
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
/**
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
* Create a delayed promise that resolves after a certain amount of time
|
|
114
|
+
* @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
|
|
115
|
+
* @returns A promise that resolves after the delay
|
|
116
|
+
*/
|
|
118
117
|
function delay(time) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
requestAnimationFrame(step);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
requestAnimationFrame(step);
|
|
133
|
-
});
|
|
118
|
+
return new Promise((resolve) => {
|
|
119
|
+
const interval = getValidNumber(time, MILLISECONDS);
|
|
120
|
+
let start;
|
|
121
|
+
function step(now) {
|
|
122
|
+
start ??= now;
|
|
123
|
+
if (interval === MILLISECONDS || now - start >= interval - BUFFER_INTERVAL) resolve();
|
|
124
|
+
else requestAnimationFrame(step);
|
|
125
|
+
}
|
|
126
|
+
requestAnimationFrame(step);
|
|
127
|
+
});
|
|
134
128
|
}
|
|
135
129
|
|
|
136
130
|
function is(names, value) {
|
|
137
|
-
|
|
131
|
+
return names.includes(value?.$timer);
|
|
138
132
|
}
|
|
139
133
|
/**
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
* Is the value a repeating timer?
|
|
135
|
+
* @param value Value to check
|
|
136
|
+
* @returns `true` if the value is a repeating timer
|
|
137
|
+
*/
|
|
142
138
|
function isRepeated(value) {
|
|
143
|
-
|
|
139
|
+
return is([TYPE_REPEAT], value);
|
|
144
140
|
}
|
|
145
141
|
/**
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
* Is the value a timer?
|
|
143
|
+
* @param value Value to check
|
|
144
|
+
* @returns `true` if the value is a timer
|
|
145
|
+
*/
|
|
148
146
|
function isTimer(value) {
|
|
149
|
-
|
|
147
|
+
return is([TYPE_REPEAT, TYPE_WAIT], value);
|
|
150
148
|
}
|
|
151
149
|
/**
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
* Is the value a waiting timer?
|
|
151
|
+
* @param value Value to check
|
|
152
|
+
* @returns `true` if the value is a waiting timer
|
|
153
|
+
*/
|
|
154
154
|
function isWaited(value) {
|
|
155
|
-
|
|
155
|
+
return is([TYPE_WAIT], value);
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
* Is the value a conditional timer?
|
|
159
|
+
* @param value Value to check
|
|
160
|
+
* @returns `true` if the value is a conditional timer
|
|
161
|
+
*/
|
|
160
162
|
function isWhen(value) {
|
|
161
|
-
|
|
163
|
+
return is([TYPE_WHEN], value) && typeof value.then === "function";
|
|
162
164
|
}
|
|
163
165
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
166
|
+
var TimerTrace = class extends Error {
|
|
167
|
+
constructor() {
|
|
168
|
+
super();
|
|
169
|
+
this.name = "TimerTrace";
|
|
170
|
+
}
|
|
171
|
+
};
|
|
170
172
|
|
|
171
173
|
function finish(timer, state, options, success) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
options.onAfter?.(success);
|
|
182
|
-
}
|
|
174
|
+
cancelAnimationFrame(state.frame);
|
|
175
|
+
TIMERS_ACTIVE.delete(timer.instance);
|
|
176
|
+
state.active = false;
|
|
177
|
+
state.elapsed = 0;
|
|
178
|
+
state.frame = void 0;
|
|
179
|
+
if (timer.type === TYPE_WAIT) state.callback();
|
|
180
|
+
else options.onAfter?.(success);
|
|
183
181
|
}
|
|
184
182
|
function ignore(type, state) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (state.paused) {
|
|
189
|
-
return type === WORK_PAUSE || type === WORK_START;
|
|
190
|
-
}
|
|
191
|
-
return state.active && type === WORK_START;
|
|
183
|
+
if (state.destroyed) return type !== WORK_STOP;
|
|
184
|
+
if (state.paused) return type === WORK_PAUSE || type === WORK_START;
|
|
185
|
+
return state.active && type === WORK_START;
|
|
192
186
|
}
|
|
193
187
|
function pause(timer, state) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
188
|
+
cancelAnimationFrame(state.frame);
|
|
189
|
+
state.frame = void 0;
|
|
190
|
+
return timer.instance;
|
|
197
191
|
}
|
|
198
192
|
function run(timer, state, options) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
state.frame = requestAnimationFrame(step);
|
|
228
|
-
};
|
|
193
|
+
let last;
|
|
194
|
+
let start;
|
|
195
|
+
return function step(now) {
|
|
196
|
+
if (!state.active) return;
|
|
197
|
+
last ??= now;
|
|
198
|
+
start ??= now;
|
|
199
|
+
const difference = now - last;
|
|
200
|
+
state.elapsed += difference;
|
|
201
|
+
state.total += difference;
|
|
202
|
+
last = now;
|
|
203
|
+
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
204
|
+
options.onError?.();
|
|
205
|
+
finish(timer, state, options, false);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
if (options.interval === MILLISECONDS || state.elapsed >= options.interval - BUFFER_INTERVAL) {
|
|
209
|
+
if (options.count > -1) state.callback(state.index);
|
|
210
|
+
start = now;
|
|
211
|
+
state.elapsed = 0;
|
|
212
|
+
state.index += 1;
|
|
213
|
+
if (options.count === -1 || options.count > 0 && state.index >= options.count) {
|
|
214
|
+
finish(timer, state, options, true);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
state.frame = requestAnimationFrame(step);
|
|
219
|
+
};
|
|
229
220
|
}
|
|
230
221
|
function setState(type, state) {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
222
|
+
const pausable = type === WORK_CONTINUE || type === WORK_PAUSE;
|
|
223
|
+
state.elapsed = pausable ? state.elapsed : 0;
|
|
224
|
+
state.index = pausable ? state.index : 0;
|
|
225
|
+
state.total = pausable ? state.total : 0;
|
|
235
226
|
}
|
|
236
227
|
function stop(timer, state, options) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
228
|
+
cancelAnimationFrame(state.frame);
|
|
229
|
+
TIMERS_ACTIVE.delete(timer.instance);
|
|
230
|
+
options.onAfter?.(false);
|
|
231
|
+
state.active = !stop;
|
|
232
|
+
state.frame = void 0;
|
|
233
|
+
state.paused = false;
|
|
234
|
+
return timer.instance;
|
|
244
235
|
}
|
|
245
236
|
function work(type, timer, state, options) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return pause(timer, state);
|
|
261
|
-
}
|
|
262
|
-
activeTimers.add(timer.instance);
|
|
263
|
-
const runner = run(timer, state, options);
|
|
264
|
-
state.frame = requestAnimationFrame(runner);
|
|
265
|
-
return timer.instance;
|
|
237
|
+
if (ignore(type, state)) return timer.instance;
|
|
238
|
+
setState(type, state);
|
|
239
|
+
if (type === WORK_STOP) return stop(timer, state, options);
|
|
240
|
+
if (type === WORK_PAUSE || type === WORK_RESTART) {
|
|
241
|
+
cancelAnimationFrame(state.frame);
|
|
242
|
+
state.frame = void 0;
|
|
243
|
+
}
|
|
244
|
+
state.active = true;
|
|
245
|
+
state.paused = type === WORK_PAUSE;
|
|
246
|
+
if (state.paused) return pause(timer, state);
|
|
247
|
+
TIMERS_ACTIVE.add(timer.instance);
|
|
248
|
+
const runner = run(timer, state, options);
|
|
249
|
+
state.frame = requestAnimationFrame(runner);
|
|
250
|
+
return timer.instance;
|
|
266
251
|
}
|
|
267
252
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
#work(type) {
|
|
361
|
-
return work(type, {
|
|
362
|
-
instance: this,
|
|
363
|
-
type: this.$timer,
|
|
364
|
-
}, this.state, this.options);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
253
|
+
var Timer = class {
|
|
254
|
+
state;
|
|
255
|
+
/**
|
|
256
|
+
* Is the timer active?
|
|
257
|
+
*/
|
|
258
|
+
get active() {
|
|
259
|
+
return this.state.active;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Is the timer destroyed?
|
|
263
|
+
*/
|
|
264
|
+
get destroyed() {
|
|
265
|
+
return this.state.destroyed;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Is the timer paused?
|
|
269
|
+
*/
|
|
270
|
+
get paused() {
|
|
271
|
+
return this.state.paused;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get the timer's origin _(if debugging is enabled)_
|
|
275
|
+
*/
|
|
276
|
+
get trace() {
|
|
277
|
+
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.trace : void 0;
|
|
278
|
+
}
|
|
279
|
+
constructor(type, state, options, start) {
|
|
280
|
+
this.options = options;
|
|
281
|
+
this.$timer = type;
|
|
282
|
+
this.state = {
|
|
283
|
+
...state,
|
|
284
|
+
active: false,
|
|
285
|
+
destroyed: false,
|
|
286
|
+
elapsed: 0,
|
|
287
|
+
frame: void 0,
|
|
288
|
+
index: 0,
|
|
289
|
+
paused: false,
|
|
290
|
+
total: 0
|
|
291
|
+
};
|
|
292
|
+
if (start) this.start();
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Continue running the timer _(if it's paused)_
|
|
296
|
+
*/
|
|
297
|
+
continue() {
|
|
298
|
+
return this.#work(WORK_CONTINUE);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Destroy the timer
|
|
302
|
+
*/
|
|
303
|
+
destroy() {
|
|
304
|
+
this.state.destroyed = true;
|
|
305
|
+
this.options.onAfter = noop;
|
|
306
|
+
this.options.onError = noop;
|
|
307
|
+
this.state.callback = noop;
|
|
308
|
+
if (!globalThis._oscarpalmer_timer_debug) this.state.trace = void 0;
|
|
309
|
+
stop({
|
|
310
|
+
instance: this,
|
|
311
|
+
type: this.$timer
|
|
312
|
+
}, this.state, this.options);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Pause the timer _(if it's running)_
|
|
316
|
+
*/
|
|
317
|
+
pause() {
|
|
318
|
+
return this.#work(WORK_PAUSE);
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Restart the timer _(or start it, if it's not running)_
|
|
322
|
+
*/
|
|
323
|
+
restart() {
|
|
324
|
+
return this.#work(WORK_RESTART);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Start the timer _(if it's not running)_
|
|
328
|
+
*/
|
|
329
|
+
start() {
|
|
330
|
+
return this.#work(WORK_START);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Stop the timer _(if it's running)_
|
|
334
|
+
*/
|
|
335
|
+
stop() {
|
|
336
|
+
return this.#work(WORK_STOP);
|
|
337
|
+
}
|
|
338
|
+
#work(type) {
|
|
339
|
+
return work(type, {
|
|
340
|
+
instance: this,
|
|
341
|
+
type: this.$timer
|
|
342
|
+
}, this.state, this.options);
|
|
343
|
+
}
|
|
344
|
+
};
|
|
367
345
|
|
|
368
346
|
/**
|
|
369
|
-
|
|
370
|
-
|
|
347
|
+
* Create a repeating timer
|
|
348
|
+
* @param callback Callback to run on each interval
|
|
349
|
+
* @param options Timer options
|
|
350
|
+
* @returns Timer instance
|
|
351
|
+
*/
|
|
371
352
|
function repeat(callback, options) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
353
|
+
return new Timer(TYPE_REPEAT, {
|
|
354
|
+
callback: getCallback(callback),
|
|
355
|
+
trace: new TimerTrace().stack
|
|
356
|
+
}, {
|
|
357
|
+
onAfter: getCallback(options?.onAfter),
|
|
358
|
+
onError: getCallback(options?.onTimeout),
|
|
359
|
+
count: getValidNumber(options?.count),
|
|
360
|
+
interval: getValidNumber(options?.interval, MILLISECONDS),
|
|
361
|
+
timeout: getValidNumber(options?.timeout)
|
|
362
|
+
}, true);
|
|
382
363
|
}
|
|
383
364
|
|
|
384
365
|
/**
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
366
|
+
* Create a waiting timer
|
|
367
|
+
* @param callback Callback to run when the timer has finished
|
|
368
|
+
* @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
|
|
369
|
+
*/
|
|
389
370
|
function wait(callback, time) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
371
|
+
return new Timer(TYPE_WAIT, {
|
|
372
|
+
callback: getCallback(callback),
|
|
373
|
+
trace: new TimerTrace().stack
|
|
374
|
+
}, {
|
|
375
|
+
onAfter: void 0,
|
|
376
|
+
onError: void 0,
|
|
377
|
+
count: -1,
|
|
378
|
+
interval: getValidNumber(time, MILLISECONDS),
|
|
379
|
+
timeout: 0
|
|
380
|
+
}, true);
|
|
400
381
|
}
|
|
401
382
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
383
|
+
var When = class {
|
|
384
|
+
$timer = TYPE_WHEN;
|
|
385
|
+
state = {
|
|
386
|
+
promise: void 0,
|
|
387
|
+
rejecter: void 0,
|
|
388
|
+
resolver: void 0,
|
|
389
|
+
started: false,
|
|
390
|
+
timer: void 0
|
|
391
|
+
};
|
|
392
|
+
/**
|
|
393
|
+
* Is the timer active?
|
|
394
|
+
*/
|
|
395
|
+
get active() {
|
|
396
|
+
return this.state.timer?.active ?? false;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Is the timer destroyed?
|
|
400
|
+
*/
|
|
401
|
+
get destroyed() {
|
|
402
|
+
return this.state.timer == null;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Is the timer paused?
|
|
406
|
+
*/
|
|
407
|
+
get paused() {
|
|
408
|
+
return this.state.timer?.paused ?? false;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Get the timer's origin _(if debugging is enabled)_
|
|
412
|
+
*/
|
|
413
|
+
get trace() {
|
|
414
|
+
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
|
|
415
|
+
}
|
|
416
|
+
constructor(condition, options) {
|
|
417
|
+
const { state } = this;
|
|
418
|
+
state.promise = new Promise((resolve, reject) => {
|
|
419
|
+
state.resolver = resolve;
|
|
420
|
+
state.rejecter = reject;
|
|
421
|
+
});
|
|
422
|
+
let result = false;
|
|
423
|
+
this.state.timer = new Timer(TYPE_WHEN, {
|
|
424
|
+
callback() {
|
|
425
|
+
try {
|
|
426
|
+
if (condition()) {
|
|
427
|
+
result = true;
|
|
428
|
+
state.timer.stop();
|
|
429
|
+
}
|
|
430
|
+
} catch {
|
|
431
|
+
state.timer.stop();
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
trace: new TimerTrace().stack
|
|
435
|
+
}, {
|
|
436
|
+
onAfter: () => {
|
|
437
|
+
if (result) state.resolver?.();
|
|
438
|
+
else state.rejecter?.();
|
|
439
|
+
this.destroy();
|
|
440
|
+
},
|
|
441
|
+
onError: () => {
|
|
442
|
+
state.rejecter?.();
|
|
443
|
+
this.destroy();
|
|
444
|
+
},
|
|
445
|
+
count: getValidNumber(options?.count),
|
|
446
|
+
interval: getValidNumber(options?.interval, MILLISECONDS),
|
|
447
|
+
timeout: getValidTimeout(options?.timeout)
|
|
448
|
+
}, false);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Continues the timer _(if it was paused)_
|
|
452
|
+
*/
|
|
453
|
+
continue() {
|
|
454
|
+
this.state.timer?.continue();
|
|
455
|
+
return this;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Destroys the timer _(and stops it,if it was running)_
|
|
459
|
+
*/
|
|
460
|
+
destroy() {
|
|
461
|
+
const { state } = this;
|
|
462
|
+
state.timer?.destroy();
|
|
463
|
+
state.promise = void 0;
|
|
464
|
+
state.resolver = noop;
|
|
465
|
+
state.rejecter = noop;
|
|
466
|
+
state.timer = void 0;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Pauses the timer _(if it was running)_
|
|
470
|
+
*/
|
|
471
|
+
pause() {
|
|
472
|
+
this.state.timer?.pause();
|
|
473
|
+
return this;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Start the timer
|
|
477
|
+
* @param resolve Optional resolve callback
|
|
478
|
+
* @param reject Optional reject callback
|
|
479
|
+
* @returns Promise that resolves when the condition is met
|
|
480
|
+
*/
|
|
481
|
+
start(resolve, reject) {
|
|
482
|
+
const { state } = this;
|
|
483
|
+
if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
|
|
484
|
+
if (state.started) throw new Error(MESSAGE_STARTED);
|
|
485
|
+
state.started = true;
|
|
486
|
+
state.timer.start();
|
|
487
|
+
return state.promise.then(resolve ?? noop, reject ?? noop);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Stops the timer _(if it was running)_
|
|
491
|
+
*/
|
|
492
|
+
stop() {
|
|
493
|
+
this.state.timer?.stop();
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Start the timer
|
|
498
|
+
* @deprecated Use `start()` instead
|
|
499
|
+
* @param resolve Optional resolve callback
|
|
500
|
+
* @param reject Optional reject callback
|
|
501
|
+
* @returns Promise that resolves when the condition is met
|
|
502
|
+
*/
|
|
503
|
+
then(resolve, reject) {
|
|
504
|
+
return this.start(resolve, reject);
|
|
505
|
+
}
|
|
506
|
+
};
|
|
525
507
|
/**
|
|
526
|
-
|
|
527
|
-
|
|
508
|
+
* Create a conditional timer
|
|
509
|
+
* @param condition Condition to check
|
|
510
|
+
* @param options Timer options
|
|
511
|
+
* @returns Timer instance
|
|
512
|
+
*/
|
|
528
513
|
function when(condition, options) {
|
|
529
|
-
|
|
514
|
+
return new When(condition, options);
|
|
530
515
|
}
|
|
531
516
|
|
|
532
|
-
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
|
517
|
+
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|