@oscarpalmer/timer 0.44.0 → 0.46.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 +134 -254
- package/dist/{get.d.mts → misc.d.mts} +6 -3
- package/dist/misc.mjs +37 -0
- package/dist/models.d.mts +25 -3
- package/dist/repeat.mjs +1 -1
- package/dist/timer.mjs +15 -28
- package/dist/wait.mjs +1 -1
- package/dist/when.mjs +11 -24
- package/dist/work.d.mts +3 -3
- package/dist/work.mjs +27 -35
- 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 +55 -0
- package/src/models.ts +25 -2
- package/src/repeat.ts +1 -1
- package/src/timer.ts +17 -43
- package/src/wait.ts +1 -1
- package/src/when.ts +12 -33
- package/src/work.ts +34 -61
- package/dist/delay.d.mts +0 -2
- package/dist/delay.mjs +0 -2
- 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,110 +17,123 @@ const WORK_RESTART = "restart";
|
|
|
25
17
|
const WORK_START = "start";
|
|
26
18
|
const WORK_STOP = "stop";
|
|
27
19
|
//#endregion
|
|
28
|
-
//#region
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
});
|
|
20
|
+
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
21
|
+
/**
|
|
22
|
+
* A function that does nothing, which can be useful, I guess…
|
|
23
|
+
*/
|
|
24
|
+
function noop() {}
|
|
43
25
|
//#endregion
|
|
44
|
-
//#region
|
|
45
|
-
function
|
|
46
|
-
|
|
26
|
+
//#region src/work.ts
|
|
27
|
+
function finish(state, success) {
|
|
28
|
+
updateStates(state);
|
|
29
|
+
cancelAnimationFrame(state.frame);
|
|
30
|
+
state.active = false;
|
|
31
|
+
state.elapsed = 0;
|
|
32
|
+
state.frame = void 0;
|
|
33
|
+
if (state.name === "wait") state.callback();
|
|
34
|
+
else state.options.onAfter?.(success);
|
|
47
35
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
36
|
+
function ignore(type, state) {
|
|
37
|
+
if (state.paused) return type === "pause" || type === "start";
|
|
38
|
+
return state.active && (type === "continue" || type === "start");
|
|
39
|
+
}
|
|
40
|
+
function run(state) {
|
|
41
|
+
let last;
|
|
42
|
+
return function step(now) {
|
|
43
|
+
if (!state.active) return;
|
|
44
|
+
last ??= now;
|
|
45
|
+
const difference = now - last;
|
|
46
|
+
state.elapsed += difference;
|
|
47
|
+
state.total += difference;
|
|
48
|
+
last = now;
|
|
49
|
+
if (state.options.timeout > 0 && state.total >= state.options.timeout) {
|
|
50
|
+
state.options.onError?.();
|
|
51
|
+
finish(state, false);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (state.options.interval === 0 || state.elapsed >= state.options.interval - 5) {
|
|
55
|
+
if (state.options.count > -1) state.callback(state.index);
|
|
56
|
+
state.elapsed = 0;
|
|
57
|
+
state.index += 1;
|
|
58
|
+
if (state.options.count === -1 || state.options.count > 0 && state.index >= state.options.count) {
|
|
59
|
+
finish(state, true);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
state.frame = requestAnimationFrame(step);
|
|
70
64
|
};
|
|
71
|
-
return timer;
|
|
72
65
|
}
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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;
|
|
66
|
+
function setState(type, state) {
|
|
67
|
+
const pausable = type === "continue" || type === "pause";
|
|
68
|
+
state.elapsed = pausable ? state.elapsed : 0;
|
|
69
|
+
state.index = pausable ? state.index : 0;
|
|
70
|
+
state.total = pausable ? state.total : 0;
|
|
88
71
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
};
|
|
72
|
+
function stop(state) {
|
|
73
|
+
updateStates(state);
|
|
74
|
+
cancelAnimationFrame(state.frame);
|
|
75
|
+
state.options.onAfter?.(false);
|
|
76
|
+
state.active = false;
|
|
77
|
+
state.frame = void 0;
|
|
78
|
+
state.paused = false;
|
|
79
|
+
return state.timer;
|
|
102
80
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
81
|
+
function work(type, state, hide) {
|
|
82
|
+
if (ignore(type, state)) return state.timer;
|
|
83
|
+
setState(type, state);
|
|
84
|
+
if (type === "stop") return stop(state);
|
|
85
|
+
if (type === "pause" || type === "restart") {
|
|
86
|
+
cancelAnimationFrame(state.frame);
|
|
87
|
+
state.frame = void 0;
|
|
88
|
+
}
|
|
89
|
+
state.active = true;
|
|
90
|
+
state.paused = type === WORK_PAUSE;
|
|
91
|
+
updateStates(state, state.paused ? hide : false);
|
|
92
|
+
if (state.paused) return state.timer;
|
|
93
|
+
const runner = run(state);
|
|
94
|
+
state.frame = requestAnimationFrame(runner);
|
|
95
|
+
return state.timer;
|
|
108
96
|
}
|
|
109
97
|
//#endregion
|
|
110
|
-
//#region
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
98
|
+
//#region src/misc.ts
|
|
99
|
+
function getCallback(value) {
|
|
100
|
+
return typeof value === "function" ? value : noop;
|
|
101
|
+
}
|
|
102
|
+
function getValidNumber(value, defaultValue) {
|
|
103
|
+
const actualDefault = defaultValue ?? 0;
|
|
104
|
+
return typeof value === "number" && value > actualDefault ? value : actualDefault;
|
|
105
|
+
}
|
|
106
|
+
function getValidTimeout(value) {
|
|
107
|
+
return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
|
|
108
|
+
}
|
|
109
|
+
/* istanbul ignore next */
|
|
110
|
+
function onVisibilityChange() {
|
|
111
|
+
const from = document.hidden ? STATES.active : STATES.hidden;
|
|
112
|
+
const type = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
|
|
113
|
+
for (const stored of from) {
|
|
114
|
+
const state = stored instanceof WeakRef ? stored.deref() : stored;
|
|
115
|
+
if (state == null) from.delete(stored);
|
|
116
|
+
else work(type, state, true);
|
|
117
117
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
});
|
|
118
|
+
}
|
|
119
|
+
function updateStates(state, hide) {
|
|
120
|
+
STATES.active.delete(state);
|
|
121
|
+
/* istanbul ignore next */
|
|
122
|
+
STATES.hidden.delete(state.reference);
|
|
123
|
+
if (hide == null) return;
|
|
124
|
+
/* istanbul ignore if */
|
|
125
|
+
if (hide) {
|
|
126
|
+
state.reference ??= new WeakRef(state);
|
|
127
|
+
STATES.hidden.add(state.reference);
|
|
128
|
+
} else STATES.active.add(state);
|
|
130
129
|
}
|
|
131
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
|
|
132
137
|
//#region src/is.ts
|
|
133
138
|
function is(names, value) {
|
|
134
139
|
return names.includes(value?.$timer);
|
|
@@ -166,24 +171,6 @@ function isWhen(value) {
|
|
|
166
171
|
return is(["when"], value) && typeof value.start === "function";
|
|
167
172
|
}
|
|
168
173
|
//#endregion
|
|
169
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
170
|
-
/**
|
|
171
|
-
* A function that does nothing, which can be useful, I guess…
|
|
172
|
-
*/
|
|
173
|
-
function noop() {}
|
|
174
|
-
//#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
174
|
//#region src/models.ts
|
|
188
175
|
var TimerTrace = class extends Error {
|
|
189
176
|
constructor() {
|
|
@@ -192,112 +179,28 @@ var TimerTrace = class extends Error {
|
|
|
192
179
|
}
|
|
193
180
|
};
|
|
194
181
|
//#endregion
|
|
195
|
-
//#region src/work.ts
|
|
196
|
-
function finish(timer, state, options, success) {
|
|
197
|
-
cancelAnimationFrame(state.frame);
|
|
198
|
-
TIMERS_ACTIVE.delete(timer.instance);
|
|
199
|
-
state.active = false;
|
|
200
|
-
state.elapsed = 0;
|
|
201
|
-
state.frame = void 0;
|
|
202
|
-
if (timer.name === "wait") state.callback();
|
|
203
|
-
else options.onAfter?.(success);
|
|
204
|
-
}
|
|
205
|
-
function ignore(type, state) {
|
|
206
|
-
if (state.destroyed) return type !== WORK_STOP;
|
|
207
|
-
if (state.paused) return type === "pause" || type === "start";
|
|
208
|
-
return state.active && type === "start";
|
|
209
|
-
}
|
|
210
|
-
function pause(timer, state) {
|
|
211
|
-
cancelAnimationFrame(state.frame);
|
|
212
|
-
state.frame = void 0;
|
|
213
|
-
return timer.instance;
|
|
214
|
-
}
|
|
215
|
-
function run(timer, state, options) {
|
|
216
|
-
let last;
|
|
217
|
-
let start;
|
|
218
|
-
return function step(now) {
|
|
219
|
-
if (!state.active) return;
|
|
220
|
-
last ??= now;
|
|
221
|
-
start ??= now;
|
|
222
|
-
const difference = now - last;
|
|
223
|
-
state.elapsed += difference;
|
|
224
|
-
state.total += difference;
|
|
225
|
-
last = now;
|
|
226
|
-
if (options.timeout > 0 && state.total >= options.timeout) {
|
|
227
|
-
options.onError?.();
|
|
228
|
-
finish(timer, state, options, false);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
if (options.interval === 0 || state.elapsed >= options.interval - 5) {
|
|
232
|
-
if (options.count > -1) state.callback(state.index);
|
|
233
|
-
start = now;
|
|
234
|
-
state.elapsed = 0;
|
|
235
|
-
state.index += 1;
|
|
236
|
-
if (options.count === -1 || options.count > 0 && state.index >= options.count) {
|
|
237
|
-
finish(timer, state, options, true);
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
state.frame = requestAnimationFrame(step);
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function setState(type, state) {
|
|
245
|
-
const pausable = type === "continue" || type === "pause";
|
|
246
|
-
state.elapsed = pausable ? state.elapsed : 0;
|
|
247
|
-
state.index = pausable ? state.index : 0;
|
|
248
|
-
state.total = pausable ? state.total : 0;
|
|
249
|
-
}
|
|
250
|
-
function stop(timer, state, options) {
|
|
251
|
-
cancelAnimationFrame(state.frame);
|
|
252
|
-
TIMERS_ACTIVE.delete(timer.instance);
|
|
253
|
-
options.onAfter?.(false);
|
|
254
|
-
state.active = !stop;
|
|
255
|
-
state.frame = void 0;
|
|
256
|
-
state.paused = false;
|
|
257
|
-
return timer.instance;
|
|
258
|
-
}
|
|
259
|
-
function work(type, timer, state, options) {
|
|
260
|
-
if (ignore(type, state)) return timer.instance;
|
|
261
|
-
setState(type, state);
|
|
262
|
-
if (type === "stop") return stop(timer, state, options);
|
|
263
|
-
if (type === "pause" || type === "restart") {
|
|
264
|
-
cancelAnimationFrame(state.frame);
|
|
265
|
-
state.frame = void 0;
|
|
266
|
-
}
|
|
267
|
-
state.active = true;
|
|
268
|
-
state.paused = type === WORK_PAUSE;
|
|
269
|
-
if (state.paused) return pause(timer, state);
|
|
270
|
-
TIMERS_ACTIVE.add(timer.instance);
|
|
271
|
-
const runner = run(timer, state, options);
|
|
272
|
-
state.frame = requestAnimationFrame(runner);
|
|
273
|
-
return timer.instance;
|
|
274
|
-
}
|
|
275
|
-
//#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: {
|
|
@@ -306,11 +209,11 @@ function createTimer(name, pick, options, start) {
|
|
|
306
209
|
},
|
|
307
210
|
active: {
|
|
308
211
|
enumerable: true,
|
|
309
|
-
get: () => state.active
|
|
212
|
+
get: () => state.active && !state.paused
|
|
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 };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { TimerState } from "./models.mjs";
|
|
1
2
|
import { GenericCallback } from "@oscarpalmer/atoms/models";
|
|
2
|
-
//#region src/
|
|
3
|
+
//#region src/misc.d.ts
|
|
3
4
|
declare function getCallback(value: unknown): GenericCallback;
|
|
4
|
-
declare function getValidTimeout(value: unknown): number;
|
|
5
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, hide?: boolean): void;
|
|
6
9
|
//#endregion
|
|
7
|
-
export { getCallback, getValidNumber, getValidTimeout };
|
|
10
|
+
export { getCallback, getValidNumber, getValidTimeout, onVisibilityChange, updateStates };
|
package/dist/misc.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
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) from.delete(stored);
|
|
22
|
+
else work(type, state, true);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function updateStates(state, hide) {
|
|
26
|
+
STATES.active.delete(state);
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
STATES.hidden.delete(state.reference);
|
|
29
|
+
if (hide == null) return;
|
|
30
|
+
/* istanbul ignore if */
|
|
31
|
+
if (hide) {
|
|
32
|
+
state.reference ??= new WeakRef(state);
|
|
33
|
+
STATES.hidden.add(state.reference);
|
|
34
|
+
} else STATES.active.add(state);
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
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,25 @@ 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
|
+
reference?: WeakRef<TimerState>;
|
|
92
|
+
timer: Timer;
|
|
85
93
|
total: number;
|
|
86
|
-
trace
|
|
94
|
+
trace?: string;
|
|
95
|
+
};
|
|
96
|
+
type TimerStates = {
|
|
97
|
+
/**
|
|
98
|
+
* A set of all active timers
|
|
99
|
+
*/
|
|
100
|
+
active: Set<TimerState>;
|
|
101
|
+
/**
|
|
102
|
+
* A set of timers that were paused due to the document being hidden
|
|
103
|
+
*/
|
|
104
|
+
hidden: Set<WeakRef<TimerState>>;
|
|
87
105
|
};
|
|
88
106
|
declare class TimerTrace extends Error {
|
|
89
107
|
constructor();
|
|
@@ -95,6 +113,8 @@ type When = {
|
|
|
95
113
|
get active(): boolean;
|
|
96
114
|
/**
|
|
97
115
|
* Is the timer destroyed?
|
|
116
|
+
*
|
|
117
|
+
* @deprecated Timers take care of their own cleanup; this always returns `false`
|
|
98
118
|
*/
|
|
99
119
|
get destroyed(): boolean;
|
|
100
120
|
/**
|
|
@@ -111,6 +131,8 @@ type When = {
|
|
|
111
131
|
continue(): When;
|
|
112
132
|
/**
|
|
113
133
|
* Destroys the timer _(and stops it,if it was running)_
|
|
134
|
+
*
|
|
135
|
+
* @deprecated Timers take care of their own cleanup
|
|
114
136
|
*/
|
|
115
137
|
destroy(): void;
|
|
116
138
|
/**
|
|
@@ -161,4 +183,4 @@ type WorkHandlerTimer = {
|
|
|
161
183
|
};
|
|
162
184
|
type WorkHandlerType = 'continue' | 'pause' | 'restart' | 'start' | 'stop';
|
|
163
185
|
//#endregion
|
|
164
|
-
export { RepeatOptions, Timer, TimerName, TimerOptions, TimerState, TimerTrace, When, WhenOptions, WhenState, WorkHandler, WorkHandlerTimer, WorkHandlerType };
|
|
186
|
+
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";
|