@oscarpalmer/timer 0.22.0 → 0.22.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/timer.js +170 -0
- package/package.json +3 -3
package/dist/timer.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var activeTimers = new Set;
|
|
3
|
+
var hiddenTimers = new Set;
|
|
4
|
+
var milliseconds = 1000 / 60;
|
|
5
|
+
|
|
6
|
+
// src/functions.ts
|
|
7
|
+
function getOptions(options, isRepeated) {
|
|
8
|
+
return {
|
|
9
|
+
afterCallback: options.afterCallback,
|
|
10
|
+
count: getValueOrDefault(options.count, isRepeated ? Number.POSITIVE_INFINITY : 1),
|
|
11
|
+
errorCallback: options.errorCallback,
|
|
12
|
+
interval: getValueOrDefault(options.interval, milliseconds, milliseconds),
|
|
13
|
+
timeout: getValueOrDefault(options.timeout, isRepeated ? Number.POSITIVE_INFINITY : 30000)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function getValueOrDefault(value, defaultValue, minimum) {
|
|
17
|
+
return typeof value === "number" && value > (minimum ?? 0) ? value : defaultValue;
|
|
18
|
+
}
|
|
19
|
+
function work(type, timer, state, options) {
|
|
20
|
+
if (["continue", "start"].includes(type) && state.active || ["pause", "stop"].includes(type) && !state.active) {
|
|
21
|
+
return timer;
|
|
22
|
+
}
|
|
23
|
+
const { count, interval, timeout } = options;
|
|
24
|
+
const { isRepeated, minimum } = state;
|
|
25
|
+
if (["pause", "restart", "stop"].includes(type)) {
|
|
26
|
+
const isStop = type === "stop";
|
|
27
|
+
activeTimers.delete(timer);
|
|
28
|
+
cancelAnimationFrame(state.frame);
|
|
29
|
+
if (isStop) {
|
|
30
|
+
options.afterCallback?.(false);
|
|
31
|
+
}
|
|
32
|
+
state.active = false;
|
|
33
|
+
state.frame = undefined;
|
|
34
|
+
state.paused = !isStop;
|
|
35
|
+
if (isStop) {
|
|
36
|
+
state.elapsed = undefined;
|
|
37
|
+
state.index = undefined;
|
|
38
|
+
}
|
|
39
|
+
return type === "restart" ? work("start", timer, state, options) : timer;
|
|
40
|
+
}
|
|
41
|
+
state.active = true;
|
|
42
|
+
state.paused = false;
|
|
43
|
+
const elapsed = type === "continue" ? +(state.elapsed ?? 0) : 0;
|
|
44
|
+
let index = type === "continue" ? +(state.index ?? 0) : 0;
|
|
45
|
+
state.elapsed = elapsed;
|
|
46
|
+
state.index = index;
|
|
47
|
+
const total = (count === Number.POSITIVE_INFINITY ? Number.POSITIVE_INFINITY : (count - index) * (interval > 0 ? interval : milliseconds)) - elapsed;
|
|
48
|
+
let current;
|
|
49
|
+
let start;
|
|
50
|
+
function finish(finished, error) {
|
|
51
|
+
activeTimers.delete(timer);
|
|
52
|
+
state.active = false;
|
|
53
|
+
state.elapsed = undefined;
|
|
54
|
+
state.frame = undefined;
|
|
55
|
+
state.index = undefined;
|
|
56
|
+
if (error) {
|
|
57
|
+
options.errorCallback?.();
|
|
58
|
+
}
|
|
59
|
+
options.afterCallback?.(finished);
|
|
60
|
+
}
|
|
61
|
+
function step(timestamp) {
|
|
62
|
+
if (!state.active) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
current ??= timestamp;
|
|
66
|
+
start ??= timestamp;
|
|
67
|
+
const time = timestamp - current;
|
|
68
|
+
state.elapsed = elapsed + (current - start);
|
|
69
|
+
const finished = time - elapsed >= total;
|
|
70
|
+
if (timestamp - start >= timeout - elapsed) {
|
|
71
|
+
finish(finished, !finished);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (finished || time >= minimum) {
|
|
75
|
+
if (state.active) {
|
|
76
|
+
state.callback(isRepeated ? index : undefined);
|
|
77
|
+
}
|
|
78
|
+
index += 1;
|
|
79
|
+
state.index = index;
|
|
80
|
+
if (!finished && index < count) {
|
|
81
|
+
current = null;
|
|
82
|
+
} else {
|
|
83
|
+
finish(true, false);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
state.frame = requestAnimationFrame(step);
|
|
88
|
+
}
|
|
89
|
+
activeTimers.add(timer);
|
|
90
|
+
state.frame = requestAnimationFrame(step);
|
|
91
|
+
return timer;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/timer.ts
|
|
95
|
+
function repeat(callback, options) {
|
|
96
|
+
return timer("repeat", callback, options ?? {}, true);
|
|
97
|
+
}
|
|
98
|
+
function timer(type, callback, partial, start) {
|
|
99
|
+
const isRepeated = type === "repeat";
|
|
100
|
+
const options = getOptions(partial, isRepeated);
|
|
101
|
+
const instance = new Timer(type, {
|
|
102
|
+
callback,
|
|
103
|
+
isRepeated,
|
|
104
|
+
active: false,
|
|
105
|
+
minimum: options.interval - options.interval % milliseconds / 2,
|
|
106
|
+
paused: false,
|
|
107
|
+
trace: new TimerTrace
|
|
108
|
+
}, options);
|
|
109
|
+
if (start) {
|
|
110
|
+
instance.start();
|
|
111
|
+
}
|
|
112
|
+
return instance;
|
|
113
|
+
}
|
|
114
|
+
function wait(callback, options) {
|
|
115
|
+
return timer("wait", callback, options == null || typeof options === "number" ? {
|
|
116
|
+
interval: options
|
|
117
|
+
} : options, true);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class BasicTimer {
|
|
121
|
+
constructor(type, state) {
|
|
122
|
+
this.$timer = type;
|
|
123
|
+
this.state = state;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
class Timer extends BasicTimer {
|
|
128
|
+
get active() {
|
|
129
|
+
return this.state.active;
|
|
130
|
+
}
|
|
131
|
+
get paused() {
|
|
132
|
+
return this.state.paused;
|
|
133
|
+
}
|
|
134
|
+
get trace() {
|
|
135
|
+
return globalThis._oscarpalmer_timer_debug ? this.state.trace : undefined;
|
|
136
|
+
}
|
|
137
|
+
constructor(type, state, options) {
|
|
138
|
+
super(type, state);
|
|
139
|
+
this.options = options;
|
|
140
|
+
}
|
|
141
|
+
continue() {
|
|
142
|
+
return work("continue", this, this.state, this.options);
|
|
143
|
+
}
|
|
144
|
+
pause() {
|
|
145
|
+
return work("pause", this, this.state, this.options);
|
|
146
|
+
}
|
|
147
|
+
restart() {
|
|
148
|
+
return work("restart", this, this.state, this.options);
|
|
149
|
+
}
|
|
150
|
+
start() {
|
|
151
|
+
return work("start", this, this.state, this.options);
|
|
152
|
+
}
|
|
153
|
+
stop() {
|
|
154
|
+
return work("stop", this, this.state, this.options);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
class TimerTrace extends Error {
|
|
159
|
+
constructor() {
|
|
160
|
+
super();
|
|
161
|
+
this.name = "TimerTrace";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
wait,
|
|
166
|
+
timer,
|
|
167
|
+
repeat,
|
|
168
|
+
Timer,
|
|
169
|
+
BasicTimer
|
|
170
|
+
};
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"bun": "./src/index.ts",
|
|
21
21
|
"import": {
|
|
22
22
|
"types": "./types/index.d.ts",
|
|
23
|
-
"default": "./dist/
|
|
23
|
+
"default": "./dist/index.mjs"
|
|
24
24
|
},
|
|
25
25
|
"require": {
|
|
26
26
|
"types": "./types/index.d.cts",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"types": "bun run types:cjs && bun run types:esm",
|
|
47
47
|
"types:cjs": "bunx dts-bundle-generator --out-file ./types/index.d.cts --external-inlines '@oscarpalmer/atoms' --no-check --silent ./src/index.ts",
|
|
48
48
|
"types:esm": "bunx tsc -p ./tsconfig.json",
|
|
49
|
-
"watch": "bun build ./src/index.ts --outfile ./dist/
|
|
49
|
+
"watch": "bun build ./src/index.ts --outfile ./dist/index.js --watch"
|
|
50
50
|
},
|
|
51
51
|
"type": "module",
|
|
52
52
|
"types": "types/index.d.cts",
|
|
53
|
-
"version": "0.22.
|
|
53
|
+
"version": "0.22.1"
|
|
54
54
|
}
|