@oscarpalmer/timer 0.44.0 → 0.45.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.d.mts +3 -14
- package/dist/constants.mjs +5 -13
- package/dist/global.d.mts +3 -0
- package/dist/global.mjs +5 -14
- package/dist/index.d.mts +12 -33
- package/dist/index.mjs +132 -252
- package/dist/misc.d.mts +10 -0
- package/dist/misc.mjs +34 -0
- package/dist/models.d.mts +24 -3
- package/dist/repeat.mjs +1 -1
- package/dist/timer.mjs +14 -27
- package/dist/wait.mjs +1 -1
- package/dist/when.mjs +11 -24
- package/dist/work.d.mts +3 -3
- package/dist/work.mjs +26 -31
- package/package.json +2 -6
- package/src/constants.ts +5 -15
- package/src/global.ts +11 -21
- package/src/index.ts +0 -1
- package/src/misc.ts +49 -0
- package/src/models.ts +24 -2
- package/src/repeat.ts +1 -1
- package/src/timer.ts +16 -42
- package/src/wait.ts +1 -1
- package/src/when.ts +12 -33
- package/src/work.ts +33 -56
- package/dist/delay.d.mts +0 -2
- package/dist/delay.mjs +0 -2
- package/dist/get.d.mts +0 -7
- package/dist/get.mjs +0 -15
- package/src/delay.ts +0 -1
- package/src/get.ts +0 -17
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
//#region src/constants.ts
|
|
2
2
|
const DEFAULT_TIMEOUT = 3e4;
|
|
3
3
|
/**
|
|
4
|
-
* Message to show when a when-timer is destroyed
|
|
5
|
-
*/
|
|
6
|
-
const MESSAGE_DESTROYED = "Timer has already been destroyed";
|
|
7
|
-
/**
|
|
8
4
|
* Message to show when a when-timer is started
|
|
9
5
|
*/
|
|
10
6
|
const MESSAGE_STARTED = "Timer has already been started";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* A set of timers that were paused due to the document being hidden
|
|
17
|
-
*/
|
|
18
|
-
const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
|
|
7
|
+
const STATES = {
|
|
8
|
+
active: /* @__PURE__ */ new Set(),
|
|
9
|
+
hidden: /* @__PURE__ */ new Set()
|
|
10
|
+
};
|
|
19
11
|
const TYPE_REPEAT = "repeat";
|
|
20
12
|
const TYPE_WAIT = "wait";
|
|
21
13
|
const TYPE_WHEN = "when";
|
|
@@ -25,194 +17,27 @@ const WORK_RESTART = "restart";
|
|
|
25
17
|
const WORK_START = "start";
|
|
26
18
|
const WORK_STOP = "stop";
|
|
27
19
|
//#endregion
|
|
28
|
-
//#region src/global.ts
|
|
29
|
-
if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
30
|
-
return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
|
|
31
|
-
} });
|
|
32
|
-
/* istanbul ignore next */
|
|
33
|
-
document.addEventListener("visibilitychange", () => {
|
|
34
|
-
const from = document.hidden ? TIMERS_ACTIVE : TIMERS_HIDDEN;
|
|
35
|
-
const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
36
|
-
const to = document.hidden ? TIMERS_HIDDEN : TIMERS_ACTIVE;
|
|
37
|
-
for (const timer of from) {
|
|
38
|
-
timer[method]();
|
|
39
|
-
to.add(timer);
|
|
40
|
-
}
|
|
41
|
-
from.clear();
|
|
42
|
-
});
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/timer.mjs
|
|
45
|
-
function getInterval(value) {
|
|
46
|
-
return typeof value === "number" && value > 0 ? value : 0;
|
|
47
|
-
}
|
|
48
|
-
function getTimer(type, callback, time) {
|
|
49
|
-
function run() {
|
|
50
|
-
const now = performance.now();
|
|
51
|
-
start ??= now;
|
|
52
|
-
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
53
|
-
start = throttle ? now : void 0;
|
|
54
|
-
callback(...args);
|
|
55
|
-
} else id = startTimer(run);
|
|
56
|
-
}
|
|
57
|
-
const interval = getInterval(time);
|
|
58
|
-
const throttle = type === TIMER_THROTTLE;
|
|
59
|
-
let args;
|
|
60
|
-
let id;
|
|
61
|
-
let start;
|
|
62
|
-
const timer = (...parameters) => {
|
|
63
|
-
timer.cancel();
|
|
64
|
-
args = parameters;
|
|
65
|
-
if (throttle) run();
|
|
66
|
-
else id = startTimer(run);
|
|
67
|
-
};
|
|
68
|
-
timer.cancel = () => {
|
|
69
|
-
clearTimer(id);
|
|
70
|
-
};
|
|
71
|
-
return timer;
|
|
72
|
-
}
|
|
73
|
-
const OFFSET = 5;
|
|
74
|
-
const TIMER_THROTTLE = "throttle";
|
|
75
|
-
const TIMER_WAIT = "wait";
|
|
76
|
-
// istanbul ignore next
|
|
77
|
-
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
78
|
-
// istanbul ignore next
|
|
79
|
-
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region node_modules/@oscarpalmer/atoms/dist/promise/models.mjs
|
|
82
|
-
const PROMISE_ABORT_EVENT = "abort";
|
|
83
|
-
const PROMISE_ABORT_OPTIONS = { once: true };
|
|
84
|
-
//#endregion
|
|
85
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
86
|
-
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
87
|
-
return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? Math.floor(value) : defaultValue;
|
|
88
|
-
}
|
|
89
|
-
//#endregion
|
|
90
|
-
//#region node_modules/@oscarpalmer/atoms/dist/promise/helpers.mjs
|
|
91
|
-
function getPromiseOptions(input) {
|
|
92
|
-
if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
|
|
93
|
-
if (input instanceof AbortSignal) return {
|
|
94
|
-
signal: input,
|
|
95
|
-
time: 0
|
|
96
|
-
};
|
|
97
|
-
const options = typeof input === "object" && input !== null ? input : {};
|
|
98
|
-
return {
|
|
99
|
-
signal: options.signal instanceof AbortSignal ? options.signal : void 0,
|
|
100
|
-
time: getNumberOrDefault(options.time, 0)
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
//#endregion
|
|
104
|
-
//#region node_modules/@oscarpalmer/atoms/dist/promise/misc.mjs
|
|
105
|
-
function settlePromise(aborter, settler, value, signal) {
|
|
106
|
-
signal?.removeEventListener(PROMISE_ABORT_EVENT, aborter);
|
|
107
|
-
settler(value);
|
|
108
|
-
}
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region node_modules/@oscarpalmer/atoms/dist/promise/delay.mjs
|
|
111
|
-
function delay(options) {
|
|
112
|
-
const { signal, time } = getPromiseOptions(options);
|
|
113
|
-
if (signal?.aborted ?? false) return Promise.reject(signal.reason);
|
|
114
|
-
function abort() {
|
|
115
|
-
timer.cancel();
|
|
116
|
-
rejector(signal.reason);
|
|
117
|
-
}
|
|
118
|
-
const timer = getTimer(TIMER_WAIT, () => {
|
|
119
|
-
settlePromise(abort, resolver, void 0, signal);
|
|
120
|
-
}, time);
|
|
121
|
-
signal?.addEventListener(PROMISE_ABORT_EVENT, abort, PROMISE_ABORT_OPTIONS);
|
|
122
|
-
let rejector;
|
|
123
|
-
let resolver;
|
|
124
|
-
return new Promise((resolve, reject) => {
|
|
125
|
-
rejector = reject;
|
|
126
|
-
resolver = resolve;
|
|
127
|
-
if (time === 0) settlePromise(abort, resolve, void 0, signal);
|
|
128
|
-
else timer();
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region src/is.ts
|
|
133
|
-
function is(names, value) {
|
|
134
|
-
return names.includes(value?.$timer);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Is the value a repeating timer?
|
|
138
|
-
* @param value Value to check
|
|
139
|
-
* @returns `true` if the value is a repeating timer
|
|
140
|
-
*/
|
|
141
|
-
function isRepeated(value) {
|
|
142
|
-
return is([TYPE_REPEAT], value);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Is the value a timer?
|
|
146
|
-
* @param value Value to check
|
|
147
|
-
* @returns `true` if the value is a timer
|
|
148
|
-
*/
|
|
149
|
-
function isTimer(value) {
|
|
150
|
-
return is([TYPE_REPEAT, TYPE_WAIT], value);
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Is the value a waiting timer?
|
|
154
|
-
* @param value Value to check
|
|
155
|
-
* @returns `true` if the value is a waiting timer
|
|
156
|
-
*/
|
|
157
|
-
function isWaited(value) {
|
|
158
|
-
return is([TYPE_WAIT], value);
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Is the value a conditional timer?
|
|
162
|
-
* @param value Value to check
|
|
163
|
-
* @returns `true` if the value is a conditional timer
|
|
164
|
-
*/
|
|
165
|
-
function isWhen(value) {
|
|
166
|
-
return is(["when"], value) && typeof value.start === "function";
|
|
167
|
-
}
|
|
168
|
-
//#endregion
|
|
169
20
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
170
21
|
/**
|
|
171
22
|
* A function that does nothing, which can be useful, I guess…
|
|
172
23
|
*/
|
|
173
24
|
function noop() {}
|
|
174
25
|
//#endregion
|
|
175
|
-
//#region src/get.ts
|
|
176
|
-
function getCallback(value) {
|
|
177
|
-
return typeof value === "function" ? value : noop;
|
|
178
|
-
}
|
|
179
|
-
function getValidTimeout(value) {
|
|
180
|
-
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
181
|
-
}
|
|
182
|
-
function getValidNumber(value, defaultValue) {
|
|
183
|
-
const actualDefault = defaultValue ?? 0;
|
|
184
|
-
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
185
|
-
}
|
|
186
|
-
//#endregion
|
|
187
|
-
//#region src/models.ts
|
|
188
|
-
var TimerTrace = class extends Error {
|
|
189
|
-
constructor() {
|
|
190
|
-
super();
|
|
191
|
-
this.name = "TimerTrace";
|
|
192
|
-
}
|
|
193
|
-
};
|
|
194
|
-
//#endregion
|
|
195
26
|
//#region src/work.ts
|
|
196
|
-
function finish(
|
|
27
|
+
function finish(state, success) {
|
|
28
|
+
updateStates(state);
|
|
197
29
|
cancelAnimationFrame(state.frame);
|
|
198
|
-
TIMERS_ACTIVE.delete(timer.instance);
|
|
199
30
|
state.active = false;
|
|
200
31
|
state.elapsed = 0;
|
|
201
32
|
state.frame = void 0;
|
|
202
|
-
if (
|
|
203
|
-
else options.onAfter?.(success);
|
|
33
|
+
if (state.name === "wait") state.callback();
|
|
34
|
+
else state.options.onAfter?.(success);
|
|
204
35
|
}
|
|
205
36
|
function ignore(type, state) {
|
|
206
|
-
if (state.destroyed) return type !== WORK_STOP;
|
|
207
37
|
if (state.paused) return type === "pause" || type === "start";
|
|
208
38
|
return state.active && type === "start";
|
|
209
39
|
}
|
|
210
|
-
function
|
|
211
|
-
cancelAnimationFrame(state.frame);
|
|
212
|
-
state.frame = void 0;
|
|
213
|
-
return timer.instance;
|
|
214
|
-
}
|
|
215
|
-
function run(timer, state, options) {
|
|
40
|
+
function run(state) {
|
|
216
41
|
let last;
|
|
217
42
|
let start;
|
|
218
43
|
return function step(now) {
|
|
@@ -223,18 +48,18 @@ function run(timer, state, options) {
|
|
|
223
48
|
state.elapsed += difference;
|
|
224
49
|
state.total += difference;
|
|
225
50
|
last = now;
|
|
226
|
-
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
227
|
-
options.onError?.();
|
|
228
|
-
finish(
|
|
51
|
+
if (state.options.timeout > 0 && state.total >= state.options.timeout) {
|
|
52
|
+
state.options.onError?.();
|
|
53
|
+
finish(state, false);
|
|
229
54
|
return;
|
|
230
55
|
}
|
|
231
|
-
if (options.interval === 0 || state.elapsed >= options.interval - 5) {
|
|
232
|
-
if (options.count > -1) state.callback(state.index);
|
|
56
|
+
if (state.options.interval === 0 || state.elapsed >= state.options.interval - 5) {
|
|
57
|
+
if (state.options.count > -1) state.callback(state.index);
|
|
233
58
|
start = now;
|
|
234
59
|
state.elapsed = 0;
|
|
235
60
|
state.index += 1;
|
|
236
|
-
if (options.count === -1 || options.count > 0 && state.index >= options.count) {
|
|
237
|
-
finish(
|
|
61
|
+
if (state.options.count === -1 || state.options.count > 0 && state.index >= state.options.count) {
|
|
62
|
+
finish(state, true);
|
|
238
63
|
return;
|
|
239
64
|
}
|
|
240
65
|
}
|
|
@@ -247,57 +72,135 @@ function setState(type, state) {
|
|
|
247
72
|
state.index = pausable ? state.index : 0;
|
|
248
73
|
state.total = pausable ? state.total : 0;
|
|
249
74
|
}
|
|
250
|
-
function stop(
|
|
75
|
+
function stop(state) {
|
|
76
|
+
updateStates(state);
|
|
251
77
|
cancelAnimationFrame(state.frame);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
state.active = !stop;
|
|
78
|
+
state.options.onAfter?.(false);
|
|
79
|
+
state.active = false;
|
|
255
80
|
state.frame = void 0;
|
|
256
81
|
state.paused = false;
|
|
257
|
-
return timer
|
|
82
|
+
return state.timer;
|
|
258
83
|
}
|
|
259
|
-
function work(type,
|
|
260
|
-
if (ignore(type, state)) return timer
|
|
84
|
+
function work(type, state, hide) {
|
|
85
|
+
if (ignore(type, state)) return state.timer;
|
|
261
86
|
setState(type, state);
|
|
262
|
-
if (type === "stop") return stop(
|
|
87
|
+
if (type === "stop") return stop(state);
|
|
263
88
|
if (type === "pause" || type === "restart") {
|
|
264
89
|
cancelAnimationFrame(state.frame);
|
|
265
90
|
state.frame = void 0;
|
|
266
91
|
}
|
|
267
92
|
state.active = true;
|
|
268
93
|
state.paused = type === WORK_PAUSE;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const runner = run(
|
|
94
|
+
updateStates(state, state.paused ? hide ?? false ? "hidden" : void 0 : "active");
|
|
95
|
+
if (state.paused) return state.timer;
|
|
96
|
+
const runner = run(state);
|
|
272
97
|
state.frame = requestAnimationFrame(runner);
|
|
273
|
-
return timer
|
|
98
|
+
return state.timer;
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/misc.ts
|
|
102
|
+
function getCallback(value) {
|
|
103
|
+
return typeof value === "function" ? value : noop;
|
|
104
|
+
}
|
|
105
|
+
function getValidNumber(value, defaultValue) {
|
|
106
|
+
const actualDefault = defaultValue ?? 0;
|
|
107
|
+
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
108
|
+
}
|
|
109
|
+
function getValidTimeout(value) {
|
|
110
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
111
|
+
}
|
|
112
|
+
/* istanbul ignore next */
|
|
113
|
+
function onVisibilityChange() {
|
|
114
|
+
const from = document.hidden ? STATES.active : STATES.hidden;
|
|
115
|
+
const type = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
116
|
+
for (const stored of from) {
|
|
117
|
+
const state = stored instanceof WeakRef ? stored.deref() : stored;
|
|
118
|
+
if (state != null) work(type, state, true);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function updateStates(state, key) {
|
|
122
|
+
STATES.active.delete(state);
|
|
123
|
+
const hidden = [...STATES.hidden].find((stored) => stored.deref() === state);
|
|
124
|
+
/* istanbul ignore next */
|
|
125
|
+
if (hidden != null) STATES.hidden.delete(hidden);
|
|
126
|
+
if (key != null)
|
|
127
|
+
/* istanbul ignore next */
|
|
128
|
+
STATES[key].add(key === "hidden" ? new WeakRef(state) : state);
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/global.ts
|
|
132
|
+
Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
|
|
133
|
+
return globalThis._oscarpalmer_timer_debug ? [...STATES.active].map((state) => state.timer) : [];
|
|
134
|
+
} });
|
|
135
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/is.ts
|
|
138
|
+
function is(names, value) {
|
|
139
|
+
return names.includes(value?.$timer);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Is the value a repeating timer?
|
|
143
|
+
* @param value Value to check
|
|
144
|
+
* @returns `true` if the value is a repeating timer
|
|
145
|
+
*/
|
|
146
|
+
function isRepeated(value) {
|
|
147
|
+
return is([TYPE_REPEAT], value);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Is the value a timer?
|
|
151
|
+
* @param value Value to check
|
|
152
|
+
* @returns `true` if the value is a timer
|
|
153
|
+
*/
|
|
154
|
+
function isTimer(value) {
|
|
155
|
+
return is([TYPE_REPEAT, TYPE_WAIT], value);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Is the value a waiting timer?
|
|
159
|
+
* @param value Value to check
|
|
160
|
+
* @returns `true` if the value is a waiting timer
|
|
161
|
+
*/
|
|
162
|
+
function isWaited(value) {
|
|
163
|
+
return is([TYPE_WAIT], value);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Is the value a conditional timer?
|
|
167
|
+
* @param value Value to check
|
|
168
|
+
* @returns `true` if the value is a conditional timer
|
|
169
|
+
*/
|
|
170
|
+
function isWhen(value) {
|
|
171
|
+
return is(["when"], value) && typeof value.start === "function";
|
|
274
172
|
}
|
|
275
173
|
//#endregion
|
|
174
|
+
//#region src/models.ts
|
|
175
|
+
var TimerTrace = class extends Error {
|
|
176
|
+
constructor() {
|
|
177
|
+
super();
|
|
178
|
+
this.name = "TimerTrace";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
//#endregion
|
|
276
182
|
//#region src/timer.ts
|
|
277
183
|
function createTimer(name, pick, options, start) {
|
|
278
|
-
function worker(type) {
|
|
279
|
-
return work(type, {
|
|
280
|
-
name,
|
|
281
|
-
instance
|
|
282
|
-
}, state, options);
|
|
283
|
-
}
|
|
284
184
|
const state = {
|
|
285
185
|
...pick,
|
|
186
|
+
name,
|
|
187
|
+
options,
|
|
286
188
|
active: false,
|
|
287
189
|
destroyed: false,
|
|
288
190
|
elapsed: 0,
|
|
289
191
|
frame: void 0,
|
|
290
192
|
index: 0,
|
|
291
193
|
paused: false,
|
|
194
|
+
timer: void 0,
|
|
292
195
|
total: 0
|
|
293
196
|
};
|
|
294
197
|
const instance = {
|
|
295
|
-
continue: () =>
|
|
296
|
-
destroy:
|
|
297
|
-
pause: () =>
|
|
298
|
-
restart: () =>
|
|
299
|
-
start: () =>
|
|
300
|
-
stop: () =>
|
|
198
|
+
continue: () => work(WORK_CONTINUE, state),
|
|
199
|
+
destroy: noop,
|
|
200
|
+
pause: () => work(WORK_PAUSE, state),
|
|
201
|
+
restart: () => work(WORK_RESTART, state),
|
|
202
|
+
start: () => work(WORK_START, state),
|
|
203
|
+
stop: () => work(WORK_STOP, state)
|
|
301
204
|
};
|
|
302
205
|
Object.defineProperties(instance, {
|
|
303
206
|
$timer: {
|
|
@@ -310,7 +213,7 @@ function createTimer(name, pick, options, start) {
|
|
|
310
213
|
},
|
|
311
214
|
destroyed: {
|
|
312
215
|
enumerable: true,
|
|
313
|
-
|
|
216
|
+
value: false
|
|
314
217
|
},
|
|
315
218
|
paused: {
|
|
316
219
|
enumerable: true,
|
|
@@ -321,19 +224,9 @@ function createTimer(name, pick, options, start) {
|
|
|
321
224
|
get: () => globalThis._oscarpalmer_timer_debug ?? false ? state.trace : void 0
|
|
322
225
|
}
|
|
323
226
|
});
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
function destroyTimer(name, instance, state, options) {
|
|
328
|
-
state.destroyed = true;
|
|
329
|
-
options.onAfter = noop;
|
|
330
|
-
options.onError = noop;
|
|
331
|
-
state.callback = noop;
|
|
332
|
-
if (!globalThis._oscarpalmer_timer_debug) state.trace = void 0;
|
|
333
|
-
stop({
|
|
334
|
-
instance,
|
|
335
|
-
name
|
|
336
|
-
}, state, options);
|
|
227
|
+
state.timer = Object.freeze(instance);
|
|
228
|
+
if (start) state.timer.start();
|
|
229
|
+
return state.timer;
|
|
337
230
|
}
|
|
338
231
|
//#endregion
|
|
339
232
|
//#region src/repeat.ts
|
|
@@ -378,17 +271,9 @@ function wait(callback, time) {
|
|
|
378
271
|
}
|
|
379
272
|
//#endregion
|
|
380
273
|
//#region src/when.ts
|
|
381
|
-
function
|
|
382
|
-
state.timer?.destroy();
|
|
383
|
-
state.promise = void 0;
|
|
384
|
-
state.resolver = noop;
|
|
385
|
-
state.rejecter = noop;
|
|
386
|
-
state.timer = void 0;
|
|
387
|
-
}
|
|
388
|
-
function onAfter(instance, state) {
|
|
274
|
+
function onAfter(state) {
|
|
389
275
|
if (state.result) state.resolver?.();
|
|
390
276
|
else state.rejecter?.();
|
|
391
|
-
instance.destroy();
|
|
392
277
|
}
|
|
393
278
|
function onCallback(condition, state) {
|
|
394
279
|
try {
|
|
@@ -400,16 +285,11 @@ function onCallback(condition, state) {
|
|
|
400
285
|
state.timer.stop();
|
|
401
286
|
}
|
|
402
287
|
}
|
|
403
|
-
function onError(instance, state) {
|
|
404
|
-
state.rejecter?.();
|
|
405
|
-
instance.destroy();
|
|
406
|
-
}
|
|
407
288
|
function onWhen(type, instance, state) {
|
|
408
289
|
state.timer?.[type]?.();
|
|
409
290
|
return instance;
|
|
410
291
|
}
|
|
411
292
|
function startWhen(state, resolve) {
|
|
412
|
-
if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
|
|
413
293
|
if (state.started) throw new Error(MESSAGE_STARTED);
|
|
414
294
|
state.started = true;
|
|
415
295
|
state.timer.start();
|
|
@@ -437,18 +317,18 @@ function when(condition, options) {
|
|
|
437
317
|
callback: () => onCallback(condition, state),
|
|
438
318
|
trace: new TimerTrace().stack
|
|
439
319
|
}, {
|
|
440
|
-
onAfter: () => onAfter(
|
|
441
|
-
onError: () =>
|
|
320
|
+
onAfter: () => onAfter(state),
|
|
321
|
+
onError: () => state.rejecter?.(),
|
|
442
322
|
count: getValidNumber(options?.count),
|
|
443
323
|
interval: getValidNumber(options?.interval),
|
|
444
324
|
timeout: getValidTimeout(options?.timeout)
|
|
445
325
|
}, false);
|
|
446
326
|
instance = {
|
|
447
327
|
continue: () => onWhen(WORK_CONTINUE, instance, state),
|
|
448
|
-
destroy:
|
|
449
|
-
pause: () => onWhen(
|
|
328
|
+
destroy: noop,
|
|
329
|
+
pause: () => onWhen(WORK_PAUSE, instance, state),
|
|
450
330
|
start: (resolve) => startWhen(state, resolve),
|
|
451
|
-
stop: () => onWhen(
|
|
331
|
+
stop: () => onWhen(WORK_STOP, instance, state)
|
|
452
332
|
};
|
|
453
333
|
Object.defineProperties(instance, {
|
|
454
334
|
$timer: {
|
|
@@ -457,15 +337,15 @@ function when(condition, options) {
|
|
|
457
337
|
},
|
|
458
338
|
active: {
|
|
459
339
|
enumerable: true,
|
|
460
|
-
get: () => state.timer
|
|
340
|
+
get: () => state.timer.active
|
|
461
341
|
},
|
|
462
342
|
destroyed: {
|
|
463
343
|
enumerable: true,
|
|
464
|
-
|
|
344
|
+
value: false
|
|
465
345
|
},
|
|
466
346
|
paused: {
|
|
467
347
|
enumerable: true,
|
|
468
|
-
get: () => state.timer
|
|
348
|
+
get: () => state.timer.paused
|
|
469
349
|
},
|
|
470
350
|
trace: {
|
|
471
351
|
enumerable: true,
|
|
@@ -475,4 +355,4 @@ function when(condition, options) {
|
|
|
475
355
|
return Object.freeze(instance);
|
|
476
356
|
}
|
|
477
357
|
//#endregion
|
|
478
|
-
export {
|
|
358
|
+
export { isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
|
package/dist/misc.d.mts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TimerState, TimerStates } from "./models.mjs";
|
|
2
|
+
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
3
|
+
//#region src/misc.d.ts
|
|
4
|
+
declare function getCallback(value: unknown): GenericCallback;
|
|
5
|
+
declare function getValidNumber(value: unknown, defaultValue?: number): number;
|
|
6
|
+
declare function getValidTimeout(value: unknown): number;
|
|
7
|
+
declare function onVisibilityChange(): void;
|
|
8
|
+
declare function updateStates(state: TimerState, key?: keyof TimerStates): void;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getCallback, getValidNumber, getValidTimeout, onVisibilityChange, updateStates };
|
package/dist/misc.mjs
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { DEFAULT_TIMEOUT, STATES, WORK_CONTINUE, WORK_PAUSE } from "./constants.mjs";
|
|
2
|
+
import { work } from "./work.mjs";
|
|
3
|
+
import { noop } from "@oscarpalmer/atoms/function";
|
|
4
|
+
//#region src/misc.ts
|
|
5
|
+
function getCallback(value) {
|
|
6
|
+
return typeof value === "function" ? value : noop;
|
|
7
|
+
}
|
|
8
|
+
function getValidNumber(value, defaultValue) {
|
|
9
|
+
const actualDefault = defaultValue ?? 0;
|
|
10
|
+
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
11
|
+
}
|
|
12
|
+
function getValidTimeout(value) {
|
|
13
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
14
|
+
}
|
|
15
|
+
/* istanbul ignore next */
|
|
16
|
+
function onVisibilityChange() {
|
|
17
|
+
const from = document.hidden ? STATES.active : STATES.hidden;
|
|
18
|
+
const type = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
19
|
+
for (const stored of from) {
|
|
20
|
+
const state = stored instanceof WeakRef ? stored.deref() : stored;
|
|
21
|
+
if (state != null) work(type, state, true);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function updateStates(state, key) {
|
|
25
|
+
STATES.active.delete(state);
|
|
26
|
+
const hidden = [...STATES.hidden].find((stored) => stored.deref() === state);
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
if (hidden != null) STATES.hidden.delete(hidden);
|
|
29
|
+
if (key != null)
|
|
30
|
+
/* istanbul ignore next */
|
|
31
|
+
STATES[key].add(key === "hidden" ? new WeakRef(state) : state);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { getCallback, getValidNumber, getValidTimeout, onVisibilityChange, updateStates };
|
package/dist/models.d.mts
CHANGED
|
@@ -31,6 +31,8 @@ type Timer = {
|
|
|
31
31
|
get active(): boolean;
|
|
32
32
|
/**
|
|
33
33
|
* Is the timer destroyed?
|
|
34
|
+
*
|
|
35
|
+
* @deprecated Timers take care of their own cleanup; this always returns `false`
|
|
34
36
|
*/
|
|
35
37
|
get destroyed(): boolean;
|
|
36
38
|
/**
|
|
@@ -47,6 +49,8 @@ type Timer = {
|
|
|
47
49
|
continue(): Timer;
|
|
48
50
|
/**
|
|
49
51
|
* Destroy the timer
|
|
52
|
+
*
|
|
53
|
+
* @deprecated Timers take care of their own cleanup
|
|
50
54
|
*/
|
|
51
55
|
destroy(): void;
|
|
52
56
|
/**
|
|
@@ -79,11 +83,24 @@ type TimerState = {
|
|
|
79
83
|
callback: () => void;
|
|
80
84
|
destroyed: boolean;
|
|
81
85
|
elapsed: number;
|
|
82
|
-
frame
|
|
86
|
+
frame?: number;
|
|
83
87
|
index: number;
|
|
88
|
+
name: TimerName;
|
|
89
|
+
options: TimerOptions;
|
|
84
90
|
paused: boolean;
|
|
91
|
+
timer: Timer;
|
|
85
92
|
total: number;
|
|
86
|
-
trace
|
|
93
|
+
trace?: string;
|
|
94
|
+
};
|
|
95
|
+
type TimerStates = {
|
|
96
|
+
/**
|
|
97
|
+
* A set of all active timers
|
|
98
|
+
*/
|
|
99
|
+
active: Set<TimerState>;
|
|
100
|
+
/**
|
|
101
|
+
* A set of timers that were paused due to the document being hidden
|
|
102
|
+
*/
|
|
103
|
+
hidden: Set<WeakRef<TimerState>>;
|
|
87
104
|
};
|
|
88
105
|
declare class TimerTrace extends Error {
|
|
89
106
|
constructor();
|
|
@@ -95,6 +112,8 @@ type When = {
|
|
|
95
112
|
get active(): boolean;
|
|
96
113
|
/**
|
|
97
114
|
* Is the timer destroyed?
|
|
115
|
+
*
|
|
116
|
+
* @deprecated Timers take care of their own cleanup; this always returns `false`
|
|
98
117
|
*/
|
|
99
118
|
get destroyed(): boolean;
|
|
100
119
|
/**
|
|
@@ -111,6 +130,8 @@ type When = {
|
|
|
111
130
|
continue(): When;
|
|
112
131
|
/**
|
|
113
132
|
* Destroys the timer _(and stops it,if it was running)_
|
|
133
|
+
*
|
|
134
|
+
* @deprecated Timers take care of their own cleanup
|
|
114
135
|
*/
|
|
115
136
|
destroy(): void;
|
|
116
137
|
/**
|
|
@@ -161,4 +182,4 @@ type WorkHandlerTimer = {
|
|
|
161
182
|
};
|
|
162
183
|
type WorkHandlerType = 'continue' | 'pause' | 'restart' | 'start' | 'stop';
|
|
163
184
|
//#endregion
|
|
164
|
-
export { RepeatOptions, Timer, TimerName, TimerOptions, TimerState, TimerTrace, When, WhenOptions, WhenState, WorkHandler, WorkHandlerTimer, WorkHandlerType };
|
|
185
|
+
export { RepeatOptions, Timer, TimerName, TimerOptions, TimerState, TimerStates, TimerTrace, When, WhenOptions, WhenState, WorkHandler, WorkHandlerTimer, WorkHandlerType };
|
package/dist/repeat.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TYPE_REPEAT } from "./constants.mjs";
|
|
2
|
-
import { getCallback, getValidNumber } from "./
|
|
2
|
+
import { getCallback, getValidNumber } from "./misc.mjs";
|
|
3
3
|
import "./global.mjs";
|
|
4
4
|
import { TimerTrace } from "./models.mjs";
|
|
5
5
|
import { createTimer } from "./timer.mjs";
|