@oscarpalmer/timer 0.28.0 → 0.29.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 +32 -4
- package/dist/constants.js +26 -9
- package/dist/delay.cjs +24 -0
- package/dist/delay.js +20 -0
- package/dist/get.cjs +15 -0
- package/dist/get.js +10 -0
- package/dist/global.cjs +17 -2
- package/dist/global.js +15 -1
- package/dist/index.cjs +16 -44
- package/dist/index.js +6 -50
- package/dist/is.cjs +11 -8
- package/dist/is.js +8 -12
- package/dist/models.cjs +5 -2
- package/dist/models.js +2 -3
- package/dist/node_modules/@oscarpalmer/atoms/dist/function.cjs +8 -0
- package/dist/node_modules/@oscarpalmer/atoms/dist/function.js +4 -0
- package/dist/repeat.cjs +30 -0
- package/dist/repeat.js +26 -0
- package/dist/timer.cjs +59 -71
- package/dist/timer.full.js +469 -0
- package/dist/timer.js +56 -72
- package/dist/wait.cjs +30 -0
- package/dist/wait.js +26 -0
- package/dist/when.cjs +59 -44
- package/dist/when.js +55 -44
- package/dist/work.cjs +72 -0
- package/dist/work.js +68 -0
- package/package.json +50 -9
- package/src/constants.ts +48 -6
- package/src/delay.ts +25 -0
- package/src/get.ts +12 -0
- package/src/global.ts +16 -1
- package/src/index.ts +5 -48
- package/src/is.ts +6 -6
- package/src/models.ts +55 -47
- package/src/repeat.ts +32 -0
- package/src/timer.ts +67 -151
- package/src/wait.ts +31 -0
- package/src/when.ts +49 -24
- package/src/work.ts +129 -0
- package/types/constants.d.cts +49 -74
- package/types/constants.d.ts +15 -6
- package/types/delay.d.cts +8 -0
- package/types/delay.d.ts +4 -0
- package/types/get.d.cts +7 -0
- package/types/get.d.ts +3 -0
- package/types/index.d.cts +89 -94
- package/types/index.d.ts +5 -6
- package/types/is.d.cts +50 -69
- package/types/models.d.cts +61 -63
- package/types/models.d.ts +43 -40
- package/types/repeat.d.cts +98 -0
- package/types/repeat.d.ts +7 -0
- package/types/timer.d.cts +35 -97
- package/types/timer.d.ts +19 -52
- package/types/wait.d.cts +83 -0
- package/types/wait.d.ts +8 -0
- package/types/when.d.cts +65 -69
- package/types/when.d.ts +18 -5
- package/types/work.d.cts +78 -0
- package/types/work.d.ts +3 -0
- package/dist/functions.cjs +0 -99
- package/dist/functions.js +0 -99
- package/dist/timer.iife.js +0 -431
- package/src/functions.ts +0 -158
- package/types/functions.d.cts +0 -113
- package/types/functions.d.ts +0 -4
package/dist/timer.iife.js
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
var Timer = (function (exports) {
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
function noop() {
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A set of all active timers
|
|
9
|
-
*/
|
|
10
|
-
const activeTimers = new Set();
|
|
11
|
-
/**
|
|
12
|
-
* A set of types that allow work to begin
|
|
13
|
-
*/
|
|
14
|
-
const beginTypes = new Set(['continue', 'start']);
|
|
15
|
-
/**
|
|
16
|
-
* A set of types that allow work to end
|
|
17
|
-
*/
|
|
18
|
-
const endTypes = new Set(['pause', 'stop']);
|
|
19
|
-
/**
|
|
20
|
-
* A set of types that allow work to end or restart
|
|
21
|
-
*/
|
|
22
|
-
const endOrRestartTypes = new Set([
|
|
23
|
-
'pause',
|
|
24
|
-
'restart',
|
|
25
|
-
'stop',
|
|
26
|
-
]);
|
|
27
|
-
/**
|
|
28
|
-
* A set of timers that were paused due to the document being hidden
|
|
29
|
-
*/
|
|
30
|
-
const hiddenTimers = new Set();
|
|
31
|
-
/**
|
|
32
|
-
* Milliseconds in a frame, probably ;-)
|
|
33
|
-
*/
|
|
34
|
-
const milliseconds = 1_000 / 60;
|
|
35
|
-
|
|
36
|
-
if (globalThis._oscarpalmer_timers == null) {
|
|
37
|
-
Object.defineProperty(globalThis, '_oscarpalmer_timers', {
|
|
38
|
-
get() {
|
|
39
|
-
return globalThis._oscarpalmer_timer_debug ? [...activeTimers] : [];
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getOptions(options, isRepeated) {
|
|
45
|
-
return {
|
|
46
|
-
afterCallback: options.afterCallback,
|
|
47
|
-
count: getNumberOrDefault(options.count, isRepeated ? Number.POSITIVE_INFINITY : 1),
|
|
48
|
-
errorCallback: options.errorCallback,
|
|
49
|
-
interval: getNumberOrDefault(options.interval, milliseconds, milliseconds),
|
|
50
|
-
timeout: getNumberOrDefault(options.timeout, isRepeated ? Number.POSITIVE_INFINITY : 30_000),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
function getNumberOrDefault(value, defaultValue, minimum) {
|
|
54
|
-
return typeof value === 'number' && value > (minimum ?? 0)
|
|
55
|
-
? value
|
|
56
|
-
: defaultValue;
|
|
57
|
-
}
|
|
58
|
-
function work(type, timer, state, options) {
|
|
59
|
-
if ((state.destroyed && type !== 'stop') ||
|
|
60
|
-
(beginTypes.has(type) && state.active) ||
|
|
61
|
-
(endTypes.has(type) && !state.active)) {
|
|
62
|
-
return timer;
|
|
63
|
-
}
|
|
64
|
-
const { count, interval, timeout } = options;
|
|
65
|
-
const { isRepeated, minimum } = state;
|
|
66
|
-
if (endOrRestartTypes.has(type)) {
|
|
67
|
-
const isStop = type === 'stop';
|
|
68
|
-
activeTimers.delete(timer);
|
|
69
|
-
cancelAnimationFrame(state.frame);
|
|
70
|
-
if (isStop) {
|
|
71
|
-
options.afterCallback?.(false);
|
|
72
|
-
}
|
|
73
|
-
state.active = false;
|
|
74
|
-
state.frame = undefined;
|
|
75
|
-
state.paused = !isStop;
|
|
76
|
-
if (isStop) {
|
|
77
|
-
state.elapsed = undefined;
|
|
78
|
-
state.index = undefined;
|
|
79
|
-
}
|
|
80
|
-
return type === 'restart' ? work('start', timer, state, options) : timer;
|
|
81
|
-
}
|
|
82
|
-
state.active = true;
|
|
83
|
-
state.paused = false;
|
|
84
|
-
const elapsed = type === 'continue' ? Number(state.elapsed ?? 0) : 0;
|
|
85
|
-
let index = type === 'continue' ? Number(state.index ?? 0) : 0;
|
|
86
|
-
state.elapsed = elapsed;
|
|
87
|
-
state.index = index;
|
|
88
|
-
const total = (count === Number.POSITIVE_INFINITY
|
|
89
|
-
? Number.POSITIVE_INFINITY
|
|
90
|
-
: (count - index) * (interval > 0 ? interval : milliseconds)) - elapsed;
|
|
91
|
-
let current;
|
|
92
|
-
let start;
|
|
93
|
-
function finish(finished, error) {
|
|
94
|
-
activeTimers.delete(timer);
|
|
95
|
-
state.active = false;
|
|
96
|
-
state.elapsed = undefined;
|
|
97
|
-
state.frame = undefined;
|
|
98
|
-
state.index = undefined;
|
|
99
|
-
if (error) {
|
|
100
|
-
options.errorCallback?.();
|
|
101
|
-
}
|
|
102
|
-
options.afterCallback?.(finished);
|
|
103
|
-
}
|
|
104
|
-
function step(timestamp) {
|
|
105
|
-
if (!state.active) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
current ??= timestamp;
|
|
109
|
-
start ??= timestamp;
|
|
110
|
-
const time = timestamp - current;
|
|
111
|
-
state.elapsed = elapsed + (current - start);
|
|
112
|
-
const finished = time - elapsed >= total;
|
|
113
|
-
if (timestamp - start >= timeout - elapsed) {
|
|
114
|
-
finish(finished, !finished);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
if (finished || time >= minimum) {
|
|
118
|
-
if (state.active) {
|
|
119
|
-
state.callback((isRepeated ? index : undefined));
|
|
120
|
-
}
|
|
121
|
-
index += 1;
|
|
122
|
-
state.index = index;
|
|
123
|
-
if (!finished && index < count) {
|
|
124
|
-
current = null;
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
finish(true, false);
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
state.frame = requestAnimationFrame(step);
|
|
132
|
-
}
|
|
133
|
-
activeTimers.add(timer);
|
|
134
|
-
state.frame = requestAnimationFrame(step);
|
|
135
|
-
return timer;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
class TimerTrace extends Error {
|
|
139
|
-
constructor() {
|
|
140
|
-
super();
|
|
141
|
-
this.name = 'TimerTrace';
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
class BasicTimer {
|
|
146
|
-
constructor(type, state) {
|
|
147
|
-
this.$timer = type;
|
|
148
|
-
this.state = state;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* A timer that can be started, stopped, and restarted as neeeded
|
|
153
|
-
*/
|
|
154
|
-
class Timer extends BasicTimer {
|
|
155
|
-
get active() {
|
|
156
|
-
return this.state.active;
|
|
157
|
-
}
|
|
158
|
-
get destroyed() {
|
|
159
|
-
return this.state.destroyed;
|
|
160
|
-
}
|
|
161
|
-
get paused() {
|
|
162
|
-
return this.state.paused;
|
|
163
|
-
}
|
|
164
|
-
get trace() {
|
|
165
|
-
return globalThis._oscarpalmer_timer_debug ? this.state.trace : undefined;
|
|
166
|
-
}
|
|
167
|
-
constructor(type, state, options) {
|
|
168
|
-
super(type, state);
|
|
169
|
-
this.options = options;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Continues the timer _(if it was paused)_
|
|
173
|
-
*/
|
|
174
|
-
continue() {
|
|
175
|
-
return work('continue', this, this.state, this.options);
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Destroys the timer _(after stopping it, if it was running)_
|
|
179
|
-
*/
|
|
180
|
-
destroy() {
|
|
181
|
-
if (!this.state.destroyed) {
|
|
182
|
-
this.state.destroyed = true;
|
|
183
|
-
this.stop();
|
|
184
|
-
this.options.afterCallback = undefined;
|
|
185
|
-
this.options.errorCallback = undefined;
|
|
186
|
-
this.state.callback = undefined;
|
|
187
|
-
this.state.trace = undefined;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Pauses the timer _(if it was running)_
|
|
192
|
-
*/
|
|
193
|
-
pause() {
|
|
194
|
-
return work('pause', this, this.state, this.options);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Restarts the timer _(if it was running)_
|
|
198
|
-
*/
|
|
199
|
-
restart() {
|
|
200
|
-
return work('restart', this, this.state, this.options);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Starts the timer _(if it was stopped)_
|
|
204
|
-
*/
|
|
205
|
-
start() {
|
|
206
|
-
return work('start', this, this.state, this.options);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Stops the timer _(if it was running)_
|
|
210
|
-
*/
|
|
211
|
-
stop() {
|
|
212
|
-
return work('stop', this, this.state, this.options);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Creates a timer which:
|
|
217
|
-
* - calls a callback after a certain amount of time...
|
|
218
|
-
* - ... and repeats it a certain amount of times
|
|
219
|
-
* ---
|
|
220
|
-
* - `options.count` defaults to `Infinity`
|
|
221
|
-
* - `options.interval` defaults to `1000/60` _(1 frame)_
|
|
222
|
-
* - `options.timeout` defaults to `Infinity`
|
|
223
|
-
*/
|
|
224
|
-
function repeat(callback, options) {
|
|
225
|
-
return timer('repeat', callback, options ?? {}, true);
|
|
226
|
-
}
|
|
227
|
-
function timer(type, callback, partial, start) {
|
|
228
|
-
const isRepeated = type === 'repeat';
|
|
229
|
-
const options = getOptions(partial, isRepeated);
|
|
230
|
-
const instance = new Timer(type, {
|
|
231
|
-
callback,
|
|
232
|
-
isRepeated,
|
|
233
|
-
active: false,
|
|
234
|
-
destroyed: false,
|
|
235
|
-
minimum: options.interval - (options.interval % milliseconds) / 2,
|
|
236
|
-
paused: false,
|
|
237
|
-
trace: new TimerTrace().stack,
|
|
238
|
-
}, options);
|
|
239
|
-
if (start) {
|
|
240
|
-
instance.start();
|
|
241
|
-
}
|
|
242
|
-
return instance;
|
|
243
|
-
}
|
|
244
|
-
function wait(callback, options) {
|
|
245
|
-
return timer('wait', callback, options == null || typeof options === 'number'
|
|
246
|
-
? {
|
|
247
|
-
interval: options,
|
|
248
|
-
}
|
|
249
|
-
: options, true);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function is(pattern, value) {
|
|
253
|
-
return pattern.test(value?.$timer);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Is the value a repeating timer?
|
|
257
|
-
*/
|
|
258
|
-
function isRepeated(value) {
|
|
259
|
-
return is(/^repeat$/, value);
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Is the value a timer?
|
|
263
|
-
*/
|
|
264
|
-
function isTimer(value) {
|
|
265
|
-
return is(/^repeat|wait$/, value);
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Is the value a waiting timer?
|
|
269
|
-
*/
|
|
270
|
-
function isWaited(value) {
|
|
271
|
-
return is(/^wait$/, value);
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Is the value a conditional timer?
|
|
275
|
-
*/
|
|
276
|
-
function isWhen(value) {
|
|
277
|
-
return is(/^when$/, value) && typeof value.then === 'function';
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const destroyedMessage = 'Timer has already been destroyed';
|
|
281
|
-
const startedMessage = 'Timer has already been started';
|
|
282
|
-
class When extends BasicTimer {
|
|
283
|
-
get active() {
|
|
284
|
-
return this.state.timer?.active ?? false;
|
|
285
|
-
}
|
|
286
|
-
get destroyed() {
|
|
287
|
-
return this.state.timer == null;
|
|
288
|
-
}
|
|
289
|
-
get paused() {
|
|
290
|
-
return this.state.timer?.paused ?? false;
|
|
291
|
-
}
|
|
292
|
-
get trace() {
|
|
293
|
-
return this.state.timer?.trace;
|
|
294
|
-
}
|
|
295
|
-
constructor(state) {
|
|
296
|
-
super('when', state);
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Continues the timer _(if it was paused)_
|
|
300
|
-
*/
|
|
301
|
-
continue() {
|
|
302
|
-
this.state.timer?.continue();
|
|
303
|
-
return this;
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Destroys the timer _(and stops it,if it was running)_
|
|
307
|
-
*/
|
|
308
|
-
destroy() {
|
|
309
|
-
this.state.timer?.destroy();
|
|
310
|
-
this.state.promise = undefined;
|
|
311
|
-
this.state.resolver = noop;
|
|
312
|
-
this.state.rejecter = noop;
|
|
313
|
-
this.state.timer = undefined;
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Pauses the timer _(if it was running)_
|
|
317
|
-
*/
|
|
318
|
-
pause() {
|
|
319
|
-
this.state.timer?.pause();
|
|
320
|
-
return this;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Stops the timer _(if it was running)_
|
|
324
|
-
*/
|
|
325
|
-
stop() {
|
|
326
|
-
this.state.timer?.stop();
|
|
327
|
-
return this;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Starts the timer and returns a promise that resolves when the condition is met
|
|
331
|
-
*/
|
|
332
|
-
// biome-ignore lint/suspicious/noThenProperty: returning a promise-like object, so it's ok ;)
|
|
333
|
-
then(resolve, reject) {
|
|
334
|
-
if (this.state.timer == null || this.state?.started) {
|
|
335
|
-
throw new Error(this.state.timer == null ? destroyedMessage : startedMessage);
|
|
336
|
-
}
|
|
337
|
-
this.state.started = true;
|
|
338
|
-
this.state.timer.start();
|
|
339
|
-
return this.state.promise.then(resolve ?? noop, reject ?? noop);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* - Creates a promise that resolves when a condition is met
|
|
344
|
-
* - If the condition is never met in a timely manner, the promise will reject
|
|
345
|
-
*/
|
|
346
|
-
function when(condition, options) {
|
|
347
|
-
let result = false;
|
|
348
|
-
const state = {
|
|
349
|
-
started: false,
|
|
350
|
-
timer: timer('repeat', () => {
|
|
351
|
-
if (condition()) {
|
|
352
|
-
result = true;
|
|
353
|
-
state.timer.stop();
|
|
354
|
-
}
|
|
355
|
-
}, {
|
|
356
|
-
afterCallback() {
|
|
357
|
-
if (!state.timer.paused) {
|
|
358
|
-
if (result) {
|
|
359
|
-
state.resolver?.();
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
state.rejecter?.();
|
|
363
|
-
}
|
|
364
|
-
instance.destroy();
|
|
365
|
-
}
|
|
366
|
-
},
|
|
367
|
-
errorCallback() {
|
|
368
|
-
state.rejecter?.();
|
|
369
|
-
instance.destroy();
|
|
370
|
-
},
|
|
371
|
-
count: options?.count,
|
|
372
|
-
interval: options?.interval,
|
|
373
|
-
timeout: options?.timeout,
|
|
374
|
-
}, false),
|
|
375
|
-
};
|
|
376
|
-
const promise = new Promise((resolve, reject) => {
|
|
377
|
-
state.resolver = resolve;
|
|
378
|
-
state.rejecter = reject;
|
|
379
|
-
});
|
|
380
|
-
state.promise = promise;
|
|
381
|
-
const instance = new When(state);
|
|
382
|
-
return instance;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Creates a delayed promise that resolves after a certain amount of time _(or rejects when timed out)_
|
|
387
|
-
*/
|
|
388
|
-
function delay(time, timeout) {
|
|
389
|
-
return new Promise((resolve, reject) => {
|
|
390
|
-
let delayed = wait(() => {
|
|
391
|
-
delayed?.destroy();
|
|
392
|
-
delayed = null;
|
|
393
|
-
(resolve ?? noop)();
|
|
394
|
-
}, {
|
|
395
|
-
timeout,
|
|
396
|
-
errorCallback: () => {
|
|
397
|
-
delayed?.destroy();
|
|
398
|
-
delayed = null;
|
|
399
|
-
(reject ?? noop)();
|
|
400
|
-
},
|
|
401
|
-
interval: time,
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
document.addEventListener('visibilitychange', () => {
|
|
406
|
-
if (document.hidden) {
|
|
407
|
-
for (const timer of activeTimers) {
|
|
408
|
-
hiddenTimers.add(timer);
|
|
409
|
-
timer.pause();
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
for (const timer of hiddenTimers) {
|
|
414
|
-
timer.continue();
|
|
415
|
-
}
|
|
416
|
-
hiddenTimers.clear();
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
exports.delay = delay;
|
|
421
|
-
exports.isRepeated = isRepeated;
|
|
422
|
-
exports.isTimer = isTimer;
|
|
423
|
-
exports.isWaited = isWaited;
|
|
424
|
-
exports.isWhen = isWhen;
|
|
425
|
-
exports.repeat = repeat;
|
|
426
|
-
exports.wait = wait;
|
|
427
|
-
exports.when = when;
|
|
428
|
-
|
|
429
|
-
return exports;
|
|
430
|
-
|
|
431
|
-
})({});
|
package/src/functions.ts
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
activeTimers,
|
|
3
|
-
beginTypes,
|
|
4
|
-
endOrRestartTypes,
|
|
5
|
-
endTypes,
|
|
6
|
-
milliseconds,
|
|
7
|
-
} from './constants';
|
|
8
|
-
import type {TimerOptions, TimerState, WorkType} from './models';
|
|
9
|
-
import type {Timer} from './timer';
|
|
10
|
-
|
|
11
|
-
export function getOptions(
|
|
12
|
-
options: Partial<TimerOptions>,
|
|
13
|
-
isRepeated: boolean,
|
|
14
|
-
): TimerOptions {
|
|
15
|
-
return {
|
|
16
|
-
afterCallback: options.afterCallback,
|
|
17
|
-
count: getNumberOrDefault(
|
|
18
|
-
options.count,
|
|
19
|
-
isRepeated ? Number.POSITIVE_INFINITY : 1,
|
|
20
|
-
),
|
|
21
|
-
errorCallback: options.errorCallback,
|
|
22
|
-
interval: getNumberOrDefault(options.interval, milliseconds, milliseconds),
|
|
23
|
-
timeout: getNumberOrDefault(
|
|
24
|
-
options.timeout,
|
|
25
|
-
isRepeated ? Number.POSITIVE_INFINITY : 30_000,
|
|
26
|
-
),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getNumberOrDefault(
|
|
31
|
-
value: unknown,
|
|
32
|
-
defaultValue: number,
|
|
33
|
-
minimum?: number,
|
|
34
|
-
): number {
|
|
35
|
-
return typeof value === 'number' && value > (minimum ?? 0)
|
|
36
|
-
? value
|
|
37
|
-
: defaultValue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function work(
|
|
41
|
-
type: WorkType,
|
|
42
|
-
timer: Timer,
|
|
43
|
-
state: TimerState,
|
|
44
|
-
options: TimerOptions,
|
|
45
|
-
): Timer {
|
|
46
|
-
if (
|
|
47
|
-
(state.destroyed && type !== 'stop') ||
|
|
48
|
-
(beginTypes.has(type) && state.active) ||
|
|
49
|
-
(endTypes.has(type) && !state.active)
|
|
50
|
-
) {
|
|
51
|
-
return timer;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const {count, interval, timeout} = options;
|
|
55
|
-
const {isRepeated, minimum} = state;
|
|
56
|
-
|
|
57
|
-
if (endOrRestartTypes.has(type)) {
|
|
58
|
-
const isStop = type === 'stop';
|
|
59
|
-
|
|
60
|
-
activeTimers.delete(timer);
|
|
61
|
-
|
|
62
|
-
cancelAnimationFrame(state.frame as never);
|
|
63
|
-
|
|
64
|
-
if (isStop) {
|
|
65
|
-
options.afterCallback?.(false);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
state.active = false;
|
|
69
|
-
state.frame = undefined;
|
|
70
|
-
state.paused = !isStop;
|
|
71
|
-
|
|
72
|
-
if (isStop) {
|
|
73
|
-
state.elapsed = undefined;
|
|
74
|
-
state.index = undefined;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return type === 'restart' ? work('start', timer, state, options) : timer;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
state.active = true;
|
|
81
|
-
state.paused = false;
|
|
82
|
-
|
|
83
|
-
const elapsed = type === 'continue' ? Number(state.elapsed ?? 0) : 0;
|
|
84
|
-
|
|
85
|
-
let index = type === 'continue' ? Number(state.index ?? 0) : 0;
|
|
86
|
-
|
|
87
|
-
state.elapsed = elapsed;
|
|
88
|
-
state.index = index;
|
|
89
|
-
|
|
90
|
-
const total =
|
|
91
|
-
(count === Number.POSITIVE_INFINITY
|
|
92
|
-
? Number.POSITIVE_INFINITY
|
|
93
|
-
: (count - index) * (interval > 0 ? interval : milliseconds)) - elapsed;
|
|
94
|
-
|
|
95
|
-
let current: DOMHighResTimeStamp | null;
|
|
96
|
-
let start: DOMHighResTimeStamp | null;
|
|
97
|
-
|
|
98
|
-
function finish(finished: boolean, error: boolean) {
|
|
99
|
-
activeTimers.delete(timer);
|
|
100
|
-
|
|
101
|
-
state.active = false;
|
|
102
|
-
state.elapsed = undefined;
|
|
103
|
-
state.frame = undefined;
|
|
104
|
-
state.index = undefined;
|
|
105
|
-
|
|
106
|
-
if (error) {
|
|
107
|
-
options.errorCallback?.();
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
options.afterCallback?.(finished);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function step(timestamp: DOMHighResTimeStamp): void {
|
|
114
|
-
if (!state.active) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
current ??= timestamp;
|
|
119
|
-
start ??= timestamp;
|
|
120
|
-
|
|
121
|
-
const time = timestamp - current;
|
|
122
|
-
|
|
123
|
-
state.elapsed = elapsed + (current - start);
|
|
124
|
-
|
|
125
|
-
const finished = time - elapsed >= total;
|
|
126
|
-
|
|
127
|
-
if (timestamp - start >= timeout - elapsed) {
|
|
128
|
-
finish(finished, !finished);
|
|
129
|
-
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (finished || time >= minimum) {
|
|
134
|
-
if (state.active) {
|
|
135
|
-
state.callback((isRepeated ? index : undefined) as never);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
index += 1;
|
|
139
|
-
|
|
140
|
-
state.index = index;
|
|
141
|
-
|
|
142
|
-
if (!finished && index < count) {
|
|
143
|
-
current = null;
|
|
144
|
-
} else {
|
|
145
|
-
finish(true, false);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
state.frame = requestAnimationFrame(step);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
activeTimers.add(timer);
|
|
154
|
-
|
|
155
|
-
state.frame = requestAnimationFrame(step);
|
|
156
|
-
|
|
157
|
-
return timer;
|
|
158
|
-
}
|
package/types/functions.d.cts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
-
|
|
3
|
-
declare abstract class BasicTimer<State> {
|
|
4
|
-
protected readonly $timer: string;
|
|
5
|
-
protected readonly state: State;
|
|
6
|
-
constructor(type: "repeat" | "wait" | "when", state: State);
|
|
7
|
-
/**
|
|
8
|
-
* Is the timer running?
|
|
9
|
-
*/
|
|
10
|
-
abstract readonly active: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Is the timer destroyed?
|
|
13
|
-
*/
|
|
14
|
-
abstract readonly destroyed: boolean;
|
|
15
|
-
/**
|
|
16
|
-
* Is the timer paused?
|
|
17
|
-
*/
|
|
18
|
-
abstract readonly paused: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Gets the traced location of the timer
|
|
21
|
-
*/
|
|
22
|
-
abstract readonly trace: string | undefined;
|
|
23
|
-
}
|
|
24
|
-
declare class Timer extends BasicTimer<TimerState> {
|
|
25
|
-
private readonly options;
|
|
26
|
-
get active(): boolean;
|
|
27
|
-
get destroyed(): boolean;
|
|
28
|
-
get paused(): boolean;
|
|
29
|
-
get trace(): string | undefined;
|
|
30
|
-
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
|
-
/**
|
|
32
|
-
* Continues the timer _(if it was paused)_
|
|
33
|
-
*/
|
|
34
|
-
continue(): Timer;
|
|
35
|
-
/**
|
|
36
|
-
* Destroys the timer _(after stopping it, if it was running)_
|
|
37
|
-
*/
|
|
38
|
-
destroy(): void;
|
|
39
|
-
/**
|
|
40
|
-
* Pauses the timer _(if it was running)_
|
|
41
|
-
*/
|
|
42
|
-
pause(): Timer;
|
|
43
|
-
/**
|
|
44
|
-
* Restarts the timer _(if it was running)_
|
|
45
|
-
*/
|
|
46
|
-
restart(): Timer;
|
|
47
|
-
/**
|
|
48
|
-
* Starts the timer _(if it was stopped)_
|
|
49
|
-
*/
|
|
50
|
-
start(): Timer;
|
|
51
|
-
/**
|
|
52
|
-
* Stops the timer _(if it was running)_
|
|
53
|
-
*/
|
|
54
|
-
stop(): Timer;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Callback that runs after the timer has finished (or is stopped)
|
|
58
|
-
* - `finished` is `true` if the timer was allowed to finish, and `false` if it was stopped
|
|
59
|
-
*/
|
|
60
|
-
export type AfterCallback = (finished: boolean) => void;
|
|
61
|
-
export type AnyCallback = (() => void) | IndexedCallback;
|
|
62
|
-
/**
|
|
63
|
-
* Callback that runs for each iteration of the timer
|
|
64
|
-
*/
|
|
65
|
-
export type IndexedCallback = (index: number) => void;
|
|
66
|
-
export type BaseOptions = {
|
|
67
|
-
/**
|
|
68
|
-
* Interval between each callback
|
|
69
|
-
*/
|
|
70
|
-
interval: number;
|
|
71
|
-
/**
|
|
72
|
-
* Maximum amount of time the timer may run for
|
|
73
|
-
*/
|
|
74
|
-
timeout: number;
|
|
75
|
-
};
|
|
76
|
-
export type OptionsWithCount = {
|
|
77
|
-
/**
|
|
78
|
-
* How many times the timer should repeat
|
|
79
|
-
*/
|
|
80
|
-
count: number;
|
|
81
|
-
} & BaseOptions;
|
|
82
|
-
export type OptionsWithError = {
|
|
83
|
-
/**
|
|
84
|
-
* Callback to run when an error occurs _(usually a timeout)_
|
|
85
|
-
*/
|
|
86
|
-
errorCallback?: () => void;
|
|
87
|
-
};
|
|
88
|
-
export type RepeatOptions = {
|
|
89
|
-
/**
|
|
90
|
-
* Callback to run after the timer has finished (or is stopped)
|
|
91
|
-
* - `finished` is `true` if the timer was allowed to finish, and `false` if it was stopped
|
|
92
|
-
*/
|
|
93
|
-
afterCallback?: AfterCallback;
|
|
94
|
-
} & OptionsWithCount & OptionsWithError;
|
|
95
|
-
export type TimerOptions = {} & RepeatOptions;
|
|
96
|
-
export type TimerState = {
|
|
97
|
-
active: boolean;
|
|
98
|
-
callback: AnyCallback;
|
|
99
|
-
destroyed: boolean;
|
|
100
|
-
count?: number;
|
|
101
|
-
elapsed?: number;
|
|
102
|
-
frame?: number;
|
|
103
|
-
index?: number;
|
|
104
|
-
isRepeated: boolean;
|
|
105
|
-
minimum: number;
|
|
106
|
-
paused: boolean;
|
|
107
|
-
trace?: string;
|
|
108
|
-
};
|
|
109
|
-
export type WorkType = "continue" | "pause" | "restart" | "start" | "stop";
|
|
110
|
-
export declare function getOptions(options: Partial<TimerOptions>, isRepeated: boolean): TimerOptions;
|
|
111
|
-
export declare function work(type: WorkType, timer: Timer, state: TimerState, options: TimerOptions): Timer;
|
|
112
|
-
|
|
113
|
-
export {};
|
package/types/functions.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { TimerOptions, TimerState, WorkType } from './models';
|
|
2
|
-
import type { Timer } from './timer';
|
|
3
|
-
export declare function getOptions(options: Partial<TimerOptions>, isRepeated: boolean): TimerOptions;
|
|
4
|
-
export declare function work(type: WorkType, timer: Timer, state: TimerState, options: TimerOptions): Timer;
|