@oscarpalmer/timer 0.36.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +13 -13
  2. package/dist/constants.js +11 -13
  3. package/dist/delay.js +3 -3
  4. package/dist/get.js +2 -2
  5. package/dist/global.js +5 -4
  6. package/dist/index.js +4 -4
  7. package/dist/is.js +1 -1
  8. package/dist/repeat.js +2 -2
  9. package/dist/toretto.full.js +515 -0
  10. package/dist/wait.js +2 -2
  11. package/dist/when.js +11 -8
  12. package/dist/work.js +11 -11
  13. package/package.json +36 -61
  14. package/src/constants.ts +20 -14
  15. package/src/delay.ts +6 -7
  16. package/src/get.ts +4 -6
  17. package/src/global.ts +5 -9
  18. package/src/is.ts +9 -1
  19. package/src/models.ts +35 -40
  20. package/src/repeat.ts +6 -6
  21. package/src/timer.ts +4 -17
  22. package/src/wait.ts +2 -2
  23. package/src/when.ts +35 -31
  24. package/src/work.ts +17 -32
  25. package/types/constants.d.ts +12 -12
  26. package/types/delay.d.ts +3 -1
  27. package/types/get.d.ts +1 -1
  28. package/types/is.d.ts +8 -0
  29. package/types/repeat.d.ts +3 -0
  30. package/types/when.d.ts +15 -1
  31. package/dist/constants.cjs +0 -53
  32. package/dist/delay.cjs +0 -15
  33. package/dist/get.cjs +0 -16
  34. package/dist/global.cjs +0 -14
  35. package/dist/index.cjs +0 -14
  36. package/dist/is.cjs +0 -20
  37. package/dist/models.cjs +0 -7
  38. package/dist/repeat.cjs +0 -18
  39. package/dist/rolldown_runtime.cjs +0 -21
  40. package/dist/timer.cjs +0 -67
  41. package/dist/timer.full.js +0 -530
  42. package/dist/wait.cjs +0 -18
  43. package/dist/when.cjs +0 -95
  44. package/dist/work.cjs +0 -82
  45. package/types/constants.d.cts +0 -104
  46. package/types/delay.d.cts +0 -8
  47. package/types/get.d.cts +0 -11
  48. package/types/global.d.cts +0 -3
  49. package/types/index.d.cts +0 -187
  50. package/types/is.d.cts +0 -144
  51. package/types/models.d.cts +0 -128
  52. package/types/repeat.d.cts +0 -99
  53. package/types/timer.d.cts +0 -70
  54. package/types/wait.d.cts +0 -76
  55. package/types/when.d.cts +0 -66
  56. package/types/work.d.cts +0 -81
@@ -1,530 +0,0 @@
1
- function calculate$1() {
2
- return new Promise(resolve => {
3
- const values = [];
4
- let last;
5
- function step(now) {
6
- if (last != null) {
7
- values.push(now - last);
8
- }
9
- last = now;
10
- if (values.length >= 10) {
11
- const median = values
12
- .sort()
13
- .slice(2, -2)
14
- .reduce((first, second) => first + second, 0) /
15
- (values.length - 4);
16
- resolve(median);
17
- }
18
- else {
19
- requestAnimationFrame(step);
20
- }
21
- }
22
- requestAnimationFrame(step);
23
- });
24
- }
25
- //
26
- const defaultTimeout = 30_000;
27
- /**
28
- * A set of all active timers
29
- */
30
- const activeTimers = new Set();
31
- /**
32
- * Buffer value to use when evaluating if a specific time is within a certain range
33
- */
34
- const intervalBuffer = 5;
35
- /**
36
- * Message to show when a when-timer is destroyed
37
- */
38
- const destroyedMessage = 'Timer has already been destroyed';
39
- /**
40
- * A set of timers that were paused due to the document being hidden
41
- */
42
- const hiddenTimers = new Set();
43
- /**
44
- * Message to show when a when-timer is started
45
- */
46
- const startedMessage = 'Timer has already been started';
47
- const TYPE_REPEAT = 'repeat';
48
- const TYPE_WAIT = 'wait';
49
- const TYPE_WHEN = 'when';
50
- const WORK_CONTINUE = 'continue';
51
- const WORK_PAUSE = 'pause';
52
- const WORK_RESTART = 'restart';
53
- const WORK_START = 'start';
54
- const WORK_STOP = 'stop';
55
- //
56
- /**
57
- * A calculated average of the refresh rate of the display _(in milliseconds)_
58
- */
59
- let milliseconds = 1000 / 60;
60
- calculate$1().then(value => {
61
- milliseconds = value;
62
- });
63
-
64
- if (globalThis._oscarpalmer_timers == null) {
65
- Object.defineProperty(globalThis, '_oscarpalmer_timers', {
66
- get() {
67
- return globalThis._oscarpalmer_timer_debug ? [...activeTimers] : [];
68
- },
69
- });
70
- }
71
- document.addEventListener('visibilitychange', () => {
72
- const from = document.hidden ? activeTimers : hiddenTimers;
73
- const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
74
- const to = document.hidden ? hiddenTimers : activeTimers;
75
- for (const timer of from) {
76
- timer[method]();
77
- to.add(timer);
78
- }
79
- from.clear();
80
- });
81
-
82
- function calculate() {
83
- return new Promise((resolve) => {
84
- const values = [];
85
- let last;
86
- function step(now) {
87
- if (last != null) values.push(now - last);
88
- if (last = now, values.length >= 10) {
89
- const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4);
90
- resolve(median);
91
- } else requestAnimationFrame(step);
92
- }
93
- requestAnimationFrame(step);
94
- });
95
- }
96
- function noop() {}
97
- calculate().then((value) => {
98
- });
99
-
100
- function getCallback(value) {
101
- return typeof value === 'function' ? value : noop;
102
- }
103
- function getValidTimeout(value) {
104
- return typeof value === 'number' && value > 0 ? value : defaultTimeout;
105
- }
106
- function getValidNumber(value, defaultValue) {
107
- const actualDefault = defaultValue ?? 0;
108
- return typeof value === 'number' && value > actualDefault
109
- ? value
110
- : actualDefault;
111
- }
112
-
113
- /**
114
- * Create a delayed promise that resolves after a certain amount of time _(in milliseconds; defaults to screen refresh rate)_
115
- */
116
- function delay(time) {
117
- return new Promise(resolve => {
118
- const interval = getValidNumber(time, milliseconds);
119
- let start;
120
- function step(now) {
121
- start ??= now;
122
- if (interval === milliseconds ||
123
- now - start >= interval - intervalBuffer) {
124
- resolve();
125
- }
126
- else {
127
- requestAnimationFrame(step);
128
- }
129
- }
130
- requestAnimationFrame(step);
131
- });
132
- }
133
-
134
- function is(names, value) {
135
- return names.includes(value?.$timer);
136
- }
137
- /**
138
- * Is the value a repeating timer?
139
- */
140
- function isRepeated(value) {
141
- return is([TYPE_REPEAT], value);
142
- }
143
- /**
144
- * Is the value a timer?
145
- */
146
- function isTimer(value) {
147
- return is([TYPE_REPEAT, TYPE_WAIT], value);
148
- }
149
- /**
150
- * Is the value a waiting timer?
151
- */
152
- function isWaited(value) {
153
- return is([TYPE_WAIT], value);
154
- }
155
- /**
156
- * Is the value a conditional timer?
157
- */
158
- function isWhen(value) {
159
- return is([TYPE_WHEN], value) && typeof value.then === 'function';
160
- }
161
-
162
- class TimerTrace extends Error {
163
- constructor() {
164
- super();
165
- this.name = 'TimerTrace';
166
- }
167
- }
168
-
169
- function finish(timer, state, options, success) {
170
- cancelAnimationFrame(state.frame);
171
- activeTimers.delete(timer.instance);
172
- state.active = false;
173
- state.elapsed = 0;
174
- state.frame = undefined;
175
- if (timer.type === TYPE_WAIT) {
176
- state.callback();
177
- }
178
- else {
179
- options.onAfter?.(success);
180
- }
181
- }
182
- function ignore(type, state) {
183
- if (state.destroyed) {
184
- return type !== WORK_STOP;
185
- }
186
- if (state.paused) {
187
- return type === WORK_PAUSE || type === WORK_START;
188
- }
189
- return state.active && type === WORK_START;
190
- }
191
- function pause(timer, state) {
192
- cancelAnimationFrame(state.frame);
193
- state.frame = undefined;
194
- return timer.instance;
195
- }
196
- function run(timer, state, options) {
197
- let last;
198
- return function step(now) {
199
- if (!state.active) {
200
- return;
201
- }
202
- last ??= now;
203
- const difference = now - last;
204
- state.elapsed += difference;
205
- state.total += difference;
206
- last = now;
207
- if (options.timeout > 0 && state.total >= options.timeout) {
208
- options.onError?.();
209
- finish(timer, state, options, false);
210
- return;
211
- }
212
- if (options.interval === milliseconds ||
213
- state.elapsed >= options.interval - intervalBuffer) {
214
- if (options.count > -1) {
215
- state.callback(state.index);
216
- }
217
- state.elapsed = 0;
218
- state.index += 1;
219
- if (options.count === -1 ||
220
- (options.count > 0 && state.index >= options.count)) {
221
- finish(timer, state, options, true);
222
- return;
223
- }
224
- }
225
- state.frame = requestAnimationFrame(step);
226
- };
227
- }
228
- function setState(type, state) {
229
- const pausable = type === WORK_CONTINUE || type === WORK_PAUSE;
230
- state.elapsed = pausable ? state.elapsed : 0;
231
- state.index = pausable ? state.index : 0;
232
- state.total = pausable ? state.total : 0;
233
- }
234
- function stop(timer, state, options) {
235
- cancelAnimationFrame(state.frame);
236
- activeTimers.delete(timer.instance);
237
- options.onAfter?.(false);
238
- state.active = !stop;
239
- state.frame = undefined;
240
- state.paused = false;
241
- return timer.instance;
242
- }
243
- function work(type, timer, state, options) {
244
- if (ignore(type, state)) {
245
- return timer.instance;
246
- }
247
- setState(type, state);
248
- if (type === WORK_STOP) {
249
- return stop(timer, state, options);
250
- }
251
- if (type === WORK_PAUSE || type === WORK_RESTART) {
252
- cancelAnimationFrame(state.frame);
253
- state.frame = undefined;
254
- }
255
- state.active = true;
256
- state.paused = type === WORK_PAUSE;
257
- if (state.paused) {
258
- return pause(timer, state);
259
- }
260
- activeTimers.add(timer.instance);
261
- const runner = run(timer, state, options);
262
- state.frame = requestAnimationFrame(runner);
263
- return timer.instance;
264
- }
265
-
266
- class Timer {
267
- options;
268
- state;
269
- /**
270
- * Is the timer active?
271
- */
272
- get active() {
273
- return this.state.active;
274
- }
275
- /**
276
- * Is the timer destroyed?
277
- */
278
- get destroyed() {
279
- return this.state.destroyed;
280
- }
281
- /**
282
- * Is the timer paused?
283
- */
284
- get paused() {
285
- return this.state.paused;
286
- }
287
- /**
288
- * Get the timer's origin _(if debugging is enabled)_
289
- */
290
- get trace() {
291
- return (globalThis._oscarpalmer_timer_debug ?? false)
292
- ? this.state.trace
293
- : undefined;
294
- }
295
- constructor(type, state, options, start) {
296
- this.options = options;
297
- this.$timer = type;
298
- this.state = {
299
- ...state,
300
- active: false,
301
- destroyed: false,
302
- elapsed: 0,
303
- frame: undefined,
304
- index: 0,
305
- paused: false,
306
- total: 0,
307
- };
308
- if (start) {
309
- this.start();
310
- }
311
- }
312
- /**
313
- * Continue running the timer _(if it's paused)_
314
- */
315
- continue() {
316
- return this.#work(WORK_CONTINUE);
317
- }
318
- /**
319
- * Destroy the timer
320
- */
321
- destroy() {
322
- this.state.destroyed = true;
323
- this.options.onAfter = noop;
324
- this.options.onError = noop;
325
- this.state.callback = noop;
326
- if (!globalThis._oscarpalmer_timer_debug) {
327
- this.state.trace = undefined;
328
- }
329
- stop({
330
- instance: this,
331
- type: this.$timer,
332
- }, this.state, this.options);
333
- }
334
- /**
335
- * Pause the timer _(if it's running)_
336
- */
337
- pause() {
338
- return this.#work(WORK_PAUSE);
339
- }
340
- /**
341
- * Restart the timer _(or start it, if it's not running)_
342
- */
343
- restart() {
344
- return this.#work(WORK_RESTART);
345
- }
346
- /**
347
- * Start the timer _(if it's not running)_
348
- */
349
- start() {
350
- return this.#work(WORK_START);
351
- }
352
- /**
353
- * Stop the timer _(if it's running)_
354
- */
355
- stop() {
356
- return this.#work(WORK_STOP);
357
- }
358
- #work(type) {
359
- return work(type, {
360
- instance: this,
361
- type: this.$timer,
362
- }, this.state, this.options);
363
- }
364
- }
365
-
366
- /**
367
- * Create a repeating timer
368
- */
369
- function repeat(callback, options) {
370
- return new Timer(TYPE_REPEAT, {
371
- callback: getCallback(callback),
372
- trace: new TimerTrace().stack,
373
- }, {
374
- onAfter: getCallback(options?.onAfter),
375
- onError: getCallback(options?.onTimeout),
376
- count: getValidNumber(options?.count),
377
- interval: getValidNumber(options?.interval, milliseconds),
378
- timeout: getValidNumber(options?.timeout),
379
- }, true);
380
- }
381
-
382
- /**
383
- * Create a waiting timer
384
- * @param callback Callback to run when the timer has finished
385
- * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
386
- */
387
- function wait(callback, time) {
388
- return new Timer(TYPE_WAIT, {
389
- callback: getCallback(callback),
390
- trace: new TimerTrace().stack,
391
- }, {
392
- onAfter: undefined,
393
- onError: undefined,
394
- count: -1,
395
- interval: getValidNumber(time, milliseconds),
396
- timeout: 0,
397
- }, true);
398
- }
399
-
400
- class When {
401
- $timer = TYPE_WHEN;
402
- state = {
403
- promise: undefined,
404
- rejecter: undefined,
405
- resolver: undefined,
406
- started: false,
407
- timer: undefined,
408
- };
409
- /**
410
- * Is the timer active?
411
- */
412
- get active() {
413
- return this.state.timer?.active ?? false;
414
- }
415
- /**
416
- * Is the timer destroyed?
417
- */
418
- get destroyed() {
419
- return this.state.timer == null;
420
- }
421
- /**
422
- * Is the timer paused?
423
- */
424
- get paused() {
425
- return this.state.timer?.paused ?? false;
426
- }
427
- /**
428
- * Get the timer's origin _(if debugging is enabled)_
429
- */
430
- get trace() {
431
- return (globalThis._oscarpalmer_timer_debug ?? false)
432
- ? this.state.timer?.trace
433
- : undefined;
434
- }
435
- constructor(condition, options) {
436
- const { state } = this;
437
- state.promise = new Promise((resolve, reject) => {
438
- state.resolver = resolve;
439
- state.rejecter = reject;
440
- });
441
- let result = false;
442
- this.state.timer = new Timer(TYPE_WHEN, {
443
- callback() {
444
- try {
445
- if (condition()) {
446
- result = true;
447
- state.timer.stop();
448
- }
449
- }
450
- catch {
451
- state.timer.stop();
452
- }
453
- },
454
- trace: new TimerTrace().stack,
455
- }, {
456
- onAfter: () => {
457
- if (result) {
458
- state.resolver?.();
459
- }
460
- else {
461
- state.rejecter?.();
462
- }
463
- this.destroy();
464
- },
465
- onError: () => {
466
- state.rejecter?.();
467
- this.destroy();
468
- },
469
- count: getValidNumber(options?.count),
470
- interval: getValidNumber(options?.interval, milliseconds),
471
- timeout: getValidTimeout(options?.timeout),
472
- }, false);
473
- }
474
- /**
475
- * Continues the timer _(if it was paused)_
476
- */
477
- continue() {
478
- this.state.timer?.continue();
479
- return this;
480
- }
481
- /**
482
- * Destroys the timer _(and stops it,if it was running)_
483
- */
484
- destroy() {
485
- const { state } = this;
486
- state.timer?.destroy();
487
- state.promise = undefined;
488
- state.resolver = noop;
489
- state.rejecter = noop;
490
- state.timer = undefined;
491
- }
492
- /**
493
- * Pauses the timer _(if it was running)_
494
- */
495
- pause() {
496
- this.state.timer?.pause();
497
- return this;
498
- }
499
- /**
500
- * Stops the timer _(if it was running)_
501
- */
502
- stop() {
503
- this.state.timer?.stop();
504
- return this;
505
- }
506
- /**
507
- * Starts the timer and returns a promise that resolves when the condition is met
508
- */
509
- // biome-ignore lint/suspicious/noThenProperty: returning a promise-like object, so it's ok ;)
510
- then(resolve, reject) {
511
- const { state } = this;
512
- if (state.timer == null) {
513
- throw new Error(destroyedMessage);
514
- }
515
- if (state.started) {
516
- throw new Error(startedMessage);
517
- }
518
- state.started = true;
519
- state.timer.start();
520
- return state.promise.then(resolve ?? noop, reject ?? noop);
521
- }
522
- }
523
- /**
524
- * Create a conditional timer
525
- */
526
- function when(condition, options) {
527
- return new When(condition, options);
528
- }
529
-
530
- export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
package/dist/wait.cjs DELETED
@@ -1,18 +0,0 @@
1
- const require_constants = require("./constants.cjs");
2
- const require_get = require("./get.cjs");
3
- require("./global.cjs");
4
- const require_models = require("./models.cjs");
5
- const require_timer = require("./timer.cjs");
6
- function wait(callback, time) {
7
- return new require_timer.Timer(require_constants.TYPE_WAIT, {
8
- callback: require_get.getCallback(callback),
9
- trace: new require_models.TimerTrace().stack
10
- }, {
11
- onAfter: void 0,
12
- onError: void 0,
13
- count: -1,
14
- interval: require_get.getValidNumber(time, require_constants.milliseconds),
15
- timeout: 0
16
- }, true);
17
- }
18
- exports.wait = wait;
package/dist/when.cjs DELETED
@@ -1,95 +0,0 @@
1
- const require_rolldown_runtime = require("./rolldown_runtime.cjs");
2
- const require_constants = require("./constants.cjs");
3
- const require_get = require("./get.cjs");
4
- require("./global.cjs");
5
- const require_models = require("./models.cjs");
6
- const require_timer = require("./timer.cjs");
7
- const __oscarpalmer_atoms_function = require_rolldown_runtime.__toESM(require("@oscarpalmer/atoms/function"));
8
- var When = class {
9
- $timer = require_constants.TYPE_WHEN;
10
- state = {
11
- promise: void 0,
12
- rejecter: void 0,
13
- resolver: void 0,
14
- started: false,
15
- timer: void 0
16
- };
17
- get active() {
18
- return this.state.timer?.active ?? false;
19
- }
20
- get destroyed() {
21
- return this.state.timer == null;
22
- }
23
- get paused() {
24
- return this.state.timer?.paused ?? false;
25
- }
26
- get trace() {
27
- return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
28
- }
29
- constructor(condition, options) {
30
- const { state } = this;
31
- state.promise = new Promise((resolve, reject) => {
32
- state.resolver = resolve;
33
- state.rejecter = reject;
34
- });
35
- let result = false;
36
- this.state.timer = new require_timer.Timer(require_constants.TYPE_WHEN, {
37
- callback() {
38
- try {
39
- if (condition()) {
40
- result = true;
41
- state.timer.stop();
42
- }
43
- } catch {
44
- state.timer.stop();
45
- }
46
- },
47
- trace: new require_models.TimerTrace().stack
48
- }, {
49
- onAfter: () => {
50
- if (result) state.resolver?.();
51
- else state.rejecter?.();
52
- this.destroy();
53
- },
54
- onError: () => {
55
- state.rejecter?.();
56
- this.destroy();
57
- },
58
- count: require_get.getValidNumber(options?.count),
59
- interval: require_get.getValidNumber(options?.interval, require_constants.milliseconds),
60
- timeout: require_get.getValidTimeout(options?.timeout)
61
- }, false);
62
- }
63
- continue() {
64
- this.state.timer?.continue();
65
- return this;
66
- }
67
- destroy() {
68
- const { state } = this;
69
- state.timer?.destroy();
70
- state.promise = void 0;
71
- state.resolver = __oscarpalmer_atoms_function.noop;
72
- state.rejecter = __oscarpalmer_atoms_function.noop;
73
- state.timer = void 0;
74
- }
75
- pause() {
76
- this.state.timer?.pause();
77
- return this;
78
- }
79
- stop() {
80
- this.state.timer?.stop();
81
- return this;
82
- }
83
- then(resolve, reject) {
84
- const { state } = this;
85
- if (state.timer == null) throw new Error(require_constants.destroyedMessage);
86
- if (state.started) throw new Error(require_constants.startedMessage);
87
- state.started = true;
88
- state.timer.start();
89
- return state.promise.then(resolve ?? __oscarpalmer_atoms_function.noop, reject ?? __oscarpalmer_atoms_function.noop);
90
- }
91
- };
92
- function when(condition, options) {
93
- return new When(condition, options);
94
- }
95
- exports.when = when;