@oscarpalmer/timer 0.37.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.
package/README.md CHANGED
@@ -36,24 +36,24 @@ const repeated = new Timer(repeatedCallback, 10);
36
36
 
37
37
  When creating a _Timer_, either with the new `new`-keyword or using the functions, you can configure the timer with a few parameters:
38
38
 
39
- |Parameter|Description|
40
- |--------:|:----------|
41
- |`callback`|Callback function to be invoked for each run that are __required__ for all timers.<br>For more information on callbacks, please read [the callbacks section](#callbacks).|
42
- |`count`|How many times the timer should run.<br>If no value is provided, it will default to `1` when using the `new`-keyword and the `wait`-method, but throws an error for the `repeat`-method.|
43
- |`time`|How many milliseconds between each invokations of the provided callback.<br>Defaults to `0`, which is not really _0_ milliseconds, but close enough :wink:|
44
- |`after`|A callback to run after the timer finishes, both when cancelled and completed.<br>If _count_ is greater than `1` and _after_ __is not__ `undefined`, a function is expected.|
39
+ | Parameter | Description |
40
+ | ---------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | `callback` | Callback function to be invoked for each run that are **required** for all timers.<br>For more information on callbacks, please read [the callbacks section](#callbacks). |
42
+ | `count` | How many times the timer should run.<br>If no value is provided, it will default to `1` when using the `new`-keyword and the `wait`-method, but throws an error for the `repeat`-method. |
43
+ | `time` | How many milliseconds between each invokations of the provided callback.<br>Defaults to `0`, which is not really _0_ milliseconds, but close enough :wink: |
44
+ | `after` | A callback to run after the timer finishes, both when cancelled and completed.<br>If _count_ is greater than `1` and _after_ **is not** `undefined`, a function is expected. |
45
45
 
46
46
  ## Methods and properties
47
47
 
48
48
  An instance of _Timer_ also has a few helpful methods and properties:
49
49
 
50
- |Name|Type|Description|
51
- |---:|----|:----------|
52
- |`active`|_Property_|A `boolean` value to check if the timer is running|
53
- |`finished`|_Property_|A `boolean` value to check if the timer was able to finish|
54
- |`start()`|_Method_|Starts the timer.<br>Necessary when creating a timer using the class syntax _(e.g. `new Waited...`)_, but helpful when the timer needs to be started at other times, as well.|
55
- |`stop()`|_Method_|Stops the timer|
56
- |`restart()`|_Method_|Restarts the timer|
50
+ | Name | Type | Description |
51
+ | ----------: | ---------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
52
+ | `active` | _Property_ | A `boolean` value to check if the timer is running |
53
+ | `finished` | _Property_ | A `boolean` value to check if the timer was able to finish |
54
+ | `start()` | _Method_ | Starts the timer.<br>Necessary when creating a timer using the class syntax _(e.g. `new Waited...`)_, but helpful when the timer needs to be started at other times, as well. |
55
+ | `stop()` | _Method_ | Stops the timer |
56
+ | `restart()` | _Method_ | Restarts the timer |
57
57
 
58
58
  ## Callbacks
59
59
 
package/dist/constants.js CHANGED
@@ -5,20 +5,18 @@ function calculate() {
5
5
  function step(now) {
6
6
  if (last != null) values.push(now - last);
7
7
  last = now;
8
- if (values.length >= 10) {
9
- const median = values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4);
10
- resolve(median);
11
- } else requestAnimationFrame(step);
8
+ if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
9
+ else requestAnimationFrame(step);
12
10
  }
13
11
  requestAnimationFrame(step);
14
12
  });
15
13
  }
16
- const defaultTimeout = 3e4;
17
- const activeTimers = /* @__PURE__ */ new Set();
18
- const intervalBuffer = 5;
19
- const destroyedMessage = "Timer has already been destroyed";
20
- const hiddenTimers = /* @__PURE__ */ new Set();
21
- const startedMessage = "Timer has already been started";
14
+ const BUFFER_INTERVAL = 5;
15
+ const DEFAULT_TIMEOUT = 3e4;
16
+ const MESSAGE_DESTROYED = "Timer has already been destroyed";
17
+ const MESSAGE_STARTED = "Timer has already been started";
18
+ const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
19
+ const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
22
20
  const TYPE_REPEAT = "repeat";
23
21
  const TYPE_WAIT = "wait";
24
22
  const TYPE_WHEN = "when";
@@ -27,8 +25,8 @@ const WORK_PAUSE = "pause";
27
25
  const WORK_RESTART = "restart";
28
26
  const WORK_START = "start";
29
27
  const WORK_STOP = "stop";
30
- let milliseconds = 1e3 / 60;
28
+ let MILLISECONDS = 1e3 / 60;
31
29
  calculate().then((value) => {
32
- milliseconds = value;
30
+ MILLISECONDS = value;
33
31
  });
34
- export { TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP, activeTimers, defaultTimeout, destroyedMessage, hiddenTimers, intervalBuffer, milliseconds, startedMessage };
32
+ export { BUFFER_INTERVAL, DEFAULT_TIMEOUT, MESSAGE_DESTROYED, MESSAGE_STARTED, MILLISECONDS, TIMERS_ACTIVE, TIMERS_HIDDEN, TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP };
package/dist/delay.js CHANGED
@@ -1,12 +1,12 @@
1
- import { intervalBuffer, milliseconds } from "./constants.js";
1
+ import { BUFFER_INTERVAL, MILLISECONDS } from "./constants.js";
2
2
  import { getValidNumber } from "./get.js";
3
3
  function delay(time) {
4
4
  return new Promise((resolve) => {
5
- const interval = getValidNumber(time, milliseconds);
5
+ const interval = getValidNumber(time, MILLISECONDS);
6
6
  let start;
7
7
  function step(now) {
8
8
  start ??= now;
9
- if (interval === milliseconds || now - start >= interval - 5) resolve();
9
+ if (interval === MILLISECONDS || now - start >= interval - 5) resolve();
10
10
  else requestAnimationFrame(step);
11
11
  }
12
12
  requestAnimationFrame(step);
package/dist/get.js CHANGED
@@ -1,10 +1,10 @@
1
- import { defaultTimeout } from "./constants.js";
1
+ import { DEFAULT_TIMEOUT } from "./constants.js";
2
2
  import { noop } from "@oscarpalmer/atoms/function";
3
3
  function getCallback(value) {
4
4
  return typeof value === "function" ? value : noop;
5
5
  }
6
6
  function getValidTimeout(value) {
7
- return typeof value === "number" && value > 0 ? value : defaultTimeout;
7
+ return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
8
8
  }
9
9
  function getValidNumber(value, defaultValue) {
10
10
  const actualDefault = defaultValue ?? 0;
package/dist/global.js CHANGED
@@ -1,12 +1,12 @@
1
- import { WORK_CONTINUE, WORK_PAUSE, activeTimers, hiddenTimers } from "./constants.js";
1
+ import { TIMERS_ACTIVE, TIMERS_HIDDEN, WORK_CONTINUE, WORK_PAUSE } from "./constants.js";
2
2
  if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
3
- return globalThis._oscarpalmer_timer_debug ? [...activeTimers] : [];
3
+ return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
4
4
  } });
5
5
  /* istanbul ignore next */
6
6
  document.addEventListener("visibilitychange", () => {
7
- const from = document.hidden ? activeTimers : hiddenTimers;
7
+ const from = document.hidden ? TIMERS_ACTIVE : TIMERS_HIDDEN;
8
8
  const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
9
- const to = document.hidden ? hiddenTimers : activeTimers;
9
+ const to = document.hidden ? TIMERS_HIDDEN : TIMERS_ACTIVE;
10
10
  for (const timer of from) {
11
11
  timer[method]();
12
12
  to.add(timer);
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
+ import { delay } from "./delay.js";
1
2
  import "./global.js";
2
- import { when } from "./when.js";
3
- import { wait } from "./wait.js";
4
- import { repeat } from "./repeat.js";
5
3
  import { isRepeated, isTimer, isWaited, isWhen } from "./is.js";
6
- import { delay } from "./delay.js";
4
+ import { repeat } from "./repeat.js";
5
+ import { wait } from "./wait.js";
6
+ import { when } from "./when.js";
7
7
  export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
package/dist/repeat.js CHANGED
@@ -1,4 +1,4 @@
1
- import { TYPE_REPEAT, milliseconds } from "./constants.js";
1
+ import { MILLISECONDS, TYPE_REPEAT } from "./constants.js";
2
2
  import { getCallback, getValidNumber } from "./get.js";
3
3
  import "./global.js";
4
4
  import { TimerTrace } from "./models.js";
@@ -11,7 +11,7 @@ function repeat(callback, options) {
11
11
  onAfter: getCallback(options?.onAfter),
12
12
  onError: getCallback(options?.onTimeout),
13
13
  count: getValidNumber(options?.count),
14
- interval: getValidNumber(options?.interval, milliseconds),
14
+ interval: getValidNumber(options?.interval, MILLISECONDS),
15
15
  timeout: getValidNumber(options?.timeout)
16
16
  }, true);
17
17
  }
@@ -0,0 +1,515 @@
1
+ function calculate$1() {
2
+ return new Promise((resolve) => {
3
+ const values = [];
4
+ let last;
5
+ function step(now) {
6
+ if (last != null) values.push(now - last);
7
+ last = now;
8
+ if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
9
+ else requestAnimationFrame(step);
10
+ }
11
+ requestAnimationFrame(step);
12
+ });
13
+ }
14
+ /**
15
+ * Buffer value to use when evaluating if a specific time is within a certain range
16
+ */
17
+ const BUFFER_INTERVAL = 5;
18
+ const DEFAULT_TIMEOUT = 3e4;
19
+ /**
20
+ * Message to show when a when-timer is destroyed
21
+ */
22
+ const MESSAGE_DESTROYED = "Timer has already been destroyed";
23
+ /**
24
+ * Message to show when a when-timer is started
25
+ */
26
+ const MESSAGE_STARTED = "Timer has already been started";
27
+ /**
28
+ * A set of all active timers
29
+ */
30
+ const TIMERS_ACTIVE = /* @__PURE__ */ new Set();
31
+ /**
32
+ * A set of timers that were paused due to the document being hidden
33
+ */
34
+ const TIMERS_HIDDEN = /* @__PURE__ */ new Set();
35
+ const TYPE_REPEAT = "repeat";
36
+ const TYPE_WAIT = "wait";
37
+ const TYPE_WHEN = "when";
38
+ const WORK_CONTINUE = "continue";
39
+ const WORK_PAUSE = "pause";
40
+ const WORK_RESTART = "restart";
41
+ const WORK_START = "start";
42
+ const WORK_STOP = "stop";
43
+ /**
44
+ * A calculated average of the refresh rate of the display _(in milliseconds)_
45
+ */
46
+ let MILLISECONDS = 1e3 / 60;
47
+ calculate$1().then((value) => {
48
+ MILLISECONDS = value;
49
+ });
50
+
51
+ if (globalThis._oscarpalmer_timers == null) Object.defineProperty(globalThis, "_oscarpalmer_timers", { get() {
52
+ return globalThis._oscarpalmer_timer_debug ? [...TIMERS_ACTIVE] : [];
53
+ } });
54
+ /* istanbul ignore next */
55
+ document.addEventListener("visibilitychange", () => {
56
+ const from = document.hidden ? TIMERS_ACTIVE : TIMERS_HIDDEN;
57
+ const method = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
58
+ const to = document.hidden ? TIMERS_HIDDEN : TIMERS_ACTIVE;
59
+ for (const timer of from) {
60
+ timer[method]();
61
+ to.add(timer);
62
+ }
63
+ from.clear();
64
+ });
65
+
66
+ var typeArrays = new Set([
67
+ Int8Array,
68
+ Uint8Array,
69
+ Uint8ClampedArray,
70
+ Int16Array,
71
+ Uint16Array,
72
+ Int32Array,
73
+ Uint32Array,
74
+ Float32Array,
75
+ Float64Array,
76
+ BigInt64Array,
77
+ BigUint64Array
78
+ ]);
79
+
80
+ function calculate() {
81
+ return new Promise((resolve) => {
82
+ const values = [];
83
+ let last;
84
+ function step(now) {
85
+ if (last != null) values.push(now - last);
86
+ last = now;
87
+ if (values.length >= 10) resolve(values.sort().slice(2, -2).reduce((first, second) => first + second, 0) / (values.length - 4));
88
+ else requestAnimationFrame(step);
89
+ }
90
+ requestAnimationFrame(step);
91
+ });
92
+ }
93
+ function noop() {}
94
+ let milliseconds = 1e3 / 60;
95
+ calculate().then((value) => {
96
+ milliseconds = value;
97
+ });
98
+
99
+ function getCallback(value) {
100
+ return typeof value === "function" ? value : noop;
101
+ }
102
+ function getValidTimeout(value) {
103
+ return typeof value === "number" && value > 0 ? value : DEFAULT_TIMEOUT;
104
+ }
105
+ function getValidNumber(value, defaultValue) {
106
+ const actualDefault = defaultValue ?? 0;
107
+ return typeof value === "number" && value > actualDefault ? value : actualDefault;
108
+ }
109
+
110
+ /**
111
+ * Create a delayed promise that resolves after a certain amount of time
112
+ * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
113
+ * @returns A promise that resolves after the delay
114
+ */
115
+ function delay(time) {
116
+ return new Promise((resolve) => {
117
+ const interval = getValidNumber(time, MILLISECONDS);
118
+ let start;
119
+ function step(now) {
120
+ start ??= now;
121
+ if (interval === MILLISECONDS || now - start >= interval - BUFFER_INTERVAL) resolve();
122
+ else requestAnimationFrame(step);
123
+ }
124
+ requestAnimationFrame(step);
125
+ });
126
+ }
127
+
128
+ function is(names, value) {
129
+ return names.includes(value?.$timer);
130
+ }
131
+ /**
132
+ * Is the value a repeating timer?
133
+ * @param value Value to check
134
+ * @returns `true` if the value is a repeating timer
135
+ */
136
+ function isRepeated(value) {
137
+ return is([TYPE_REPEAT], value);
138
+ }
139
+ /**
140
+ * Is the value a timer?
141
+ * @param value Value to check
142
+ * @returns `true` if the value is a timer
143
+ */
144
+ function isTimer(value) {
145
+ return is([TYPE_REPEAT, TYPE_WAIT], value);
146
+ }
147
+ /**
148
+ * Is the value a waiting timer?
149
+ * @param value Value to check
150
+ * @returns `true` if the value is a waiting timer
151
+ */
152
+ function isWaited(value) {
153
+ return is([TYPE_WAIT], value);
154
+ }
155
+ /**
156
+ * Is the value a conditional timer?
157
+ * @param value Value to check
158
+ * @returns `true` if the value is a conditional timer
159
+ */
160
+ function isWhen(value) {
161
+ return is([TYPE_WHEN], value) && typeof value.then === "function";
162
+ }
163
+
164
+ var TimerTrace = class extends Error {
165
+ constructor() {
166
+ super();
167
+ this.name = "TimerTrace";
168
+ }
169
+ };
170
+
171
+ function finish(timer, state, options, success) {
172
+ cancelAnimationFrame(state.frame);
173
+ TIMERS_ACTIVE.delete(timer.instance);
174
+ state.active = false;
175
+ state.elapsed = 0;
176
+ state.frame = void 0;
177
+ if (timer.type === TYPE_WAIT) state.callback();
178
+ else options.onAfter?.(success);
179
+ }
180
+ function ignore(type, state) {
181
+ if (state.destroyed) return type !== WORK_STOP;
182
+ if (state.paused) return type === WORK_PAUSE || type === WORK_START;
183
+ return state.active && type === WORK_START;
184
+ }
185
+ function pause(timer, state) {
186
+ cancelAnimationFrame(state.frame);
187
+ state.frame = void 0;
188
+ return timer.instance;
189
+ }
190
+ function run(timer, state, options) {
191
+ let last;
192
+ let start;
193
+ return function step(now) {
194
+ if (!state.active) return;
195
+ last ??= now;
196
+ start ??= now;
197
+ const difference = now - last;
198
+ state.elapsed += difference;
199
+ state.total += difference;
200
+ last = now;
201
+ if (options.timeout > 0 && state.total >= options.timeout) {
202
+ options.onError?.();
203
+ finish(timer, state, options, false);
204
+ return;
205
+ }
206
+ if (options.interval === MILLISECONDS || state.elapsed >= options.interval - BUFFER_INTERVAL) {
207
+ if (options.count > -1) state.callback(state.index);
208
+ start = now;
209
+ state.elapsed = 0;
210
+ state.index += 1;
211
+ if (options.count === -1 || options.count > 0 && state.index >= options.count) {
212
+ finish(timer, state, options, true);
213
+ return;
214
+ }
215
+ }
216
+ state.frame = requestAnimationFrame(step);
217
+ };
218
+ }
219
+ function setState(type, state) {
220
+ const pausable = type === WORK_CONTINUE || type === WORK_PAUSE;
221
+ state.elapsed = pausable ? state.elapsed : 0;
222
+ state.index = pausable ? state.index : 0;
223
+ state.total = pausable ? state.total : 0;
224
+ }
225
+ function stop(timer, state, options) {
226
+ cancelAnimationFrame(state.frame);
227
+ TIMERS_ACTIVE.delete(timer.instance);
228
+ options.onAfter?.(false);
229
+ state.active = !stop;
230
+ state.frame = void 0;
231
+ state.paused = false;
232
+ return timer.instance;
233
+ }
234
+ function work(type, timer, state, options) {
235
+ if (ignore(type, state)) return timer.instance;
236
+ setState(type, state);
237
+ if (type === WORK_STOP) return stop(timer, state, options);
238
+ if (type === WORK_PAUSE || type === WORK_RESTART) {
239
+ cancelAnimationFrame(state.frame);
240
+ state.frame = void 0;
241
+ }
242
+ state.active = true;
243
+ state.paused = type === WORK_PAUSE;
244
+ if (state.paused) return pause(timer, state);
245
+ TIMERS_ACTIVE.add(timer.instance);
246
+ const runner = run(timer, state, options);
247
+ state.frame = requestAnimationFrame(runner);
248
+ return timer.instance;
249
+ }
250
+
251
+ var Timer = class {
252
+ state;
253
+ /**
254
+ * Is the timer active?
255
+ */
256
+ get active() {
257
+ return this.state.active;
258
+ }
259
+ /**
260
+ * Is the timer destroyed?
261
+ */
262
+ get destroyed() {
263
+ return this.state.destroyed;
264
+ }
265
+ /**
266
+ * Is the timer paused?
267
+ */
268
+ get paused() {
269
+ return this.state.paused;
270
+ }
271
+ /**
272
+ * Get the timer's origin _(if debugging is enabled)_
273
+ */
274
+ get trace() {
275
+ return globalThis._oscarpalmer_timer_debug ?? false ? this.state.trace : void 0;
276
+ }
277
+ constructor(type, state, options, start) {
278
+ this.options = options;
279
+ this.$timer = type;
280
+ this.state = {
281
+ ...state,
282
+ active: false,
283
+ destroyed: false,
284
+ elapsed: 0,
285
+ frame: void 0,
286
+ index: 0,
287
+ paused: false,
288
+ total: 0
289
+ };
290
+ if (start) this.start();
291
+ }
292
+ /**
293
+ * Continue running the timer _(if it's paused)_
294
+ */
295
+ continue() {
296
+ return this.#work(WORK_CONTINUE);
297
+ }
298
+ /**
299
+ * Destroy the timer
300
+ */
301
+ destroy() {
302
+ this.state.destroyed = true;
303
+ this.options.onAfter = noop;
304
+ this.options.onError = noop;
305
+ this.state.callback = noop;
306
+ if (!globalThis._oscarpalmer_timer_debug) this.state.trace = void 0;
307
+ stop({
308
+ instance: this,
309
+ type: this.$timer
310
+ }, this.state, this.options);
311
+ }
312
+ /**
313
+ * Pause the timer _(if it's running)_
314
+ */
315
+ pause() {
316
+ return this.#work(WORK_PAUSE);
317
+ }
318
+ /**
319
+ * Restart the timer _(or start it, if it's not running)_
320
+ */
321
+ restart() {
322
+ return this.#work(WORK_RESTART);
323
+ }
324
+ /**
325
+ * Start the timer _(if it's not running)_
326
+ */
327
+ start() {
328
+ return this.#work(WORK_START);
329
+ }
330
+ /**
331
+ * Stop the timer _(if it's running)_
332
+ */
333
+ stop() {
334
+ return this.#work(WORK_STOP);
335
+ }
336
+ #work(type) {
337
+ return work(type, {
338
+ instance: this,
339
+ type: this.$timer
340
+ }, this.state, this.options);
341
+ }
342
+ };
343
+
344
+ /**
345
+ * Create a repeating timer
346
+ * @param callback Callback to run on each interval
347
+ * @param options Timer options
348
+ * @returns Timer instance
349
+ */
350
+ function repeat(callback, options) {
351
+ return new Timer(TYPE_REPEAT, {
352
+ callback: getCallback(callback),
353
+ trace: new TimerTrace().stack
354
+ }, {
355
+ onAfter: getCallback(options?.onAfter),
356
+ onError: getCallback(options?.onTimeout),
357
+ count: getValidNumber(options?.count),
358
+ interval: getValidNumber(options?.interval, MILLISECONDS),
359
+ timeout: getValidNumber(options?.timeout)
360
+ }, true);
361
+ }
362
+
363
+ /**
364
+ * Create a waiting timer
365
+ * @param callback Callback to run when the timer has finished
366
+ * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
367
+ */
368
+ function wait(callback, time) {
369
+ return new Timer(TYPE_WAIT, {
370
+ callback: getCallback(callback),
371
+ trace: new TimerTrace().stack
372
+ }, {
373
+ onAfter: void 0,
374
+ onError: void 0,
375
+ count: -1,
376
+ interval: getValidNumber(time, MILLISECONDS),
377
+ timeout: 0
378
+ }, true);
379
+ }
380
+
381
+ var When = class {
382
+ $timer = TYPE_WHEN;
383
+ state = {
384
+ promise: void 0,
385
+ rejecter: void 0,
386
+ resolver: void 0,
387
+ started: false,
388
+ timer: void 0
389
+ };
390
+ /**
391
+ * Is the timer active?
392
+ */
393
+ get active() {
394
+ return this.state.timer?.active ?? false;
395
+ }
396
+ /**
397
+ * Is the timer destroyed?
398
+ */
399
+ get destroyed() {
400
+ return this.state.timer == null;
401
+ }
402
+ /**
403
+ * Is the timer paused?
404
+ */
405
+ get paused() {
406
+ return this.state.timer?.paused ?? false;
407
+ }
408
+ /**
409
+ * Get the timer's origin _(if debugging is enabled)_
410
+ */
411
+ get trace() {
412
+ return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
413
+ }
414
+ constructor(condition, options) {
415
+ const { state } = this;
416
+ state.promise = new Promise((resolve, reject) => {
417
+ state.resolver = resolve;
418
+ state.rejecter = reject;
419
+ });
420
+ let result = false;
421
+ this.state.timer = new Timer(TYPE_WHEN, {
422
+ callback() {
423
+ try {
424
+ if (condition()) {
425
+ result = true;
426
+ state.timer.stop();
427
+ }
428
+ } catch {
429
+ state.timer.stop();
430
+ }
431
+ },
432
+ trace: new TimerTrace().stack
433
+ }, {
434
+ onAfter: () => {
435
+ if (result) state.resolver?.();
436
+ else state.rejecter?.();
437
+ this.destroy();
438
+ },
439
+ onError: () => {
440
+ state.rejecter?.();
441
+ this.destroy();
442
+ },
443
+ count: getValidNumber(options?.count),
444
+ interval: getValidNumber(options?.interval, MILLISECONDS),
445
+ timeout: getValidTimeout(options?.timeout)
446
+ }, false);
447
+ }
448
+ /**
449
+ * Continues the timer _(if it was paused)_
450
+ */
451
+ continue() {
452
+ this.state.timer?.continue();
453
+ return this;
454
+ }
455
+ /**
456
+ * Destroys the timer _(and stops it,if it was running)_
457
+ */
458
+ destroy() {
459
+ const { state } = this;
460
+ state.timer?.destroy();
461
+ state.promise = void 0;
462
+ state.resolver = noop;
463
+ state.rejecter = noop;
464
+ state.timer = void 0;
465
+ }
466
+ /**
467
+ * Pauses the timer _(if it was running)_
468
+ */
469
+ pause() {
470
+ this.state.timer?.pause();
471
+ return this;
472
+ }
473
+ /**
474
+ * Start the timer
475
+ * @param resolve Optional resolve callback
476
+ * @param reject Optional reject callback
477
+ * @returns Promise that resolves when the condition is met
478
+ */
479
+ start(resolve, reject) {
480
+ const { state } = this;
481
+ if (state.timer == null) throw new Error(MESSAGE_DESTROYED);
482
+ if (state.started) throw new Error(MESSAGE_STARTED);
483
+ state.started = true;
484
+ state.timer.start();
485
+ return state.promise.then(resolve ?? noop, reject ?? noop);
486
+ }
487
+ /**
488
+ * Stops the timer _(if it was running)_
489
+ */
490
+ stop() {
491
+ this.state.timer?.stop();
492
+ return this;
493
+ }
494
+ /**
495
+ * Start the timer
496
+ * @deprecated Use `start()` instead
497
+ * @param resolve Optional resolve callback
498
+ * @param reject Optional reject callback
499
+ * @returns Promise that resolves when the condition is met
500
+ */
501
+ then(resolve, reject) {
502
+ return this.start(resolve, reject);
503
+ }
504
+ };
505
+ /**
506
+ * Create a conditional timer
507
+ * @param condition Condition to check
508
+ * @param options Timer options
509
+ * @returns Timer instance
510
+ */
511
+ function when(condition, options) {
512
+ return new When(condition, options);
513
+ }
514
+
515
+ export { delay, isRepeated, isTimer, isWaited, isWhen, repeat, wait, when };
package/dist/wait.js CHANGED
@@ -1,4 +1,4 @@
1
- import { TYPE_WAIT, milliseconds } from "./constants.js";
1
+ import { MILLISECONDS, TYPE_WAIT } from "./constants.js";
2
2
  import { getCallback, getValidNumber } from "./get.js";
3
3
  import "./global.js";
4
4
  import { TimerTrace } from "./models.js";
@@ -11,7 +11,7 @@ function wait(callback, time) {
11
11
  onAfter: void 0,
12
12
  onError: void 0,
13
13
  count: -1,
14
- interval: getValidNumber(time, milliseconds),
14
+ interval: getValidNumber(time, MILLISECONDS),
15
15
  timeout: 0
16
16
  }, true);
17
17
  }