@oscarpalmer/timer 0.31.0 → 0.33.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.cjs +23 -19
- package/dist/constants.js +23 -20
- package/dist/delay.cjs +1 -1
- package/dist/delay.js +2 -2
- package/dist/repeat.cjs +1 -2
- package/dist/repeat.js +1 -2
- package/dist/timer.cjs +14 -5
- package/dist/timer.full.js +189 -155
- package/dist/timer.js +14 -5
- package/dist/wait.cjs +1 -2
- package/dist/wait.js +1 -2
- package/dist/when.cjs +65 -62
- package/dist/when.js +65 -62
- package/dist/work.cjs +43 -28
- package/dist/work.js +44 -30
- package/package.json +4 -4
- package/src/constants.ts +36 -27
- package/src/delay.ts +5 -2
- package/src/repeat.ts +1 -2
- package/src/timer.ts +14 -6
- package/src/wait.ts +1 -2
- package/src/when.ts +74 -71
- package/src/work.ts +77 -41
- package/types/constants.d.cts +5 -7
- package/types/constants.d.ts +4 -0
- package/types/index.d.cts +2 -16
- package/types/is.d.cts +18 -15
- package/types/models.d.cts +1 -2
- package/types/repeat.d.cts +1 -8
- package/types/repeat.d.ts +1 -0
- package/types/timer.d.cts +1 -8
- package/types/timer.d.ts +2 -3
- package/types/wait.d.cts +1 -8
- package/types/wait.d.ts +1 -0
- package/types/when.d.cts +1 -81
- package/types/when.d.ts +3 -2
- package/types/work.d.cts +6 -3
- package/types/work.d.ts +1 -0
package/dist/constants.cjs
CHANGED
|
@@ -2,25 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
function calculate() {
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
const values = [];
|
|
8
|
+
let last;
|
|
9
|
+
function step(now) {
|
|
10
|
+
if (last != null) {
|
|
11
|
+
values.push(now - last);
|
|
12
|
+
}
|
|
13
|
+
last = now;
|
|
14
|
+
if (values.length >= 10) {
|
|
15
|
+
const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4);
|
|
16
|
+
resolve(median);
|
|
17
|
+
} else {
|
|
18
|
+
requestAnimationFrame(step);
|
|
19
|
+
}
|
|
17
20
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
+
requestAnimationFrame(step);
|
|
22
|
+
});
|
|
21
23
|
}
|
|
22
24
|
const activeTimers = /* @__PURE__ */ new Set();
|
|
23
25
|
const beginTypes = /* @__PURE__ */ new Set(["continue", "start"]);
|
|
26
|
+
const intervalBuffer = 5;
|
|
24
27
|
const destroyedMessage = "Timer has already been destroyed";
|
|
25
28
|
const endTypes = /* @__PURE__ */ new Set(["pause", "stop"]);
|
|
26
29
|
const endOrRestartTypes = /* @__PURE__ */ new Set([
|
|
@@ -31,10 +34,10 @@ const endOrRestartTypes = /* @__PURE__ */ new Set([
|
|
|
31
34
|
const hiddenTimers = /* @__PURE__ */ new Set();
|
|
32
35
|
const pauseTypes = /* @__PURE__ */ new Set(["continue", "pause"]);
|
|
33
36
|
const startedMessage = "Timer has already been started";
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
exports.milliseconds =
|
|
37
|
-
|
|
37
|
+
exports.milliseconds = 1e3 / 60;
|
|
38
|
+
calculate().then((value) => {
|
|
39
|
+
exports.milliseconds = value;
|
|
40
|
+
});
|
|
38
41
|
|
|
39
42
|
exports.activeTimers = activeTimers;
|
|
40
43
|
exports.beginTypes = beginTypes;
|
|
@@ -42,5 +45,6 @@ exports.destroyedMessage = destroyedMessage;
|
|
|
42
45
|
exports.endOrRestartTypes = endOrRestartTypes;
|
|
43
46
|
exports.endTypes = endTypes;
|
|
44
47
|
exports.hiddenTimers = hiddenTimers;
|
|
48
|
+
exports.intervalBuffer = intervalBuffer;
|
|
45
49
|
exports.pauseTypes = pauseTypes;
|
|
46
50
|
exports.startedMessage = startedMessage;
|
package/dist/constants.js
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
function calculate() {
|
|
2
|
+
return new Promise((resolve) => {
|
|
3
|
+
const values = [];
|
|
4
|
+
let last;
|
|
5
|
+
function step(now) {
|
|
6
|
+
if (last != null) {
|
|
7
|
+
values.push(now - last);
|
|
8
|
+
}
|
|
9
|
+
last = now;
|
|
10
|
+
if (values.length >= 10) {
|
|
11
|
+
const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4);
|
|
12
|
+
resolve(median);
|
|
13
|
+
} else {
|
|
14
|
+
requestAnimationFrame(step);
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
+
requestAnimationFrame(step);
|
|
18
|
+
});
|
|
17
19
|
}
|
|
18
20
|
const activeTimers = /* @__PURE__ */ new Set();
|
|
19
21
|
const beginTypes = /* @__PURE__ */ new Set(["continue", "start"]);
|
|
22
|
+
const intervalBuffer = 5;
|
|
20
23
|
const destroyedMessage = "Timer has already been destroyed";
|
|
21
24
|
const endTypes = /* @__PURE__ */ new Set(["pause", "stop"]);
|
|
22
25
|
const endOrRestartTypes = /* @__PURE__ */ new Set([
|
|
@@ -27,9 +30,9 @@ const endOrRestartTypes = /* @__PURE__ */ new Set([
|
|
|
27
30
|
const hiddenTimers = /* @__PURE__ */ new Set();
|
|
28
31
|
const pauseTypes = /* @__PURE__ */ new Set(["continue", "pause"]);
|
|
29
32
|
const startedMessage = "Timer has already been started";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
let milliseconds = 1e3 / 60;
|
|
34
|
+
calculate().then((value) => {
|
|
35
|
+
milliseconds = value;
|
|
36
|
+
});
|
|
34
37
|
|
|
35
|
-
export { activeTimers, beginTypes, destroyedMessage, endOrRestartTypes, endTypes, hiddenTimers, milliseconds, pauseTypes, startedMessage };
|
|
38
|
+
export { activeTimers, beginTypes, destroyedMessage, endOrRestartTypes, endTypes, hiddenTimers, intervalBuffer, milliseconds, pauseTypes, startedMessage };
|
package/dist/delay.cjs
CHANGED
|
@@ -11,7 +11,7 @@ function delay(time) {
|
|
|
11
11
|
let start;
|
|
12
12
|
function step(now) {
|
|
13
13
|
start ??= now;
|
|
14
|
-
if (interval === constants.milliseconds || now - start >= interval -
|
|
14
|
+
if (interval === constants.milliseconds || now - start >= interval - constants.intervalBuffer) {
|
|
15
15
|
resolve();
|
|
16
16
|
} else {
|
|
17
17
|
requestAnimationFrame(step);
|
package/dist/delay.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { milliseconds } from './constants.js';
|
|
1
|
+
import { milliseconds, intervalBuffer } from './constants.js';
|
|
2
2
|
import { getValidNumber } from './get.js';
|
|
3
3
|
|
|
4
4
|
function delay(time) {
|
|
@@ -7,7 +7,7 @@ function delay(time) {
|
|
|
7
7
|
let start;
|
|
8
8
|
function step(now) {
|
|
9
9
|
start ??= now;
|
|
10
|
-
if (interval === milliseconds || now - start >= interval -
|
|
10
|
+
if (interval === milliseconds || now - start >= interval - intervalBuffer) {
|
|
11
11
|
resolve();
|
|
12
12
|
} else {
|
|
13
13
|
requestAnimationFrame(step);
|
package/dist/repeat.cjs
CHANGED
|
@@ -4,14 +4,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
|
|
5
5
|
const constants = require('./constants.cjs');
|
|
6
6
|
const get = require('./get.cjs');
|
|
7
|
+
require('./global.cjs');
|
|
7
8
|
const models = require('./models.cjs');
|
|
8
9
|
const timer = require('./timer.cjs');
|
|
9
|
-
const work = require('./work.cjs');
|
|
10
10
|
|
|
11
11
|
function repeat(callback, options) {
|
|
12
12
|
return new timer.Timer(
|
|
13
13
|
"repeat",
|
|
14
|
-
work.work,
|
|
15
14
|
{
|
|
16
15
|
callback: get.getCallback(callback),
|
|
17
16
|
trace: new models.TimerTrace().stack
|
package/dist/repeat.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { milliseconds } from './constants.js';
|
|
2
2
|
import { getCallback, getValidNumber } from './get.js';
|
|
3
|
+
import './global.js';
|
|
3
4
|
import { TimerTrace } from './models.js';
|
|
4
5
|
import { Timer } from './timer.js';
|
|
5
|
-
import { work } from './work.js';
|
|
6
6
|
|
|
7
7
|
function repeat(callback, options) {
|
|
8
8
|
return new Timer(
|
|
9
9
|
"repeat",
|
|
10
|
-
work,
|
|
11
10
|
{
|
|
12
11
|
callback: getCallback(callback),
|
|
13
12
|
trace: new TimerTrace().stack
|
package/dist/timer.cjs
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const _function = require('@oscarpalmer/atoms/function');
|
|
6
|
+
const work = require('./work.cjs');
|
|
6
7
|
|
|
7
8
|
class Timer {
|
|
8
|
-
constructor(type,
|
|
9
|
-
this.worker = worker;
|
|
9
|
+
constructor(type, state, options, start) {
|
|
10
10
|
this.options = options;
|
|
11
11
|
this.$timer = type;
|
|
12
12
|
this.state = {
|
|
@@ -62,8 +62,17 @@ class Timer {
|
|
|
62
62
|
this.options.onAfter = _function.noop;
|
|
63
63
|
this.options.onError = _function.noop;
|
|
64
64
|
this.state.callback = _function.noop;
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if (!globalThis._oscarpalmer_timer_debug) {
|
|
66
|
+
this.state.trace = void 0;
|
|
67
|
+
}
|
|
68
|
+
work.stop(
|
|
69
|
+
{
|
|
70
|
+
instance: this,
|
|
71
|
+
type: this.$timer
|
|
72
|
+
},
|
|
73
|
+
this.state,
|
|
74
|
+
this.options
|
|
75
|
+
);
|
|
67
76
|
}
|
|
68
77
|
/**
|
|
69
78
|
* Pause the timer _(if it's running)_
|
|
@@ -90,7 +99,7 @@ class Timer {
|
|
|
90
99
|
return this.#work("stop");
|
|
91
100
|
}
|
|
92
101
|
#work(type) {
|
|
93
|
-
return
|
|
102
|
+
return work.work(
|
|
94
103
|
type,
|
|
95
104
|
{
|
|
96
105
|
instance: this,
|
package/dist/timer.full.js
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
function calculate() {
|
|
2
|
+
return new Promise(resolve => {
|
|
3
|
+
const values = [];
|
|
4
|
+
let last;
|
|
5
|
+
function step(now) {
|
|
6
|
+
if (last != null) {
|
|
7
|
+
values.push(now - last);
|
|
8
|
+
}
|
|
9
|
+
last = now;
|
|
10
|
+
if (values.length >= 10) {
|
|
11
|
+
const median = values
|
|
12
|
+
.sort()
|
|
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
|
+
}
|
|
15
21
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
22
|
+
requestAnimationFrame(step);
|
|
23
|
+
});
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
26
|
* A set of all active timers
|
|
@@ -25,6 +30,10 @@ const activeTimers = new Set();
|
|
|
25
30
|
* A set of types that allow work to begin
|
|
26
31
|
*/
|
|
27
32
|
const beginTypes = new Set(['continue', 'start']);
|
|
33
|
+
/**
|
|
34
|
+
* Buffer value to use when evaluating if a specific time is within a certain range
|
|
35
|
+
*/
|
|
36
|
+
const intervalBuffer = 5;
|
|
28
37
|
/**
|
|
29
38
|
* Message to show when a when-timer is destroyed
|
|
30
39
|
*/
|
|
@@ -51,13 +60,13 @@ const pauseTypes = new Set(['continue', 'pause']);
|
|
|
51
60
|
*/
|
|
52
61
|
const startedMessage = 'Timer has already been started';
|
|
53
62
|
//
|
|
54
|
-
const values = [];
|
|
55
|
-
let last;
|
|
56
63
|
/**
|
|
57
64
|
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
58
65
|
*/
|
|
59
|
-
let milliseconds =
|
|
60
|
-
|
|
66
|
+
let milliseconds = 1000 / 60;
|
|
67
|
+
calculate().then(value => {
|
|
68
|
+
milliseconds = value;
|
|
69
|
+
});
|
|
61
70
|
|
|
62
71
|
if (globalThis._oscarpalmer_timers == null) {
|
|
63
72
|
Object.defineProperty(globalThis, '_oscarpalmer_timers', {
|
|
@@ -102,7 +111,8 @@ function delay(time) {
|
|
|
102
111
|
let start;
|
|
103
112
|
function step(now) {
|
|
104
113
|
start ??= now;
|
|
105
|
-
if (interval === milliseconds ||
|
|
114
|
+
if (interval === milliseconds ||
|
|
115
|
+
now - start >= interval - intervalBuffer) {
|
|
106
116
|
resolve();
|
|
107
117
|
}
|
|
108
118
|
else {
|
|
@@ -148,8 +158,92 @@ class TimerTrace extends Error {
|
|
|
148
158
|
}
|
|
149
159
|
}
|
|
150
160
|
|
|
161
|
+
function endOrRestart(type, timer, state, options) {
|
|
162
|
+
cancelAnimationFrame(state.frame);
|
|
163
|
+
if (type === 'stop') {
|
|
164
|
+
options.onAfter?.(false);
|
|
165
|
+
}
|
|
166
|
+
state.active = false;
|
|
167
|
+
state.frame = undefined;
|
|
168
|
+
state.paused = type === 'pause';
|
|
169
|
+
return type === 'restart'
|
|
170
|
+
? work('start', timer, state, options)
|
|
171
|
+
: timer.instance;
|
|
172
|
+
}
|
|
173
|
+
function finish(timer, state, options, success) {
|
|
174
|
+
activeTimers.delete(timer.instance);
|
|
175
|
+
state.active = false;
|
|
176
|
+
state.elapsed = 0;
|
|
177
|
+
state.frame = undefined;
|
|
178
|
+
if (timer.type === 'wait') {
|
|
179
|
+
state.callback();
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
options.onAfter?.(success);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function ignore(type, state) {
|
|
186
|
+
return ((state.destroyed && type !== 'stop') ||
|
|
187
|
+
(state.active ? beginTypes.has(type) : endTypes.has(type)));
|
|
188
|
+
}
|
|
189
|
+
function run(timer, state, options) {
|
|
190
|
+
let last;
|
|
191
|
+
return function step(now) {
|
|
192
|
+
if (!state.active) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
last ??= now;
|
|
196
|
+
const difference = now - last;
|
|
197
|
+
state.elapsed += difference;
|
|
198
|
+
state.total += difference;
|
|
199
|
+
last = now;
|
|
200
|
+
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
201
|
+
options.onError?.();
|
|
202
|
+
finish(timer, state, options, false);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (options.interval === milliseconds ||
|
|
206
|
+
state.elapsed >= options.interval - intervalBuffer) {
|
|
207
|
+
if (options.count > -1) {
|
|
208
|
+
state.callback(state.index);
|
|
209
|
+
}
|
|
210
|
+
state.elapsed = 0;
|
|
211
|
+
state.index += 1;
|
|
212
|
+
if (options.count === -1 ||
|
|
213
|
+
(options.count > 0 && state.index >= options.count)) {
|
|
214
|
+
finish(timer, state, options, true);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
state.frame = requestAnimationFrame(step);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function setState(type, state) {
|
|
222
|
+
const pausable = pauseTypes.has(type);
|
|
223
|
+
state.elapsed = pausable ? state.elapsed : 0;
|
|
224
|
+
state.index = pausable ? state.index : 0;
|
|
225
|
+
state.total = pausable ? state.total : 0;
|
|
226
|
+
}
|
|
227
|
+
function stop(timer, state, options) {
|
|
228
|
+
endOrRestart('stop', timer, state, options);
|
|
229
|
+
}
|
|
230
|
+
function work(type, timer, state, options) {
|
|
231
|
+
if (ignore(type, state)) {
|
|
232
|
+
return timer.instance;
|
|
233
|
+
}
|
|
234
|
+
setState(type, state);
|
|
235
|
+
if (endOrRestartTypes.has(type)) {
|
|
236
|
+
return endOrRestart(type, timer, state, options);
|
|
237
|
+
}
|
|
238
|
+
state.active = true;
|
|
239
|
+
state.paused = false;
|
|
240
|
+
activeTimers.add(timer.instance);
|
|
241
|
+
const runner = run(timer, state, options);
|
|
242
|
+
state.frame = requestAnimationFrame(runner);
|
|
243
|
+
return timer.instance;
|
|
244
|
+
}
|
|
245
|
+
|
|
151
246
|
class Timer {
|
|
152
|
-
worker;
|
|
153
247
|
options;
|
|
154
248
|
state;
|
|
155
249
|
/**
|
|
@@ -178,8 +272,7 @@ class Timer {
|
|
|
178
272
|
? this.state.trace
|
|
179
273
|
: undefined;
|
|
180
274
|
}
|
|
181
|
-
constructor(type,
|
|
182
|
-
this.worker = worker;
|
|
275
|
+
constructor(type, state, options, start) {
|
|
183
276
|
this.options = options;
|
|
184
277
|
this.$timer = type;
|
|
185
278
|
this.state = {
|
|
@@ -210,8 +303,13 @@ class Timer {
|
|
|
210
303
|
this.options.onAfter = noop;
|
|
211
304
|
this.options.onError = noop;
|
|
212
305
|
this.state.callback = noop;
|
|
213
|
-
|
|
214
|
-
|
|
306
|
+
if (!globalThis._oscarpalmer_timer_debug) {
|
|
307
|
+
this.state.trace = undefined;
|
|
308
|
+
}
|
|
309
|
+
stop({
|
|
310
|
+
instance: this,
|
|
311
|
+
type: this.$timer,
|
|
312
|
+
}, this.state, this.options);
|
|
215
313
|
}
|
|
216
314
|
/**
|
|
217
315
|
* Pause the timer _(if it's running)_
|
|
@@ -238,89 +336,18 @@ class Timer {
|
|
|
238
336
|
return this.#work('stop');
|
|
239
337
|
}
|
|
240
338
|
#work(type) {
|
|
241
|
-
return
|
|
339
|
+
return work(type, {
|
|
242
340
|
instance: this,
|
|
243
341
|
type: this.$timer,
|
|
244
342
|
}, this.state, this.options);
|
|
245
343
|
}
|
|
246
344
|
}
|
|
247
345
|
|
|
248
|
-
function finish(timer, state, options, success) {
|
|
249
|
-
activeTimers.delete(timer.instance);
|
|
250
|
-
state.active = false;
|
|
251
|
-
state.elapsed = 0;
|
|
252
|
-
state.frame = undefined;
|
|
253
|
-
if (timer.type === 'wait') {
|
|
254
|
-
state.callback();
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
options.onAfter?.(success);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
function work(type, timer, state, options) {
|
|
261
|
-
if ((state.destroyed && type !== 'stop') ||
|
|
262
|
-
(state.active ? beginTypes.has(type) : endTypes.has(type))) {
|
|
263
|
-
return timer.instance;
|
|
264
|
-
}
|
|
265
|
-
const pausable = pauseTypes.has(type);
|
|
266
|
-
state.elapsed = pausable ? state.elapsed : 0;
|
|
267
|
-
state.index = pausable ? state.index : 0;
|
|
268
|
-
state.total = pausable ? state.total : 0;
|
|
269
|
-
if (endOrRestartTypes.has(type)) {
|
|
270
|
-
activeTimers.delete(timer.instance);
|
|
271
|
-
cancelAnimationFrame(state.frame);
|
|
272
|
-
if (type === 'stop') {
|
|
273
|
-
options.onAfter?.(false);
|
|
274
|
-
}
|
|
275
|
-
state.active = false;
|
|
276
|
-
state.frame = undefined;
|
|
277
|
-
state.paused = type === 'pause';
|
|
278
|
-
return type === 'restart'
|
|
279
|
-
? work('start', timer, state, options)
|
|
280
|
-
: timer.instance;
|
|
281
|
-
}
|
|
282
|
-
state.active = true;
|
|
283
|
-
state.paused = false;
|
|
284
|
-
let start;
|
|
285
|
-
function step(now) {
|
|
286
|
-
if (!state.active) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
start ??= now;
|
|
290
|
-
const difference = now - start;
|
|
291
|
-
state.elapsed += difference;
|
|
292
|
-
state.total += difference;
|
|
293
|
-
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
294
|
-
options.onError?.();
|
|
295
|
-
finish(timer, state, options, false);
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
if (options.interval === milliseconds ||
|
|
299
|
-
state.elapsed >= options.interval - 5) {
|
|
300
|
-
if (options.count > -1) {
|
|
301
|
-
state.callback(state.index);
|
|
302
|
-
}
|
|
303
|
-
start = now;
|
|
304
|
-
state.elapsed = 0;
|
|
305
|
-
state.index += 1;
|
|
306
|
-
if (options.count === -1 ||
|
|
307
|
-
(options.count > 0 && state.index >= options.count)) {
|
|
308
|
-
finish(timer, state, options, true);
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
state.frame = requestAnimationFrame(step);
|
|
313
|
-
}
|
|
314
|
-
activeTimers.add(timer.instance);
|
|
315
|
-
state.frame = requestAnimationFrame(step);
|
|
316
|
-
return timer.instance;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
346
|
/**
|
|
320
347
|
* Create a repeating timer
|
|
321
348
|
*/
|
|
322
349
|
function repeat(callback, options) {
|
|
323
|
-
return new Timer('repeat',
|
|
350
|
+
return new Timer('repeat', {
|
|
324
351
|
callback: getCallback(callback),
|
|
325
352
|
trace: new TimerTrace().stack,
|
|
326
353
|
}, {
|
|
@@ -338,7 +365,7 @@ function repeat(callback, options) {
|
|
|
338
365
|
* @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
|
|
339
366
|
*/
|
|
340
367
|
function wait(callback, time) {
|
|
341
|
-
return new Timer('wait',
|
|
368
|
+
return new Timer('wait', {
|
|
342
369
|
callback: getCallback(callback),
|
|
343
370
|
trace: new TimerTrace().stack,
|
|
344
371
|
}, {
|
|
@@ -352,7 +379,13 @@ function wait(callback, time) {
|
|
|
352
379
|
|
|
353
380
|
class When {
|
|
354
381
|
$timer = 'when';
|
|
355
|
-
state
|
|
382
|
+
state = {
|
|
383
|
+
promise: undefined,
|
|
384
|
+
rejecter: undefined,
|
|
385
|
+
resolver: undefined,
|
|
386
|
+
started: false,
|
|
387
|
+
timer: undefined,
|
|
388
|
+
};
|
|
356
389
|
/**
|
|
357
390
|
* Is the timer active?
|
|
358
391
|
*/
|
|
@@ -379,8 +412,44 @@ class When {
|
|
|
379
412
|
? this.state.timer?.trace
|
|
380
413
|
: undefined;
|
|
381
414
|
}
|
|
382
|
-
constructor(
|
|
383
|
-
|
|
415
|
+
constructor(condition, options) {
|
|
416
|
+
const { state } = this;
|
|
417
|
+
state.promise = new Promise((resolve, reject) => {
|
|
418
|
+
state.resolver = resolve;
|
|
419
|
+
state.rejecter = reject;
|
|
420
|
+
});
|
|
421
|
+
let result = false;
|
|
422
|
+
this.state.timer = new Timer('when', {
|
|
423
|
+
callback() {
|
|
424
|
+
try {
|
|
425
|
+
if (condition()) {
|
|
426
|
+
result = true;
|
|
427
|
+
state.timer.stop();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
state.timer.stop();
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
trace: new TimerTrace().stack,
|
|
435
|
+
}, {
|
|
436
|
+
onAfter: () => {
|
|
437
|
+
if (result) {
|
|
438
|
+
state.resolver?.();
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
state.rejecter?.();
|
|
442
|
+
}
|
|
443
|
+
this.destroy();
|
|
444
|
+
},
|
|
445
|
+
onError: () => {
|
|
446
|
+
state.rejecter?.();
|
|
447
|
+
this.destroy();
|
|
448
|
+
},
|
|
449
|
+
count: getValidNumber(options?.count),
|
|
450
|
+
interval: getValidNumber(options?.interval, milliseconds),
|
|
451
|
+
timeout: getValidNumber(options?.timeout),
|
|
452
|
+
}, false);
|
|
384
453
|
}
|
|
385
454
|
/**
|
|
386
455
|
* Continues the timer _(if it was paused)_
|
|
@@ -393,11 +462,12 @@ class When {
|
|
|
393
462
|
* Destroys the timer _(and stops it,if it was running)_
|
|
394
463
|
*/
|
|
395
464
|
destroy() {
|
|
396
|
-
this
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
465
|
+
const { state } = this;
|
|
466
|
+
state.timer?.destroy();
|
|
467
|
+
state.promise = undefined;
|
|
468
|
+
state.resolver = noop;
|
|
469
|
+
state.rejecter = noop;
|
|
470
|
+
state.timer = undefined;
|
|
401
471
|
}
|
|
402
472
|
/**
|
|
403
473
|
* Pauses the timer _(if it was running)_
|
|
@@ -418,59 +488,23 @@ class When {
|
|
|
418
488
|
*/
|
|
419
489
|
// biome-ignore lint/suspicious/noThenProperty: returning a promise-like object, so it's ok ;)
|
|
420
490
|
then(resolve, reject) {
|
|
421
|
-
|
|
422
|
-
|
|
491
|
+
const { state } = this;
|
|
492
|
+
if (state.timer == null) {
|
|
493
|
+
throw new Error(destroyedMessage);
|
|
423
494
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
495
|
+
if (state.started) {
|
|
496
|
+
throw new Error(startedMessage);
|
|
497
|
+
}
|
|
498
|
+
state.started = true;
|
|
499
|
+
state.timer.start();
|
|
500
|
+
return state.promise.then(resolve ?? noop, reject ?? noop);
|
|
427
501
|
}
|
|
428
502
|
}
|
|
429
503
|
/**
|
|
430
504
|
* Create a conditional timer
|
|
431
505
|
*/
|
|
432
506
|
function when(condition, options) {
|
|
433
|
-
|
|
434
|
-
let result = false;
|
|
435
|
-
const state = {
|
|
436
|
-
started: false,
|
|
437
|
-
timer: new Timer('when', work, {
|
|
438
|
-
callback() {
|
|
439
|
-
if (condition()) {
|
|
440
|
-
result = true;
|
|
441
|
-
state.timer.stop();
|
|
442
|
-
}
|
|
443
|
-
},
|
|
444
|
-
trace: new TimerTrace().stack,
|
|
445
|
-
}, {
|
|
446
|
-
onAfter() {
|
|
447
|
-
if (!(state.timer?.paused ?? false) && !called) {
|
|
448
|
-
called = true;
|
|
449
|
-
if (result) {
|
|
450
|
-
state.resolver?.();
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
state.rejecter?.();
|
|
454
|
-
}
|
|
455
|
-
instance.destroy();
|
|
456
|
-
}
|
|
457
|
-
},
|
|
458
|
-
onError() {
|
|
459
|
-
state.rejecter?.();
|
|
460
|
-
instance.destroy();
|
|
461
|
-
},
|
|
462
|
-
count: getValidNumber(options?.count),
|
|
463
|
-
interval: getValidNumber(options?.interval, milliseconds),
|
|
464
|
-
timeout: getValidNumber(options?.timeout),
|
|
465
|
-
}, false),
|
|
466
|
-
};
|
|
467
|
-
const promise = new Promise((resolve, reject) => {
|
|
468
|
-
state.resolver = resolve;
|
|
469
|
-
state.rejecter = reject;
|
|
470
|
-
});
|
|
471
|
-
state.promise = promise;
|
|
472
|
-
const instance = new When(state);
|
|
473
|
-
return instance;
|
|
507
|
+
return new When(condition, options);
|
|
474
508
|
}
|
|
475
509
|
|
|
476
510
|
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|