@oscarpalmer/atoms 0.46.0 → 0.47.1
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/js/index.js +35 -13
- package/dist/js/timer.js +35 -13
- package/dist/js/timer.mjs +35 -13
- package/package.json +3 -7
- package/src/js/timer.ts +77 -31
- package/types/timer.d.ts +25 -11
package/dist/js/index.js
CHANGED
|
@@ -875,6 +875,12 @@ var timer = function(type, callback, partial) {
|
|
|
875
875
|
active: false
|
|
876
876
|
};
|
|
877
877
|
const instance = Object.create({
|
|
878
|
+
continue() {
|
|
879
|
+
return work2("continue", this, state, options, isRepeated2);
|
|
880
|
+
},
|
|
881
|
+
pause() {
|
|
882
|
+
return work2("pause", this, state, options, isRepeated2);
|
|
883
|
+
},
|
|
878
884
|
restart() {
|
|
879
885
|
return work2("restart", this, state, options, isRepeated2);
|
|
880
886
|
},
|
|
@@ -925,6 +931,12 @@ function when(condition, options) {
|
|
|
925
931
|
rejecter = reject;
|
|
926
932
|
});
|
|
927
933
|
const instance = Object.create({
|
|
934
|
+
continue() {
|
|
935
|
+
repeated.continue();
|
|
936
|
+
},
|
|
937
|
+
pause() {
|
|
938
|
+
repeated.pause();
|
|
939
|
+
},
|
|
928
940
|
stop() {
|
|
929
941
|
if (repeated.active) {
|
|
930
942
|
repeated.stop();
|
|
@@ -951,29 +963,37 @@ function when(condition, options) {
|
|
|
951
963
|
return instance;
|
|
952
964
|
}
|
|
953
965
|
var work2 = function(type, timer2, state, options, isRepeated2) {
|
|
954
|
-
if (
|
|
966
|
+
if (["continue", "start"].includes(type) && state.active || ["pause", "stop"].includes(type) && !state.active) {
|
|
955
967
|
return timer2;
|
|
956
968
|
}
|
|
957
969
|
const { count, interval, timeout } = options;
|
|
958
|
-
if (
|
|
970
|
+
if (["pause", "stop"].includes(type)) {
|
|
971
|
+
activeTimers.delete(timer2);
|
|
959
972
|
cancelAnimationFrame(state.frame);
|
|
960
973
|
options.afterCallback?.(false);
|
|
961
|
-
}
|
|
962
|
-
if (type === "stop") {
|
|
963
|
-
activeTimers.delete(timer2);
|
|
964
974
|
state.active = false;
|
|
965
975
|
state.frame = undefined;
|
|
976
|
+
if (type === "stop") {
|
|
977
|
+
state.elapsed = undefined;
|
|
978
|
+
state.index = undefined;
|
|
979
|
+
}
|
|
966
980
|
return timer2;
|
|
967
981
|
}
|
|
968
982
|
state.active = true;
|
|
969
983
|
const canTimeout = timeout > 0 && timeout < Number.POSITIVE_INFINITY;
|
|
970
|
-
const
|
|
984
|
+
const elapsed = type === "continue" ? +(state.elapsed ?? 0) : 0;
|
|
985
|
+
let index = type === "continue" ? +(state.index ?? 0) : 0;
|
|
986
|
+
state.elapsed = elapsed;
|
|
987
|
+
state.index = index;
|
|
988
|
+
const total = (count === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : (count - index) * (interval > 0 ? interval : 62.5)) - elapsed;
|
|
971
989
|
let current;
|
|
972
990
|
let start;
|
|
973
|
-
let index = 0;
|
|
974
991
|
function finish(finished, error) {
|
|
992
|
+
activeTimers.delete(timer2);
|
|
975
993
|
state.active = false;
|
|
994
|
+
state.elapsed = undefined;
|
|
976
995
|
state.frame = undefined;
|
|
996
|
+
state.index = undefined;
|
|
977
997
|
if (error) {
|
|
978
998
|
options.errorCallback?.();
|
|
979
999
|
}
|
|
@@ -985,15 +1005,17 @@ var work2 = function(type, timer2, state, options, isRepeated2) {
|
|
|
985
1005
|
}
|
|
986
1006
|
current ??= timestamp;
|
|
987
1007
|
start ??= timestamp;
|
|
988
|
-
const
|
|
989
|
-
|
|
990
|
-
|
|
1008
|
+
const time2 = timestamp - current;
|
|
1009
|
+
state.elapsed = elapsed + (current - start);
|
|
1010
|
+
const finished = time2 - elapsed >= total;
|
|
1011
|
+
if (finished || time2 - 2 < interval && interval < time2 + 2) {
|
|
991
1012
|
if (state.active) {
|
|
992
1013
|
state.callback(isRepeated2 ? index : undefined);
|
|
993
1014
|
}
|
|
994
1015
|
index += 1;
|
|
1016
|
+
state.index = index;
|
|
995
1017
|
switch (true) {
|
|
996
|
-
case (canTimeout && !finished && timestamp - start >= timeout):
|
|
1018
|
+
case (canTimeout && !finished && timestamp - start >= timeout - elapsed):
|
|
997
1019
|
finish(false, true);
|
|
998
1020
|
return;
|
|
999
1021
|
case (!finished && index < count):
|
|
@@ -1016,11 +1038,11 @@ document.addEventListener("visibilitychange", () => {
|
|
|
1016
1038
|
if (document.hidden) {
|
|
1017
1039
|
for (const timer2 of activeTimers) {
|
|
1018
1040
|
hiddenTimers.add(timer2);
|
|
1019
|
-
timer2.
|
|
1041
|
+
timer2.pause();
|
|
1020
1042
|
}
|
|
1021
1043
|
} else {
|
|
1022
1044
|
for (const timer2 of hiddenTimers) {
|
|
1023
|
-
timer2.
|
|
1045
|
+
timer2.continue();
|
|
1024
1046
|
}
|
|
1025
1047
|
hiddenTimers.clear();
|
|
1026
1048
|
}
|
package/dist/js/timer.js
CHANGED
|
@@ -34,6 +34,12 @@ var timer = function(type, callback, partial) {
|
|
|
34
34
|
active: false
|
|
35
35
|
};
|
|
36
36
|
const instance = Object.create({
|
|
37
|
+
continue() {
|
|
38
|
+
return work("continue", this, state, options, isRepeated2);
|
|
39
|
+
},
|
|
40
|
+
pause() {
|
|
41
|
+
return work("pause", this, state, options, isRepeated2);
|
|
42
|
+
},
|
|
37
43
|
restart() {
|
|
38
44
|
return work("restart", this, state, options, isRepeated2);
|
|
39
45
|
},
|
|
@@ -84,6 +90,12 @@ function when(condition, options) {
|
|
|
84
90
|
rejecter = reject;
|
|
85
91
|
});
|
|
86
92
|
const instance = Object.create({
|
|
93
|
+
continue() {
|
|
94
|
+
repeated.continue();
|
|
95
|
+
},
|
|
96
|
+
pause() {
|
|
97
|
+
repeated.pause();
|
|
98
|
+
},
|
|
87
99
|
stop() {
|
|
88
100
|
if (repeated.active) {
|
|
89
101
|
repeated.stop();
|
|
@@ -110,29 +122,37 @@ function when(condition, options) {
|
|
|
110
122
|
return instance;
|
|
111
123
|
}
|
|
112
124
|
var work = function(type, timer2, state, options, isRepeated2) {
|
|
113
|
-
if (
|
|
125
|
+
if (["continue", "start"].includes(type) && state.active || ["pause", "stop"].includes(type) && !state.active) {
|
|
114
126
|
return timer2;
|
|
115
127
|
}
|
|
116
128
|
const { count, interval, timeout } = options;
|
|
117
|
-
if (
|
|
129
|
+
if (["pause", "stop"].includes(type)) {
|
|
130
|
+
activeTimers.delete(timer2);
|
|
118
131
|
cancelAnimationFrame(state.frame);
|
|
119
132
|
options.afterCallback?.(false);
|
|
120
|
-
}
|
|
121
|
-
if (type === "stop") {
|
|
122
|
-
activeTimers.delete(timer2);
|
|
123
133
|
state.active = false;
|
|
124
134
|
state.frame = undefined;
|
|
135
|
+
if (type === "stop") {
|
|
136
|
+
state.elapsed = undefined;
|
|
137
|
+
state.index = undefined;
|
|
138
|
+
}
|
|
125
139
|
return timer2;
|
|
126
140
|
}
|
|
127
141
|
state.active = true;
|
|
128
142
|
const canTimeout = timeout > 0 && timeout < Number.POSITIVE_INFINITY;
|
|
129
|
-
const
|
|
143
|
+
const elapsed = type === "continue" ? +(state.elapsed ?? 0) : 0;
|
|
144
|
+
let index = type === "continue" ? +(state.index ?? 0) : 0;
|
|
145
|
+
state.elapsed = elapsed;
|
|
146
|
+
state.index = index;
|
|
147
|
+
const total = (count === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : (count - index) * (interval > 0 ? interval : 62.5)) - elapsed;
|
|
130
148
|
let current;
|
|
131
149
|
let start;
|
|
132
|
-
let index = 0;
|
|
133
150
|
function finish(finished, error) {
|
|
151
|
+
activeTimers.delete(timer2);
|
|
134
152
|
state.active = false;
|
|
153
|
+
state.elapsed = undefined;
|
|
135
154
|
state.frame = undefined;
|
|
155
|
+
state.index = undefined;
|
|
136
156
|
if (error) {
|
|
137
157
|
options.errorCallback?.();
|
|
138
158
|
}
|
|
@@ -144,15 +164,17 @@ var work = function(type, timer2, state, options, isRepeated2) {
|
|
|
144
164
|
}
|
|
145
165
|
current ??= timestamp;
|
|
146
166
|
start ??= timestamp;
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
167
|
+
const time = timestamp - current;
|
|
168
|
+
state.elapsed = elapsed + (current - start);
|
|
169
|
+
const finished = time - elapsed >= total;
|
|
170
|
+
if (finished || time - 2 < interval && interval < time + 2) {
|
|
150
171
|
if (state.active) {
|
|
151
172
|
state.callback(isRepeated2 ? index : undefined);
|
|
152
173
|
}
|
|
153
174
|
index += 1;
|
|
175
|
+
state.index = index;
|
|
154
176
|
switch (true) {
|
|
155
|
-
case (canTimeout && !finished && timestamp - start >= timeout):
|
|
177
|
+
case (canTimeout && !finished && timestamp - start >= timeout - elapsed):
|
|
156
178
|
finish(false, true);
|
|
157
179
|
return;
|
|
158
180
|
case (!finished && index < count):
|
|
@@ -175,11 +197,11 @@ document.addEventListener("visibilitychange", () => {
|
|
|
175
197
|
if (document.hidden) {
|
|
176
198
|
for (const timer2 of activeTimers) {
|
|
177
199
|
hiddenTimers.add(timer2);
|
|
178
|
-
timer2.
|
|
200
|
+
timer2.pause();
|
|
179
201
|
}
|
|
180
202
|
} else {
|
|
181
203
|
for (const timer2 of hiddenTimers) {
|
|
182
|
-
timer2.
|
|
204
|
+
timer2.continue();
|
|
183
205
|
}
|
|
184
206
|
hiddenTimers.clear();
|
|
185
207
|
}
|
package/dist/js/timer.mjs
CHANGED
|
@@ -34,6 +34,12 @@ var timer = function(type, callback, partial) {
|
|
|
34
34
|
active: false
|
|
35
35
|
};
|
|
36
36
|
const instance = Object.create({
|
|
37
|
+
continue() {
|
|
38
|
+
return work("continue", this, state, options, isRepeated2);
|
|
39
|
+
},
|
|
40
|
+
pause() {
|
|
41
|
+
return work("pause", this, state, options, isRepeated2);
|
|
42
|
+
},
|
|
37
43
|
restart() {
|
|
38
44
|
return work("restart", this, state, options, isRepeated2);
|
|
39
45
|
},
|
|
@@ -84,6 +90,12 @@ function when(condition, options) {
|
|
|
84
90
|
rejecter = reject;
|
|
85
91
|
});
|
|
86
92
|
const instance = Object.create({
|
|
93
|
+
continue() {
|
|
94
|
+
repeated.continue();
|
|
95
|
+
},
|
|
96
|
+
pause() {
|
|
97
|
+
repeated.pause();
|
|
98
|
+
},
|
|
87
99
|
stop() {
|
|
88
100
|
if (repeated.active) {
|
|
89
101
|
repeated.stop();
|
|
@@ -110,29 +122,37 @@ function when(condition, options) {
|
|
|
110
122
|
return instance;
|
|
111
123
|
}
|
|
112
124
|
var work = function(type, timer2, state, options, isRepeated2) {
|
|
113
|
-
if (
|
|
125
|
+
if (["continue", "start"].includes(type) && state.active || ["pause", "stop"].includes(type) && !state.active) {
|
|
114
126
|
return timer2;
|
|
115
127
|
}
|
|
116
128
|
const { count, interval, timeout } = options;
|
|
117
|
-
if (
|
|
129
|
+
if (["pause", "stop"].includes(type)) {
|
|
130
|
+
activeTimers.delete(timer2);
|
|
118
131
|
cancelAnimationFrame(state.frame);
|
|
119
132
|
options.afterCallback?.(false);
|
|
120
|
-
}
|
|
121
|
-
if (type === "stop") {
|
|
122
|
-
activeTimers.delete(timer2);
|
|
123
133
|
state.active = false;
|
|
124
134
|
state.frame = undefined;
|
|
135
|
+
if (type === "stop") {
|
|
136
|
+
state.elapsed = undefined;
|
|
137
|
+
state.index = undefined;
|
|
138
|
+
}
|
|
125
139
|
return timer2;
|
|
126
140
|
}
|
|
127
141
|
state.active = true;
|
|
128
142
|
const canTimeout = timeout > 0 && timeout < Number.POSITIVE_INFINITY;
|
|
129
|
-
const
|
|
143
|
+
const elapsed = type === "continue" ? +(state.elapsed ?? 0) : 0;
|
|
144
|
+
let index = type === "continue" ? +(state.index ?? 0) : 0;
|
|
145
|
+
state.elapsed = elapsed;
|
|
146
|
+
state.index = index;
|
|
147
|
+
const total = (count === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : (count - index) * (interval > 0 ? interval : 62.5)) - elapsed;
|
|
130
148
|
let current;
|
|
131
149
|
let start;
|
|
132
|
-
let index = 0;
|
|
133
150
|
function finish(finished, error) {
|
|
151
|
+
activeTimers.delete(timer2);
|
|
134
152
|
state.active = false;
|
|
153
|
+
state.elapsed = undefined;
|
|
135
154
|
state.frame = undefined;
|
|
155
|
+
state.index = undefined;
|
|
136
156
|
if (error) {
|
|
137
157
|
options.errorCallback?.();
|
|
138
158
|
}
|
|
@@ -144,15 +164,17 @@ var work = function(type, timer2, state, options, isRepeated2) {
|
|
|
144
164
|
}
|
|
145
165
|
current ??= timestamp;
|
|
146
166
|
start ??= timestamp;
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
167
|
+
const time = timestamp - current;
|
|
168
|
+
state.elapsed = elapsed + (current - start);
|
|
169
|
+
const finished = time - elapsed >= total;
|
|
170
|
+
if (finished || time - 2 < interval && interval < time + 2) {
|
|
150
171
|
if (state.active) {
|
|
151
172
|
state.callback(isRepeated2 ? index : undefined);
|
|
152
173
|
}
|
|
153
174
|
index += 1;
|
|
175
|
+
state.index = index;
|
|
154
176
|
switch (true) {
|
|
155
|
-
case (canTimeout && !finished && timestamp - start >= timeout):
|
|
177
|
+
case (canTimeout && !finished && timestamp - start >= timeout - elapsed):
|
|
156
178
|
finish(false, true);
|
|
157
179
|
return;
|
|
158
180
|
case (!finished && index < count):
|
|
@@ -175,11 +197,11 @@ document.addEventListener("visibilitychange", () => {
|
|
|
175
197
|
if (document.hidden) {
|
|
176
198
|
for (const timer2 of activeTimers) {
|
|
177
199
|
hiddenTimers.add(timer2);
|
|
178
|
-
timer2.
|
|
200
|
+
timer2.pause();
|
|
179
201
|
}
|
|
180
202
|
} else {
|
|
181
203
|
for (const timer2 of hiddenTimers) {
|
|
182
|
-
timer2.
|
|
204
|
+
timer2.continue();
|
|
183
205
|
}
|
|
184
206
|
hiddenTimers.clear();
|
|
185
207
|
}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"description": "Sweet little atomic goodies…",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@biomejs/biome": "^1.7",
|
|
12
|
-
"@happy-dom/global-registrator": "^14.
|
|
12
|
+
"@happy-dom/global-registrator": "^14.12",
|
|
13
13
|
"bun": "^1.1",
|
|
14
14
|
"sass": "^1.77",
|
|
15
15
|
"typescript": "^5.4"
|
|
@@ -105,11 +105,7 @@
|
|
|
105
105
|
},
|
|
106
106
|
"./package.json": "./package.json"
|
|
107
107
|
},
|
|
108
|
-
"files": [
|
|
109
|
-
"dist",
|
|
110
|
-
"src",
|
|
111
|
-
"types"
|
|
112
|
-
],
|
|
108
|
+
"files": ["dist", "src", "types"],
|
|
113
109
|
"keywords": [],
|
|
114
110
|
"license": "MIT",
|
|
115
111
|
"main": "./dist/js/index.js",
|
|
@@ -131,5 +127,5 @@
|
|
|
131
127
|
},
|
|
132
128
|
"type": "module",
|
|
133
129
|
"types": "./types/index.d.ts",
|
|
134
|
-
"version": "0.
|
|
130
|
+
"version": "0.47.1"
|
|
135
131
|
}
|
package/src/js/timer.ts
CHANGED
|
@@ -24,6 +24,13 @@ type BaseOptions = {
|
|
|
24
24
|
timeout: number;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
+
type BaseTimer = {
|
|
28
|
+
/**
|
|
29
|
+
* Is the timer running?
|
|
30
|
+
*/
|
|
31
|
+
get active(): boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
27
34
|
type OptionsWithCount = {
|
|
28
35
|
/**
|
|
29
36
|
* How many times the timer should repeat
|
|
@@ -50,7 +57,10 @@ type RepeatOptions = {
|
|
|
50
57
|
type State = {
|
|
51
58
|
active: boolean;
|
|
52
59
|
callback: AnyCallback;
|
|
60
|
+
count?: number;
|
|
61
|
+
elapsed?: number;
|
|
53
62
|
frame?: number;
|
|
63
|
+
index?: number;
|
|
54
64
|
};
|
|
55
65
|
|
|
56
66
|
/**
|
|
@@ -58,22 +68,26 @@ type State = {
|
|
|
58
68
|
*/
|
|
59
69
|
export type Timer = {
|
|
60
70
|
/**
|
|
61
|
-
*
|
|
71
|
+
* Continues the timer _(if it was paused)_
|
|
62
72
|
*/
|
|
63
|
-
|
|
73
|
+
continue(): Timer;
|
|
74
|
+
/**
|
|
75
|
+
* Pauses the timer _(if it was running)_
|
|
76
|
+
*/
|
|
77
|
+
pause(): Timer;
|
|
64
78
|
/**
|
|
65
|
-
* Restarts the timer
|
|
79
|
+
* Restarts the timer _(if it was running)_
|
|
66
80
|
*/
|
|
67
81
|
restart(): Timer;
|
|
68
82
|
/**
|
|
69
|
-
* Starts the timer
|
|
83
|
+
* Starts the timer _(if it was stopped)_
|
|
70
84
|
*/
|
|
71
85
|
start(): Timer;
|
|
72
86
|
/**
|
|
73
|
-
* Stops the timer
|
|
87
|
+
* Stops the timer _(if it was running)_
|
|
74
88
|
*/
|
|
75
89
|
stop(): Timer;
|
|
76
|
-
};
|
|
90
|
+
} & BaseTimer;
|
|
77
91
|
|
|
78
92
|
type TimerOptions = {} & RepeatOptions;
|
|
79
93
|
|
|
@@ -81,13 +95,17 @@ type WaitOptions = {} & BaseOptions & OptionsWithError;
|
|
|
81
95
|
|
|
82
96
|
export type When = {
|
|
83
97
|
/**
|
|
84
|
-
*
|
|
98
|
+
* Continues the timer _(if it was paused)_
|
|
85
99
|
*/
|
|
86
|
-
|
|
100
|
+
continue(): Timer;
|
|
87
101
|
/**
|
|
88
|
-
*
|
|
102
|
+
* Pauses the timer _(if it was running)_
|
|
89
103
|
*/
|
|
90
|
-
|
|
104
|
+
pause(): Timer;
|
|
105
|
+
/**
|
|
106
|
+
* Stops the timer _(if it was running)_
|
|
107
|
+
*/
|
|
108
|
+
stop(): Timer;
|
|
91
109
|
/**
|
|
92
110
|
* Starts the timer and returns a promise that resolves when the condition is met
|
|
93
111
|
*/
|
|
@@ -95,11 +113,11 @@ export type When = {
|
|
|
95
113
|
resolve?: (() => void) | null,
|
|
96
114
|
reject?: (() => void) | null,
|
|
97
115
|
): Promise<void>;
|
|
98
|
-
};
|
|
116
|
+
} & BaseTimer;
|
|
99
117
|
|
|
100
118
|
type WhenOptions = {} & OptionsWithCount;
|
|
101
119
|
|
|
102
|
-
type WorkType = 'restart' | 'start' | 'stop';
|
|
120
|
+
type WorkType = 'continue' | 'pause' | 'restart' | 'start' | 'stop';
|
|
103
121
|
|
|
104
122
|
const activeTimers = new Set<Timer>();
|
|
105
123
|
const hiddenTimers = new Set<Timer>();
|
|
@@ -183,6 +201,12 @@ function timer(
|
|
|
183
201
|
};
|
|
184
202
|
|
|
185
203
|
const instance = Object.create({
|
|
204
|
+
continue() {
|
|
205
|
+
return work('continue', this as Timer, state, options, isRepeated);
|
|
206
|
+
},
|
|
207
|
+
pause() {
|
|
208
|
+
return work('pause', this as Timer, state, options, isRepeated);
|
|
209
|
+
},
|
|
186
210
|
restart() {
|
|
187
211
|
return work('restart', this as Timer, state, options, isRepeated);
|
|
188
212
|
},
|
|
@@ -280,6 +304,12 @@ export function when(
|
|
|
280
304
|
});
|
|
281
305
|
|
|
282
306
|
const instance = Object.create({
|
|
307
|
+
continue() {
|
|
308
|
+
repeated.continue();
|
|
309
|
+
},
|
|
310
|
+
pause() {
|
|
311
|
+
repeated.pause();
|
|
312
|
+
},
|
|
283
313
|
stop() {
|
|
284
314
|
if (repeated.active) {
|
|
285
315
|
repeated.stop();
|
|
@@ -319,46 +349,57 @@ function work(
|
|
|
319
349
|
isRepeated: boolean,
|
|
320
350
|
): Timer {
|
|
321
351
|
if (
|
|
322
|
-
(
|
|
323
|
-
(
|
|
352
|
+
(['continue', 'start'].includes(type) && state.active) ||
|
|
353
|
+
(['pause', 'stop'].includes(type) && !state.active)
|
|
324
354
|
) {
|
|
325
355
|
return timer;
|
|
326
356
|
}
|
|
327
357
|
|
|
328
358
|
const {count, interval, timeout} = options;
|
|
329
359
|
|
|
330
|
-
if (
|
|
331
|
-
|
|
360
|
+
if (['pause', 'stop'].includes(type)) {
|
|
361
|
+
activeTimers.delete(timer);
|
|
332
362
|
|
|
333
|
-
|
|
334
|
-
}
|
|
363
|
+
cancelAnimationFrame(state.frame as never);
|
|
335
364
|
|
|
336
|
-
|
|
337
|
-
activeTimers.delete(timer);
|
|
365
|
+
options.afterCallback?.(false);
|
|
338
366
|
|
|
339
367
|
state.active = false;
|
|
340
368
|
state.frame = undefined;
|
|
341
369
|
|
|
370
|
+
if (type === 'stop') {
|
|
371
|
+
state.elapsed = undefined;
|
|
372
|
+
state.index = undefined;
|
|
373
|
+
}
|
|
374
|
+
|
|
342
375
|
return timer;
|
|
343
376
|
}
|
|
344
377
|
|
|
345
378
|
state.active = true;
|
|
346
379
|
|
|
347
380
|
const canTimeout = timeout > 0 && timeout < Number.POSITIVE_INFINITY;
|
|
381
|
+
const elapsed = type === 'continue' ? +(state.elapsed ?? 0) : 0;
|
|
382
|
+
|
|
383
|
+
let index = type === 'continue' ? +(state.index ?? 0) : 0;
|
|
384
|
+
|
|
385
|
+
state.elapsed = elapsed;
|
|
386
|
+
state.index = index;
|
|
348
387
|
|
|
349
388
|
const total =
|
|
350
|
-
count === Number.POSITIVE_INFINITY
|
|
351
|
-
?
|
|
352
|
-
: count * (interval > 0 ? interval :
|
|
389
|
+
(count === Number.POSITIVE_INFINITY
|
|
390
|
+
? Number.POSITIVE_INFINITY
|
|
391
|
+
: (count - index) * (interval > 0 ? interval : 1000 / 16)) - elapsed;
|
|
353
392
|
|
|
354
393
|
let current: DOMHighResTimeStamp | null;
|
|
355
394
|
let start: DOMHighResTimeStamp | null;
|
|
356
395
|
|
|
357
|
-
let index = 0;
|
|
358
|
-
|
|
359
396
|
function finish(finished: boolean, error: boolean) {
|
|
397
|
+
activeTimers.delete(timer);
|
|
398
|
+
|
|
360
399
|
state.active = false;
|
|
400
|
+
state.elapsed = undefined;
|
|
361
401
|
state.frame = undefined;
|
|
402
|
+
state.index = undefined;
|
|
362
403
|
|
|
363
404
|
if (error) {
|
|
364
405
|
options.errorCallback?.();
|
|
@@ -375,18 +416,23 @@ function work(
|
|
|
375
416
|
current ??= timestamp;
|
|
376
417
|
start ??= timestamp;
|
|
377
418
|
|
|
378
|
-
const
|
|
379
|
-
|
|
419
|
+
const time = timestamp - current;
|
|
420
|
+
|
|
421
|
+
state.elapsed = elapsed + (current - start);
|
|
380
422
|
|
|
381
|
-
|
|
423
|
+
const finished = time - elapsed >= total;
|
|
424
|
+
|
|
425
|
+
if (finished || (time - 2 < interval && interval < time + 2)) {
|
|
382
426
|
if (state.active) {
|
|
383
427
|
state.callback((isRepeated ? index : undefined) as never);
|
|
384
428
|
}
|
|
385
429
|
|
|
386
430
|
index += 1;
|
|
387
431
|
|
|
432
|
+
state.index = index;
|
|
433
|
+
|
|
388
434
|
switch (true) {
|
|
389
|
-
case canTimeout && !finished && timestamp - start >= timeout:
|
|
435
|
+
case canTimeout && !finished && timestamp - start >= timeout - elapsed:
|
|
390
436
|
finish(false, true);
|
|
391
437
|
return;
|
|
392
438
|
|
|
@@ -414,11 +460,11 @@ document.addEventListener('visibilitychange', () => {
|
|
|
414
460
|
if (document.hidden) {
|
|
415
461
|
for (const timer of activeTimers) {
|
|
416
462
|
hiddenTimers.add(timer);
|
|
417
|
-
timer.
|
|
463
|
+
timer.pause();
|
|
418
464
|
}
|
|
419
465
|
} else {
|
|
420
466
|
for (const timer of hiddenTimers) {
|
|
421
|
-
timer.
|
|
467
|
+
timer.continue();
|
|
422
468
|
}
|
|
423
469
|
|
|
424
470
|
hiddenTimers.clear();
|
package/types/timer.d.ts
CHANGED
|
@@ -17,6 +17,12 @@ type BaseOptions = {
|
|
|
17
17
|
*/
|
|
18
18
|
timeout: number;
|
|
19
19
|
};
|
|
20
|
+
type BaseTimer = {
|
|
21
|
+
/**
|
|
22
|
+
* Is the timer running?
|
|
23
|
+
*/
|
|
24
|
+
get active(): boolean;
|
|
25
|
+
};
|
|
20
26
|
type OptionsWithCount = {
|
|
21
27
|
/**
|
|
22
28
|
* How many times the timer should repeat
|
|
@@ -41,37 +47,45 @@ type RepeatOptions = {
|
|
|
41
47
|
*/
|
|
42
48
|
export type Timer = {
|
|
43
49
|
/**
|
|
44
|
-
*
|
|
50
|
+
* Continues the timer _(if it was paused)_
|
|
45
51
|
*/
|
|
46
|
-
|
|
52
|
+
continue(): Timer;
|
|
53
|
+
/**
|
|
54
|
+
* Pauses the timer _(if it was running)_
|
|
55
|
+
*/
|
|
56
|
+
pause(): Timer;
|
|
47
57
|
/**
|
|
48
|
-
* Restarts the timer
|
|
58
|
+
* Restarts the timer _(if it was running)_
|
|
49
59
|
*/
|
|
50
60
|
restart(): Timer;
|
|
51
61
|
/**
|
|
52
|
-
* Starts the timer
|
|
62
|
+
* Starts the timer _(if it was stopped)_
|
|
53
63
|
*/
|
|
54
64
|
start(): Timer;
|
|
55
65
|
/**
|
|
56
|
-
* Stops the timer
|
|
66
|
+
* Stops the timer _(if it was running)_
|
|
57
67
|
*/
|
|
58
68
|
stop(): Timer;
|
|
59
|
-
};
|
|
69
|
+
} & BaseTimer;
|
|
60
70
|
type WaitOptions = {} & BaseOptions & OptionsWithError;
|
|
61
71
|
export type When = {
|
|
62
72
|
/**
|
|
63
|
-
*
|
|
73
|
+
* Continues the timer _(if it was paused)_
|
|
64
74
|
*/
|
|
65
|
-
|
|
75
|
+
continue(): Timer;
|
|
66
76
|
/**
|
|
67
|
-
*
|
|
77
|
+
* Pauses the timer _(if it was running)_
|
|
68
78
|
*/
|
|
69
|
-
|
|
79
|
+
pause(): Timer;
|
|
80
|
+
/**
|
|
81
|
+
* Stops the timer _(if it was running)_
|
|
82
|
+
*/
|
|
83
|
+
stop(): Timer;
|
|
70
84
|
/**
|
|
71
85
|
* Starts the timer and returns a promise that resolves when the condition is met
|
|
72
86
|
*/
|
|
73
87
|
then(resolve?: (() => void) | null, reject?: (() => void) | null): Promise<void>;
|
|
74
|
-
};
|
|
88
|
+
} & BaseTimer;
|
|
75
89
|
type WhenOptions = {} & OptionsWithCount;
|
|
76
90
|
/**
|
|
77
91
|
* Is the value a repeating timer?
|