@oscarpalmer/timer 0.45.0 → 0.46.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/index.mjs CHANGED
@@ -35,15 +35,13 @@ function finish(state, success) {
35
35
  }
36
36
  function ignore(type, state) {
37
37
  if (state.paused) return type === "pause" || type === "start";
38
- return state.active && type === "start";
38
+ return state.active && (type === "continue" || type === "start");
39
39
  }
40
40
  function run(state) {
41
41
  let last;
42
- let start;
43
42
  return function step(now) {
44
43
  if (!state.active) return;
45
44
  last ??= now;
46
- start ??= now;
47
45
  const difference = now - last;
48
46
  state.elapsed += difference;
49
47
  state.total += difference;
@@ -55,7 +53,6 @@ function run(state) {
55
53
  }
56
54
  if (state.options.interval === 0 || state.elapsed >= state.options.interval - 5) {
57
55
  if (state.options.count > -1) state.callback(state.index);
58
- start = now;
59
56
  state.elapsed = 0;
60
57
  state.index += 1;
61
58
  if (state.options.count === -1 || state.options.count > 0 && state.index >= state.options.count) {
@@ -91,7 +88,7 @@ function work(type, state, hide) {
91
88
  }
92
89
  state.active = true;
93
90
  state.paused = type === WORK_PAUSE;
94
- updateStates(state, state.paused ? hide ?? false ? "hidden" : void 0 : "active");
91
+ updateStates(state, state.paused ? hide : false);
95
92
  if (state.paused) return state.timer;
96
93
  const runner = run(state);
97
94
  state.frame = requestAnimationFrame(runner);
@@ -115,17 +112,20 @@ function onVisibilityChange() {
115
112
  const type = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
116
113
  for (const stored of from) {
117
114
  const state = stored instanceof WeakRef ? stored.deref() : stored;
118
- if (state != null) work(type, state, true);
115
+ if (state == null) from.delete(stored);
116
+ else work(type, state, true);
119
117
  }
120
118
  }
121
- function updateStates(state, key) {
119
+ function updateStates(state, hide) {
122
120
  STATES.active.delete(state);
123
- const hidden = [...STATES.hidden].find((stored) => stored.deref() === state);
124
121
  /* istanbul ignore next */
125
- if (hidden != null) STATES.hidden.delete(hidden);
126
- if (key != null)
127
- /* istanbul ignore next */
128
- STATES[key].add(key === "hidden" ? new WeakRef(state) : state);
122
+ STATES.hidden.delete(state.reference);
123
+ if (hide == null) return;
124
+ /* istanbul ignore if */
125
+ if (hide) {
126
+ state.reference ??= new WeakRef(state);
127
+ STATES.hidden.add(state.reference);
128
+ } else STATES.active.add(state);
129
129
  }
130
130
  //#endregion
131
131
  //#region src/global.ts
@@ -209,7 +209,7 @@ function createTimer(name, pick, options, start) {
209
209
  },
210
210
  active: {
211
211
  enumerable: true,
212
- get: () => state.active
212
+ get: () => state.active && !state.paused
213
213
  },
214
214
  destroyed: {
215
215
  enumerable: true,
package/dist/misc.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import { TimerState, TimerStates } from "./models.mjs";
1
+ import { TimerState } from "./models.mjs";
2
2
  import { GenericCallback } from "@oscarpalmer/atoms/models";
3
3
  //#region src/misc.d.ts
4
4
  declare function getCallback(value: unknown): GenericCallback;
5
5
  declare function getValidNumber(value: unknown, defaultValue?: number): number;
6
6
  declare function getValidTimeout(value: unknown): number;
7
7
  declare function onVisibilityChange(): void;
8
- declare function updateStates(state: TimerState, key?: keyof TimerStates): void;
8
+ declare function updateStates(state: TimerState, hide?: boolean): void;
9
9
  //#endregion
10
10
  export { getCallback, getValidNumber, getValidTimeout, onVisibilityChange, updateStates };
package/dist/misc.mjs CHANGED
@@ -18,17 +18,20 @@ function onVisibilityChange() {
18
18
  const type = document.hidden ? WORK_PAUSE : WORK_CONTINUE;
19
19
  for (const stored of from) {
20
20
  const state = stored instanceof WeakRef ? stored.deref() : stored;
21
- if (state != null) work(type, state, true);
21
+ if (state == null) from.delete(stored);
22
+ else work(type, state, true);
22
23
  }
23
24
  }
24
- function updateStates(state, key) {
25
+ function updateStates(state, hide) {
25
26
  STATES.active.delete(state);
26
- const hidden = [...STATES.hidden].find((stored) => stored.deref() === state);
27
27
  /* istanbul ignore next */
28
- if (hidden != null) STATES.hidden.delete(hidden);
29
- if (key != null)
30
- /* istanbul ignore next */
31
- STATES[key].add(key === "hidden" ? new WeakRef(state) : state);
28
+ STATES.hidden.delete(state.reference);
29
+ if (hide == null) return;
30
+ /* istanbul ignore if */
31
+ if (hide) {
32
+ state.reference ??= new WeakRef(state);
33
+ STATES.hidden.add(state.reference);
34
+ } else STATES.active.add(state);
32
35
  }
33
36
  //#endregion
34
37
  export { getCallback, getValidNumber, getValidTimeout, onVisibilityChange, updateStates };
package/dist/models.d.mts CHANGED
@@ -88,6 +88,7 @@ type TimerState = {
88
88
  name: TimerName;
89
89
  options: TimerOptions;
90
90
  paused: boolean;
91
+ reference?: WeakRef<TimerState>;
91
92
  timer: Timer;
92
93
  total: number;
93
94
  trace?: string;
package/dist/timer.mjs CHANGED
@@ -31,7 +31,7 @@ function createTimer(name, pick, options, start) {
31
31
  },
32
32
  active: {
33
33
  enumerable: true,
34
- get: () => state.active
34
+ get: () => state.active && !state.paused
35
35
  },
36
36
  destroyed: {
37
37
  enumerable: true,
package/dist/work.mjs CHANGED
@@ -12,15 +12,13 @@ function finish(state, success) {
12
12
  }
13
13
  function ignore(type, state) {
14
14
  if (state.paused) return type === "pause" || type === "start";
15
- return state.active && type === "start";
15
+ return state.active && (type === "continue" || type === "start");
16
16
  }
17
17
  function run(state) {
18
18
  let last;
19
- let start;
20
19
  return function step(now) {
21
20
  if (!state.active) return;
22
21
  last ??= now;
23
- start ??= now;
24
22
  const difference = now - last;
25
23
  state.elapsed += difference;
26
24
  state.total += difference;
@@ -32,7 +30,6 @@ function run(state) {
32
30
  }
33
31
  if (state.options.interval === 0 || state.elapsed >= state.options.interval - 5) {
34
32
  if (state.options.count > -1) state.callback(state.index);
35
- start = now;
36
33
  state.elapsed = 0;
37
34
  state.index += 1;
38
35
  if (state.options.count === -1 || state.options.count > 0 && state.index >= state.options.count) {
@@ -68,7 +65,7 @@ function work(type, state, hide) {
68
65
  }
69
66
  state.active = true;
70
67
  state.paused = type === WORK_PAUSE;
71
- updateStates(state, state.paused ? hide ?? false ? "hidden" : void 0 : "active");
68
+ updateStates(state, state.paused ? hide : false);
72
69
  if (state.paused) return state.timer;
73
70
  const runner = run(state);
74
71
  state.frame = requestAnimationFrame(runner);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/timer",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "description": "A better solution for timeout- and interval-based timers.",
5
5
  "keywords": [
6
6
  "requestAnimationFrame",
package/src/misc.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import {noop} from '@oscarpalmer/atoms/function';
2
2
  import type {GenericCallback} from '@oscarpalmer/atoms/models';
3
3
  import {DEFAULT_TIMEOUT, STATES, WORK_CONTINUE, WORK_PAUSE} from './constants';
4
- import type {TimerStates, TimerState} from './models';
4
+ import type {TimerState} from './models';
5
5
  import {work} from './work';
6
6
 
7
7
  export function getCallback(value: unknown): GenericCallback {
@@ -26,24 +26,30 @@ export function onVisibilityChange(): void {
26
26
  for (const stored of from) {
27
27
  const state = stored instanceof WeakRef ? stored.deref() : stored;
28
28
 
29
- if (state != null) {
29
+ if (state == null) {
30
+ from.delete(stored as never);
31
+ } else {
30
32
  work(type, state, true);
31
33
  }
32
34
  }
33
35
  }
34
36
 
35
- export function updateStates(state: TimerState, key?: keyof TimerStates): void {
37
+ export function updateStates(state: TimerState, hide?: boolean): void {
36
38
  STATES.active.delete(state);
37
39
 
38
- const hidden = [...STATES.hidden].find(stored => stored.deref() === state);
39
-
40
40
  /* istanbul ignore next */
41
- if (hidden != null) {
42
- STATES.hidden.delete(hidden);
41
+ STATES.hidden.delete(state.reference!);
42
+
43
+ if (hide == null) {
44
+ return;
43
45
  }
44
46
 
45
- if (key != null) {
46
- /* istanbul ignore next */
47
- STATES[key].add((key === 'hidden' ? new WeakRef(state) : state) as never);
47
+ /* istanbul ignore if */
48
+ if (hide) {
49
+ state.reference ??= new WeakRef(state);
50
+
51
+ STATES.hidden.add(state.reference);
52
+ } else {
53
+ STATES.active.add(state);
48
54
  }
49
55
  }
package/src/models.ts CHANGED
@@ -100,6 +100,7 @@ export type TimerState = {
100
100
  name: TimerName;
101
101
  options: TimerOptions;
102
102
  paused: boolean;
103
+ reference?: WeakRef<TimerState>;
103
104
  timer: Timer;
104
105
  total: number;
105
106
  trace?: string;
package/src/timer.ts CHANGED
@@ -39,7 +39,7 @@ export function createTimer(
39
39
  },
40
40
  active: {
41
41
  enumerable: true,
42
- get: () => state.active,
42
+ get: () => state.active && !state.paused,
43
43
  },
44
44
  destroyed: {
45
45
  enumerable: true,
package/src/work.ts CHANGED
@@ -31,12 +31,11 @@ function ignore(type: WorkHandlerType, state: TimerState): boolean {
31
31
  return type === WORK_PAUSE || type === WORK_START;
32
32
  }
33
33
 
34
- return state.active && type === WORK_START;
34
+ return state.active && (type === WORK_CONTINUE || type === WORK_START);
35
35
  }
36
36
 
37
37
  function run(state: TimerState): (now: DOMHighResTimeStamp) => void {
38
38
  let last: DOMHighResTimeStamp | undefined;
39
- let start: DOMHighResTimeStamp | undefined;
40
39
 
41
40
  return function step(now: DOMHighResTimeStamp): void {
42
41
  if (!state.active) {
@@ -44,7 +43,6 @@ function run(state: TimerState): (now: DOMHighResTimeStamp) => void {
44
43
  }
45
44
 
46
45
  last ??= now;
47
- start ??= now;
48
46
 
49
47
  const difference = now - last;
50
48
 
@@ -66,8 +64,6 @@ function run(state: TimerState): (now: DOMHighResTimeStamp) => void {
66
64
  (state.callback as (index: number) => void)(state.index);
67
65
  }
68
66
 
69
- start = now;
70
-
71
67
  state.elapsed = 0;
72
68
  state.index += 1;
73
69
 
@@ -127,7 +123,7 @@ export function work(type: WorkHandlerType, state: TimerState, hide?: boolean):
127
123
  state.active = true;
128
124
  state.paused = type === WORK_PAUSE;
129
125
 
130
- updateStates(state, state.paused ? ((hide ?? false) ? 'hidden' : undefined) : 'active');
126
+ updateStates(state, state.paused ? hide : false);
131
127
 
132
128
  if (state.paused) {
133
129
  return state.timer;