@oscarpalmer/timer 0.42.0 → 0.43.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/README.md CHANGED
@@ -64,7 +64,7 @@ function callback(index) {
64
64
  // 'index' is the current step
65
65
  // starts at 0, goes up to a maximum of count - 1
66
66
  // for this example: 0 → 9
67
- };
67
+ }
68
68
  ```
69
69
 
70
70
  When you create a repeated timer, you can also provide a callback to run when the timer stops, as below:
package/dist/index.d.mts CHANGED
@@ -117,13 +117,16 @@ declare global {
117
117
  }
118
118
  //#endregion
119
119
  //#region node_modules/@oscarpalmer/atoms/dist/promise/models.d.mts
120
+ /**
121
+ * Options for a _Promise_-handling function
122
+ */
120
123
  type PromiseOptions = {
121
124
  /**
122
- * AbortSignal for aborting the promise; when aborted, the promise will reject with the reason of the signal
125
+ * AbortSignal for aborting the _Promise_; when aborted, the _Promise_ will reject with the reason of the signal
123
126
  */
124
127
  signal?: AbortSignal;
125
128
  /**
126
- * How long to wait for (in milliseconds; defaults to `0`)
129
+ * How long to wait for _(in milliseconds; defaults to `0`)_
127
130
  */
128
131
  time?: number;
129
132
  };
@@ -132,12 +135,14 @@ type PromiseOptions = {
132
135
  //#region src/promise/delay.d.ts
133
136
  /**
134
137
  * Create a delayed promise that resolves after a certain amount of time, or rejects if aborted
138
+ *
135
139
  * @param options Options for the delay
136
140
  * @returns Delayed promise
137
141
  */
138
142
  declare function delay(options?: PromiseOptions): Promise<void>;
139
143
  /**
140
144
  * Create a delayed promise that resolves after a certain amount of time
145
+ *
141
146
  * @param time How long to wait for _(in milliseconds; defaults to `0`)_
142
147
  * @returns Delayed promise
143
148
  */
@@ -178,23 +183,15 @@ declare class When {
178
183
  pause(): When;
179
184
  /**
180
185
  * Start the timer
186
+ *
181
187
  * @param resolve Optional resolve callback
182
- * @param reject Optional reject callback
183
188
  * @returns Promise that resolves when the condition is met
184
189
  */
185
- start(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void>;
190
+ start(resolve?: (() => void) | null): Promise<void>;
186
191
  /**
187
192
  * Stops the timer _(if it was running)_
188
193
  */
189
194
  stop(): When;
190
- /**
191
- * Start the timer
192
- * @deprecated Use `start()` instead
193
- * @param resolve Optional resolve callback
194
- * @param reject Optional reject callback
195
- * @returns Promise that resolves when the condition is met
196
- */
197
- then(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void>;
198
195
  }
199
196
  /**
200
197
  * Create a conditional timer
@@ -233,6 +230,7 @@ declare function isWhen(value: unknown): value is When;
233
230
  //#region src/repeat.d.ts
234
231
  /**
235
232
  * Create a repeating timer
233
+ *
236
234
  * @param callback Callback to run on each interval
237
235
  * @param options Timer options
238
236
  * @returns Timer instance
@@ -242,9 +240,10 @@ declare function repeat(callback: (index: number) => void, options?: Partial<Rep
242
240
  //#region src/wait.d.ts
243
241
  /**
244
242
  * Create a waiting timer
243
+ *
245
244
  * @param callback Callback to run when the timer has finished
246
245
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
247
246
  */
248
247
  declare function wait(callback: () => void, time?: number): Timer;
249
248
  //#endregion
250
- export { PromiseOptions, type RepeatOptions, type Timer, type When, delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
249
+ export { type PromiseOptions, type RepeatOptions, type Timer, type When, delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
package/dist/index.mjs CHANGED
@@ -46,42 +46,50 @@ function getInterval(value) {
46
46
  return typeof value === "number" && value > 0 ? value : 0;
47
47
  }
48
48
  function getTimer(type, callback, time) {
49
- const interval = getInterval(time);
50
- function run(now) {
49
+ function run() {
50
+ const now = performance.now();
51
51
  start ??= now;
52
52
  if (interval === 0 || now - start >= interval - OFFSET) {
53
- if (throttle) start = now;
53
+ start = throttle ? now : void 0;
54
54
  callback(...args);
55
- } else frame = requestAnimationFrame(run);
55
+ } else id = startTimer(run);
56
56
  }
57
+ const interval = getInterval(time);
57
58
  const throttle = type === TIMER_THROTTLE;
58
59
  let args;
59
- let frame;
60
+ let id;
60
61
  let start;
61
62
  const timer = (...parameters) => {
62
63
  timer.cancel();
63
64
  args = parameters;
64
- frame = requestAnimationFrame(run);
65
+ if (throttle) run();
66
+ else id = startTimer(run);
65
67
  };
66
68
  timer.cancel = () => {
67
- cancelAnimationFrame(frame);
69
+ clearTimer(id);
68
70
  };
69
71
  return timer;
70
72
  }
71
73
  const OFFSET = 5;
72
74
  const TIMER_THROTTLE = "throttle";
73
75
  const TIMER_WAIT = "wait";
76
+ // istanbul ignore next
77
+ const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
78
+ // istanbul ignore next
79
+ const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
74
80
  //#endregion
75
81
  //#region node_modules/@oscarpalmer/atoms/dist/promise/models.mjs
76
82
  const PROMISE_ABORT_EVENT = "abort";
77
83
  const PROMISE_ABORT_OPTIONS = { once: true };
78
84
  //#endregion
79
- //#region node_modules/@oscarpalmer/atoms/dist/promise/helpers.mjs
80
- function getNumberOrDefault(value) {
81
- return typeof value === "number" && value > 0 ? value : 0;
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;
82
88
  }
89
+ //#endregion
90
+ //#region node_modules/@oscarpalmer/atoms/dist/promise/helpers.mjs
83
91
  function getPromiseOptions(input) {
84
- if (typeof input === "number") return { time: getNumberOrDefault(input) };
92
+ if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
85
93
  if (input instanceof AbortSignal) return {
86
94
  signal: input,
87
95
  time: 0
@@ -89,7 +97,7 @@ function getPromiseOptions(input) {
89
97
  const options = typeof input === "object" && input !== null ? input : {};
90
98
  return {
91
99
  signal: options.signal instanceof AbortSignal ? options.signal : void 0,
92
- time: getNumberOrDefault(options.time)
100
+ time: getNumberOrDefault(options.time, 0)
93
101
  };
94
102
  }
95
103
  //#endregion
@@ -155,7 +163,7 @@ function isWaited(value) {
155
163
  * @returns `true` if the value is a conditional timer
156
164
  */
157
165
  function isWhen(value) {
158
- return is(["when"], value) && typeof value.then === "function";
166
+ return is(["when"], value) && typeof value.start === "function";
159
167
  }
160
168
  //#endregion
161
169
  //#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
@@ -267,6 +275,7 @@ function work(type, timer, state, options) {
267
275
  //#endregion
268
276
  //#region src/timer.ts
269
277
  var Timer = class {
278
+ options;
270
279
  state;
271
280
  /**
272
281
  * Is the timer active?
@@ -362,6 +371,7 @@ var Timer = class {
362
371
  //#region src/repeat.ts
363
372
  /**
364
373
  * Create a repeating timer
374
+ *
365
375
  * @param callback Callback to run on each interval
366
376
  * @param options Timer options
367
377
  * @returns Timer instance
@@ -382,6 +392,7 @@ function repeat(callback, options) {
382
392
  //#region src/wait.ts
383
393
  /**
384
394
  * Create a waiting timer
395
+ *
385
396
  * @param callback Callback to run when the timer has finished
386
397
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
387
398
  */
@@ -493,17 +504,17 @@ var When = class {
493
504
  }
494
505
  /**
495
506
  * Start the timer
507
+ *
496
508
  * @param resolve Optional resolve callback
497
- * @param reject Optional reject callback
498
509
  * @returns Promise that resolves when the condition is met
499
510
  */
500
- start(resolve, reject) {
511
+ start(resolve) {
501
512
  const { state } = this;
502
513
  if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
503
514
  if (state.started) throw new Error(MESSAGE_STARTED);
504
515
  state.started = true;
505
516
  state.timer.start();
506
- return state.promise.then(resolve ?? noop, reject ?? noop);
517
+ return state.promise.then(resolve);
507
518
  }
508
519
  /**
509
520
  * Stops the timer _(if it was running)_
@@ -512,16 +523,6 @@ var When = class {
512
523
  this.state.timer?.stop();
513
524
  return this;
514
525
  }
515
- /**
516
- * Start the timer
517
- * @deprecated Use `start()` instead
518
- * @param resolve Optional resolve callback
519
- * @param reject Optional reject callback
520
- * @returns Promise that resolves when the condition is met
521
- */
522
- then(resolve, reject) {
523
- return this.start(resolve, reject);
524
- }
525
526
  };
526
527
  /**
527
528
  * Create a conditional timer
package/dist/is.mjs CHANGED
@@ -33,7 +33,7 @@ function isWaited(value) {
33
33
  * @returns `true` if the value is a conditional timer
34
34
  */
35
35
  function isWhen(value) {
36
- return is(["when"], value) && typeof value.then === "function";
36
+ return is(["when"], value) && typeof value.start === "function";
37
37
  }
38
38
  //#endregion
39
39
  export { isRepeated, isTimer, isWaited, isWhen };
package/dist/repeat.d.mts CHANGED
@@ -3,6 +3,7 @@ import { RepeatOptions } from "./models.mjs";
3
3
  //#region src/repeat.d.ts
4
4
  /**
5
5
  * Create a repeating timer
6
+ *
6
7
  * @param callback Callback to run on each interval
7
8
  * @param options Timer options
8
9
  * @returns Timer instance
package/dist/repeat.mjs CHANGED
@@ -6,6 +6,7 @@ import { Timer } from "./timer.mjs";
6
6
  //#region src/repeat.ts
7
7
  /**
8
8
  * Create a repeating timer
9
+ *
9
10
  * @param callback Callback to run on each interval
10
11
  * @param options Timer options
11
12
  * @returns Timer instance
package/dist/wait.d.mts CHANGED
@@ -2,6 +2,7 @@ import { Timer } from "./timer.mjs";
2
2
  //#region src/wait.d.ts
3
3
  /**
4
4
  * Create a waiting timer
5
+ *
5
6
  * @param callback Callback to run when the timer has finished
6
7
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
7
8
  */
package/dist/wait.mjs CHANGED
@@ -6,6 +6,7 @@ import { Timer } from "./timer.mjs";
6
6
  //#region src/wait.ts
7
7
  /**
8
8
  * Create a waiting timer
9
+ *
9
10
  * @param callback Callback to run when the timer has finished
10
11
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
11
12
  */
package/dist/when.d.mts CHANGED
@@ -34,23 +34,15 @@ declare class When {
34
34
  pause(): When;
35
35
  /**
36
36
  * Start the timer
37
+ *
37
38
  * @param resolve Optional resolve callback
38
- * @param reject Optional reject callback
39
39
  * @returns Promise that resolves when the condition is met
40
40
  */
41
- start(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void>;
41
+ start(resolve?: (() => void) | null): Promise<void>;
42
42
  /**
43
43
  * Stops the timer _(if it was running)_
44
44
  */
45
45
  stop(): When;
46
- /**
47
- * Start the timer
48
- * @deprecated Use `start()` instead
49
- * @param resolve Optional resolve callback
50
- * @param reject Optional reject callback
51
- * @returns Promise that resolves when the condition is met
52
- */
53
- then(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void>;
54
46
  }
55
47
  /**
56
48
  * Create a conditional timer
package/dist/when.mjs CHANGED
@@ -99,17 +99,17 @@ var When = class {
99
99
  }
100
100
  /**
101
101
  * Start the timer
102
+ *
102
103
  * @param resolve Optional resolve callback
103
- * @param reject Optional reject callback
104
104
  * @returns Promise that resolves when the condition is met
105
105
  */
106
- start(resolve, reject) {
106
+ start(resolve) {
107
107
  const { state } = this;
108
108
  if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
109
109
  if (state.started) throw new Error(MESSAGE_STARTED);
110
110
  state.started = true;
111
111
  state.timer.start();
112
- return state.promise.then(resolve ?? noop, reject ?? noop);
112
+ return state.promise.then(resolve);
113
113
  }
114
114
  /**
115
115
  * Stops the timer _(if it was running)_
@@ -118,16 +118,6 @@ var When = class {
118
118
  this.state.timer?.stop();
119
119
  return this;
120
120
  }
121
- /**
122
- * Start the timer
123
- * @deprecated Use `start()` instead
124
- * @param resolve Optional resolve callback
125
- * @param reject Optional reject callback
126
- * @returns Promise that resolves when the condition is met
127
- */
128
- then(resolve, reject) {
129
- return this.start(resolve, reject);
130
- }
131
121
  };
132
122
  /**
133
123
  * Create a conditional timer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/timer",
3
- "version": "0.42.0",
3
+ "version": "0.43.0",
4
4
  "description": "A better solution for timeout- and interval-based timers.",
5
5
  "keywords": [
6
6
  "requestAnimationFrame",
@@ -56,14 +56,15 @@
56
56
  "watch": "npx vite build --watch"
57
57
  },
58
58
  "dependencies": {
59
- "@oscarpalmer/atoms": "^0.165"
59
+ "@oscarpalmer/atoms": "^0.187"
60
60
  },
61
61
  "devDependencies": {
62
- "@types/node": "^25.5",
62
+ "@oxlint/plugins": "^1.66",
63
+ "@types/node": "^25.9",
63
64
  "@vitest/coverage-istanbul": "^4.1",
64
- "jsdom": "^28.1",
65
- "tsdown": "^0.21",
66
- "typescript": "^5.9",
65
+ "jsdom": "^29.1",
66
+ "tsdown": "^0.22",
67
+ "typescript": "^6",
67
68
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
68
69
  "vite-plus": "latest",
69
70
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
package/src/is.ts CHANGED
@@ -40,5 +40,5 @@ export function isWaited(value: unknown): value is Timer {
40
40
  * @returns `true` if the value is a conditional timer
41
41
  */
42
42
  export function isWhen(value: unknown): value is When {
43
- return is([TYPE_WHEN], value) && typeof (value as When).then === 'function';
43
+ return is([TYPE_WHEN], value) && typeof (value as When).start === 'function';
44
44
  }
package/src/repeat.ts CHANGED
@@ -6,6 +6,7 @@ import {Timer} from './timer';
6
6
 
7
7
  /**
8
8
  * Create a repeating timer
9
+ *
9
10
  * @param callback Callback to run on each interval
10
11
  * @param options Timer options
11
12
  * @returns Timer instance
package/src/wait.ts CHANGED
@@ -6,6 +6,7 @@ import {Timer} from './timer';
6
6
 
7
7
  /**
8
8
  * Create a waiting timer
9
+ *
9
10
  * @param callback Callback to run when the timer has finished
10
11
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
11
12
  */
package/src/when.ts CHANGED
@@ -131,11 +131,11 @@ class When {
131
131
 
132
132
  /**
133
133
  * Start the timer
134
+ *
134
135
  * @param resolve Optional resolve callback
135
- * @param reject Optional reject callback
136
136
  * @returns Promise that resolves when the condition is met
137
137
  */
138
- start(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void> {
138
+ start(resolve?: (() => void) | null): Promise<void> {
139
139
  const {state} = this;
140
140
 
141
141
  if (state.timer == null) {
@@ -150,7 +150,7 @@ class When {
150
150
 
151
151
  state.timer.start();
152
152
 
153
- return state.promise.then(resolve ?? noop, reject ?? noop);
153
+ return state.promise.then(resolve);
154
154
  }
155
155
 
156
156
  /**
@@ -161,18 +161,6 @@ class When {
161
161
 
162
162
  return this;
163
163
  }
164
-
165
- /**
166
- * Start the timer
167
- * @deprecated Use `start()` instead
168
- * @param resolve Optional resolve callback
169
- * @param reject Optional reject callback
170
- * @returns Promise that resolves when the condition is met
171
- */
172
- // oxlint-disable-next-line no-thenable: Returning a promise-like object, so it's ok ;)
173
- then(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void> {
174
- return this.start(resolve, reject);
175
- }
176
164
  }
177
165
 
178
166
  /**