@oscarpalmer/timer 0.28.0 → 0.30.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 (67) hide show
  1. package/dist/constants.cjs +32 -4
  2. package/dist/constants.js +26 -9
  3. package/dist/delay.cjs +24 -0
  4. package/dist/delay.js +20 -0
  5. package/dist/get.cjs +15 -0
  6. package/dist/get.js +10 -0
  7. package/dist/global.cjs +17 -2
  8. package/dist/global.js +15 -1
  9. package/dist/index.cjs +16 -44
  10. package/dist/index.js +6 -50
  11. package/dist/is.cjs +11 -8
  12. package/dist/is.js +8 -12
  13. package/dist/models.cjs +5 -2
  14. package/dist/models.js +2 -3
  15. package/dist/node_modules/@oscarpalmer/atoms/dist/function.cjs +8 -0
  16. package/dist/node_modules/@oscarpalmer/atoms/dist/function.js +4 -0
  17. package/dist/repeat.cjs +30 -0
  18. package/dist/repeat.js +26 -0
  19. package/dist/timer.cjs +59 -71
  20. package/dist/timer.full.js +472 -0
  21. package/dist/timer.js +56 -72
  22. package/dist/wait.cjs +30 -0
  23. package/dist/wait.js +26 -0
  24. package/dist/when.cjs +59 -44
  25. package/dist/when.js +55 -44
  26. package/dist/work.cjs +72 -0
  27. package/dist/work.js +68 -0
  28. package/package.json +49 -9
  29. package/src/constants.ts +51 -6
  30. package/src/delay.ts +25 -0
  31. package/src/get.ts +12 -0
  32. package/src/global.ts +16 -1
  33. package/src/index.ts +5 -48
  34. package/src/is.ts +6 -6
  35. package/src/models.ts +55 -47
  36. package/src/repeat.ts +32 -0
  37. package/src/timer.ts +67 -151
  38. package/src/wait.ts +31 -0
  39. package/src/when.ts +49 -24
  40. package/src/work.ts +129 -0
  41. package/types/constants.d.cts +49 -74
  42. package/types/constants.d.ts +15 -6
  43. package/types/delay.d.cts +8 -0
  44. package/types/delay.d.ts +4 -0
  45. package/types/get.d.cts +7 -0
  46. package/types/get.d.ts +3 -0
  47. package/types/index.d.cts +89 -94
  48. package/types/index.d.ts +5 -6
  49. package/types/is.d.cts +50 -69
  50. package/types/models.d.cts +61 -63
  51. package/types/models.d.ts +43 -40
  52. package/types/repeat.d.cts +98 -0
  53. package/types/repeat.d.ts +7 -0
  54. package/types/timer.d.cts +35 -97
  55. package/types/timer.d.ts +19 -52
  56. package/types/wait.d.cts +83 -0
  57. package/types/wait.d.ts +8 -0
  58. package/types/when.d.cts +65 -69
  59. package/types/when.d.ts +18 -5
  60. package/types/work.d.cts +78 -0
  61. package/types/work.d.ts +3 -0
  62. package/dist/functions.cjs +0 -99
  63. package/dist/functions.js +0 -99
  64. package/dist/timer.iife.js +0 -431
  65. package/src/functions.ts +0 -158
  66. package/types/functions.d.cts +0 -113
  67. package/types/functions.d.ts +0 -4
package/dist/when.cjs CHANGED
@@ -1,42 +1,56 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const _function = require("@oscarpalmer/atoms/function");
4
- const timer = require("./timer.cjs");
5
- const destroyedMessage = "Timer has already been destroyed";
6
- const startedMessage = "Timer has already been started";
7
- class When extends timer.BasicTimer {
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const _function = require('./node_modules/@oscarpalmer/atoms/dist/function.cjs');
6
+ const constants = require('./constants.cjs');
7
+ const get = require('./get.cjs');
8
+ const models = require('./models.cjs');
9
+ const timer = require('./timer.cjs');
10
+ const work = require('./work.cjs');
11
+
12
+ class When {
13
+ $timer = "when";
14
+ state;
15
+ /**
16
+ * Is the timer active?
17
+ */
8
18
  get active() {
9
- var _a;
10
- return ((_a = this.state.timer) == null ? void 0 : _a.active) ?? false;
19
+ return this.state.timer?.active ?? false;
11
20
  }
21
+ /**
22
+ * Is the timer destroyed?
23
+ */
12
24
  get destroyed() {
13
25
  return this.state.timer == null;
14
26
  }
27
+ /**
28
+ * Is the timer paused?
29
+ */
15
30
  get paused() {
16
- var _a;
17
- return ((_a = this.state.timer) == null ? void 0 : _a.paused) ?? false;
31
+ return this.state.timer?.paused ?? false;
18
32
  }
33
+ /**
34
+ * Get the timer's origin _(if debugging is enabled)_
35
+ */
19
36
  get trace() {
20
- var _a;
21
- return (_a = this.state.timer) == null ? void 0 : _a.trace;
37
+ return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
22
38
  }
23
39
  constructor(state) {
24
- super("when", state);
40
+ this.state = state;
25
41
  }
26
42
  /**
27
43
  * Continues the timer _(if it was paused)_
28
44
  */
29
45
  continue() {
30
- var _a;
31
- (_a = this.state.timer) == null ? void 0 : _a.continue();
46
+ this.state.timer?.continue();
32
47
  return this;
33
48
  }
34
49
  /**
35
50
  * Destroys the timer _(and stops it,if it was running)_
36
51
  */
37
52
  destroy() {
38
- var _a;
39
- (_a = this.state.timer) == null ? void 0 : _a.destroy();
53
+ this.state.timer?.destroy();
40
54
  this.state.promise = void 0;
41
55
  this.state.resolver = _function.noop;
42
56
  this.state.rejecter = _function.noop;
@@ -46,16 +60,14 @@ class When extends timer.BasicTimer {
46
60
  * Pauses the timer _(if it was running)_
47
61
  */
48
62
  pause() {
49
- var _a;
50
- (_a = this.state.timer) == null ? void 0 : _a.pause();
63
+ this.state.timer?.pause();
51
64
  return this;
52
65
  }
53
66
  /**
54
67
  * Stops the timer _(if it was running)_
55
68
  */
56
69
  stop() {
57
- var _a;
58
- (_a = this.state.timer) == null ? void 0 : _a.stop();
70
+ this.state.timer?.stop();
59
71
  return this;
60
72
  }
61
73
  /**
@@ -63,10 +75,9 @@ class When extends timer.BasicTimer {
63
75
  */
64
76
  // biome-ignore lint/suspicious/noThenProperty: returning a promise-like object, so it's ok ;)
65
77
  then(resolve, reject) {
66
- var _a;
67
- if (this.state.timer == null || ((_a = this.state) == null ? void 0 : _a.started)) {
78
+ if (this.state.timer == null || this.state?.started) {
68
79
  throw new Error(
69
- this.state.timer == null ? destroyedMessage : startedMessage
80
+ this.state.timer == null ? constants.destroyedMessage : constants.startedMessage
70
81
  );
71
82
  }
72
83
  this.state.started = true;
@@ -75,37 +86,41 @@ class When extends timer.BasicTimer {
75
86
  }
76
87
  }
77
88
  function when(condition, options) {
89
+ let called = false;
78
90
  let result = false;
79
91
  const state = {
80
92
  started: false,
81
- timer: timer.timer(
82
- "repeat",
83
- () => {
84
- if (condition()) {
85
- result = true;
86
- state.timer.stop();
87
- }
93
+ timer: new timer.Timer(
94
+ "when",
95
+ work.work,
96
+ {
97
+ callback() {
98
+ if (condition()) {
99
+ result = true;
100
+ state.timer.stop();
101
+ }
102
+ },
103
+ trace: new models.TimerTrace().stack
88
104
  },
89
105
  {
90
- afterCallback() {
91
- var _a, _b;
92
- if (!state.timer.paused) {
106
+ onAfter() {
107
+ if (!(state.timer?.paused ?? false) && !called) {
108
+ called = true;
93
109
  if (result) {
94
- (_a = state.resolver) == null ? void 0 : _a.call(state);
110
+ state.resolver?.();
95
111
  } else {
96
- (_b = state.rejecter) == null ? void 0 : _b.call(state);
112
+ state.rejecter?.();
97
113
  }
98
114
  instance.destroy();
99
115
  }
100
116
  },
101
- errorCallback() {
102
- var _a;
103
- (_a = state.rejecter) == null ? void 0 : _a.call(state);
117
+ onError() {
118
+ state.rejecter?.();
104
119
  instance.destroy();
105
120
  },
106
- count: options == null ? void 0 : options.count,
107
- interval: options == null ? void 0 : options.interval,
108
- timeout: options == null ? void 0 : options.timeout
121
+ count: get.getValidNumber(options?.count),
122
+ interval: get.getValidNumber(options?.interval, constants.milliseconds),
123
+ timeout: get.getValidNumber(options?.timeout)
109
124
  },
110
125
  false
111
126
  )
@@ -118,5 +133,5 @@ function when(condition, options) {
118
133
  const instance = new When(state);
119
134
  return instance;
120
135
  }
121
- exports.When = When;
136
+
122
137
  exports.when = when;
package/dist/when.js CHANGED
@@ -1,40 +1,52 @@
1
- import { noop } from "@oscarpalmer/atoms/function";
2
- import { BasicTimer, timer } from "./timer.js";
3
- const destroyedMessage = "Timer has already been destroyed";
4
- const startedMessage = "Timer has already been started";
5
- class When extends BasicTimer {
1
+ import { noop } from './node_modules/@oscarpalmer/atoms/dist/function.js';
2
+ import { milliseconds, destroyedMessage, startedMessage } from './constants.js';
3
+ import { getValidNumber } from './get.js';
4
+ import { TimerTrace } from './models.js';
5
+ import { Timer } from './timer.js';
6
+ import { work } from './work.js';
7
+
8
+ class When {
9
+ $timer = "when";
10
+ state;
11
+ /**
12
+ * Is the timer active?
13
+ */
6
14
  get active() {
7
- var _a;
8
- return ((_a = this.state.timer) == null ? void 0 : _a.active) ?? false;
15
+ return this.state.timer?.active ?? false;
9
16
  }
17
+ /**
18
+ * Is the timer destroyed?
19
+ */
10
20
  get destroyed() {
11
21
  return this.state.timer == null;
12
22
  }
23
+ /**
24
+ * Is the timer paused?
25
+ */
13
26
  get paused() {
14
- var _a;
15
- return ((_a = this.state.timer) == null ? void 0 : _a.paused) ?? false;
27
+ return this.state.timer?.paused ?? false;
16
28
  }
29
+ /**
30
+ * Get the timer's origin _(if debugging is enabled)_
31
+ */
17
32
  get trace() {
18
- var _a;
19
- return (_a = this.state.timer) == null ? void 0 : _a.trace;
33
+ return globalThis._oscarpalmer_timer_debug ?? false ? this.state.timer?.trace : void 0;
20
34
  }
21
35
  constructor(state) {
22
- super("when", state);
36
+ this.state = state;
23
37
  }
24
38
  /**
25
39
  * Continues the timer _(if it was paused)_
26
40
  */
27
41
  continue() {
28
- var _a;
29
- (_a = this.state.timer) == null ? void 0 : _a.continue();
42
+ this.state.timer?.continue();
30
43
  return this;
31
44
  }
32
45
  /**
33
46
  * Destroys the timer _(and stops it,if it was running)_
34
47
  */
35
48
  destroy() {
36
- var _a;
37
- (_a = this.state.timer) == null ? void 0 : _a.destroy();
49
+ this.state.timer?.destroy();
38
50
  this.state.promise = void 0;
39
51
  this.state.resolver = noop;
40
52
  this.state.rejecter = noop;
@@ -44,16 +56,14 @@ class When extends BasicTimer {
44
56
  * Pauses the timer _(if it was running)_
45
57
  */
46
58
  pause() {
47
- var _a;
48
- (_a = this.state.timer) == null ? void 0 : _a.pause();
59
+ this.state.timer?.pause();
49
60
  return this;
50
61
  }
51
62
  /**
52
63
  * Stops the timer _(if it was running)_
53
64
  */
54
65
  stop() {
55
- var _a;
56
- (_a = this.state.timer) == null ? void 0 : _a.stop();
66
+ this.state.timer?.stop();
57
67
  return this;
58
68
  }
59
69
  /**
@@ -61,8 +71,7 @@ class When extends BasicTimer {
61
71
  */
62
72
  // biome-ignore lint/suspicious/noThenProperty: returning a promise-like object, so it's ok ;)
63
73
  then(resolve, reject) {
64
- var _a;
65
- if (this.state.timer == null || ((_a = this.state) == null ? void 0 : _a.started)) {
74
+ if (this.state.timer == null || this.state?.started) {
66
75
  throw new Error(
67
76
  this.state.timer == null ? destroyedMessage : startedMessage
68
77
  );
@@ -73,37 +82,41 @@ class When extends BasicTimer {
73
82
  }
74
83
  }
75
84
  function when(condition, options) {
85
+ let called = false;
76
86
  let result = false;
77
87
  const state = {
78
88
  started: false,
79
- timer: timer(
80
- "repeat",
81
- () => {
82
- if (condition()) {
83
- result = true;
84
- state.timer.stop();
85
- }
89
+ timer: new Timer(
90
+ "when",
91
+ work,
92
+ {
93
+ callback() {
94
+ if (condition()) {
95
+ result = true;
96
+ state.timer.stop();
97
+ }
98
+ },
99
+ trace: new TimerTrace().stack
86
100
  },
87
101
  {
88
- afterCallback() {
89
- var _a, _b;
90
- if (!state.timer.paused) {
102
+ onAfter() {
103
+ if (!(state.timer?.paused ?? false) && !called) {
104
+ called = true;
91
105
  if (result) {
92
- (_a = state.resolver) == null ? void 0 : _a.call(state);
106
+ state.resolver?.();
93
107
  } else {
94
- (_b = state.rejecter) == null ? void 0 : _b.call(state);
108
+ state.rejecter?.();
95
109
  }
96
110
  instance.destroy();
97
111
  }
98
112
  },
99
- errorCallback() {
100
- var _a;
101
- (_a = state.rejecter) == null ? void 0 : _a.call(state);
113
+ onError() {
114
+ state.rejecter?.();
102
115
  instance.destroy();
103
116
  },
104
- count: options == null ? void 0 : options.count,
105
- interval: options == null ? void 0 : options.interval,
106
- timeout: options == null ? void 0 : options.timeout
117
+ count: getValidNumber(options?.count),
118
+ interval: getValidNumber(options?.interval, milliseconds),
119
+ timeout: getValidNumber(options?.timeout)
107
120
  },
108
121
  false
109
122
  )
@@ -116,7 +129,5 @@ function when(condition, options) {
116
129
  const instance = new When(state);
117
130
  return instance;
118
131
  }
119
- export {
120
- When,
121
- when
122
- };
132
+
133
+ export { when };
package/dist/work.cjs ADDED
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const constants = require('./constants.cjs');
6
+
7
+ function finish(timer, state, options, success) {
8
+ constants.activeTimers.delete(timer.instance);
9
+ state.active = false;
10
+ state.elapsed = 0;
11
+ state.frame = void 0;
12
+ if (timer.type === "wait") {
13
+ state.callback();
14
+ } else {
15
+ options.onAfter?.(success);
16
+ }
17
+ }
18
+ function work(type, timer, state, options) {
19
+ if (state.destroyed && type !== "stop" || (state.active ? constants.beginTypes.has(type) : constants.endTypes.has(type))) {
20
+ return timer.instance;
21
+ }
22
+ const pausable = constants.pauseTypes.has(type);
23
+ state.elapsed = pausable ? state.elapsed : 0;
24
+ state.index = pausable ? state.index : 0;
25
+ state.total = pausable ? state.total : 0;
26
+ if (constants.endOrRestartTypes.has(type)) {
27
+ constants.activeTimers.delete(timer.instance);
28
+ cancelAnimationFrame(state.frame);
29
+ if (type === "stop") {
30
+ options.onAfter?.(false);
31
+ }
32
+ state.active = false;
33
+ state.frame = void 0;
34
+ state.paused = type === "pause";
35
+ return type === "restart" ? work("start", timer, state, options) : timer.instance;
36
+ }
37
+ state.active = true;
38
+ state.paused = false;
39
+ let start;
40
+ function step(now) {
41
+ if (!state.active) {
42
+ return;
43
+ }
44
+ start ??= now;
45
+ const difference = now - start;
46
+ state.elapsed += difference;
47
+ state.total += difference;
48
+ if (options.timeout > 0 && state.total >= options.timeout) {
49
+ options.onError?.();
50
+ finish(timer, state, options, false);
51
+ return;
52
+ }
53
+ if (options.interval === constants.milliseconds || state.elapsed >= options.interval - 5) {
54
+ if (options.count > -1) {
55
+ state.callback(state.index);
56
+ }
57
+ start = now;
58
+ state.elapsed = 0;
59
+ state.index += 1;
60
+ if (options.count === -1 || options.count > 0 && state.index >= options.count) {
61
+ finish(timer, state, options, true);
62
+ return;
63
+ }
64
+ }
65
+ state.frame = requestAnimationFrame(step);
66
+ }
67
+ constants.activeTimers.add(timer.instance);
68
+ state.frame = requestAnimationFrame(step);
69
+ return timer.instance;
70
+ }
71
+
72
+ exports.work = work;
package/dist/work.js ADDED
@@ -0,0 +1,68 @@
1
+ import { beginTypes, endTypes, pauseTypes, endOrRestartTypes, activeTimers, milliseconds } from './constants.js';
2
+
3
+ function finish(timer, state, options, success) {
4
+ activeTimers.delete(timer.instance);
5
+ state.active = false;
6
+ state.elapsed = 0;
7
+ state.frame = void 0;
8
+ if (timer.type === "wait") {
9
+ state.callback();
10
+ } else {
11
+ options.onAfter?.(success);
12
+ }
13
+ }
14
+ function work(type, timer, state, options) {
15
+ if (state.destroyed && type !== "stop" || (state.active ? beginTypes.has(type) : endTypes.has(type))) {
16
+ return timer.instance;
17
+ }
18
+ const pausable = pauseTypes.has(type);
19
+ state.elapsed = pausable ? state.elapsed : 0;
20
+ state.index = pausable ? state.index : 0;
21
+ state.total = pausable ? state.total : 0;
22
+ if (endOrRestartTypes.has(type)) {
23
+ activeTimers.delete(timer.instance);
24
+ cancelAnimationFrame(state.frame);
25
+ if (type === "stop") {
26
+ options.onAfter?.(false);
27
+ }
28
+ state.active = false;
29
+ state.frame = void 0;
30
+ state.paused = type === "pause";
31
+ return type === "restart" ? work("start", timer, state, options) : timer.instance;
32
+ }
33
+ state.active = true;
34
+ state.paused = false;
35
+ let start;
36
+ function step(now) {
37
+ if (!state.active) {
38
+ return;
39
+ }
40
+ start ??= now;
41
+ const difference = now - start;
42
+ state.elapsed += difference;
43
+ state.total += difference;
44
+ if (options.timeout > 0 && state.total >= options.timeout) {
45
+ options.onError?.();
46
+ finish(timer, state, options, false);
47
+ return;
48
+ }
49
+ if (options.interval === milliseconds || state.elapsed >= options.interval - 5) {
50
+ if (options.count > -1) {
51
+ state.callback(state.index);
52
+ }
53
+ start = now;
54
+ state.elapsed = 0;
55
+ state.index += 1;
56
+ if (options.count === -1 || options.count > 0 && state.index >= options.count) {
57
+ finish(timer, state, options, true);
58
+ return;
59
+ }
60
+ }
61
+ state.frame = requestAnimationFrame(step);
62
+ }
63
+ activeTimers.add(timer.instance);
64
+ state.frame = requestAnimationFrame(step);
65
+ return timer.instance;
66
+ }
67
+
68
+ export { work };
package/package.json CHANGED
@@ -4,22 +4,22 @@
4
4
  "url": "https://oscarpalmer.se"
5
5
  },
6
6
  "dependencies": {
7
- "@oscarpalmer/atoms": "^0.82"
7
+ "@oscarpalmer/atoms": "^0.99"
8
8
  },
9
9
  "description": "A better solution for timeout- and interval-based timers.",
10
10
  "devDependencies": {
11
11
  "@biomejs/biome": "^1.9",
12
12
  "@rollup/plugin-node-resolve": "^16",
13
13
  "@rollup/plugin-typescript": "^12.1",
14
- "@types/node": "^22.13",
15
- "@vitest/coverage-istanbul": "^3",
14
+ "@types/node": "^22.15",
15
+ "@vitest/coverage-istanbul": "^3.1",
16
16
  "dts-bundle-generator": "^9.5",
17
17
  "glob": "^11",
18
- "happy-dom": "^16.8",
18
+ "jsdom": "^26.1",
19
19
  "tslib": "^2.8",
20
- "typescript": "^5.7",
21
- "vite": "^6",
22
- "vitest": "^3"
20
+ "typescript": "^5.8",
21
+ "vite": "^6.3",
22
+ "vitest": "^3.1"
23
23
  },
24
24
  "exports": {
25
25
  ".": {
@@ -31,6 +31,46 @@
31
31
  "types": "./types/index.d.cts",
32
32
  "default": "./dist/index.cjs"
33
33
  }
34
+ },
35
+ "./delay": {
36
+ "import": {
37
+ "types": "./types/delay.d.ts",
38
+ "default": "./dist/delay.js"
39
+ },
40
+ "require": {
41
+ "types": "./types/delay.d.cts",
42
+ "default": "./dist/delay.cjs"
43
+ }
44
+ },
45
+ "./repeat": {
46
+ "import": {
47
+ "types": "./types/repeat.d.ts",
48
+ "default": "./dist/repeat.js"
49
+ },
50
+ "require": {
51
+ "types": "./types/repeat.d.cts",
52
+ "default": "./dist/repeat.cjs"
53
+ }
54
+ },
55
+ "./wait": {
56
+ "import": {
57
+ "types": "./types/wait.d.ts",
58
+ "default": "./dist/wait.js"
59
+ },
60
+ "require": {
61
+ "types": "./types/wait.d.cts",
62
+ "default": "./dist/wait.cjs"
63
+ }
64
+ },
65
+ "./when": {
66
+ "import": {
67
+ "types": "./types/when.d.ts",
68
+ "default": "./dist/when.js"
69
+ },
70
+ "require": {
71
+ "types": "./types/when.d.cts",
72
+ "default": "./dist/when.cjs"
73
+ }
34
74
  }
35
75
  },
36
76
  "files": ["dist", "src", "types"],
@@ -49,10 +89,10 @@
49
89
  "clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
50
90
  "rollup": "npx rollup -c",
51
91
  "test": "npx vitest --coverage",
52
- "types": "npx tsc && npx dts-bundle-generator --config ./dts.config.cts",
92
+ "types": "npx tsc && npx dts-bundle-generator --config ./dts.config.cts --silent",
53
93
  "watch": "npx vite build --watch"
54
94
  },
55
95
  "type": "module",
56
96
  "types": "types/index.d.cts",
57
- "version": "0.28.0"
97
+ "version": "0.30.0"
58
98
  }
package/src/constants.ts CHANGED
@@ -1,6 +1,32 @@
1
- import type {WorkType} from './models';
1
+ import type {WorkHandlerType} from './models';
2
2
  import type {Timer} from './timer';
3
3
 
4
+ /**
5
+ * Stepper to calculate the average refresh rate of the display
6
+ */
7
+ function stepper(now: DOMHighResTimeStamp): void {
8
+ if (values.length === 7) {
9
+ milliseconds = Math.floor(
10
+ (values.slice(2).reduce((first, second) => first + second) / 5) * 2,
11
+ ) / 2;
12
+
13
+ last = undefined;
14
+ values.length = 0;
15
+ } else {
16
+ last ??= now;
17
+
18
+ const difference = now - last;
19
+
20
+ if (difference > 0) {
21
+ values.push(difference);
22
+ }
23
+
24
+ last = now;
25
+
26
+ requestAnimationFrame(stepper);
27
+ }
28
+ }
29
+
4
30
  /**
5
31
  * A set of all active timers
6
32
  */
@@ -9,17 +35,22 @@ export const activeTimers = new Set<Timer>();
9
35
  /**
10
36
  * A set of types that allow work to begin
11
37
  */
12
- export const beginTypes = new Set<WorkType>(['continue', 'start']);
38
+ export const beginTypes = new Set<WorkHandlerType>(['continue', 'start']);
39
+
40
+ /**
41
+ * Message to show when a when-timer is destroyed
42
+ */
43
+ export const destroyedMessage = 'Timer has already been destroyed';
13
44
 
14
45
  /**
15
46
  * A set of types that allow work to end
16
47
  */
17
- export const endTypes = new Set<WorkType>(['pause', 'stop']);
48
+ export const endTypes = new Set<WorkHandlerType>(['pause', 'stop']);
18
49
 
19
50
  /**
20
51
  * A set of types that allow work to end or restart
21
52
  */
22
- export const endOrRestartTypes = new Set<WorkType>([
53
+ export const endOrRestartTypes = new Set<WorkHandlerType>([
23
54
  'pause',
24
55
  'restart',
25
56
  'stop',
@@ -30,7 +61,21 @@ export const endOrRestartTypes = new Set<WorkType>([
30
61
  */
31
62
  export const hiddenTimers = new Set<Timer>();
32
63
 
64
+ export const pauseTypes = new Set<WorkHandlerType>(['continue', 'pause']);
65
+
33
66
  /**
34
- * Milliseconds in a frame, probably ;-)
67
+ * Message to show when a when-timer is started
35
68
  */
36
- export const milliseconds = 1_000 / 60;
69
+ export const startedMessage = 'Timer has already been started';
70
+
71
+ //
72
+
73
+ const values: number[] = [];
74
+ let last: DOMHighResTimeStamp | undefined;
75
+
76
+ /**
77
+ * A calculated average of the refresh rate of the display _(in milliseconds)_
78
+ */
79
+ export let milliseconds = Math.floor((1000 / 60) * 2) / 2;
80
+
81
+ requestAnimationFrame(stepper);
package/src/delay.ts ADDED
@@ -0,0 +1,25 @@
1
+ import {milliseconds} from './constants';
2
+ import {getValidNumber} from './get';
3
+
4
+ /**
5
+ * Create a delayed promise that resolves after a certain amount of time _(in milliseconds; defaults to screen refresh rate)_
6
+ */
7
+ export function delay(time?: number): Promise<void> {
8
+ return new Promise(resolve => {
9
+ const interval = getValidNumber(time, milliseconds);
10
+
11
+ let start: DOMHighResTimeStamp;
12
+
13
+ function step(now: DOMHighResTimeStamp) {
14
+ start ??= now;
15
+
16
+ if (interval === milliseconds || now - start >= interval - 5) {
17
+ resolve();
18
+ } else {
19
+ requestAnimationFrame(step);
20
+ }
21
+ }
22
+
23
+ requestAnimationFrame(step);
24
+ });
25
+ }