lilact 0.28.0 → 0.28.4
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/bin/bundle.cjs +2 -2
- package/dist/lilact.development.js +315 -280
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +38 -36
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +38 -36
- package/docs/classes/accessories.ErrorBoundary.html +6 -6
- package/docs/classes/accessories.Suspense.html +3 -3
- package/docs/functions/accessories.DragHandle.html +1 -1
- package/docs/functions/accessories.Spinner.html +1 -1
- package/docs/functions/errors.globalErrorHandler.html +1 -1
- package/docs/functions/errors.scanBlockLabels.html +1 -1
- package/docs/functions/errors.traceError.html +1 -1
- package/docs/functions/run.lazy.html +1 -1
- package/docs/functions/run.require.html +1 -1
- package/docs/functions/run.runScripts.html +1 -1
- package/docs/functions/timers.animationFramePromise.html +3 -3
- package/docs/functions/timers.clearInterval.html +5 -3
- package/docs/functions/timers.clearTimeout.html +5 -3
- package/docs/functions/timers.grabTimers.html +4 -3
- package/docs/functions/timers.pauseTimers.html +5 -2
- package/docs/functions/timers.releaseTimers.html +4 -2
- package/docs/functions/timers.resetTimers.html +4 -2
- package/docs/functions/timers.resumeTimers.html +4 -2
- package/docs/functions/timers.setInterval.html +8 -6
- package/docs/functions/timers.setTimeout.html +8 -6
- package/docs/functions/timers.timeoutPromise.html +8 -149
- package/docs/static/demos/error-nested-1.jsx +11 -0
- package/docs/static/demos/error-nested-2.jsx +12 -0
- package/docs/static/demos/error-nested-3.jsx +12 -0
- package/docs/static/demos/error-nested-4.jsx +12 -0
- package/docs/static/demos/error-nested-5.jsx +11 -0
- package/docs/static/index.html +45 -38
- package/docs/static/lilact.development.js +315 -280
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +38 -36
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +38 -36
- package/docs/variables/accessories.SplitPane.html +1 -1
- package/docs/variables/errors.blocks_info.html +1 -1
- package/docs/variables/errors.error.html +1 -1
- package/examples/demos/error-nested-1.jsx +11 -0
- package/examples/demos/error-nested-2.jsx +12 -0
- package/examples/demos/error-nested-3.jsx +12 -0
- package/examples/demos/error-nested-4.jsx +12 -0
- package/examples/demos/error-nested-5.jsx +11 -0
- package/examples/index.html +45 -40
- package/examples/lilact.development.js +315 -280
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +38 -36
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +38 -36
- package/package.json +1 -1
- package/scripts/build.mjs +1 -1
- package/src/accessories.jsx +1 -4
- package/src/components.jsx +4 -4
- package/src/errors.jsx +50 -27
- package/src/jsx.js +3 -1
- package/src/lilact.jsx +4 -4
- package/src/run.jsx +9 -17
- package/src/timers.jsx +377 -207
package/src/timers.jsx
CHANGED
|
@@ -27,283 +27,454 @@
|
|
|
27
27
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
28
|
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
import {
|
|
31
|
+
IDX,
|
|
32
|
+
DUE,
|
|
33
|
+
REPEAT,
|
|
34
|
+
CLEARED,
|
|
35
|
+
INTERVAL,
|
|
36
|
+
CALLBACK,
|
|
37
|
+
ARGS
|
|
38
|
+
} from "./symbols.jsx";
|
|
32
39
|
|
|
33
40
|
/**
|
|
34
41
|
* Timer helpers for a promise-friendly timer framework.
|
|
35
42
|
*
|
|
36
|
-
* These functions
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
43
|
+
* These functions preserve the usual call signatures of the native
|
|
44
|
+
* `setTimeout`, `setInterval`, `clearTimeout`, and `clearInterval` APIs
|
|
45
|
+
* while adding timer tracking and lifecycle management.
|
|
46
|
+
*
|
|
47
|
+
* Managed timers can be paused, resumed, reset, or released. Promise-based
|
|
48
|
+
* helpers are also provided through `timeoutPromise` and
|
|
49
|
+
* `animationFramePromise`.
|
|
42
50
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* - `timeoutPromise` / `animationFramePromise`: promise-based convenience wrappers.
|
|
51
|
+
* The `Lilact._setTimeout`, `Lilact._setInterval`, `Lilact._clearTimeout`,
|
|
52
|
+
* and `Lilact._clearInterval` properties must reference the original native
|
|
53
|
+
* timer functions.
|
|
47
54
|
*/
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
let
|
|
51
|
-
let current_timer_idx = -1;
|
|
56
|
+
let timer_pause_time;
|
|
57
|
+
let current_timer_idx = 0;
|
|
52
58
|
let timer_list = [];
|
|
53
|
-
let timer_timeout =
|
|
54
|
-
let all_timers =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// original functions
|
|
58
|
-
const _setTimeout = window.setTimeout,
|
|
59
|
-
_setInterval = window.setInterval,
|
|
60
|
-
_clearTimeout = window.clearTimeout,
|
|
61
|
-
_clearInterval = window.clearInterval;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
function get_bucket(target)
|
|
65
|
-
{
|
|
66
|
-
let left = 0;
|
|
67
|
-
let right = timer_list.length - 1;
|
|
68
|
-
|
|
69
|
-
while (left <= right) {
|
|
70
|
-
const mid = Math.floor((left + right) / 2);
|
|
71
|
-
const mid_val = timer_list[mid][DUE];
|
|
72
|
-
|
|
73
|
-
if (mid_val === target) {
|
|
74
|
-
return [mid, timer_list[mid]];
|
|
75
|
-
}
|
|
76
|
-
else if (mid_val < target) {
|
|
77
|
-
left = mid + 1;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
right = mid - 1;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const bucket = [];
|
|
85
|
-
bucket[DUE] = target;
|
|
86
|
-
|
|
87
|
-
timer_list.splice(left, 0, bucket);
|
|
88
|
-
return [left, bucket];
|
|
89
|
-
}
|
|
59
|
+
let timer_timeout = 0;
|
|
60
|
+
let all_timers = new Map();
|
|
90
61
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Returns the timer bucket whose due time matches `target`, or creates a new
|
|
64
|
+
* bucket in sorted order.
|
|
65
|
+
*
|
|
66
|
+
* Each bucket is an array containing timers and has its due time stored under
|
|
67
|
+
* the `DUE` symbol.
|
|
68
|
+
*
|
|
69
|
+
* @param {number} target - Due time as a Unix timestamp in milliseconds.
|
|
70
|
+
* @returns {[number, Array]} The bucket index and bucket.
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
function get_bucket(target) {
|
|
74
|
+
let left = 0;
|
|
75
|
+
let right = timer_list.length - 1;
|
|
76
|
+
|
|
77
|
+
while (left <= right) {
|
|
78
|
+
const mid = Math.floor((left + right) / 2);
|
|
79
|
+
const mid_value = timer_list[mid][DUE];
|
|
80
|
+
|
|
81
|
+
if (mid_value === target) {
|
|
82
|
+
return [mid, timer_list[mid]];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (mid_value < target) {
|
|
86
|
+
left = mid + 1;
|
|
87
|
+
} else {
|
|
88
|
+
right = mid - 1;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const bucket = [];
|
|
93
|
+
bucket[DUE] = target;
|
|
94
|
+
|
|
95
|
+
timer_list.splice(left, 0, bucket);
|
|
96
|
+
|
|
97
|
+
return [left, bucket];
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
function schedule_next_timer() {
|
|
101
|
+
if (
|
|
102
|
+
timer_pause_time !== undefined ||
|
|
103
|
+
timer_list.length === 0
|
|
104
|
+
) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
100
107
|
|
|
101
|
-
|
|
108
|
+
Lilact._clearTimeout(timer_timeout);
|
|
102
109
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
const delay = Math.max(
|
|
111
|
+
0,
|
|
112
|
+
timer_list[0][DUE] - Date.now()
|
|
113
|
+
);
|
|
107
114
|
|
|
108
|
-
|
|
115
|
+
timer_timeout = Lilact._setTimeout(run_timer, delay);
|
|
109
116
|
}
|
|
110
117
|
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
const now = Date.now();
|
|
114
|
-
|
|
115
|
-
let i = 0;
|
|
116
|
-
let buck = timer_list[i];
|
|
117
|
-
|
|
118
|
-
while( buck && buck[DUE]-now <= 0 ) {
|
|
119
|
-
for(const t of buck) {
|
|
120
|
-
|
|
121
|
-
if(!t[CLEARED]) {
|
|
122
|
-
t[CALLBACK](...t[ARGS]);
|
|
123
|
-
if(t[REPEAT]) {
|
|
124
|
-
t[DUE] = Date.now()+t[INTERVAL];
|
|
125
|
-
add_timer(t, true);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
delete all_timers[t[IDX]];
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
delete all_timers[t[IDX]];
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
i++;
|
|
136
|
-
buck = timer_list[i];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
timer_list.splice(0,i);
|
|
140
|
-
|
|
141
|
-
if(timer_list.length>0) {
|
|
142
|
-
_clearTimeout( timer_timeout );
|
|
143
|
-
timer_timeout = _setTimeout( run_timer, timer_list[0][DUE] - now);
|
|
144
|
-
}
|
|
118
|
+
function add_timer(timer, is_repeat = false) {
|
|
119
|
+
const [bucket_index, bucket] = get_bucket(timer[DUE]);
|
|
145
120
|
|
|
121
|
+
if (!is_repeat) {
|
|
122
|
+
current_timer_idx += 1;
|
|
123
|
+
|
|
124
|
+
timer[IDX] = current_timer_idx;
|
|
125
|
+
all_timers.set(timer[IDX], timer);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
bucket.push(timer);
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* If this timer became the earliest timer, update the dispatcher.
|
|
132
|
+
* Do not schedule anything while paused.
|
|
133
|
+
*/
|
|
134
|
+
if (
|
|
135
|
+
bucket_index === 0 &&
|
|
136
|
+
timer_pause_time === undefined
|
|
137
|
+
) {
|
|
138
|
+
schedule_next_timer();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return timer[IDX];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function run_timer() {
|
|
145
|
+
/*
|
|
146
|
+
* The native dispatcher has already fired. Its handle is no longer
|
|
147
|
+
* pending.
|
|
148
|
+
*/
|
|
149
|
+
timer_timeout = -1;
|
|
150
|
+
|
|
151
|
+
const now = Date.now();
|
|
152
|
+
const due_buckets = [];
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* Detach all due buckets before executing any callback.
|
|
156
|
+
|
|
157
|
+
* This preserves the bucket design: all timers due at this point are
|
|
158
|
+
* processed during this dispatcher turn, but callbacks can no longer
|
|
159
|
+
* mutate the buckets currently being iterated.
|
|
160
|
+
*/
|
|
161
|
+
while (
|
|
162
|
+
timer_list.length > 0 &&
|
|
163
|
+
timer_list[0][DUE] - now <= 0
|
|
164
|
+
) {
|
|
165
|
+
due_buckets.push(timer_list.shift());
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const due_timers = [];
|
|
169
|
+
|
|
170
|
+
for (const bucket of due_buckets) {
|
|
171
|
+
for (const timer of bucket) {
|
|
172
|
+
due_timers.push(timer);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
let first_error;
|
|
177
|
+
|
|
178
|
+
for (const timer of due_timers) {
|
|
179
|
+
if (
|
|
180
|
+
timer[CLEARED] ||
|
|
181
|
+
all_timers.get(timer[IDX]) !== timer
|
|
182
|
+
) {
|
|
183
|
+
all_timers.delete(timer[IDX]);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
timer[CALLBACK](...timer[ARGS]);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
/*
|
|
191
|
+
* One callback should not prevent the other callbacks from being
|
|
192
|
+
* processed or prevent the dispatcher from being rescheduled.
|
|
193
|
+
*/
|
|
194
|
+
first_error ??= error;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/*
|
|
198
|
+
* The callback may have called clearTimeout() or clearInterval().
|
|
199
|
+
* Check again after invoking it.
|
|
200
|
+
*/
|
|
201
|
+
if (timer[CLEARED]) {
|
|
202
|
+
all_timers.delete(timer[IDX]);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/*
|
|
207
|
+
* resetTimers() may have removed this timer from all_timers.
|
|
208
|
+
* Do not resurrect it.
|
|
209
|
+
*/
|
|
210
|
+
if (all_timers.get(timer[IDX]) !== timer) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (timer[REPEAT]) {
|
|
215
|
+
timer[DUE] = Date.now() + timer[INTERVAL];
|
|
216
|
+
add_timer(timer, true);
|
|
217
|
+
} else {
|
|
218
|
+
all_timers.delete(timer[IDX]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/*
|
|
223
|
+
* Use a fresh timestamp because callbacks may have taken time to run.
|
|
224
|
+
*/
|
|
225
|
+
schedule_next_timer();
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* Report callback errors asynchronously, after timer bookkeeping has
|
|
229
|
+
* completed.
|
|
230
|
+
*/
|
|
231
|
+
if (first_error !== undefined) {
|
|
232
|
+
Lilact._setTimeout(() => {
|
|
233
|
+
throw first_error;
|
|
234
|
+
}, 0);
|
|
235
|
+
}
|
|
146
236
|
}
|
|
147
237
|
|
|
148
|
-
//---
|
|
149
238
|
|
|
150
239
|
/**
|
|
151
|
-
* Resets managed timers
|
|
240
|
+
* Resets all managed timers and removes them from the framework.
|
|
241
|
+
*
|
|
242
|
+
* Existing native timers are canceled, all managed timer registrations are
|
|
243
|
+
* discarded, and the next managed timer ID starts at zero.
|
|
244
|
+
*
|
|
152
245
|
* @returns {void}
|
|
153
246
|
*/
|
|
154
|
-
export function
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
247
|
+
export function resetTimers() {
|
|
248
|
+
Lilact._clearTimeout(timer_timeout);
|
|
249
|
+
|
|
250
|
+
for (const timer of all_timers.values()) {
|
|
251
|
+
timer[CLEARED] = true;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
timer_pause_time = undefined;
|
|
255
|
+
current_timer_idx = -1;
|
|
256
|
+
timer_list = [];
|
|
257
|
+
timer_timeout = -1;
|
|
258
|
+
all_timers = new Map();
|
|
162
259
|
}
|
|
163
260
|
|
|
261
|
+
|
|
164
262
|
/**
|
|
165
|
-
* Pauses all
|
|
263
|
+
* Pauses all currently managed timers.
|
|
264
|
+
*
|
|
265
|
+
* Timers created while the framework is paused are also held until
|
|
266
|
+
* `resumeTimers()` is called.
|
|
267
|
+
*
|
|
268
|
+
* Calling this function more than once while already paused has no effect.
|
|
269
|
+
*
|
|
166
270
|
* @returns {void}
|
|
167
271
|
*/
|
|
168
|
-
export function
|
|
169
|
-
{
|
|
170
|
-
|
|
171
|
-
|
|
272
|
+
export function pauseTimers() {
|
|
273
|
+
if (timer_pause_time !== undefined) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
Lilact._clearTimeout(timer_timeout);
|
|
278
|
+
timer_timeout = -1;
|
|
279
|
+
timer_pause_time = Date.now();
|
|
172
280
|
}
|
|
173
281
|
|
|
174
282
|
/**
|
|
175
|
-
* Resumes paused
|
|
283
|
+
* Resumes managed timers that were paused with `pauseTimers()`.
|
|
284
|
+
*
|
|
285
|
+
* Each pending timer is shifted forward by the amount of time spent paused,
|
|
286
|
+
* preserving the remaining delay it had when the pause began.
|
|
287
|
+
*
|
|
176
288
|
* @returns {void}
|
|
177
289
|
*/
|
|
178
|
-
export function resumeTimers()
|
|
179
|
-
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if(timer_list.length>0) {
|
|
183
|
-
const now = Date.now();
|
|
290
|
+
export function resumeTimers() {
|
|
291
|
+
if (timer_pause_time === undefined) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
184
294
|
|
|
185
|
-
|
|
295
|
+
const elapsed = Date.now() - timer_pause_time;
|
|
186
296
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
297
|
+
for (const bucket of timer_list) {
|
|
298
|
+
bucket[DUE] += elapsed;
|
|
299
|
+
}
|
|
190
300
|
|
|
191
|
-
|
|
192
|
-
}
|
|
301
|
+
timer_pause_time = undefined;
|
|
193
302
|
|
|
194
|
-
|
|
303
|
+
schedule_next_timer();
|
|
195
304
|
}
|
|
196
305
|
|
|
197
306
|
|
|
198
307
|
/**
|
|
199
|
-
* Creates a timeout timer
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
308
|
+
* Creates a managed timeout timer.
|
|
309
|
+
*
|
|
310
|
+
* The signature matches the native `setTimeout` API. Additional arguments are
|
|
311
|
+
* passed to the callback when it executes.
|
|
312
|
+
*
|
|
313
|
+
* @param {Function} callback - Function to execute after the delay.
|
|
314
|
+
* @param {number} [delay=0] - Delay in milliseconds.
|
|
315
|
+
* @param {...any} args - Arguments passed to `callback`.
|
|
316
|
+
* @returns {number} Managed timeout ID.
|
|
204
317
|
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
{
|
|
209
|
-
|
|
318
|
+
export function setTimeout(callback, delay = 0, ...args) {
|
|
319
|
+
const milliseconds = Math.max(0, Number(delay) || 0);
|
|
320
|
+
|
|
321
|
+
return add_timer({
|
|
322
|
+
[CALLBACK]: callback,
|
|
323
|
+
[INTERVAL]: milliseconds,
|
|
324
|
+
[DUE]: Date.now() + milliseconds,
|
|
325
|
+
[REPEAT]: false,
|
|
326
|
+
[CLEARED]: false,
|
|
327
|
+
[ARGS]: args
|
|
328
|
+
});
|
|
210
329
|
}
|
|
211
330
|
|
|
212
331
|
/**
|
|
213
|
-
* Creates
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
332
|
+
* Creates a managed interval timer.
|
|
333
|
+
*
|
|
334
|
+
* The signature matches the native `setInterval` API. Additional arguments are
|
|
335
|
+
* passed to the callback on every execution.
|
|
336
|
+
*
|
|
337
|
+
* @param {Function} callback - Function to execute repeatedly.
|
|
338
|
+
* @param {number} [interval=0] - Interval in milliseconds.
|
|
339
|
+
* @param {...any} args - Arguments passed to `callback`.
|
|
340
|
+
* @returns {number} Managed interval ID.
|
|
218
341
|
*/
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
342
|
+
export function setInterval(callback, interval = 0, ...args) {
|
|
343
|
+
const milliseconds = Math.max(0, Number(interval) || 0);
|
|
344
|
+
|
|
345
|
+
return add_timer({
|
|
346
|
+
[CALLBACK]: callback,
|
|
347
|
+
[INTERVAL]: milliseconds,
|
|
348
|
+
[DUE]: Date.now() + milliseconds,
|
|
349
|
+
[REPEAT]: true,
|
|
350
|
+
[CLEARED]: false,
|
|
351
|
+
[ARGS]: args
|
|
352
|
+
});
|
|
223
353
|
}
|
|
224
354
|
|
|
225
355
|
/**
|
|
226
|
-
* Clears a timeout
|
|
227
|
-
*
|
|
356
|
+
* Clears a managed timeout.
|
|
357
|
+
*
|
|
358
|
+
* If `id` does not belong to a managed timer, it is passed to the original
|
|
359
|
+
* native `clearTimeout` function.
|
|
360
|
+
*
|
|
361
|
+
* @param {number} id - Timeout ID returned by `setTimeout`.
|
|
228
362
|
* @returns {void}
|
|
229
363
|
*/
|
|
230
|
-
export function clearTimeout(id)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
364
|
+
export function clearTimeout(id) {
|
|
365
|
+
const timer = all_timers.get(id);
|
|
366
|
+
|
|
367
|
+
if (timer !== undefined) {
|
|
368
|
+
timer[CLEARED] = true;
|
|
369
|
+
} else {
|
|
370
|
+
Lilact._clearTimeout(id);
|
|
371
|
+
}
|
|
234
372
|
}
|
|
235
373
|
|
|
374
|
+
|
|
236
375
|
/**
|
|
237
|
-
* Clears
|
|
238
|
-
*
|
|
376
|
+
* Clears a managed interval.
|
|
377
|
+
*
|
|
378
|
+
* If `id` does not belong to a managed timer, it is passed to the original
|
|
379
|
+
* native `clearInterval` function.
|
|
380
|
+
*
|
|
381
|
+
* @param {number} id - Interval ID returned by `setInterval`.
|
|
239
382
|
* @returns {void}
|
|
240
383
|
*/
|
|
241
|
-
export function clearInterval(id)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
384
|
+
export function clearInterval(id) {
|
|
385
|
+
const timer = all_timers.get(id);
|
|
386
|
+
|
|
387
|
+
if (timer !== undefined) {
|
|
388
|
+
timer[CLEARED] = true;
|
|
389
|
+
} else {
|
|
390
|
+
Lilact._clearInterval(id);
|
|
391
|
+
}
|
|
245
392
|
}
|
|
246
393
|
|
|
394
|
+
|
|
247
395
|
/**
|
|
248
|
-
* Captures
|
|
249
|
-
*
|
|
396
|
+
* Captures global timer functions through this framework.
|
|
397
|
+
*
|
|
398
|
+
* After calling this function, global calls to `setTimeout`, `setInterval`,
|
|
399
|
+
* `clearTimeout`, and `clearInterval` use the managed implementations.
|
|
400
|
+
*
|
|
250
401
|
* @returns {void}
|
|
251
402
|
*/
|
|
252
|
-
export function grabTimers()
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
globalThis.clearInterval = Lilact.clearInterval;
|
|
403
|
+
export function grabTimers() {
|
|
404
|
+
globalThis.setTimeout = Lilact.setTimeout;
|
|
405
|
+
globalThis.setInterval = Lilact.setInterval;
|
|
406
|
+
globalThis.clearTimeout = Lilact.clearTimeout;
|
|
407
|
+
globalThis.clearInterval = Lilact.clearInterval;
|
|
258
408
|
}
|
|
259
409
|
|
|
260
410
|
/**
|
|
261
|
-
* Releases
|
|
411
|
+
* Releases global timer functions from this framework.
|
|
412
|
+
*
|
|
413
|
+
* After calling this function, global timer calls use the original native
|
|
414
|
+
* timer implementations.
|
|
415
|
+
*
|
|
262
416
|
* @returns {void}
|
|
263
417
|
*/
|
|
264
|
-
export function releaseTimers()
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
globalThis.clearInterval = _clearInterval;
|
|
418
|
+
export function releaseTimers() {
|
|
419
|
+
globalThis.setTimeout = Lilact._setTimeout;
|
|
420
|
+
globalThis.setInterval = Lilact._setInterval;
|
|
421
|
+
globalThis.clearTimeout = Lilact._clearTimeout;
|
|
422
|
+
globalThis.clearInterval = Lilact._clearInterval;
|
|
270
423
|
}
|
|
271
424
|
|
|
272
425
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
426
|
+
* Creates a Promise that resolves after a managed timeout.
|
|
427
|
+
*
|
|
428
|
+
* The returned Promise has two additional methods:
|
|
429
|
+
*
|
|
430
|
+
* - `proceed()` clears the timer and resolves the Promise.
|
|
431
|
+
* - `cancel()` clears the timer and rejects the Promise.
|
|
432
|
+
*
|
|
433
|
+
* @param {number} [duration=0] - Delay in milliseconds.
|
|
434
|
+
* @param {Object} [timerSource=Lilact] - Object providing timer functions.
|
|
435
|
+
* @returns {Promise} Promise that resolves after the timeout.
|
|
276
436
|
*/
|
|
277
|
-
export function timeoutPromise(duration=0, timerSource=Lilact)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
437
|
+
export function timeoutPromise(duration = 0, timerSource = Lilact) {
|
|
438
|
+
let id;
|
|
439
|
+
let resolve_promise;
|
|
440
|
+
let reject_promise;
|
|
441
|
+
|
|
442
|
+
const promise = new Promise((resolve, reject) => {
|
|
443
|
+
resolve_promise = resolve;
|
|
444
|
+
reject_promise = reject;
|
|
445
|
+
|
|
446
|
+
id = timerSource.setTimeout(() => {
|
|
447
|
+
resolve();
|
|
448
|
+
}, duration);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Clears the timer and resolves the Promise immediately.
|
|
453
|
+
*
|
|
454
|
+
* @returns {void}
|
|
455
|
+
*/
|
|
456
|
+
promise.proceed = () => {
|
|
457
|
+
timerSource.clearTimeout(id);
|
|
458
|
+
resolve_promise();
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Clears the timer and rejects the Promise immediately.
|
|
463
|
+
*
|
|
464
|
+
* @returns {void}
|
|
465
|
+
*/
|
|
466
|
+
promise.cancel = () => {
|
|
467
|
+
timerSource.clearTimeout(id);
|
|
468
|
+
reject_promise();
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
return promise;
|
|
302
472
|
}
|
|
303
473
|
|
|
304
474
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
475
|
+
* Creates a Promise that resolves on the next animation frame.
|
|
476
|
+
*
|
|
477
|
+
* @returns {Promise} Promise resolved when the next animation frame runs.
|
|
307
478
|
*/
|
|
308
479
|
export function animationFramePromise() {
|
|
309
480
|
return new Promise((resolve) => {
|
|
@@ -311,5 +482,4 @@ export function animationFramePromise() {
|
|
|
311
482
|
resolve();
|
|
312
483
|
});
|
|
313
484
|
});
|
|
314
|
-
}
|
|
315
|
-
|
|
485
|
+
}
|