@oscarpalmer/timer 0.26.0 → 0.27.1
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/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/timer.cjs +1 -1
- package/dist/timer.iife.js +429 -0
- package/dist/timer.js +1 -1
- package/package.json +12 -7
- package/src/constants.ts +2 -2
- package/src/functions.ts +3 -3
- package/src/global.ts +2 -2
- package/src/index.ts +3 -3
- package/src/is.ts +2 -2
- package/src/models.ts +2 -2
- package/src/timer.ts +6 -6
- package/src/when.ts +2 -2
- package/types/constants.d.cts +3 -6
- package/types/constants.d.ts +2 -2
- package/types/functions.d.cts +3 -6
- package/types/functions.d.ts +2 -2
- package/types/global.d.ts +1 -1
- package/types/index.d.cts +4 -7
- package/types/index.d.ts +1 -1
- package/types/is.d.cts +4 -7
- package/types/is.d.ts +2 -2
- package/types/models.d.cts +3 -3
- package/types/models.d.ts +2 -2
- package/types/timer.d.cts +3 -6
- package/types/timer.d.ts +3 -3
- package/types/when.d.cts +4 -7
- package/types/when.d.ts +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const _function = require("@oscarpalmer/atoms/function");
|
|
3
4
|
const constants = require("./constants.cjs");
|
|
4
5
|
require("./global.cjs");
|
|
5
|
-
const _function = require("@oscarpalmer/atoms/function");
|
|
6
6
|
const timer = require("./timer.cjs");
|
|
7
7
|
const is = require("./is.cjs");
|
|
8
8
|
const when = require("./when.cjs");
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { noop } from "@oscarpalmer/atoms/function";
|
|
1
2
|
import { activeTimers, hiddenTimers } from "./constants.js";
|
|
2
3
|
import "./global.js";
|
|
3
|
-
import { noop } from "@oscarpalmer/atoms/function";
|
|
4
4
|
import { wait } from "./timer.js";
|
|
5
5
|
import { repeat } from "./timer.js";
|
|
6
6
|
import { isRepeated, isTimer, isWaited, isWhen } from "./is.js";
|
package/dist/timer.cjs
CHANGED
|
@@ -85,7 +85,7 @@ function timer(type, callback, partial, start) {
|
|
|
85
85
|
destroyed: false,
|
|
86
86
|
minimum: options.interval - options.interval % constants.milliseconds / 2,
|
|
87
87
|
paused: false,
|
|
88
|
-
trace: new models.TimerTrace()
|
|
88
|
+
trace: new models.TimerTrace().stack
|
|
89
89
|
},
|
|
90
90
|
options
|
|
91
91
|
);
|
|
@@ -0,0 +1,429 @@
|
|
|
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: getValueOrDefault(options.count, isRepeated ? Number.POSITIVE_INFINITY : 1),
|
|
48
|
+
errorCallback: options.errorCallback,
|
|
49
|
+
interval: getValueOrDefault(options.interval, milliseconds, milliseconds),
|
|
50
|
+
timeout: getValueOrDefault(options.timeout, isRepeated ? Number.POSITIVE_INFINITY : 30_000),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function getValueOrDefault(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' ? +(state.elapsed ?? 0) : 0;
|
|
85
|
+
let index = type === 'continue' ? +(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
|
+
const delayed = wait(() => {
|
|
391
|
+
delayed.destroy();
|
|
392
|
+
(resolve ?? noop)();
|
|
393
|
+
}, {
|
|
394
|
+
timeout,
|
|
395
|
+
errorCallback: () => {
|
|
396
|
+
delayed.destroy();
|
|
397
|
+
(reject ?? noop)();
|
|
398
|
+
},
|
|
399
|
+
interval: time,
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
document.addEventListener('visibilitychange', () => {
|
|
404
|
+
if (document.hidden) {
|
|
405
|
+
for (const timer of activeTimers) {
|
|
406
|
+
hiddenTimers.add(timer);
|
|
407
|
+
timer.pause();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
for (const timer of hiddenTimers) {
|
|
412
|
+
timer.continue();
|
|
413
|
+
}
|
|
414
|
+
hiddenTimers.clear();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
exports.delay = delay;
|
|
419
|
+
exports.isRepeated = isRepeated;
|
|
420
|
+
exports.isTimer = isTimer;
|
|
421
|
+
exports.isWaited = isWaited;
|
|
422
|
+
exports.isWhen = isWhen;
|
|
423
|
+
exports.repeat = repeat;
|
|
424
|
+
exports.wait = wait;
|
|
425
|
+
exports.when = when;
|
|
426
|
+
|
|
427
|
+
return exports;
|
|
428
|
+
|
|
429
|
+
})({});
|
package/dist/timer.js
CHANGED
package/package.json
CHANGED
|
@@ -4,17 +4,21 @@
|
|
|
4
4
|
"url": "https://oscarpalmer.se"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@oscarpalmer/atoms": "0.
|
|
7
|
+
"@oscarpalmer/atoms": "0.81.0"
|
|
8
8
|
},
|
|
9
9
|
"description": "A better solution for timeout- and interval-based timers.",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@biomejs/biome": "^1.9",
|
|
12
|
-
"@
|
|
12
|
+
"@rollup/plugin-node-resolve": "^16",
|
|
13
|
+
"@rollup/plugin-typescript": "^12.1",
|
|
14
|
+
"@types/node": "^22.10",
|
|
13
15
|
"@vitest/coverage-istanbul": "^2.1",
|
|
14
16
|
"dts-bundle-generator": "^9.5",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
17
|
+
"glob": "^11",
|
|
18
|
+
"happy-dom": "^16.5",
|
|
19
|
+
"tslib": "^2.8",
|
|
20
|
+
"typescript": "^5.7",
|
|
21
|
+
"vite": "^6",
|
|
18
22
|
"vitest": "^2.1"
|
|
19
23
|
},
|
|
20
24
|
"exports": {
|
|
@@ -40,14 +44,15 @@
|
|
|
40
44
|
"url": "git+https://github.com/oscarpalmer/timer.git"
|
|
41
45
|
},
|
|
42
46
|
"scripts": {
|
|
43
|
-
"build": "npm run clean && npm run build:js && npm run types",
|
|
47
|
+
"build": "npm run clean && npm run build:js && npm run rollup && npm run types",
|
|
44
48
|
"build:js": "npx vite build",
|
|
45
49
|
"clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
|
|
50
|
+
"rollup": "npx rollup -c",
|
|
46
51
|
"test": "npx vitest --coverage",
|
|
47
52
|
"types": "npx tsc && npx dts-bundle-generator --config ./dts.config.ts",
|
|
48
53
|
"watch": "npx vite build --watch"
|
|
49
54
|
},
|
|
50
55
|
"type": "module",
|
|
51
56
|
"types": "types/index.d.cts",
|
|
52
|
-
"version": "0.
|
|
57
|
+
"version": "0.27.1"
|
|
53
58
|
}
|
package/src/constants.ts
CHANGED
package/src/functions.ts
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
endOrRestartTypes,
|
|
5
5
|
endTypes,
|
|
6
6
|
milliseconds,
|
|
7
|
-
} from '
|
|
8
|
-
import type {TimerOptions, TimerState, WorkType} from '
|
|
9
|
-
import type {Timer} from '
|
|
7
|
+
} from './constants';
|
|
8
|
+
import type {TimerOptions, TimerState, WorkType} from './models';
|
|
9
|
+
import type {Timer} from './timer';
|
|
10
10
|
|
|
11
11
|
export function getOptions(
|
|
12
12
|
options: Partial<TimerOptions>,
|
package/src/global.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {activeTimers, hiddenTimers} from '~/constants';
|
|
2
|
-
import '~/global';
|
|
3
1
|
import {noop} from '@oscarpalmer/atoms/function';
|
|
4
|
-
import {
|
|
2
|
+
import {activeTimers, hiddenTimers} from './constants';
|
|
3
|
+
import './global';
|
|
4
|
+
import {wait} from './timer';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Creates a delayed promise that resolves after a certain amount of time _(or rejects when timed out)_
|
package/src/is.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
2
|
-
import type {Timer} from '
|
|
3
|
-
import type {When} from '
|
|
2
|
+
import type {Timer} from './timer';
|
|
3
|
+
import type {When} from './when';
|
|
4
4
|
|
|
5
5
|
function is(pattern: RegExp, value: unknown) {
|
|
6
6
|
return pattern.test((value as PlainObject)?.$timer as string);
|
package/src/models.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {Timer} from '
|
|
1
|
+
import type {Timer} from './timer';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Callback that runs after the timer has finished (or is stopped)
|
|
@@ -60,7 +60,7 @@ export type TimerState = {
|
|
|
60
60
|
isRepeated: boolean;
|
|
61
61
|
minimum: number;
|
|
62
62
|
paused: boolean;
|
|
63
|
-
trace
|
|
63
|
+
trace?: string;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
export class TimerTrace extends Error {
|
package/src/timer.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {milliseconds} from '
|
|
2
|
-
import {getOptions, work} from '
|
|
1
|
+
import {milliseconds} from './constants';
|
|
2
|
+
import {getOptions, work} from './functions';
|
|
3
3
|
import {
|
|
4
|
-
TimerTrace,
|
|
5
4
|
type AnyCallback,
|
|
6
5
|
type IndexedCallback,
|
|
7
6
|
type RepeatOptions,
|
|
8
7
|
type TimerOptions,
|
|
9
8
|
type TimerState,
|
|
9
|
+
TimerTrace,
|
|
10
10
|
type WaitOptions,
|
|
11
|
-
} from '
|
|
11
|
+
} from './models';
|
|
12
12
|
|
|
13
13
|
export abstract class BasicTimer<State> {
|
|
14
14
|
protected declare readonly $timer: string;
|
|
@@ -37,7 +37,7 @@ export abstract class BasicTimer<State> {
|
|
|
37
37
|
/**
|
|
38
38
|
* Gets the traced location of the timer
|
|
39
39
|
*/
|
|
40
|
-
abstract readonly trace:
|
|
40
|
+
abstract readonly trace: string | undefined;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -159,7 +159,7 @@ export function timer(
|
|
|
159
159
|
destroyed: false,
|
|
160
160
|
minimum: options.interval - (options.interval % milliseconds) / 2,
|
|
161
161
|
paused: false,
|
|
162
|
-
trace: new TimerTrace(),
|
|
162
|
+
trace: new TimerTrace().stack,
|
|
163
163
|
},
|
|
164
164
|
options,
|
|
165
165
|
);
|
package/src/when.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {noop} from '@oscarpalmer/atoms/function';
|
|
2
|
-
import type {WhenOptions, WhenState} from '
|
|
3
|
-
import {BasicTimer, timer} from '
|
|
2
|
+
import type {WhenOptions, WhenState} from './models';
|
|
3
|
+
import {BasicTimer, timer} from './timer';
|
|
4
4
|
|
|
5
5
|
const destroyedMessage = 'Timer has already been destroyed';
|
|
6
6
|
const startedMessage = 'Timer has already been started';
|
package/types/constants.d.cts
CHANGED
|
@@ -19,14 +19,14 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
declare class Timer extends BasicTimer<TimerState> {
|
|
25
25
|
private readonly options;
|
|
26
26
|
get active(): boolean;
|
|
27
27
|
get destroyed(): boolean;
|
|
28
28
|
get paused(): boolean;
|
|
29
|
-
get trace():
|
|
29
|
+
get trace(): string | undefined;
|
|
30
30
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
31
|
/**
|
|
32
32
|
* Continues the timer _(if it was paused)_
|
|
@@ -104,11 +104,8 @@ export type TimerState = {
|
|
|
104
104
|
isRepeated: boolean;
|
|
105
105
|
minimum: number;
|
|
106
106
|
paused: boolean;
|
|
107
|
-
trace
|
|
107
|
+
trace?: string;
|
|
108
108
|
};
|
|
109
|
-
declare class TimerTrace extends Error {
|
|
110
|
-
constructor();
|
|
111
|
-
}
|
|
112
109
|
export type WorkType = "continue" | "pause" | "restart" | "start" | "stop";
|
|
113
110
|
/**
|
|
114
111
|
* A set of all active timers
|
package/types/constants.d.ts
CHANGED
package/types/functions.d.cts
CHANGED
|
@@ -19,14 +19,14 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
declare class Timer extends BasicTimer<TimerState> {
|
|
25
25
|
private readonly options;
|
|
26
26
|
get active(): boolean;
|
|
27
27
|
get destroyed(): boolean;
|
|
28
28
|
get paused(): boolean;
|
|
29
|
-
get trace():
|
|
29
|
+
get trace(): string | undefined;
|
|
30
30
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
31
|
/**
|
|
32
32
|
* Continues the timer _(if it was paused)_
|
|
@@ -104,11 +104,8 @@ export type TimerState = {
|
|
|
104
104
|
isRepeated: boolean;
|
|
105
105
|
minimum: number;
|
|
106
106
|
paused: boolean;
|
|
107
|
-
trace
|
|
107
|
+
trace?: string;
|
|
108
108
|
};
|
|
109
|
-
declare class TimerTrace extends Error {
|
|
110
|
-
constructor();
|
|
111
|
-
}
|
|
112
109
|
export type WorkType = "continue" | "pause" | "restart" | "start" | "stop";
|
|
113
110
|
export declare function getOptions(options: Partial<TimerOptions>, isRepeated: boolean): TimerOptions;
|
|
114
111
|
export declare function getValueOrDefault(value: unknown, defaultValue: number, minimum?: number): number;
|
package/types/functions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TimerOptions, TimerState, WorkType } from '
|
|
2
|
-
import type { Timer } from '
|
|
1
|
+
import type { TimerOptions, TimerState, WorkType } from './models';
|
|
2
|
+
import type { Timer } from './timer';
|
|
3
3
|
export declare function getOptions(options: Partial<TimerOptions>, isRepeated: boolean): TimerOptions;
|
|
4
4
|
export declare function getValueOrDefault(value: unknown, defaultValue: number, minimum?: number): number;
|
|
5
5
|
export declare function work(type: WorkType, timer: Timer, state: TimerState, options: TimerOptions): Timer;
|
package/types/global.d.ts
CHANGED
package/types/index.d.cts
CHANGED
|
@@ -19,7 +19,7 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* A timer that can be started, stopped, and restarted as neeeded
|
|
@@ -29,7 +29,7 @@ export declare class Timer extends BasicTimer<TimerState> {
|
|
|
29
29
|
get active(): boolean;
|
|
30
30
|
get destroyed(): boolean;
|
|
31
31
|
get paused(): boolean;
|
|
32
|
-
get trace():
|
|
32
|
+
get trace(): string | undefined;
|
|
33
33
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
34
34
|
/**
|
|
35
35
|
* Continues the timer _(if it was paused)_
|
|
@@ -131,11 +131,8 @@ export type TimerState = {
|
|
|
131
131
|
isRepeated: boolean;
|
|
132
132
|
minimum: number;
|
|
133
133
|
paused: boolean;
|
|
134
|
-
trace
|
|
134
|
+
trace?: string;
|
|
135
135
|
};
|
|
136
|
-
declare class TimerTrace extends Error {
|
|
137
|
-
constructor();
|
|
138
|
-
}
|
|
139
136
|
export type WaitOptions = {} & BaseOptions & OptionsWithError;
|
|
140
137
|
export type WhenOptions = {} & OptionsWithCount;
|
|
141
138
|
export type WhenState = {
|
|
@@ -149,7 +146,7 @@ export declare class When extends BasicTimer<WhenState> {
|
|
|
149
146
|
get active(): boolean;
|
|
150
147
|
get destroyed(): boolean;
|
|
151
148
|
get paused(): boolean;
|
|
152
|
-
get trace():
|
|
149
|
+
get trace(): string | undefined;
|
|
153
150
|
constructor(state: WhenState);
|
|
154
151
|
/**
|
|
155
152
|
* Continues the timer _(if it was paused)_
|
package/types/index.d.ts
CHANGED
package/types/is.d.cts
CHANGED
|
@@ -19,14 +19,14 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
declare class Timer extends BasicTimer<TimerState> {
|
|
25
25
|
private readonly options;
|
|
26
26
|
get active(): boolean;
|
|
27
27
|
get destroyed(): boolean;
|
|
28
28
|
get paused(): boolean;
|
|
29
|
-
get trace():
|
|
29
|
+
get trace(): string | undefined;
|
|
30
30
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
31
|
/**
|
|
32
32
|
* Continues the timer _(if it was paused)_
|
|
@@ -104,11 +104,8 @@ export type TimerState = {
|
|
|
104
104
|
isRepeated: boolean;
|
|
105
105
|
minimum: number;
|
|
106
106
|
paused: boolean;
|
|
107
|
-
trace
|
|
107
|
+
trace?: string;
|
|
108
108
|
};
|
|
109
|
-
declare class TimerTrace extends Error {
|
|
110
|
-
constructor();
|
|
111
|
-
}
|
|
112
109
|
export type WhenState = {
|
|
113
110
|
promise: Promise<void>;
|
|
114
111
|
rejecter?: () => void;
|
|
@@ -120,7 +117,7 @@ declare class When extends BasicTimer<WhenState> {
|
|
|
120
117
|
get active(): boolean;
|
|
121
118
|
get destroyed(): boolean;
|
|
122
119
|
get paused(): boolean;
|
|
123
|
-
get trace():
|
|
120
|
+
get trace(): string | undefined;
|
|
124
121
|
constructor(state: WhenState);
|
|
125
122
|
/**
|
|
126
123
|
* Continues the timer _(if it was paused)_
|
package/types/is.d.ts
CHANGED
package/types/models.d.cts
CHANGED
|
@@ -19,14 +19,14 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
declare class Timer extends BasicTimer<TimerState> {
|
|
25
25
|
private readonly options;
|
|
26
26
|
get active(): boolean;
|
|
27
27
|
get destroyed(): boolean;
|
|
28
28
|
get paused(): boolean;
|
|
29
|
-
get trace():
|
|
29
|
+
get trace(): string | undefined;
|
|
30
30
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
31
|
/**
|
|
32
32
|
* Continues the timer _(if it was paused)_
|
|
@@ -104,7 +104,7 @@ export type TimerState = {
|
|
|
104
104
|
isRepeated: boolean;
|
|
105
105
|
minimum: number;
|
|
106
106
|
paused: boolean;
|
|
107
|
-
trace
|
|
107
|
+
trace?: string;
|
|
108
108
|
};
|
|
109
109
|
export declare class TimerTrace extends Error {
|
|
110
110
|
constructor();
|
package/types/models.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Timer } from '
|
|
1
|
+
import type { Timer } from './timer';
|
|
2
2
|
/**
|
|
3
3
|
* Callback that runs after the timer has finished (or is stopped)
|
|
4
4
|
* - `finished` is `true` if the timer was allowed to finish, and `false` if it was stopped
|
|
@@ -50,7 +50,7 @@ export type TimerState = {
|
|
|
50
50
|
isRepeated: boolean;
|
|
51
51
|
minimum: number;
|
|
52
52
|
paused: boolean;
|
|
53
|
-
trace
|
|
53
|
+
trace?: string;
|
|
54
54
|
};
|
|
55
55
|
export declare class TimerTrace extends Error {
|
|
56
56
|
constructor();
|
package/types/timer.d.cts
CHANGED
|
@@ -19,7 +19,7 @@ export declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* A timer that can be started, stopped, and restarted as neeeded
|
|
@@ -29,7 +29,7 @@ export declare class Timer extends BasicTimer<TimerState> {
|
|
|
29
29
|
get active(): boolean;
|
|
30
30
|
get destroyed(): boolean;
|
|
31
31
|
get paused(): boolean;
|
|
32
|
-
get trace():
|
|
32
|
+
get trace(): string | undefined;
|
|
33
33
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
34
34
|
/**
|
|
35
35
|
* Continues the timer _(if it was paused)_
|
|
@@ -132,11 +132,8 @@ export type TimerState = {
|
|
|
132
132
|
isRepeated: boolean;
|
|
133
133
|
minimum: number;
|
|
134
134
|
paused: boolean;
|
|
135
|
-
trace
|
|
135
|
+
trace?: string;
|
|
136
136
|
};
|
|
137
|
-
declare class TimerTrace extends Error {
|
|
138
|
-
constructor();
|
|
139
|
-
}
|
|
140
137
|
export type WaitOptions = {} & BaseOptions & OptionsWithError;
|
|
141
138
|
|
|
142
139
|
export {};
|
package/types/timer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type AnyCallback, type IndexedCallback, type RepeatOptions, type TimerOptions, type TimerState, type WaitOptions } from './models';
|
|
2
2
|
export declare abstract class BasicTimer<State> {
|
|
3
3
|
protected readonly $timer: string;
|
|
4
4
|
protected readonly state: State;
|
|
@@ -18,7 +18,7 @@ export declare abstract class BasicTimer<State> {
|
|
|
18
18
|
/**
|
|
19
19
|
* Gets the traced location of the timer
|
|
20
20
|
*/
|
|
21
|
-
abstract readonly trace:
|
|
21
|
+
abstract readonly trace: string | undefined;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* A timer that can be started, stopped, and restarted as neeeded
|
|
@@ -28,7 +28,7 @@ export declare class Timer extends BasicTimer<TimerState> {
|
|
|
28
28
|
get active(): boolean;
|
|
29
29
|
get destroyed(): boolean;
|
|
30
30
|
get paused(): boolean;
|
|
31
|
-
get trace():
|
|
31
|
+
get trace(): string | undefined;
|
|
32
32
|
constructor(type: 'repeat' | 'wait', state: TimerState, options: TimerOptions);
|
|
33
33
|
/**
|
|
34
34
|
* Continues the timer _(if it was paused)_
|
package/types/when.d.cts
CHANGED
|
@@ -19,14 +19,14 @@ declare abstract class BasicTimer<State> {
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the traced location of the timer
|
|
21
21
|
*/
|
|
22
|
-
abstract readonly trace:
|
|
22
|
+
abstract readonly trace: string | undefined;
|
|
23
23
|
}
|
|
24
24
|
declare class Timer extends BasicTimer<TimerState> {
|
|
25
25
|
private readonly options;
|
|
26
26
|
get active(): boolean;
|
|
27
27
|
get destroyed(): boolean;
|
|
28
28
|
get paused(): boolean;
|
|
29
|
-
get trace():
|
|
29
|
+
get trace(): string | undefined;
|
|
30
30
|
constructor(type: "repeat" | "wait", state: TimerState, options: TimerOptions);
|
|
31
31
|
/**
|
|
32
32
|
* Continues the timer _(if it was paused)_
|
|
@@ -104,11 +104,8 @@ export type TimerState = {
|
|
|
104
104
|
isRepeated: boolean;
|
|
105
105
|
minimum: number;
|
|
106
106
|
paused: boolean;
|
|
107
|
-
trace
|
|
107
|
+
trace?: string;
|
|
108
108
|
};
|
|
109
|
-
declare class TimerTrace extends Error {
|
|
110
|
-
constructor();
|
|
111
|
-
}
|
|
112
109
|
export type WhenOptions = {} & OptionsWithCount;
|
|
113
110
|
export type WhenState = {
|
|
114
111
|
promise: Promise<void>;
|
|
@@ -121,7 +118,7 @@ export declare class When extends BasicTimer<WhenState> {
|
|
|
121
118
|
get active(): boolean;
|
|
122
119
|
get destroyed(): boolean;
|
|
123
120
|
get paused(): boolean;
|
|
124
|
-
get trace():
|
|
121
|
+
get trace(): string | undefined;
|
|
125
122
|
constructor(state: WhenState);
|
|
126
123
|
/**
|
|
127
124
|
* Continues the timer _(if it was paused)_
|
package/types/when.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { WhenOptions, WhenState } from '
|
|
2
|
-
import { BasicTimer } from '
|
|
1
|
+
import type { WhenOptions, WhenState } from './models';
|
|
2
|
+
import { BasicTimer } from './timer';
|
|
3
3
|
export declare class When extends BasicTimer<WhenState> {
|
|
4
4
|
get active(): boolean;
|
|
5
5
|
get destroyed(): boolean;
|
|
6
6
|
get paused(): boolean;
|
|
7
|
-
get trace():
|
|
7
|
+
get trace(): string | undefined;
|
|
8
8
|
constructor(state: WhenState);
|
|
9
9
|
/**
|
|
10
10
|
* Continues the timer _(if it was paused)_
|