lilact 0.27.3 → 0.28.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.
Files changed (65) hide show
  1. package/bin/bundle.cjs +2 -2
  2. package/dist/lilact.development.js +312 -280
  3. package/dist/lilact.development.js.map +3 -3
  4. package/dist/lilact.development.min.js +39 -37
  5. package/dist/lilact.development.min.js.map +3 -3
  6. package/dist/lilact.production.min.js +39 -37
  7. package/docs/classes/accessories.ErrorBoundary.html +11 -11
  8. package/docs/classes/accessories.Suspense.html +10 -10
  9. package/docs/classes/components.Component.html +11 -11
  10. package/docs/classes/components.HTMLComponent.html +11 -11
  11. package/docs/classes/components.RootComponent.html +11 -11
  12. package/docs/functions/accessories.DragHandle.html +1 -1
  13. package/docs/functions/accessories.Spinner.html +1 -1
  14. package/docs/functions/components.cloneComponent.html +1 -1
  15. package/docs/functions/components.createComponent.html +1 -1
  16. package/docs/functions/components.createPortal.html +1 -1
  17. package/docs/functions/components.createRoot.html +1 -1
  18. package/docs/functions/components.memo.html +1 -1
  19. package/docs/functions/components.render.html +1 -1
  20. package/docs/functions/errors.scanBlockLabels.html +1 -1
  21. package/docs/functions/timers.animationFramePromise.html +3 -3
  22. package/docs/functions/timers.clearInterval.html +5 -3
  23. package/docs/functions/timers.clearTimeout.html +5 -3
  24. package/docs/functions/timers.grabTimers.html +4 -3
  25. package/docs/functions/timers.pauseTimers.html +5 -2
  26. package/docs/functions/timers.releaseTimers.html +4 -2
  27. package/docs/functions/timers.resetTimers.html +4 -2
  28. package/docs/functions/timers.resumeTimers.html +4 -2
  29. package/docs/functions/timers.setInterval.html +8 -6
  30. package/docs/functions/timers.setTimeout.html +8 -6
  31. package/docs/functions/timers.timeoutPromise.html +8 -149
  32. package/docs/static/demos/error-nested-1.jsx +11 -0
  33. package/docs/static/demos/error-nested-2.jsx +12 -0
  34. package/docs/static/demos/error-nested-3.jsx +12 -0
  35. package/docs/static/demos/error-nested-4.jsx +12 -0
  36. package/docs/static/demos/error-nested-5.jsx +12 -0
  37. package/docs/static/index.html +44 -38
  38. package/docs/static/lilact.development.js +312 -280
  39. package/docs/static/lilact.development.js.map +3 -3
  40. package/docs/static/lilact.development.min.js +39 -37
  41. package/docs/static/lilact.development.min.js.map +3 -3
  42. package/docs/static/lilact.production.min.js +39 -37
  43. package/docs/variables/accessories.SplitPane.html +1 -1
  44. package/docs/variables/components.cloneElement.html +1 -1
  45. package/docs/variables/errors.blocks_info.html +1 -1
  46. package/docs/variables/errors.error.html +1 -1
  47. package/examples/demos/error-nested-1.jsx +11 -0
  48. package/examples/demos/error-nested-2.jsx +12 -0
  49. package/examples/demos/error-nested-3.jsx +12 -0
  50. package/examples/demos/error-nested-4.jsx +12 -0
  51. package/examples/demos/error-nested-5.jsx +12 -0
  52. package/examples/index.html +44 -38
  53. package/examples/lilact.development.js +312 -280
  54. package/examples/lilact.development.js.map +3 -3
  55. package/examples/lilact.development.min.js +39 -37
  56. package/examples/lilact.development.min.js.map +3 -3
  57. package/examples/lilact.production.min.js +39 -37
  58. package/package.json +1 -1
  59. package/scripts/build.mjs +1 -1
  60. package/src/accessories.jsx +1 -4
  61. package/src/components.jsx +20 -15
  62. package/src/errors.jsx +5 -3
  63. package/src/lilact.jsx +4 -4
  64. package/src/run.jsx +1 -1
  65. 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
- import { IDX, DUE, REPEAT, CLEARED, INTERVAL, CALLBACK, ARGS } from "./symbols.jsx"
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 keep the same call signatures as the standard JavaScript timer APIs where applicable
37
- * (`setTimeout`/`setInterval`/`clearTimeout`/`clearInterval`),
38
- * but add extra capabilities for promise-friendly control and lifecycle management.
39
- *
40
- * This module can “grab” timers and later pause/resume/reset/release them, plus provide promise wrappers
41
- * like `timeoutPromise` and `animationFramePromise`.
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
- * - `setTimeout` / `setInterval`: schedule callbacks (same interface as the built-ins).
44
- * - `clearTimeout` / `clearInterval`: cancel scheduled timers (same interface as the built-ins).
45
- * - `grabTimers` / `pauseTimers` / `resumeTimers` / `resetTimers` / `releaseTimers`: manage tracked timers.
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 timer_pause_time = undefined;
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 = -1;
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
- function add_timer(t, is_repeat=false)
92
- {
93
- const [i,bucket] = get_bucket(t[DUE]);
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
- if(!is_repeat) {
96
- current_timer_idx++;
97
- all_timers[current_timer_idx]=t;
98
- t[IDX] = current_timer_idx;
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
- bucket.push(t);
108
+ Lilact._clearTimeout(timer_timeout);
102
109
 
103
- if(timer_list[0][0]===t) {
104
- _clearTimeout( timer_timeout );
105
- timer_timeout = _setTimeout( run_timer, t[INTERVAL] );
106
- }
110
+ const delay = Math.max(
111
+ 0,
112
+ timer_list[0][DUE] - Date.now()
113
+ );
107
114
 
108
- return current_timer_idx;
115
+ timer_timeout = Lilact._setTimeout(run_timer, delay);
109
116
  }
110
117
 
111
- function run_timer()
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 back to their initial scheduled state.
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 resetTimers()
155
- {
156
- _clearTimeout(timer_timeout);
157
- timer_pause_time = undefined;
158
- current_timer_idx = -1;
159
- timer_list = [];
160
- timer_timeout = -1;
161
- all_timers = {};
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 grabbed timers.
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 pauseTimers()
169
- {
170
- _clearTimeout( timer_timeout );
171
- timer_pause_time = Date.now();
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 timers.
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
- if(!timer_pause_time) return;
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
- timer_pause_time -= now;
295
+ const elapsed = Date.now() - timer_pause_time;
186
296
 
187
- for( const t of timer_list ) {
188
- t[DUE] -= timer_pause_time;
189
- }
297
+ for (const bucket of timer_list) {
298
+ bucket[DUE] += elapsed;
299
+ }
190
300
 
191
- timer_timeout = _setTimeout( run_timer, timer_list[0][DUE] - now);
192
- }
301
+ timer_pause_time = undefined;
193
302
 
194
- timer_pause_time = undefined;
303
+ schedule_next_timer();
195
304
  }
196
305
 
197
306
 
198
307
  /**
199
- * Creates a timeout timer (same interface as JS `setTimeout`).
200
- * @param {Function} callback - Function to run after the delay.
201
- * @param {number} delay - Delay in milliseconds.
202
- * @param {...any} [args] - Optional arguments passed to `callback`.
203
- * @returns {any} Timeout id.
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
- export function setTimeout(callback, delay, ...args)
208
- {
209
- return add_timer( { [CALLBACK]: callback, [INTERVAL]: delay, [DUE]: Date.now()+delay, [REPEAT]: false, [ARGS]: args } );
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 an interval timer (same interface as JS `setInterval`).
214
- * @param {Function} callback - Function to run repeatedly.
215
- * @param {number} interval - Delay in milliseconds between executions.
216
- * @param {...any} [args] - Optional arguments passed to `callback`.
217
- * @returns {any} Interval id.
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
- export function setInterval(callback, interval, ...args)
221
- {
222
- return add_timer( { [CALLBACK]: callback, [INTERVAL]: interval, [DUE]: Date.now()+interval, [REPEAT]: true, [ARGS]: args } );
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 created via this framework’s `setTimeout`.
227
- * @param {any} id - Timeout id returned by `setTimeout`.
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
- if(all_timers[id]) all_timers[id][CLEARED] = true;
233
- else _clearTimeout(id);
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 an interval created via this framework’s `setInterval`.
238
- * @param {any} id - Interval id returned by `setInterval`.
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
- if(all_timers[id]) all_timers[id][CLEARED] = true;
244
- else _clearInterval(id);
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/associates all timers with the framework so they can be managed. Calling this will
249
- * shadow the global setTimeout and setInterval functions and channel them through Lilact.
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
- globalThis.setTimeout = Lilact.setTimeout;
255
- globalThis.setInterval = Lilact.setInterval;
256
- globalThis.clearTimeout = Lilact.clearTimeout;
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 timers from framework control.
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
- globalThis.setTimeout = _setTimeout;
267
- globalThis.setInterval = _setInterval;
268
- globalThis.clearTimeout = _clearTimeout;
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
- * Returns a Promise that resolves after a timeout (framework-managed) using the same delay semantics as `setTimeout`.
274
- * @param {number} duration - Delay in milliseconds.
275
- * @returns {Promise} Promise that resolves after the delay.
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
- let id, resolve, reject;
280
-
281
- const promise = new Promise((res, rej) => {
282
- resolve = res;
283
- reject = rej;
284
- id = timerSource.setTimeout(() => {
285
- resolve();
286
- }, duration);
287
- });
288
-
289
- // note: proceed interrupts the timer, and continues the flow if used with await.
290
- promise.proceed = () => {
291
- timerSource.clearTimeout(id);
292
- resolve();
293
- };
294
-
295
- // note: cancel rejects so it throws exception when using with await, this allows handling it differently.
296
- promise.cancel = () => {
297
- timerSource.clearTimeout(id);
298
- reject();
299
- };
300
-
301
- return promise;
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
- * Schedules a callback on the next animation frame and returns a Promise that resolves on that frame.
306
- * @returns {Promise} Promise that resolves when the animation frame runs.
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
+ }