@oscarpalmer/timer 0.47.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/models.d.mts CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Options for a repeating timer
4
4
  */
5
- type RepeatOptions = {
5
+ export type RepeatOptions = {
6
6
  /**
7
7
  * Callback to be called when the timer has stopped, either manually or by completing its work
8
8
  */
@@ -24,7 +24,7 @@ type RepeatOptions = {
24
24
  */
25
25
  timeout: number;
26
26
  };
27
- type Timer = {
27
+ export type Timer = {
28
28
  /**
29
29
  * Is the timer active?
30
30
  */
@@ -70,15 +70,15 @@ type Timer = {
70
70
  */
71
71
  stop(): Timer;
72
72
  };
73
- type TimerName = 'repeat' | 'wait' | 'when';
74
- type TimerOptions = {
73
+ export type TimerName = 'repeat' | 'wait' | 'when';
74
+ export type TimerOptions = {
75
75
  onAfter: ((finished: boolean) => void) | undefined;
76
76
  onError: (() => void) | undefined;
77
77
  count: number;
78
78
  interval: number;
79
79
  timeout: number;
80
80
  };
81
- type TimerState = {
81
+ export type TimerState = {
82
82
  active: boolean;
83
83
  callback: () => void;
84
84
  destroyed: boolean;
@@ -93,7 +93,7 @@ type TimerState = {
93
93
  total: number;
94
94
  trace?: string;
95
95
  };
96
- type TimerStates = {
96
+ export type TimerStates = {
97
97
  /**
98
98
  * A set of all active timers
99
99
  */
@@ -103,10 +103,10 @@ type TimerStates = {
103
103
  */
104
104
  hidden: Set<WeakRef<TimerState>>;
105
105
  };
106
- declare class TimerTrace extends Error {
106
+ export declare class TimerTrace extends Error {
107
107
  constructor();
108
108
  }
109
- type When = {
109
+ export type When = {
110
110
  /**
111
111
  * Is the timer active?
112
112
  */
@@ -154,7 +154,7 @@ type When = {
154
154
  /**
155
155
  * Options for a conditional timer
156
156
  */
157
- type WhenOptions = {
157
+ export type WhenOptions = {
158
158
  /**
159
159
  * How many times the timer should check the condition
160
160
  */
@@ -168,7 +168,8 @@ type WhenOptions = {
168
168
  */
169
169
  timeout: number;
170
170
  };
171
- type WhenState = {
171
+ export type WhenState = {
172
+ name: TimerName;
172
173
  promise: Promise<void>;
173
174
  rejecter?: () => void;
174
175
  resolver?: () => void;
@@ -176,11 +177,10 @@ type WhenState = {
176
177
  started: boolean;
177
178
  timer: Timer;
178
179
  };
179
- type WorkHandler = (type: WorkHandlerType, timer: WorkHandlerTimer, state: TimerState, options: TimerOptions) => Timer;
180
- type WorkHandlerTimer = {
180
+ export type WorkHandler = (type: WorkHandlerType, timer: WorkHandlerTimer, state: TimerState, options: TimerOptions) => Timer;
181
+ export type WorkHandlerTimer = {
181
182
  instance: Timer;
182
183
  name: TimerName;
183
184
  };
184
- type WorkHandlerType = 'continue' | 'pause' | 'restart' | 'start' | 'stop';
185
- //#endregion
186
- export { RepeatOptions, Timer, TimerName, TimerOptions, TimerState, TimerStates, TimerTrace, When, WhenOptions, WhenState, WorkHandler, WorkHandlerTimer, WorkHandlerType };
185
+ export type WorkHandlerType = 'continue' | 'pause' | 'restart' | 'start' | 'stop';
186
+ //#endregion
package/dist/repeat.d.mts CHANGED
@@ -8,6 +8,5 @@ import "./global.mjs";
8
8
  * @param options Timer options
9
9
  * @returns Repeating timer
10
10
  */
11
- declare function repeat(callback: (index: number) => void, options?: Partial<RepeatOptions>): Timer;
12
- //#endregion
13
- export { repeat };
11
+ export declare function repeat(callback: (index: number) => void, options?: Partial<RepeatOptions>): Timer;
12
+ //#endregion
package/dist/timer.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Timer, TimerName, TimerOptions, TimerState } from "./models.mjs";
2
2
  //#region src/timer.d.ts
3
- declare function createTimer(name: TimerName, pick: Pick<TimerState, 'callback' | 'trace'>, options: TimerOptions, start: boolean): Timer;
4
- //#endregion
5
- export { createTimer };
3
+ declare function Timer(this: any, name: TimerName, state: Pick<TimerState, 'callback' | 'trace'>, options: TimerOptions, start: boolean): void;
4
+ export declare function createTimer(name: TimerName, state: Pick<TimerState, 'callback' | 'trace'>, options: TimerOptions, start: boolean): Timer;
5
+ //#endregion
package/dist/timer.mjs CHANGED
@@ -1,10 +1,9 @@
1
- import { WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP } from "./constants.mjs";
1
+ import { SYMBOL, WORK_CONTINUE, WORK_PAUSE, WORK_RESTART, WORK_START, WORK_STOP } from "./constants.mjs";
2
2
  import { work } from "./work.mjs";
3
- import { noop } from "@oscarpalmer/atoms/function";
4
3
  //#region src/timer.ts
5
- function createTimer(name, pick, options, start) {
6
- const state = {
7
- ...pick,
4
+ function Timer(name, state, options, start) {
5
+ Object.defineProperty(this, SYMBOL, { value: {
6
+ ...state,
8
7
  name,
9
8
  options,
10
9
  active: false,
@@ -15,40 +14,57 @@ function createTimer(name, pick, options, start) {
15
14
  paused: false,
16
15
  timer: void 0,
17
16
  total: 0
18
- };
19
- const instance = {
20
- continue: () => work(WORK_CONTINUE, state),
21
- destroy: noop,
22
- pause: () => work(WORK_PAUSE, state),
23
- restart: () => work(WORK_RESTART, state),
24
- start: () => work(WORK_START, state),
25
- stop: () => work(WORK_STOP, state)
26
- };
27
- Object.defineProperties(instance, {
28
- $timer: {
29
- enumerable: false,
30
- value: name
31
- },
32
- active: {
33
- enumerable: true,
34
- get: () => state.active && !state.paused
35
- },
36
- destroyed: {
37
- enumerable: true,
38
- value: false
39
- },
40
- paused: {
41
- enumerable: true,
42
- get: () => state.paused
43
- },
44
- trace: {
45
- enumerable: true,
46
- get: () => globalThis._oscarpalmer_timer_debug ?? false ? state.trace : void 0
17
+ } });
18
+ if (start) startTimer.call(this);
19
+ }
20
+ Object.defineProperties(Timer.prototype, {
21
+ active: {
22
+ enumerable: true,
23
+ get() {
24
+ return isActiveTimer.call(this);
25
+ }
26
+ },
27
+ continue: { value: continueTimer },
28
+ pause: { value: pauseTimer },
29
+ paused: {
30
+ enumerable: true,
31
+ get() {
32
+ return isPausedTimer.call(this);
47
33
  }
48
- });
49
- state.timer = Object.freeze(instance);
50
- if (start) state.timer.start();
51
- return state.timer;
34
+ },
35
+ restart: { value: restartTimer },
36
+ start: { value: startTimer },
37
+ stop: { value: stopTimer },
38
+ trace: { get() {
39
+ return getTimerTrace.call(this);
40
+ } }
41
+ });
42
+ function continueTimer() {
43
+ return work(WORK_CONTINUE, this[SYMBOL]);
44
+ }
45
+ function createTimer(name, state, options, start) {
46
+ return new Timer(name, state, options, start);
47
+ }
48
+ function getTimerTrace() {
49
+ return globalThis._oscarpalmer_timer_debug ?? false ? this[SYMBOL].trace : void 0;
50
+ }
51
+ function isActiveTimer() {
52
+ return this[SYMBOL].active && !this[SYMBOL].paused;
53
+ }
54
+ function isPausedTimer() {
55
+ return this[SYMBOL].paused;
56
+ }
57
+ function pauseTimer() {
58
+ return work(WORK_PAUSE, this[SYMBOL]);
59
+ }
60
+ function restartTimer() {
61
+ return work(WORK_RESTART, this[SYMBOL]);
62
+ }
63
+ function startTimer() {
64
+ return work(WORK_START, this[SYMBOL]);
65
+ }
66
+ function stopTimer() {
67
+ return work(WORK_STOP, this[SYMBOL]);
52
68
  }
53
69
  //#endregion
54
70
  export { createTimer };
package/dist/wait.d.mts CHANGED
@@ -8,6 +8,5 @@ import "./global.mjs";
8
8
  * @param time How long to wait for _(in milliseconds; defaults to screen refresh rate)_
9
9
  * @returns Waiting timer
10
10
  */
11
- declare function wait(callback: () => void, time?: number): Timer;
12
- //#endregion
13
- export { wait };
11
+ export declare function wait(callback: () => void, time?: number): Timer;
12
+ //#endregion
package/dist/when.d.mts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { When, WhenOptions } from "./models.mjs";
2
2
  import "./global.mjs";
3
3
  //#region src/when.d.ts
4
+ declare function When(this: any, condition: () => boolean, options: WhenOptions): void;
4
5
  /**
5
6
  * Create a conditional timer
6
7
  * @param condition Condition to check
7
8
  * @param options Timer options
8
9
  * @returns Timer instance
9
10
  */
10
- declare function when(condition: () => boolean, options?: Partial<WhenOptions>): When;
11
- //#endregion
12
- export { when };
11
+ export declare function when(condition: () => boolean, options?: Partial<WhenOptions>): When;
12
+ //#endregion
package/dist/when.mjs CHANGED
@@ -1,10 +1,66 @@
1
- import { MESSAGE_STARTED, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_STOP } from "./constants.mjs";
1
+ import { MESSAGE_STARTED, SYMBOL, TYPE_WHEN, WORK_CONTINUE, WORK_PAUSE, WORK_STOP } from "./constants.mjs";
2
2
  import { getValidNumber, getValidTimeout } from "./misc.mjs";
3
3
  import "./global.mjs";
4
4
  import { TimerTrace } from "./models.mjs";
5
5
  import { createTimer } from "./timer.mjs";
6
- import { noop } from "@oscarpalmer/atoms/function";
7
6
  //#region src/when.ts
7
+ function When(condition, options) {
8
+ const state = {
9
+ name: TYPE_WHEN,
10
+ promise: void 0,
11
+ result: false,
12
+ started: false,
13
+ timer: void 0
14
+ };
15
+ Object.defineProperty(this, SYMBOL, { value: state });
16
+ state.promise = new Promise((resolve, reject) => {
17
+ state.resolver = resolve;
18
+ state.rejecter = reject;
19
+ });
20
+ state.timer = createTimer(TYPE_WHEN, {
21
+ callback: () => onCallback(condition, state),
22
+ trace: new TimerTrace().stack
23
+ }, {
24
+ ...options,
25
+ onAfter: () => onAfter(state),
26
+ onError: () => state.rejecter?.()
27
+ }, false);
28
+ }
29
+ Object.defineProperties(When.prototype, {
30
+ active: { get() {
31
+ return isActiveWhen.call(this);
32
+ } },
33
+ continue: { value: continueWhen },
34
+ pause: { value: pauseWhen },
35
+ paused: { get() {
36
+ return isPausedWhen.call(this);
37
+ } },
38
+ start: { value: startWhen },
39
+ stop: { value: stopWhen },
40
+ trace: { get() {
41
+ return getWhenTrace.call(this);
42
+ } }
43
+ });
44
+ function continueWhen() {
45
+ return onWhen(WORK_CONTINUE, this, this[SYMBOL]);
46
+ }
47
+ function getWhenOptions(input) {
48
+ const options = typeof input === "object" && input !== null ? input : {};
49
+ return {
50
+ count: getValidNumber(options?.count),
51
+ interval: getValidNumber(options?.interval),
52
+ timeout: getValidTimeout(options?.timeout)
53
+ };
54
+ }
55
+ function getWhenTrace() {
56
+ return globalThis._oscarpalmer_timer_debug ?? false ? this[SYMBOL].timer?.trace : void 0;
57
+ }
58
+ function isActiveWhen() {
59
+ return this[SYMBOL].timer.active;
60
+ }
61
+ function isPausedWhen() {
62
+ return this[SYMBOL].timer.paused;
63
+ }
8
64
  function onAfter(state) {
9
65
  if (state.result) state.resolver?.();
10
66
  else state.rejecter?.();
@@ -23,12 +79,19 @@ function onWhen(type, instance, state) {
23
79
  state.timer?.[type]?.();
24
80
  return instance;
25
81
  }
26
- function startWhen(state, resolve) {
82
+ function pauseWhen() {
83
+ return onWhen(WORK_PAUSE, this, this[SYMBOL]);
84
+ }
85
+ function startWhen(resolve) {
86
+ const state = this[SYMBOL];
27
87
  if (state.started) throw new Error(MESSAGE_STARTED);
28
88
  state.started = true;
29
89
  state.timer.start();
30
90
  return state.promise.then(resolve);
31
91
  }
92
+ function stopWhen() {
93
+ return onWhen(WORK_STOP, this, this[SYMBOL]);
94
+ }
32
95
  /**
33
96
  * Create a conditional timer
34
97
  * @param condition Condition to check
@@ -36,57 +99,7 @@ function startWhen(state, resolve) {
36
99
  * @returns Timer instance
37
100
  */
38
101
  function when(condition, options) {
39
- const state = {
40
- promise: void 0,
41
- result: false,
42
- started: false,
43
- timer: void 0
44
- };
45
- let instance;
46
- state.promise = new Promise((resolve, reject) => {
47
- state.resolver = resolve;
48
- state.rejecter = reject;
49
- });
50
- state.timer = createTimer(TYPE_WHEN, {
51
- callback: () => onCallback(condition, state),
52
- trace: new TimerTrace().stack
53
- }, {
54
- onAfter: () => onAfter(state),
55
- onError: () => state.rejecter?.(),
56
- count: getValidNumber(options?.count),
57
- interval: getValidNumber(options?.interval),
58
- timeout: getValidTimeout(options?.timeout)
59
- }, false);
60
- instance = {
61
- continue: () => onWhen(WORK_CONTINUE, instance, state),
62
- destroy: noop,
63
- pause: () => onWhen(WORK_PAUSE, instance, state),
64
- start: (resolve) => startWhen(state, resolve),
65
- stop: () => onWhen(WORK_STOP, instance, state)
66
- };
67
- Object.defineProperties(instance, {
68
- $timer: {
69
- enumerable: false,
70
- value: TYPE_WHEN
71
- },
72
- active: {
73
- enumerable: true,
74
- get: () => state.timer.active
75
- },
76
- destroyed: {
77
- enumerable: true,
78
- value: false
79
- },
80
- paused: {
81
- enumerable: true,
82
- get: () => state.timer.paused
83
- },
84
- trace: {
85
- enumerable: true,
86
- get: () => globalThis._oscarpalmer_timer_debug ?? false ? state.timer?.trace : void 0
87
- }
88
- });
89
- return Object.freeze(instance);
102
+ return new When(condition, getWhenOptions(options));
90
103
  }
91
104
  //#endregion
92
105
  export { when };
package/dist/work.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Timer, TimerState, WorkHandlerType } from "./models.mjs";
2
2
  //#region src/work.d.ts
3
- declare function stop(state: TimerState): Timer;
4
- declare function work(type: WorkHandlerType, state: TimerState, hide?: boolean): Timer;
5
- //#endregion
6
- export { stop, work };
3
+ export declare function stop(state: TimerState): Timer;
4
+ export declare function work(type: WorkHandlerType, state: TimerState, hide?: boolean): Timer;
5
+ //#endregion
package/dist/work.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { WORK_PAUSE } from "./constants.mjs";
2
- import { updateStates } from "./misc.mjs";
2
+ import { startTimer, stopTimer, updateStates } from "./misc.mjs";
3
3
  //#region src/work.ts
4
4
  function finish(state, success) {
5
5
  updateStates(state);
6
- cancelAnimationFrame(state.frame);
6
+ stopTimer(state.frame);
7
7
  state.active = false;
8
8
  state.elapsed = 0;
9
9
  state.frame = void 0;
@@ -16,8 +16,9 @@ function ignore(type, state) {
16
16
  }
17
17
  function run(state) {
18
18
  let last;
19
- return function step(now) {
19
+ return function step() {
20
20
  if (!state.active) return;
21
+ const now = performance.now();
21
22
  last ??= now;
22
23
  const difference = now - last;
23
24
  state.elapsed += difference;
@@ -37,7 +38,7 @@ function run(state) {
37
38
  return;
38
39
  }
39
40
  }
40
- state.frame = requestAnimationFrame(step);
41
+ state.frame = startTimer(step);
41
42
  };
42
43
  }
43
44
  function setState(type, state) {
@@ -48,7 +49,7 @@ function setState(type, state) {
48
49
  }
49
50
  function stop(state) {
50
51
  updateStates(state);
51
- cancelAnimationFrame(state.frame);
52
+ stopTimer(state.frame);
52
53
  state.options.onAfter?.(false);
53
54
  state.active = false;
54
55
  state.frame = void 0;
@@ -60,7 +61,7 @@ function work(type, state, hide) {
60
61
  setState(type, state);
61
62
  if (type === "stop") return stop(state);
62
63
  if (type === "pause" || type === "restart") {
63
- cancelAnimationFrame(state.frame);
64
+ stopTimer(state.frame);
64
65
  state.frame = void 0;
65
66
  }
66
67
  state.active = true;
@@ -68,7 +69,7 @@ function work(type, state, hide) {
68
69
  updateStates(state, state.paused ? hide : false);
69
70
  if (state.paused) return state.timer;
70
71
  const runner = run(state);
71
- state.frame = requestAnimationFrame(runner);
72
+ state.frame = startTimer(runner);
72
73
  return state.timer;
73
74
  }
74
75
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/timer",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "description": "A better solution for timeout- and interval-based timers.",
5
5
  "keywords": [
6
6
  "requestAnimationFrame",
@@ -60,14 +60,14 @@
60
60
  "watch": "npx vite build --watch"
61
61
  },
62
62
  "dependencies": {
63
- "@oscarpalmer/atoms": "^0.195"
63
+ "@oscarpalmer/atoms": "^0.203"
64
64
  },
65
65
  "devDependencies": {
66
- "@oxlint/plugins": "^1.80",
67
- "@types/node": "^26.4",
66
+ "@oxlint/plugins": "^1.82",
67
+ "@types/node": "^26.5",
68
68
  "@vitest/coverage-istanbul": "^4.1",
69
69
  "jsdom": "^30",
70
- "tsdown": "^0.22",
70
+ "tsdown": "^0.23",
71
71
  "typescript": "^6",
72
72
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
73
73
  "vite-plus": "latest",
package/src/constants.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type {TimerName, TimerStates, WorkHandlerType} from './models';
2
2
 
3
+ // #region Variables
4
+
3
5
  /**
4
6
  * Buffer value to use when evaluating if a specific time is within a certain range
5
7
  */
@@ -7,6 +9,8 @@ export const BUFFER_INTERVAL = 5;
7
9
 
8
10
  export const DEFAULT_TIMEOUT = 30_000;
9
11
 
12
+ export const GLOBAL_NAME = '_oscarpalmer_timers';
13
+
10
14
  /**
11
15
  * Message to show when a when-timer is started
12
16
  */
@@ -17,6 +21,8 @@ export const STATES: TimerStates = {
17
21
  hidden: new Set(),
18
22
  };
19
23
 
24
+ export const SYMBOL = Symbol('timer');
25
+
20
26
  export const TYPE_REPEAT: TimerName = 'repeat';
21
27
 
22
28
  export const TYPE_WAIT: TimerName = 'wait';
@@ -32,3 +38,5 @@ export const WORK_RESTART: WorkHandlerType = 'restart';
32
38
  export const WORK_START: WorkHandlerType = 'start';
33
39
 
34
40
  export const WORK_STOP: WorkHandlerType = 'stop';
41
+
42
+ // #endregion
package/src/global.ts CHANGED
@@ -1,7 +1,9 @@
1
- import {STATES} from './constants';
1
+ import {GLOBAL_NAME, STATES} from './constants';
2
2
  import {onVisibilityChange} from './misc';
3
3
  import type {Timer} from './models';
4
4
 
5
+ // #region Types
6
+
5
7
  declare global {
6
8
  var _oscarpalmer_timer_debug: boolean | undefined;
7
9
  /**
@@ -10,10 +12,24 @@ declare global {
10
12
  var _oscarpalmer_timers: Timer[] | undefined;
11
13
  }
12
14
 
13
- Object.defineProperty(globalThis, '_oscarpalmer_timers', {
14
- get() {
15
- return globalThis._oscarpalmer_timer_debug ? [...STATES.active].map(state => state.timer) : [];
16
- },
17
- });
15
+ // #endregion
16
+
17
+ // #region Initialization
18
+
19
+ /* istanbul ignore next */
20
+ if (!(GLOBAL_NAME in globalThis)) {
21
+ Object.defineProperty(globalThis, GLOBAL_NAME, {
22
+ get() {
23
+ return globalThis._oscarpalmer_timer_debug
24
+ ? [...STATES.active].map(state => state.timer)
25
+ : [];
26
+ },
27
+ });
28
+ }
29
+
30
+ /* istanbul ignore next */
31
+ if ('document' in globalThis) {
32
+ document.addEventListener('visibilitychange', onVisibilityChange);
33
+ }
18
34
 
19
- document.addEventListener('visibilitychange', onVisibilityChange);
35
+ // #endregion
package/src/is.ts CHANGED
@@ -1,47 +1,55 @@
1
- import type {PlainObject} from '@oscarpalmer/atoms/models';
2
- import {TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN} from './constants';
1
+ import {SYMBOL, TYPE_REPEAT, TYPE_WAIT, TYPE_WHEN} from './constants';
3
2
  import type {Timer, When} from './models';
4
3
 
5
- function is(names: string[], value: unknown) {
6
- return names.includes((value as PlainObject)?.$timer as string);
4
+ // #region Functions
5
+
6
+ function isInstance(names: string[], value: unknown) {
7
+ return (
8
+ typeof value === 'object' &&
9
+ value !== null &&
10
+ SYMBOL in value &&
11
+ names.includes((value as any)[SYMBOL].name as string)
12
+ );
7
13
  }
8
14
 
9
15
  /**
10
16
  * Is the value a repeating timer?
11
- *
17
+ *
12
18
  * @param value Value to check
13
19
  * @returns `true` if the value is a repeating timer, otherwise `false`
14
20
  */
15
21
  export function isRepeated(value: unknown): value is Timer {
16
- return is([TYPE_REPEAT], value);
22
+ return isInstance([TYPE_REPEAT], value);
17
23
  }
18
24
 
19
25
  /**
20
26
  * Is the value a timer?
21
- *
27
+ *
22
28
  * @param value Value to check
23
29
  * @returns `true` if the value is a timer, otherwise `false`
24
30
  */
25
31
  export function isTimer(value: unknown): value is Timer {
26
- return is([TYPE_REPEAT, TYPE_WAIT], value);
32
+ return isInstance([TYPE_REPEAT, TYPE_WAIT], value);
27
33
  }
28
34
 
29
35
  /**
30
36
  * Is the value a waiting timer?
31
- *
37
+ *
32
38
  * @param value Value to check
33
39
  * @returns `true` if the value is a waiting timer, otherwise `false`
34
40
  */
35
41
  export function isWaited(value: unknown): value is Timer {
36
- return is([TYPE_WAIT], value);
42
+ return isInstance([TYPE_WAIT], value);
37
43
  }
38
44
 
39
45
  /**
40
46
  * Is the value a conditional timer?
41
- *
47
+ *
42
48
  * @param value Value to check
43
49
  * @returns `true` if the value is a conditional timer, otherwise `false`
44
50
  */
45
51
  export function isWhen(value: unknown): value is When {
46
- return is([TYPE_WHEN], value) && typeof (value as When).start === 'function';
52
+ return isInstance([TYPE_WHEN], value) && typeof (value as When).start === 'function';
47
53
  }
54
+
55
+ // #endregion
package/src/misc.ts CHANGED
@@ -4,6 +4,8 @@ import {DEFAULT_TIMEOUT, STATES, WORK_CONTINUE, WORK_PAUSE} from './constants';
4
4
  import type {TimerState} from './models';
5
5
  import {work} from './work';
6
6
 
7
+ // #region Functions
8
+
7
9
  export function getCallback(value: unknown): GenericCallback {
8
10
  return typeof value === 'function' ? (value as GenericCallback) : noop;
9
11
  }
@@ -53,3 +55,16 @@ export function updateStates(state: TimerState, hide?: boolean): void {
53
55
  STATES.active.add(state);
54
56
  }
55
57
  }
58
+
59
+ // #endregion
60
+
61
+ // #region Variables
62
+
63
+ /* istanbul ignore next */
64
+ export const startTimer =
65
+ 'requestAnimationFrame' in globalThis ? requestAnimationFrame : setTimeout;
66
+
67
+ /* istanbul ignore next */
68
+ export const stopTimer = 'cancelAnimationFrame' in globalThis ? cancelAnimationFrame : clearTimeout;
69
+
70
+ // #endregion