@oscarpalmer/timer 0.36.0 → 0.38.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/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 +5 -4
- package/dist/index.js +4 -4
- package/dist/is.js +1 -1
- package/dist/repeat.js +2 -2
- package/dist/toretto.full.js +515 -0
- package/dist/wait.js +2 -2
- package/dist/when.js +11 -8
- package/dist/work.js +11 -11
- package/package.json +36 -61
- package/src/constants.ts +20 -14
- package/src/delay.ts +6 -7
- package/src/get.ts +4 -6
- package/src/global.ts +5 -9
- package/src/is.ts +9 -1
- 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/get.d.ts +1 -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 -16
- package/dist/global.cjs +0 -14
- 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 -67
- package/dist/timer.full.js +0 -530
- package/dist/wait.cjs +0 -18
- package/dist/when.cjs +0 -95
- package/dist/work.cjs +0 -82
- package/types/constants.d.cts +0 -104
- package/types/delay.d.cts +0 -8
- package/types/get.d.cts +0 -11
- package/types/global.d.cts +0 -3
- package/types/index.d.cts +0 -187
- package/types/is.d.cts +0 -144
- package/types/models.d.cts +0 -128
- package/types/repeat.d.cts +0 -99
- package/types/timer.d.cts +0 -70
- package/types/wait.d.cts +0 -76
- package/types/when.d.cts +0 -66
- package/types/work.d.cts +0 -81
package/README.md
CHANGED
|
@@ -36,24 +36,24 @@ const repeated = new Timer(repeatedCallback, 10);
|
|
|
36
36
|
|
|
37
37
|
When creating a _Timer_, either with the new `new`-keyword or using the functions, you can configure the timer with a few parameters:
|
|
38
38
|
|
|
39
|
-
|Parameter|Description|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
| Parameter | Description |
|
|
40
|
+
| ---------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `callback` | Callback function to be invoked for each run that are **required** for all timers.<br>For more information on callbacks, please read [the callbacks section](#callbacks). |
|
|
42
|
+
| `count` | How many times the timer should run.<br>If no value is provided, it will default to `1` when using the `new`-keyword and the `wait`-method, but throws an error for the `repeat`-method. |
|
|
43
|
+
| `time` | How many milliseconds between each invokations of the provided callback.<br>Defaults to `0`, which is not really _0_ milliseconds, but close enough :wink: |
|
|
44
|
+
| `after` | A callback to run after the timer finishes, both when cancelled and completed.<br>If _count_ is greater than `1` and _after_ **is not** `undefined`, a function is expected. |
|
|
45
45
|
|
|
46
46
|
## Methods and properties
|
|
47
47
|
|
|
48
48
|
An instance of _Timer_ also has a few helpful methods and properties:
|
|
49
49
|
|
|
50
|
-
|Name|Type|Description|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
| Name | Type | Description |
|
|
51
|
+
| ----------: | ---------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `active` | _Property_ | A `boolean` value to check if the timer is running |
|
|
53
|
+
| `finished` | _Property_ | A `boolean` value to check if the timer was able to finish |
|
|
54
|
+
| `start()` | _Method_ | Starts the timer.<br>Necessary when creating a timer using the class syntax _(e.g. `new Waited...`)_, but helpful when the timer needs to be started at other times, as well. |
|
|
55
|
+
| `stop()` | _Method_ | Stops the timer |
|
|
56
|
+
| `restart()` | _Method_ | Restarts the timer |
|
|
57
57
|
|
|
58
58
|
## Callbacks
|
|
59
59
|
|
package/dist/constants.js
CHANGED
|
@@ -5,20 +5,18 @@ function calculate() {
|
|
|
5
5
|
function step(now) {
|
|
6
6
|
if (last != null) values.push(now - last);
|
|
7
7
|
last = now;
|
|
8
|
-
if (values.length >= 10)
|
|
9
|
-
|
|
10
|
-
resolve(median);
|
|
11
|
-
} else requestAnimationFrame(step);
|
|
8
|
+
if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
|
|
9
|
+
else requestAnimationFrame(step);
|
|
12
10
|
}
|
|
13
11
|
requestAnimationFrame(step);
|
|
14
12
|
});
|
|
15
13
|
}
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
14
|
+
const BUFFER_INTERVAL = 5;
|
|
15
|
+
const DEFAULT_TIMEOUT = 3e4;
|
|
16
|
+
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
17
|
+
const MESSAGE_STARTED = "Timer has already been started";
|
|
18
|
+
const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
|
|
19
|
+
const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
|
|
22
20
|
const TYPE_REPEAT = "repeat";
|
|
23
21
|
const TYPE_WAIT = "wait";
|
|
24
22
|
const TYPE_WHEN = "when";
|
|
@@ -27,8 +25,8 @@ const WORK_PAUSE = "pause";
|
|
|
27
25
|
const WORK_RESTART = "restart";
|
|
28
26
|
const WORK_START = "start";
|
|
29
27
|
const WORK_STOP = "stop";
|
|
30
|
-
let
|
|
28
|
+
let MILLISECONDS = 1e3 / 60;
|
|
31
29
|
calculate().then((value) => {
|
|
32
|
-
|
|
30
|
+
MILLISECONDS = value;
|
|
33
31
|
});
|
|
34
|
-
export {
|
|
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 };
|
package/dist/delay.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BUFFER_INTERVAL, MILLISECONDS } 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, MILLISECONDS);
|
|
6
6
|
let start;
|
|
7
7
|
function step(now) {
|
|
8
8
|
start ??= now;
|
|
9
|
-
if (interval ===
|
|
9
|
+
if (interval === MILLISECONDS || now - start >= interval - 5) resolve();
|
|
10
10
|
else requestAnimationFrame(step);
|
|
11
11
|
}
|
|
12
12
|
requestAnimationFrame(step);
|
package/dist/get.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DEFAULT_TIMEOUT } from "./constants.js";
|
|
2
2
|
import { noop } from "@oscarpalmer/atoms/function";
|
|
3
3
|
function getCallback(value) {
|
|
4
4
|
return typeof value === "function" ? value : noop;
|
|
5
5
|
}
|
|
6
6
|
function getValidTimeout(value) {
|
|
7
|
-
return typeof value === "number" && value > 0 ? value :
|
|
7
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
8
8
|
}
|
|
9
9
|
function getValidNumber(value, defaultValue) {
|
|
10
10
|
const actualDefault = defaultValue ?? 0;
|
package/dist/global.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TIMERS_ACTIVE, TIMERS_HIDDEN, WORK_CONTINUE, WORK_PAUSE } from "./constants.js";
|
|
2
2
|
if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
3
|
-
return globalThis._oscarpalmer_timer_debug ? [...
|
|
3
|
+
return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
|
|
4
4
|
} });
|
|
5
|
+
/* istanbul ignore next */
|
|
5
6
|
document.addEventListener("visibilitychange", () => {
|
|
6
|
-
const from = document.hidden ?
|
|
7
|
+
const from = document.hidden ? TIMERS_ACTIVE : TIMERS_HIDDEN;
|
|
7
8
|
const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
8
|
-
const to = document.hidden ?
|
|
9
|
+
const to = document.hidden ? TIMERS_HIDDEN : TIMERS_ACTIVE;
|
|
9
10
|
for (const timer of from) {
|
|
10
11
|
timer[method]();
|
|
11
12
|
to.add(timer);
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { delay } from "./delay.js";
|
|
1
2
|
import "./global.js";
|
|
2
|
-
import { when } from "./when.js";
|
|
3
|
-
import { wait } from "./wait.js";
|
|
4
|
-
import { repeat } from "./repeat.js";
|
|
5
3
|
import { isRepeated, isTimer, isWaited, isWhen } from "./is.js";
|
|
6
|
-
import {
|
|
4
|
+
import { repeat } from "./repeat.js";
|
|
5
|
+
import { wait } from "./wait.js";
|
|
6
|
+
import { when } from "./when.js";
|
|
7
7
|
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
package/dist/is.js
CHANGED
|
@@ -12,6 +12,6 @@ function isWaited(value) {
|
|
|
12
12
|
return is([TYPE_WAIT], value);
|
|
13
13
|
}
|
|
14
14
|
function isWhen(value) {
|
|
15
|
-
return is([
|
|
15
|
+
return is(["when"], value) && typeof value.then === "function";
|
|
16
16
|
}
|
|
17
17
|
export { isRepeated, isTimer, isWaited, isWhen };
|
package/dist/repeat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MILLISECONDS, 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, MILLISECONDS),
|
|
15
15
|
timeout: getValidNumber(options?.timeout)
|
|
16
16
|
}, true);
|
|
17
17
|
}
|
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
function calculate$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
|
+
}
|
|
14
|
+
/**
|
|
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;
|
|
19
|
+
/**
|
|
20
|
+
* Message to show when a when-timer is destroyed
|
|
21
|
+
*/
|
|
22
|
+
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
23
|
+
/**
|
|
24
|
+
* Message to show when a when-timer is started
|
|
25
|
+
*/
|
|
26
|
+
const MESSAGE_STARTED = "Timer has already been started";
|
|
27
|
+
/**
|
|
28
|
+
* A set of all active timers
|
|
29
|
+
*/
|
|
30
|
+
const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
|
|
31
|
+
/**
|
|
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";
|
|
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
|
+
if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
52
|
+
return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
|
|
53
|
+
} });
|
|
54
|
+
/* istanbul ignore next */
|
|
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();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
var typeArrays = new Set([
|
|
67
|
+
Int8Array,
|
|
68
|
+
Uint8Array,
|
|
69
|
+
Uint8ClampedArray,
|
|
70
|
+
Int16Array,
|
|
71
|
+
Uint16Array,
|
|
72
|
+
Int32Array,
|
|
73
|
+
Uint32Array,
|
|
74
|
+
Float32Array,
|
|
75
|
+
Float64Array,
|
|
76
|
+
BigInt64Array,
|
|
77
|
+
BigUint64Array
|
|
78
|
+
]);
|
|
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
|
+
function getCallback(value) {
|
|
100
|
+
return typeof value === "function" ? value : noop;
|
|
101
|
+
}
|
|
102
|
+
function getValidTimeout(value) {
|
|
103
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
104
|
+
}
|
|
105
|
+
function getValidNumber(value, defaultValue) {
|
|
106
|
+
const actualDefault = defaultValue ?? 0;
|
|
107
|
+
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
108
|
+
}
|
|
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
|
+
function delay(time) {
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
const interval = getValidNumber(time, MILLISECONDS);
|
|
118
|
+
let start;
|
|
119
|
+
function step(now) {
|
|
120
|
+
start ??= now;
|
|
121
|
+
if (interval === MILLISECONDS || now - start >= interval - BUFFER_INTERVAL) resolve();
|
|
122
|
+
else requestAnimationFrame(step);
|
|
123
|
+
}
|
|
124
|
+
requestAnimationFrame(step);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function is(names, value) {
|
|
129
|
+
return names.includes(value?.$timer);
|
|
130
|
+
}
|
|
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
|
+
function isRepeated(value) {
|
|
137
|
+
return is([TYPE_REPEAT], value);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Is the value a timer?
|
|
141
|
+
* @param value Value to check
|
|
142
|
+
* @returns `true` if the value is a timer
|
|
143
|
+
*/
|
|
144
|
+
function isTimer(value) {
|
|
145
|
+
return is([TYPE_REPEAT, TYPE_WAIT], value);
|
|
146
|
+
}
|
|
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
|
+
function isWaited(value) {
|
|
153
|
+
return is([TYPE_WAIT], value);
|
|
154
|
+
}
|
|
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
|
+
function isWhen(value) {
|
|
161
|
+
return is([TYPE_WHEN], value) && typeof value.then === "function";
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var TimerTrace = class extends Error {
|
|
165
|
+
constructor() {
|
|
166
|
+
super();
|
|
167
|
+
this.name = "TimerTrace";
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
function finish(timer, state, options, success) {
|
|
172
|
+
cancelAnimationFrame(state.frame);
|
|
173
|
+
TIMERS_ACTIVE.delete(timer.instance);
|
|
174
|
+
state.active = false;
|
|
175
|
+
state.elapsed = 0;
|
|
176
|
+
state.frame = void 0;
|
|
177
|
+
if (timer.type === TYPE_WAIT) state.callback();
|
|
178
|
+
else options.onAfter?.(success);
|
|
179
|
+
}
|
|
180
|
+
function ignore(type, state) {
|
|
181
|
+
if (state.destroyed) return type !== WORK_STOP;
|
|
182
|
+
if (state.paused) return type === WORK_PAUSE || type === WORK_START;
|
|
183
|
+
return state.active && type === WORK_START;
|
|
184
|
+
}
|
|
185
|
+
function pause(timer, state) {
|
|
186
|
+
cancelAnimationFrame(state.frame);
|
|
187
|
+
state.frame = void 0;
|
|
188
|
+
return timer.instance;
|
|
189
|
+
}
|
|
190
|
+
function run(timer, state, options) {
|
|
191
|
+
let last;
|
|
192
|
+
let start;
|
|
193
|
+
return function step(now) {
|
|
194
|
+
if (!state.active) return;
|
|
195
|
+
last ??= now;
|
|
196
|
+
start ??= now;
|
|
197
|
+
const difference = now - last;
|
|
198
|
+
state.elapsed += difference;
|
|
199
|
+
state.total += difference;
|
|
200
|
+
last = now;
|
|
201
|
+
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
202
|
+
options.onError?.();
|
|
203
|
+
finish(timer, state, options, false);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (options.interval === MILLISECONDS || state.elapsed >= options.interval - BUFFER_INTERVAL) {
|
|
207
|
+
if (options.count > -1) state.callback(state.index);
|
|
208
|
+
start = now;
|
|
209
|
+
state.elapsed = 0;
|
|
210
|
+
state.index += 1;
|
|
211
|
+
if (options.count === -1 || options.count > 0 && state.index >= options.count) {
|
|
212
|
+
finish(timer, state, options, true);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
state.frame = requestAnimationFrame(step);
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function setState(type, state) {
|
|
220
|
+
const pausable = type === WORK_CONTINUE || type === WORK_PAUSE;
|
|
221
|
+
state.elapsed = pausable ? state.elapsed : 0;
|
|
222
|
+
state.index = pausable ? state.index : 0;
|
|
223
|
+
state.total = pausable ? state.total : 0;
|
|
224
|
+
}
|
|
225
|
+
function stop(timer, state, options) {
|
|
226
|
+
cancelAnimationFrame(state.frame);
|
|
227
|
+
TIMERS_ACTIVE.delete(timer.instance);
|
|
228
|
+
options.onAfter?.(false);
|
|
229
|
+
state.active = !stop;
|
|
230
|
+
state.frame = void 0;
|
|
231
|
+
state.paused = false;
|
|
232
|
+
return timer.instance;
|
|
233
|
+
}
|
|
234
|
+
function work(type, timer, state, options) {
|
|
235
|
+
if (ignore(type, state)) return timer.instance;
|
|
236
|
+
setState(type, state);
|
|
237
|
+
if (type === WORK_STOP) return stop(timer, state, options);
|
|
238
|
+
if (type === WORK_PAUSE || type === WORK_RESTART) {
|
|
239
|
+
cancelAnimationFrame(state.frame);
|
|
240
|
+
state.frame = void 0;
|
|
241
|
+
}
|
|
242
|
+
state.active = true;
|
|
243
|
+
state.paused = type === WORK_PAUSE;
|
|
244
|
+
if (state.paused) return pause(timer, state);
|
|
245
|
+
TIMERS_ACTIVE.add(timer.instance);
|
|
246
|
+
const runner = run(timer, state, options);
|
|
247
|
+
state.frame = requestAnimationFrame(runner);
|
|
248
|
+
return timer.instance;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var Timer = class {
|
|
252
|
+
state;
|
|
253
|
+
/**
|
|
254
|
+
* Is the timer active?
|
|
255
|
+
*/
|
|
256
|
+
get active() {
|
|
257
|
+
return this.state.active;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Is the timer destroyed?
|
|
261
|
+
*/
|
|
262
|
+
get destroyed() {
|
|
263
|
+
return this.state.destroyed;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Is the timer paused?
|
|
267
|
+
*/
|
|
268
|
+
get paused() {
|
|
269
|
+
return this.state.paused;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get the timer's origin _(if debugging is enabled)_
|
|
273
|
+
*/
|
|
274
|
+
get trace() {
|
|
275
|
+
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.trace : void 0;
|
|
276
|
+
}
|
|
277
|
+
constructor(type, state, options, start) {
|
|
278
|
+
this.options = options;
|
|
279
|
+
this.$timer = type;
|
|
280
|
+
this.state = {
|
|
281
|
+
...state,
|
|
282
|
+
active: false,
|
|
283
|
+
destroyed: false,
|
|
284
|
+
elapsed: 0,
|
|
285
|
+
frame: void 0,
|
|
286
|
+
index: 0,
|
|
287
|
+
paused: false,
|
|
288
|
+
total: 0
|
|
289
|
+
};
|
|
290
|
+
if (start) this.start();
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Continue running the timer _(if it's paused)_
|
|
294
|
+
*/
|
|
295
|
+
continue() {
|
|
296
|
+
return this.#work(WORK_CONTINUE);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Destroy the timer
|
|
300
|
+
*/
|
|
301
|
+
destroy() {
|
|
302
|
+
this.state.destroyed = true;
|
|
303
|
+
this.options.onAfter = noop;
|
|
304
|
+
this.options.onError = noop;
|
|
305
|
+
this.state.callback = noop;
|
|
306
|
+
if (!globalThis._oscarpalmer_timer_debug) this.state.trace = void 0;
|
|
307
|
+
stop({
|
|
308
|
+
instance: this,
|
|
309
|
+
type: this.$timer
|
|
310
|
+
}, this.state, this.options);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Pause the timer _(if it's running)_
|
|
314
|
+
*/
|
|
315
|
+
pause() {
|
|
316
|
+
return this.#work(WORK_PAUSE);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Restart the timer _(or start it, if it's not running)_
|
|
320
|
+
*/
|
|
321
|
+
restart() {
|
|
322
|
+
return this.#work(WORK_RESTART);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Start the timer _(if it's not running)_
|
|
326
|
+
*/
|
|
327
|
+
start() {
|
|
328
|
+
return this.#work(WORK_START);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Stop the timer _(if it's running)_
|
|
332
|
+
*/
|
|
333
|
+
stop() {
|
|
334
|
+
return this.#work(WORK_STOP);
|
|
335
|
+
}
|
|
336
|
+
#work(type) {
|
|
337
|
+
return work(type, {
|
|
338
|
+
instance: this,
|
|
339
|
+
type: this.$timer
|
|
340
|
+
}, this.state, this.options);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
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
|
+
function repeat(callback, options) {
|
|
351
|
+
return new Timer(TYPE_REPEAT, {
|
|
352
|
+
callback: getCallback(callback),
|
|
353
|
+
trace: new TimerTrace().stack
|
|
354
|
+
}, {
|
|
355
|
+
onAfter: getCallback(options?.onAfter),
|
|
356
|
+
onError: getCallback(options?.onTimeout),
|
|
357
|
+
count: getValidNumber(options?.count),
|
|
358
|
+
interval: getValidNumber(options?.interval, MILLISECONDS),
|
|
359
|
+
timeout: getValidNumber(options?.timeout)
|
|
360
|
+
}, true);
|
|
361
|
+
}
|
|
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
|
+
function wait(callback, time) {
|
|
369
|
+
return new Timer(TYPE_WAIT, {
|
|
370
|
+
callback: getCallback(callback),
|
|
371
|
+
trace: new TimerTrace().stack
|
|
372
|
+
}, {
|
|
373
|
+
onAfter: void 0,
|
|
374
|
+
onError: void 0,
|
|
375
|
+
count: -1,
|
|
376
|
+
interval: getValidNumber(time, MILLISECONDS),
|
|
377
|
+
timeout: 0
|
|
378
|
+
}, true);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
var When = class {
|
|
382
|
+
$timer = TYPE_WHEN;
|
|
383
|
+
state = {
|
|
384
|
+
promise: void 0,
|
|
385
|
+
rejecter: void 0,
|
|
386
|
+
resolver: void 0,
|
|
387
|
+
started: false,
|
|
388
|
+
timer: void 0
|
|
389
|
+
};
|
|
390
|
+
/**
|
|
391
|
+
* Is the timer active?
|
|
392
|
+
*/
|
|
393
|
+
get active() {
|
|
394
|
+
return this.state.timer?.active ?? false;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Is the timer destroyed?
|
|
398
|
+
*/
|
|
399
|
+
get destroyed() {
|
|
400
|
+
return this.state.timer == null;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Is the timer paused?
|
|
404
|
+
*/
|
|
405
|
+
get paused() {
|
|
406
|
+
return this.state.timer?.paused ?? false;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Get the timer's origin _(if debugging is enabled)_
|
|
410
|
+
*/
|
|
411
|
+
get trace() {
|
|
412
|
+
return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
|
|
413
|
+
}
|
|
414
|
+
constructor(condition, options) {
|
|
415
|
+
const { state } = this;
|
|
416
|
+
state.promise = new Promise((resolve, reject) => {
|
|
417
|
+
state.resolver = resolve;
|
|
418
|
+
state.rejecter = reject;
|
|
419
|
+
});
|
|
420
|
+
let result = false;
|
|
421
|
+
this.state.timer = new Timer(TYPE_WHEN, {
|
|
422
|
+
callback() {
|
|
423
|
+
try {
|
|
424
|
+
if (condition()) {
|
|
425
|
+
result = true;
|
|
426
|
+
state.timer.stop();
|
|
427
|
+
}
|
|
428
|
+
} catch {
|
|
429
|
+
state.timer.stop();
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
trace: new TimerTrace().stack
|
|
433
|
+
}, {
|
|
434
|
+
onAfter: () => {
|
|
435
|
+
if (result) state.resolver?.();
|
|
436
|
+
else state.rejecter?.();
|
|
437
|
+
this.destroy();
|
|
438
|
+
},
|
|
439
|
+
onError: () => {
|
|
440
|
+
state.rejecter?.();
|
|
441
|
+
this.destroy();
|
|
442
|
+
},
|
|
443
|
+
count: getValidNumber(options?.count),
|
|
444
|
+
interval: getValidNumber(options?.interval, MILLISECONDS),
|
|
445
|
+
timeout: getValidTimeout(options?.timeout)
|
|
446
|
+
}, false);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Continues the timer _(if it was paused)_
|
|
450
|
+
*/
|
|
451
|
+
continue() {
|
|
452
|
+
this.state.timer?.continue();
|
|
453
|
+
return this;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Destroys the timer _(and stops it,if it was running)_
|
|
457
|
+
*/
|
|
458
|
+
destroy() {
|
|
459
|
+
const { state } = this;
|
|
460
|
+
state.timer?.destroy();
|
|
461
|
+
state.promise = void 0;
|
|
462
|
+
state.resolver = noop;
|
|
463
|
+
state.rejecter = noop;
|
|
464
|
+
state.timer = void 0;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Pauses the timer _(if it was running)_
|
|
468
|
+
*/
|
|
469
|
+
pause() {
|
|
470
|
+
this.state.timer?.pause();
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
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
|
+
start(resolve, reject) {
|
|
480
|
+
const { state } = this;
|
|
481
|
+
if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
|
|
482
|
+
if (state.started) throw new Error(MESSAGE_STARTED);
|
|
483
|
+
state.started = true;
|
|
484
|
+
state.timer.start();
|
|
485
|
+
return state.promise.then(resolve ?? noop, reject ?? noop);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Stops the timer _(if it was running)_
|
|
489
|
+
*/
|
|
490
|
+
stop() {
|
|
491
|
+
this.state.timer?.stop();
|
|
492
|
+
return this;
|
|
493
|
+
}
|
|
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
|
+
then(resolve, reject) {
|
|
502
|
+
return this.start(resolve, reject);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Create a conditional timer
|
|
507
|
+
* @param condition Condition to check
|
|
508
|
+
* @param options Timer options
|
|
509
|
+
* @returns Timer instance
|
|
510
|
+
*/
|
|
511
|
+
function when(condition, options) {
|
|
512
|
+
return new When(condition, options);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
package/dist/wait.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MILLISECONDS, 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, MILLISECONDS),
|
|
15
15
|
timeout: 0
|
|
16
16
|
}, true);
|
|
17
17
|
}
|