@oscarpalmer/timer 0.38.0 → 0.39.0
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/dist/constants.js +2 -18
- package/dist/delay.js +3 -3
- package/dist/repeat.js +2 -2
- package/dist/{toretto.full.js → timer.full.js} +21 -174
- package/dist/timer.js +1 -1
- package/dist/wait.js +2 -2
- package/dist/when.js +3 -3
- package/dist/work.js +2 -2
- package/package.json +5 -5
- package/src/constants.ts +2 -43
- package/src/delay.ts +3 -3
- package/src/repeat.ts +2 -2
- package/src/timer.ts +3 -1
- package/src/wait.ts +2 -2
- package/src/when.ts +7 -3
- package/src/work.ts +2 -2
- package/types/constants.d.ts +2 -4
package/dist/constants.js
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
|
|
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
|
-
});
|
|
13
|
-
}
|
|
1
|
+
import FRAME_RATE_MS from "@oscarpalmer/atoms/frame-rate";
|
|
14
2
|
const BUFFER_INTERVAL = 5;
|
|
15
3
|
const DEFAULT_TIMEOUT = 3e4;
|
|
16
4
|
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
@@ -25,8 +13,4 @@ const WORK_PAUSE = "pause";
|
|
|
25
13
|
const WORK_RESTART = "restart";
|
|
26
14
|
const WORK_START = "start";
|
|
27
15
|
const WORK_STOP = "stop";
|
|
28
|
-
|
|
29
|
-
calculate().then((value) => {
|
|
30
|
-
MILLISECONDS = value;
|
|
31
|
-
});
|
|
32
|
-
export { BUFFER_INTERVAL, DEFAULT_TIMEOUT, MESSAGE_DESTROYED, MESSAGE_STARTED, MILLISECONDS, TIMERS_ACTIVE, TIMERS_HIDDEN, TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP };
|
|
16
|
+
export { BUFFER_INTERVAL, DEFAULT_TIMEOUT, FRAME_RATE_MS, MESSAGE_DESTROYED, MESSAGE_STARTED, TIMERS_ACTIVE, TIMERS_HIDDEN, TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP };
|
package/dist/delay.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { BUFFER_INTERVAL,
|
|
1
|
+
import { BUFFER_INTERVAL, FRAME_RATE_MS } from "./constants.js";
|
|
2
2
|
import { getValidNumber } from "./get.js";
|
|
3
3
|
function delay(time) {
|
|
4
4
|
return new Promise((resolve) => {
|
|
5
|
-
const interval = getValidNumber(time,
|
|
5
|
+
const interval = getValidNumber(time, FRAME_RATE_MS);
|
|
6
6
|
let start;
|
|
7
7
|
function step(now) {
|
|
8
8
|
start ??= now;
|
|
9
|
-
if (interval ===
|
|
9
|
+
if (interval === FRAME_RATE_MS || now - start >= interval - 5) resolve();
|
|
10
10
|
else requestAnimationFrame(step);
|
|
11
11
|
}
|
|
12
12
|
requestAnimationFrame(step);
|
package/dist/repeat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FRAME_RATE_MS, TYPE_REPEAT } from "./constants.js";
|
|
2
2
|
import { getCallback, getValidNumber } from "./get.js";
|
|
3
3
|
import "./global.js";
|
|
4
4
|
import { TimerTrace } from "./models.js";
|
|
@@ -11,7 +11,7 @@ function repeat(callback, options) {
|
|
|
11
11
|
onAfter: getCallback(options?.onAfter),
|
|
12
12
|
onError: getCallback(options?.onTimeout),
|
|
13
13
|
count: getValidNumber(options?.count),
|
|
14
|
-
interval: getValidNumber(options?.interval,
|
|
14
|
+
interval: getValidNumber(options?.interval, FRAME_RATE_MS),
|
|
15
15
|
timeout: getValidNumber(options?.timeout)
|
|
16
16
|
}, true);
|
|
17
17
|
}
|
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
function calculate
|
|
1
|
+
function calculate() {
|
|
2
2
|
return new Promise((resolve) => {
|
|
3
3
|
const values = [];
|
|
4
4
|
let last;
|
|
5
5
|
function step(now) {
|
|
6
6
|
if (last != null) values.push(now - last);
|
|
7
7
|
last = now;
|
|
8
|
-
if (values.length >=
|
|
8
|
+
if (values.length >= CALCULATION_TOTAL) resolve(values.sort().slice(CALCULATION_TRIM_PART, -CALCULATION_TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - CALCULATION_TRIM_TOTAL));
|
|
9
9
|
else requestAnimationFrame(step);
|
|
10
10
|
}
|
|
11
11
|
requestAnimationFrame(step);
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
var CALCULATION_TOTAL = 10;
|
|
15
|
+
var CALCULATION_TRIM_PART = 2;
|
|
16
|
+
var CALCULATION_TRIM_TOTAL = 4;
|
|
17
|
+
var FRAME_RATE_MS = 1e3 / 60;
|
|
18
|
+
calculate().then((value) => {
|
|
19
|
+
FRAME_RATE_MS = value;
|
|
20
|
+
});
|
|
21
|
+
var frame_rate_default = FRAME_RATE_MS;
|
|
17
22
|
const BUFFER_INTERVAL = 5;
|
|
18
23
|
const DEFAULT_TIMEOUT = 3e4;
|
|
19
|
-
/**
|
|
20
|
-
* Message to show when a when-timer is destroyed
|
|
21
|
-
*/
|
|
22
24
|
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
23
|
-
/**
|
|
24
|
-
* Message to show when a when-timer is started
|
|
25
|
-
*/
|
|
26
25
|
const MESSAGE_STARTED = "Timer has already been started";
|
|
27
|
-
/**
|
|
28
|
-
* A set of all active timers
|
|
29
|
-
*/
|
|
30
26
|
const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
|
|
31
|
-
/**
|
|
32
|
-
* A set of timers that were paused due to the document being hidden
|
|
33
|
-
*/
|
|
34
27
|
const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
|
|
35
28
|
const TYPE_REPEAT = "repeat";
|
|
36
29
|
const TYPE_WAIT = "wait";
|
|
@@ -40,14 +33,6 @@ const WORK_PAUSE = "pause";
|
|
|
40
33
|
const WORK_RESTART = "restart";
|
|
41
34
|
const WORK_START = "start";
|
|
42
35
|
const WORK_STOP = "stop";
|
|
43
|
-
/**
|
|
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;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
36
|
if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
52
37
|
return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
|
|
53
38
|
} });
|
|
@@ -62,8 +47,8 @@ document.addEventListener("visibilitychange", () => {
|
|
|
62
47
|
}
|
|
63
48
|
from.clear();
|
|
64
49
|
});
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
function noop() {}
|
|
51
|
+
new Set([
|
|
67
52
|
Int8Array,
|
|
68
53
|
Uint8Array,
|
|
69
54
|
Uint8ClampedArray,
|
|
@@ -76,26 +61,6 @@ var typeArrays = new Set([
|
|
|
76
61
|
BigInt64Array,
|
|
77
62
|
BigUint64Array
|
|
78
63
|
]);
|
|
79
|
-
|
|
80
|
-
function calculate() {
|
|
81
|
-
return new Promise((resolve) => {
|
|
82
|
-
const values = [];
|
|
83
|
-
let last;
|
|
84
|
-
function step(now) {
|
|
85
|
-
if (last != null) values.push(now - last);
|
|
86
|
-
last = now;
|
|
87
|
-
if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
|
|
88
|
-
else requestAnimationFrame(step);
|
|
89
|
-
}
|
|
90
|
-
requestAnimationFrame(step);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
function noop() {}
|
|
94
|
-
let milliseconds = 1e3 / 60;
|
|
95
|
-
calculate().then((value) => {
|
|
96
|
-
milliseconds = value;
|
|
97
|
-
});
|
|
98
|
-
|
|
99
64
|
function getCallback(value) {
|
|
100
65
|
return typeof value === "function" ? value : noop;
|
|
101
66
|
}
|
|
@@ -106,68 +71,39 @@ function getValidNumber(value, defaultValue) {
|
|
|
106
71
|
const actualDefault = defaultValue ?? 0;
|
|
107
72
|
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
108
73
|
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Create a delayed promise that resolves after a certain amount of time
|
|
112
|
-
* @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
|
|
113
|
-
* @returns A promise that resolves after the delay
|
|
114
|
-
*/
|
|
115
74
|
function delay(time) {
|
|
116
75
|
return new Promise((resolve) => {
|
|
117
|
-
const interval = getValidNumber(time,
|
|
76
|
+
const interval = getValidNumber(time, frame_rate_default);
|
|
118
77
|
let start;
|
|
119
78
|
function step(now) {
|
|
120
79
|
start ??= now;
|
|
121
|
-
if (interval ===
|
|
80
|
+
if (interval === frame_rate_default || now - start >= interval - BUFFER_INTERVAL) resolve();
|
|
122
81
|
else requestAnimationFrame(step);
|
|
123
82
|
}
|
|
124
83
|
requestAnimationFrame(step);
|
|
125
84
|
});
|
|
126
85
|
}
|
|
127
|
-
|
|
128
86
|
function is(names, value) {
|
|
129
87
|
return names.includes(value?.$timer);
|
|
130
88
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Is the value a repeating timer?
|
|
133
|
-
* @param value Value to check
|
|
134
|
-
* @returns `true` if the value is a repeating timer
|
|
135
|
-
*/
|
|
136
89
|
function isRepeated(value) {
|
|
137
90
|
return is([TYPE_REPEAT], value);
|
|
138
91
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Is the value a timer?
|
|
141
|
-
* @param value Value to check
|
|
142
|
-
* @returns `true` if the value is a timer
|
|
143
|
-
*/
|
|
144
92
|
function isTimer(value) {
|
|
145
93
|
return is([TYPE_REPEAT, TYPE_WAIT], value);
|
|
146
94
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Is the value a waiting timer?
|
|
149
|
-
* @param value Value to check
|
|
150
|
-
* @returns `true` if the value is a waiting timer
|
|
151
|
-
*/
|
|
152
95
|
function isWaited(value) {
|
|
153
96
|
return is([TYPE_WAIT], value);
|
|
154
97
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Is the value a conditional timer?
|
|
157
|
-
* @param value Value to check
|
|
158
|
-
* @returns `true` if the value is a conditional timer
|
|
159
|
-
*/
|
|
160
98
|
function isWhen(value) {
|
|
161
99
|
return is([TYPE_WHEN], value) && typeof value.then === "function";
|
|
162
100
|
}
|
|
163
|
-
|
|
164
101
|
var TimerTrace = class extends Error {
|
|
165
102
|
constructor() {
|
|
166
103
|
super();
|
|
167
104
|
this.name = "TimerTrace";
|
|
168
105
|
}
|
|
169
106
|
};
|
|
170
|
-
|
|
171
107
|
function finish(timer, state, options, success) {
|
|
172
108
|
cancelAnimationFrame(state.frame);
|
|
173
109
|
TIMERS_ACTIVE.delete(timer.instance);
|
|
@@ -203,7 +139,7 @@ function run(timer, state, options) {
|
|
|
203
139
|
finish(timer, state, options, false);
|
|
204
140
|
return;
|
|
205
141
|
}
|
|
206
|
-
if (options.interval ===
|
|
142
|
+
if (options.interval === frame_rate_default || state.elapsed >= options.interval - BUFFER_INTERVAL) {
|
|
207
143
|
if (options.count > -1) state.callback(state.index);
|
|
208
144
|
start = now;
|
|
209
145
|
state.elapsed = 0;
|
|
@@ -247,36 +183,23 @@ function work(type, timer, state, options) {
|
|
|
247
183
|
state.frame = requestAnimationFrame(runner);
|
|
248
184
|
return timer.instance;
|
|
249
185
|
}
|
|
250
|
-
|
|
251
186
|
var Timer = class {
|
|
252
187
|
state;
|
|
253
|
-
/**
|
|
254
|
-
* Is the timer active?
|
|
255
|
-
*/
|
|
256
188
|
get active() {
|
|
257
189
|
return this.state.active;
|
|
258
190
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Is the timer destroyed?
|
|
261
|
-
*/
|
|
262
191
|
get destroyed() {
|
|
263
192
|
return this.state.destroyed;
|
|
264
193
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Is the timer paused?
|
|
267
|
-
*/
|
|
268
194
|
get paused() {
|
|
269
195
|
return this.state.paused;
|
|
270
196
|
}
|
|
271
|
-
/**
|
|
272
|
-
* Get the timer's origin _(if debugging is enabled)_
|
|
273
|
-
*/
|
|
274
197
|
get trace() {
|
|
275
198
|
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.trace : void 0;
|
|
276
199
|
}
|
|
277
200
|
constructor(type, state, options, start) {
|
|
278
201
|
this.options = options;
|
|
279
|
-
this
|
|
202
|
+
Object.defineProperty(this, "$timer", { value: type });
|
|
280
203
|
this.state = {
|
|
281
204
|
...state,
|
|
282
205
|
active: false,
|
|
@@ -289,15 +212,9 @@ var Timer = class {
|
|
|
289
212
|
};
|
|
290
213
|
if (start) this.start();
|
|
291
214
|
}
|
|
292
|
-
/**
|
|
293
|
-
* Continue running the timer _(if it's paused)_
|
|
294
|
-
*/
|
|
295
215
|
continue() {
|
|
296
216
|
return this.#work(WORK_CONTINUE);
|
|
297
217
|
}
|
|
298
|
-
/**
|
|
299
|
-
* Destroy the timer
|
|
300
|
-
*/
|
|
301
218
|
destroy() {
|
|
302
219
|
this.state.destroyed = true;
|
|
303
220
|
this.options.onAfter = noop;
|
|
@@ -309,27 +226,15 @@ var Timer = class {
|
|
|
309
226
|
type: this.$timer
|
|
310
227
|
}, this.state, this.options);
|
|
311
228
|
}
|
|
312
|
-
/**
|
|
313
|
-
* Pause the timer _(if it's running)_
|
|
314
|
-
*/
|
|
315
229
|
pause() {
|
|
316
230
|
return this.#work(WORK_PAUSE);
|
|
317
231
|
}
|
|
318
|
-
/**
|
|
319
|
-
* Restart the timer _(or start it, if it's not running)_
|
|
320
|
-
*/
|
|
321
232
|
restart() {
|
|
322
233
|
return this.#work(WORK_RESTART);
|
|
323
234
|
}
|
|
324
|
-
/**
|
|
325
|
-
* Start the timer _(if it's not running)_
|
|
326
|
-
*/
|
|
327
235
|
start() {
|
|
328
236
|
return this.#work(WORK_START);
|
|
329
237
|
}
|
|
330
|
-
/**
|
|
331
|
-
* Stop the timer _(if it's running)_
|
|
332
|
-
*/
|
|
333
238
|
stop() {
|
|
334
239
|
return this.#work(WORK_STOP);
|
|
335
240
|
}
|
|
@@ -340,13 +245,6 @@ var Timer = class {
|
|
|
340
245
|
}, this.state, this.options);
|
|
341
246
|
}
|
|
342
247
|
};
|
|
343
|
-
|
|
344
|
-
/**
|
|
345
|
-
* Create a repeating timer
|
|
346
|
-
* @param callback Callback to run on each interval
|
|
347
|
-
* @param options Timer options
|
|
348
|
-
* @returns Timer instance
|
|
349
|
-
*/
|
|
350
248
|
function repeat(callback, options) {
|
|
351
249
|
return new Timer(TYPE_REPEAT, {
|
|
352
250
|
callback: getCallback(callback),
|
|
@@ -355,16 +253,10 @@ function repeat(callback, options) {
|
|
|
355
253
|
onAfter: getCallback(options?.onAfter),
|
|
356
254
|
onError: getCallback(options?.onTimeout),
|
|
357
255
|
count: getValidNumber(options?.count),
|
|
358
|
-
interval: getValidNumber(options?.interval,
|
|
256
|
+
interval: getValidNumber(options?.interval, frame_rate_default),
|
|
359
257
|
timeout: getValidNumber(options?.timeout)
|
|
360
258
|
}, true);
|
|
361
259
|
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Create a waiting timer
|
|
365
|
-
* @param callback Callback to run when the timer has finished
|
|
366
|
-
* @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
|
|
367
|
-
*/
|
|
368
260
|
function wait(callback, time) {
|
|
369
261
|
return new Timer(TYPE_WAIT, {
|
|
370
262
|
callback: getCallback(callback),
|
|
@@ -373,13 +265,11 @@ function wait(callback, time) {
|
|
|
373
265
|
onAfter: void 0,
|
|
374
266
|
onError: void 0,
|
|
375
267
|
count: -1,
|
|
376
|
-
interval: getValidNumber(time,
|
|
268
|
+
interval: getValidNumber(time, frame_rate_default),
|
|
377
269
|
timeout: 0
|
|
378
270
|
}, true);
|
|
379
271
|
}
|
|
380
|
-
|
|
381
272
|
var When = class {
|
|
382
|
-
$timer = TYPE_WHEN;
|
|
383
273
|
state = {
|
|
384
274
|
promise: void 0,
|
|
385
275
|
rejecter: void 0,
|
|
@@ -387,31 +277,20 @@ var When = class {
|
|
|
387
277
|
started: false,
|
|
388
278
|
timer: void 0
|
|
389
279
|
};
|
|
390
|
-
/**
|
|
391
|
-
* Is the timer active?
|
|
392
|
-
*/
|
|
393
280
|
get active() {
|
|
394
281
|
return this.state.timer?.active ?? false;
|
|
395
282
|
}
|
|
396
|
-
/**
|
|
397
|
-
* Is the timer destroyed?
|
|
398
|
-
*/
|
|
399
283
|
get destroyed() {
|
|
400
284
|
return this.state.timer == null;
|
|
401
285
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Is the timer paused?
|
|
404
|
-
*/
|
|
405
286
|
get paused() {
|
|
406
287
|
return this.state.timer?.paused ?? false;
|
|
407
288
|
}
|
|
408
|
-
/**
|
|
409
|
-
* Get the timer's origin _(if debugging is enabled)_
|
|
410
|
-
*/
|
|
411
289
|
get trace() {
|
|
412
290
|
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
|
|
413
291
|
}
|
|
414
292
|
constructor(condition, options) {
|
|
293
|
+
Object.defineProperty(this, "$timer", { value: TYPE_WHEN });
|
|
415
294
|
const { state } = this;
|
|
416
295
|
state.promise = new Promise((resolve, reject) => {
|
|
417
296
|
state.resolver = resolve;
|
|
@@ -441,20 +320,14 @@ var When = class {
|
|
|
441
320
|
this.destroy();
|
|
442
321
|
},
|
|
443
322
|
count: getValidNumber(options?.count),
|
|
444
|
-
interval: getValidNumber(options?.interval,
|
|
323
|
+
interval: getValidNumber(options?.interval, frame_rate_default),
|
|
445
324
|
timeout: getValidTimeout(options?.timeout)
|
|
446
325
|
}, false);
|
|
447
326
|
}
|
|
448
|
-
/**
|
|
449
|
-
* Continues the timer _(if it was paused)_
|
|
450
|
-
*/
|
|
451
327
|
continue() {
|
|
452
328
|
this.state.timer?.continue();
|
|
453
329
|
return this;
|
|
454
330
|
}
|
|
455
|
-
/**
|
|
456
|
-
* Destroys the timer _(and stops it,if it was running)_
|
|
457
|
-
*/
|
|
458
331
|
destroy() {
|
|
459
332
|
const { state } = this;
|
|
460
333
|
state.timer?.destroy();
|
|
@@ -463,19 +336,10 @@ var When = class {
|
|
|
463
336
|
state.rejecter = noop;
|
|
464
337
|
state.timer = void 0;
|
|
465
338
|
}
|
|
466
|
-
/**
|
|
467
|
-
* Pauses the timer _(if it was running)_
|
|
468
|
-
*/
|
|
469
339
|
pause() {
|
|
470
340
|
this.state.timer?.pause();
|
|
471
341
|
return this;
|
|
472
342
|
}
|
|
473
|
-
/**
|
|
474
|
-
* Start the timer
|
|
475
|
-
* @param resolve Optional resolve callback
|
|
476
|
-
* @param reject Optional reject callback
|
|
477
|
-
* @returns Promise that resolves when the condition is met
|
|
478
|
-
*/
|
|
479
343
|
start(resolve, reject) {
|
|
480
344
|
const { state } = this;
|
|
481
345
|
if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
|
|
@@ -484,32 +348,15 @@ var When = class {
|
|
|
484
348
|
state.timer.start();
|
|
485
349
|
return state.promise.then(resolve ?? noop, reject ?? noop);
|
|
486
350
|
}
|
|
487
|
-
/**
|
|
488
|
-
* Stops the timer _(if it was running)_
|
|
489
|
-
*/
|
|
490
351
|
stop() {
|
|
491
352
|
this.state.timer?.stop();
|
|
492
353
|
return this;
|
|
493
354
|
}
|
|
494
|
-
/**
|
|
495
|
-
* Start the timer
|
|
496
|
-
* @deprecated Use `start()` instead
|
|
497
|
-
* @param resolve Optional resolve callback
|
|
498
|
-
* @param reject Optional reject callback
|
|
499
|
-
* @returns Promise that resolves when the condition is met
|
|
500
|
-
*/
|
|
501
355
|
then(resolve, reject) {
|
|
502
356
|
return this.start(resolve, reject);
|
|
503
357
|
}
|
|
504
358
|
};
|
|
505
|
-
/**
|
|
506
|
-
* Create a conditional timer
|
|
507
|
-
* @param condition Condition to check
|
|
508
|
-
* @param options Timer options
|
|
509
|
-
* @returns Timer instance
|
|
510
|
-
*/
|
|
511
359
|
function when(condition, options) {
|
|
512
360
|
return new When(condition, options);
|
|
513
361
|
}
|
|
514
|
-
|
|
515
|
-
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
|
362
|
+
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
package/dist/timer.js
CHANGED
package/dist/wait.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FRAME_RATE_MS, TYPE_WAIT } from "./constants.js";
|
|
2
2
|
import { getCallback, getValidNumber } from "./get.js";
|
|
3
3
|
import "./global.js";
|
|
4
4
|
import { TimerTrace } from "./models.js";
|
|
@@ -11,7 +11,7 @@ function wait(callback, time) {
|
|
|
11
11
|
onAfter: void 0,
|
|
12
12
|
onError: void 0,
|
|
13
13
|
count: -1,
|
|
14
|
-
interval: getValidNumber(time,
|
|
14
|
+
interval: getValidNumber(time, FRAME_RATE_MS),
|
|
15
15
|
timeout: 0
|
|
16
16
|
}, true);
|
|
17
17
|
}
|
package/dist/when.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { MESSAGE_DESTROYED, MESSAGE_STARTED,
|
|
1
|
+
import { FRAME_RATE_MS, MESSAGE_DESTROYED, MESSAGE_STARTED, TYPE_WHEN } from "./constants.js";
|
|
2
2
|
import { getValidNumber, getValidTimeout } from "./get.js";
|
|
3
3
|
import "./global.js";
|
|
4
4
|
import { TimerTrace } from "./models.js";
|
|
5
5
|
import { Timer } from "./timer.js";
|
|
6
6
|
import { noop } from "@oscarpalmer/atoms/function";
|
|
7
7
|
var When = class {
|
|
8
|
-
$timer = TYPE_WHEN;
|
|
9
8
|
state = {
|
|
10
9
|
promise: void 0,
|
|
11
10
|
rejecter: void 0,
|
|
@@ -26,6 +25,7 @@ var When = class {
|
|
|
26
25
|
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
|
|
27
26
|
}
|
|
28
27
|
constructor(condition, options) {
|
|
28
|
+
Object.defineProperty(this, "$timer", { value: TYPE_WHEN });
|
|
29
29
|
const { state } = this;
|
|
30
30
|
state.promise = new Promise((resolve, reject) => {
|
|
31
31
|
state.resolver = resolve;
|
|
@@ -55,7 +55,7 @@ var When = class {
|
|
|
55
55
|
this.destroy();
|
|
56
56
|
},
|
|
57
57
|
count: getValidNumber(options?.count),
|
|
58
|
-
interval: getValidNumber(options?.interval,
|
|
58
|
+
interval: getValidNumber(options?.interval, FRAME_RATE_MS),
|
|
59
59
|
timeout: getValidTimeout(options?.timeout)
|
|
60
60
|
}, false);
|
|
61
61
|
}
|
package/dist/work.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BUFFER_INTERVAL,
|
|
1
|
+
import { BUFFER_INTERVAL, FRAME_RATE_MS, TIMERS_ACTIVE, TYPE_WAIT, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP } from "./constants.js";
|
|
2
2
|
function finish(timer, state, options, success) {
|
|
3
3
|
cancelAnimationFrame(state.frame);
|
|
4
4
|
TIMERS_ACTIVE.delete(timer.instance);
|
|
@@ -34,7 +34,7 @@ function run(timer, state, options) {
|
|
|
34
34
|
finish(timer, state, options, false);
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
|
-
if (options.interval ===
|
|
37
|
+
if (options.interval === FRAME_RATE_MS || state.elapsed >= options.interval - 5) {
|
|
38
38
|
if (options.count > -1) state.callback(state.index);
|
|
39
39
|
start = now;
|
|
40
40
|
state.elapsed = 0;
|
package/package.json
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@oscarpalmer/atoms": "^0.
|
|
7
|
+
"@oscarpalmer/atoms": "^0.117"
|
|
8
8
|
},
|
|
9
9
|
"description": "A better solution for timeout- and interval-based timers.",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@types/node": "^25",
|
|
12
12
|
"@vitest/coverage-istanbul": "^4",
|
|
13
13
|
"jsdom": "^27.3",
|
|
14
|
-
"oxfmt": "^0.
|
|
15
|
-
"oxlint": "^1.
|
|
14
|
+
"oxfmt": "^0.19",
|
|
15
|
+
"oxlint": "^1.34",
|
|
16
16
|
"rolldown": "1.0.0-beta.55",
|
|
17
17
|
"tslib": "^2.8",
|
|
18
18
|
"typescript": "^5.9",
|
|
@@ -64,11 +64,11 @@
|
|
|
64
64
|
"build": "npm run clean && npx vite build && npm run rolldown:build && npx tsc",
|
|
65
65
|
"clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
|
|
66
66
|
"rolldown:build": "npx rolldown -c",
|
|
67
|
-
"rolldown:watch": "npx rolldown -c --watch",
|
|
67
|
+
"rolldown:watch": "npx rolldown -c ./rolldown.config.js --watch",
|
|
68
68
|
"test": "npx vitest --coverage",
|
|
69
69
|
"watch": "npx vite build --watch"
|
|
70
70
|
},
|
|
71
71
|
"type": "module",
|
|
72
72
|
"types": "types/index.d.ts",
|
|
73
|
-
"version": "0.
|
|
73
|
+
"version": "0.39.0"
|
|
74
74
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1,39 +1,7 @@
|
|
|
1
|
+
import FRAME_RATE_MS from '@oscarpalmer/atoms/frame-rate';
|
|
1
2
|
import type {TimerType, WorkHandlerType} from './models';
|
|
2
3
|
import type {Timer} from './timer';
|
|
3
4
|
|
|
4
|
-
function calculate(): Promise<number> {
|
|
5
|
-
return new Promise(resolve => {
|
|
6
|
-
const values: number[] = [];
|
|
7
|
-
|
|
8
|
-
let last: DOMHighResTimeStamp | undefined;
|
|
9
|
-
|
|
10
|
-
function step(now: DOMHighResTimeStamp): void {
|
|
11
|
-
if (last != null) {
|
|
12
|
-
values.push(now - last);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
last = now;
|
|
16
|
-
|
|
17
|
-
if (values.length >= 10) {
|
|
18
|
-
const median =
|
|
19
|
-
values
|
|
20
|
-
.sort()
|
|
21
|
-
.slice(2, -2)
|
|
22
|
-
.reduce((first, second) => first + second, 0) /
|
|
23
|
-
(values.length - 4);
|
|
24
|
-
|
|
25
|
-
resolve(median);
|
|
26
|
-
} else {
|
|
27
|
-
requestAnimationFrame(step);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
requestAnimationFrame(step);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
|
|
37
5
|
/**
|
|
38
6
|
* Buffer value to use when evaluating if a specific time is within a certain range
|
|
39
7
|
*/
|
|
@@ -77,13 +45,4 @@ export const WORK_START: WorkHandlerType = 'start';
|
|
|
77
45
|
|
|
78
46
|
export const WORK_STOP: WorkHandlerType = 'stop';
|
|
79
47
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
84
|
-
*/
|
|
85
|
-
export let MILLISECONDS = 1000 / 60;
|
|
86
|
-
|
|
87
|
-
calculate().then(value => {
|
|
88
|
-
MILLISECONDS = value;
|
|
89
|
-
});
|
|
48
|
+
export {FRAME_RATE_MS};
|
package/src/delay.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {BUFFER_INTERVAL,
|
|
1
|
+
import {BUFFER_INTERVAL, FRAME_RATE_MS} from './constants';
|
|
2
2
|
import {getValidNumber} from './get';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -8,14 +8,14 @@ import {getValidNumber} from './get';
|
|
|
8
8
|
*/
|
|
9
9
|
export function delay(time?: number): Promise<void> {
|
|
10
10
|
return new Promise(resolve => {
|
|
11
|
-
const interval = getValidNumber(time,
|
|
11
|
+
const interval = getValidNumber(time, FRAME_RATE_MS);
|
|
12
12
|
|
|
13
13
|
let start: DOMHighResTimeStamp;
|
|
14
14
|
|
|
15
15
|
function step(now: DOMHighResTimeStamp) {
|
|
16
16
|
start ??= now;
|
|
17
17
|
|
|
18
|
-
if (interval ===
|
|
18
|
+
if (interval === FRAME_RATE_MS || now - start >= interval - BUFFER_INTERVAL) {
|
|
19
19
|
resolve();
|
|
20
20
|
} else {
|
|
21
21
|
requestAnimationFrame(step);
|
package/src/repeat.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {FRAME_RATE_MS, TYPE_REPEAT} from './constants';
|
|
2
2
|
import {getCallback, getValidNumber} from './get';
|
|
3
3
|
import './global';
|
|
4
4
|
import {type RepeatOptions, TimerTrace} from './models';
|
|
@@ -21,7 +21,7 @@ export function repeat(callback: (index: number) => void, options?: Partial<Repe
|
|
|
21
21
|
onAfter: getCallback(options?.onAfter),
|
|
22
22
|
onError: getCallback(options?.onTimeout),
|
|
23
23
|
count: getValidNumber(options?.count),
|
|
24
|
-
interval: getValidNumber(options?.interval,
|
|
24
|
+
interval: getValidNumber(options?.interval, FRAME_RATE_MS),
|
|
25
25
|
timeout: getValidNumber(options?.timeout),
|
|
26
26
|
},
|
|
27
27
|
true,
|
package/src/timer.ts
CHANGED
package/src/wait.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {FRAME_RATE_MS, TYPE_WAIT} from './constants';
|
|
2
2
|
import {getCallback, getValidNumber} from './get';
|
|
3
3
|
import './global';
|
|
4
4
|
import {TimerTrace} from './models';
|
|
@@ -20,7 +20,7 @@ export function wait(callback: () => void, time?: number): Timer {
|
|
|
20
20
|
onAfter: undefined,
|
|
21
21
|
onError: undefined,
|
|
22
22
|
count: -1,
|
|
23
|
-
interval: getValidNumber(time,
|
|
23
|
+
interval: getValidNumber(time, FRAME_RATE_MS),
|
|
24
24
|
timeout: 0,
|
|
25
25
|
},
|
|
26
26
|
true,
|
package/src/when.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {noop} from '@oscarpalmer/atoms/function';
|
|
2
|
-
import {
|
|
2
|
+
import {FRAME_RATE_MS, MESSAGE_DESTROYED, MESSAGE_STARTED, TYPE_WHEN} from './constants';
|
|
3
3
|
import {getValidNumber, getValidTimeout} from './get';
|
|
4
4
|
import './global';
|
|
5
5
|
import {TimerTrace, type WhenOptions, type WhenState} from './models';
|
|
6
6
|
import {Timer} from './timer';
|
|
7
7
|
|
|
8
8
|
class When {
|
|
9
|
-
private readonly $timer
|
|
9
|
+
private declare readonly $timer: string;
|
|
10
10
|
|
|
11
11
|
private readonly state: WhenState = {
|
|
12
12
|
promise: undefined as never,
|
|
@@ -45,6 +45,10 @@ class When {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
constructor(condition: () => boolean, options?: Partial<WhenOptions>) {
|
|
48
|
+
Object.defineProperty(this, '$timer', {
|
|
49
|
+
value: TYPE_WHEN,
|
|
50
|
+
});
|
|
51
|
+
|
|
48
52
|
const {state} = this;
|
|
49
53
|
|
|
50
54
|
state.promise = new Promise<void>((resolve, reject) => {
|
|
@@ -86,7 +90,7 @@ class When {
|
|
|
86
90
|
this.destroy();
|
|
87
91
|
},
|
|
88
92
|
count: getValidNumber(options?.count),
|
|
89
|
-
interval: getValidNumber(options?.interval,
|
|
93
|
+
interval: getValidNumber(options?.interval, FRAME_RATE_MS),
|
|
90
94
|
timeout: getValidTimeout(options?.timeout),
|
|
91
95
|
},
|
|
92
96
|
false,
|
package/src/work.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TIMERS_ACTIVE,
|
|
3
3
|
BUFFER_INTERVAL,
|
|
4
|
-
|
|
4
|
+
FRAME_RATE_MS,
|
|
5
5
|
TYPE_WAIT,
|
|
6
6
|
WORK_CONTINUE,
|
|
7
7
|
WORK_PAUSE,
|
|
@@ -84,7 +84,7 @@ function run(
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
if (options.interval ===
|
|
87
|
+
if (options.interval === FRAME_RATE_MS || state.elapsed >= options.interval - BUFFER_INTERVAL) {
|
|
88
88
|
if (options.count > -1) {
|
|
89
89
|
(state.callback as (index: number) => void)(state.index);
|
|
90
90
|
}
|
package/types/constants.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import FRAME_RATE_MS from '@oscarpalmer/atoms/frame-rate';
|
|
1
2
|
import type { TimerType, WorkHandlerType } from './models';
|
|
2
3
|
import type { Timer } from './timer';
|
|
3
4
|
/**
|
|
@@ -29,7 +30,4 @@ export declare const WORK_PAUSE: WorkHandlerType;
|
|
|
29
30
|
export declare const WORK_RESTART: WorkHandlerType;
|
|
30
31
|
export declare const WORK_START: WorkHandlerType;
|
|
31
32
|
export declare const WORK_STOP: WorkHandlerType;
|
|
32
|
-
|
|
33
|
-
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
34
|
-
*/
|
|
35
|
-
export declare let MILLISECONDS: number;
|
|
33
|
+
export { FRAME_RATE_MS };
|