@alwatr/delay 5.5.11 → 6.0.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.
- package/CHANGELOG.md +37 -0
- package/README.md +66 -63
- package/dist/main.cjs +77 -63
- package/dist/main.cjs.map +2 -2
- package/dist/main.d.ts +49 -33
- package/dist/main.d.ts.map +1 -1
- package/dist/main.mjs +74 -62
- package/dist/main.mjs.map +2 -2
- package/dist/polyfill.d.ts +21 -4
- package/dist/polyfill.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,43 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [6.0.0](https://github.com/Alwatr/nanolib/compare/@alwatr/delay@5.5.11...@alwatr/delay@6.0.0) (2025-09-08)
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* **delay:** The API has been completely redesigned. All previous standalone functions are removed and replaced by methods on the `delay` object.
|
|
11
|
+
|
|
12
|
+
- **REMOVED:**
|
|
13
|
+
- `untilNextAnimationFrame`
|
|
14
|
+
- `untilIdle`
|
|
15
|
+
- `untilDomEvent`
|
|
16
|
+
- `untilEvent`
|
|
17
|
+
- `immediate`
|
|
18
|
+
- `nextMicrotask`
|
|
19
|
+
|
|
20
|
+
- **ADDED:**
|
|
21
|
+
- `delay.animationFrame` (replaces `waitForAnimationFrame`)
|
|
22
|
+
- `delay.idleCallback` (replaces `waitForIdle`)
|
|
23
|
+
- `delay.domEvent` (replaces `waitForDomEvent`)
|
|
24
|
+
- `delay.event` (replaces `waitForEvent`)
|
|
25
|
+
- `delay.nextMacrotask` (replaces `waitForImmediate`)
|
|
26
|
+
- `delay.nextMicrotask` (replaces `waitForMicrotask`)
|
|
27
|
+
|
|
28
|
+
Users must update their code to import the `delay` object and use the new method names. For example, `delay.immediate()` should be changed to `delay.nextMacrotask()`.
|
|
29
|
+
|
|
30
|
+
### ✨ Features
|
|
31
|
+
|
|
32
|
+
* **delay:** Overhaul delay module with improved API and corrected implementations ([7c12483](https://github.com/Alwatr/nanolib/commit/7c1248354f2535a65cb7981c42ad4e319badb4aa))
|
|
33
|
+
|
|
34
|
+
### 🔨 Code Refactoring
|
|
35
|
+
|
|
36
|
+
* **polyfill:** rename global_ to globalThis for clarity and consistency ([7d1484f](https://github.com/Alwatr/nanolib/commit/7d1484fb91a66d46b62011d0fb7825f3089183f8))
|
|
37
|
+
* **polyfill:** streamline requestAnimationFrame and requestIdleCallback implementations ([d18443d](https://github.com/Alwatr/nanolib/commit/d18443d4dedddff8f54227aa7aff2bca5aaacdfa))
|
|
38
|
+
|
|
39
|
+
### 🧹 Miscellaneous Chores
|
|
40
|
+
|
|
41
|
+
* **main:** export requestAnimationFrame and requestIdleCallback from main module ([ef80797](https://github.com/Alwatr/nanolib/commit/ef80797319e3bded5c36e98352b6317427d08a59))
|
|
42
|
+
|
|
6
43
|
## [5.5.11](https://github.com/Alwatr/nanolib/compare/@alwatr/delay@5.5.10...@alwatr/delay@5.5.11) (2025-09-06)
|
|
7
44
|
|
|
8
45
|
**Note:** Version bump only for package @alwatr/delay
|
package/README.md
CHANGED
|
@@ -1,106 +1,109 @@
|
|
|
1
1
|
# @alwatr/delay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A robust and lightweight utility library for managing asynchronous operations in JavaScript and TypeScript. `@alwatr/delay` provides a collection of promise-based functions to pause execution until specific conditions are met, such as timeouts, animation frames, idle callbacks, or DOM events. This helps create clean, readable, and predictable asynchronous code.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
+
# Using npm
|
|
8
9
|
npm install @alwatr/delay
|
|
9
|
-
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
# Using yarn
|
|
12
12
|
yarn add @alwatr/delay
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **waitForTimeout(duration: number): Promise<void>**
|
|
20
|
-
|
|
21
|
-
- Waits for a specified duration (in milliseconds) before resolving.
|
|
22
|
-
- Example:
|
|
17
|
+
All functions are available under the `delay` object and return a `Promise`. You can use them with `async/await` for clean and linear code flow.
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
```typescript
|
|
20
|
+
import {delay} from '@alwatr/delay';
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- Useful for synchronizing UI updates with browser rendering.
|
|
34
|
-
- Example:
|
|
22
|
+
async function main() {
|
|
23
|
+
console.log('Waiting for 1 second...');
|
|
24
|
+
await delay.by('1s');
|
|
25
|
+
console.log('Done.');
|
|
26
|
+
}
|
|
27
|
+
```
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
import {waitForAnimationFrame} from '@alwatr/delay';
|
|
29
|
+
### API Reference
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
```
|
|
31
|
+
- **`delay.by(duration: Duration): Promise<void>`**
|
|
41
32
|
|
|
42
|
-
|
|
33
|
+
Pauses execution for a specified duration. The duration can be a number (in milliseconds) or a string (e.g., `'2s'`, `'500ms'`).
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
```typescript
|
|
36
|
+
await delay.by(2000); // Waits for 2 seconds
|
|
37
|
+
await delay.by('5m'); // Waits for 5 minutes
|
|
38
|
+
```
|
|
48
39
|
|
|
49
|
-
|
|
50
|
-
import {waitForIdle} from '@alwatr/delay';
|
|
40
|
+
- **`delay.animationFrame(): Promise<DOMHighResTimeStamp>`**
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
```
|
|
42
|
+
Resolves at the beginning of the next browser animation frame. Useful for synchronizing animations and DOM updates with the browser's rendering cycle to avoid layout thrashing.
|
|
54
43
|
|
|
55
|
-
|
|
44
|
+
```typescript
|
|
45
|
+
const timestamp = await delay.animationFrame();
|
|
46
|
+
console.log(`Rendering next frame at ${timestamp}`);
|
|
47
|
+
// Perform DOM updates here
|
|
48
|
+
```
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
- Example:
|
|
50
|
+
- **`delay.idleCallback(options?: IdleRequestOptions): Promise<IdleDeadline>`**
|
|
59
51
|
|
|
60
|
-
|
|
61
|
-
import {waitForDomEvent} from '@alwatr/delay';
|
|
52
|
+
Resolves when the browser's event loop is idle. Ideal for deferring non-critical background tasks to avoid impacting user experience.
|
|
62
53
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
```typescript
|
|
55
|
+
const deadline = await delay.idleCallback({timeout: 1000});
|
|
56
|
+
if (!deadline.didTimeout) {
|
|
57
|
+
console.log('Running background task during idle time.');
|
|
58
|
+
}
|
|
59
|
+
```
|
|
66
60
|
|
|
67
|
-
-
|
|
61
|
+
- **`delay.domEvent<T extends keyof HTMLElementEventMap>(element: HTMLElement, eventName: T, options?: AddEventListenerOptions): Promise<HTMLElementEventMap[T]>`**
|
|
68
62
|
|
|
69
|
-
|
|
70
|
-
- Example:
|
|
63
|
+
Waits for a specific DOM event to be dispatched on an `HTMLElement`.
|
|
71
64
|
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
const button = document.getElementById('my-button');
|
|
67
|
+
if (button) {
|
|
68
|
+
const event = await delay.domEvent(button, 'click');
|
|
69
|
+
console.log('Button was clicked!', event);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
await waitForEvent(server, 'request'); // Waits for request event on server
|
|
77
|
-
```
|
|
73
|
+
- **`delay.event(target: EventTarget, eventName: string, options?: AddEventListenerOptions): Promise<Event>`**
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
A more generic version of `domEvent`. Waits for any event on any `EventTarget` (e.g., `window`, `document`, or custom event emitters).
|
|
80
76
|
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
```typescript
|
|
78
|
+
console.log('Waiting for window resize...');
|
|
79
|
+
await delay.event(window, 'resize');
|
|
80
|
+
console.log('Window was resized!');
|
|
81
|
+
```
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
import {waitForImmediate} from '@alwatr/delay';
|
|
83
|
+
- **`delay.nextMacrotask(): Promise<void>`**
|
|
86
84
|
|
|
87
|
-
|
|
88
|
-
```
|
|
85
|
+
Schedules a macrotask to run in the next cycle of the event loop. This is useful for yielding control back to the browser, allowing it to handle rendering and other user-facing tasks. Implemented with `setTimeout(..., 0)`.
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
```typescript
|
|
88
|
+
console.log('A');
|
|
89
|
+
await delay.nextMacrotask();
|
|
90
|
+
console.log('B'); // This will log after 'A' and after the browser has had a chance to breathe.
|
|
91
|
+
```
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
- Example:
|
|
93
|
+
- **`delay.nextMicrotask(): Promise<void>`**
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
import {waitForMicrotask} from '@alwatr/delay';
|
|
95
|
+
Queues a microtask to be executed immediately after the current task completes, before the event loop proceeds to the next macrotask. Useful for scheduling work that needs to happen synchronously after an operation but without blocking the main thread.
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
```typescript
|
|
98
|
+
console.log('A');
|
|
99
|
+
Promise.resolve().then(() => console.log('C'));
|
|
100
|
+
await delay.nextMicrotask();
|
|
101
|
+
console.log('B'); // Logs A, C, B
|
|
102
|
+
```
|
|
100
103
|
|
|
101
104
|
## Contributing
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
Contributions are welcome\! Please feel free to open an issue or submit a pull request. Read our [contribution guidelines](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) to get started.
|
|
104
107
|
|
|
105
108
|
## Sponsors
|
|
106
109
|
|
package/dist/main.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @alwatr/delay
|
|
1
|
+
/* @alwatr/delay v6.0.0 */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -21,7 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/main.ts
|
|
22
22
|
var main_exports = {};
|
|
23
23
|
__export(main_exports, {
|
|
24
|
-
delay: () => delay
|
|
24
|
+
delay: () => delay,
|
|
25
|
+
requestAnimationFrame: () => requestAnimationFrame,
|
|
26
|
+
requestIdleCallback: () => requestIdleCallback
|
|
25
27
|
});
|
|
26
28
|
module.exports = __toCommonJS(main_exports);
|
|
27
29
|
var import_package_tracer = require("@alwatr/package-tracer");
|
|
@@ -29,127 +31,139 @@ var import_parse_duration = require("@alwatr/parse-duration");
|
|
|
29
31
|
|
|
30
32
|
// src/polyfill.ts
|
|
31
33
|
var import_global_this = require("@alwatr/global-this");
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
var globalThis = /* @__PURE__ */ (0, import_global_this.getGlobalThis)();
|
|
35
|
+
var requestAnimationFrame = /* @__PURE__ */ globalThis.requestAnimationFrame?.bind(globalThis) ?? ((callback) => setTimeout(() => callback(performance.now()), 1e3 / 60));
|
|
36
|
+
var requestIdleCallback = /* @__PURE__ */ globalThis.requestIdleCallback?.bind(globalThis) ?? ((callback, options) => {
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
return setTimeout(() => {
|
|
39
|
+
callback({
|
|
40
|
+
didTimeout: !!options?.timeout,
|
|
41
|
+
timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime))
|
|
42
|
+
});
|
|
43
|
+
}, options?.timeout ?? 20);
|
|
44
|
+
});
|
|
37
45
|
|
|
38
46
|
// src/main.ts
|
|
39
|
-
__dev_mode__: import_package_tracer.packageTracer.add("@alwatr/delay", "
|
|
47
|
+
__dev_mode__: import_package_tracer.packageTracer.add("@alwatr/delay", "6.0.0");
|
|
40
48
|
var delay = {
|
|
41
49
|
/**
|
|
42
|
-
*
|
|
50
|
+
* Pauses execution for a specified duration.
|
|
43
51
|
*
|
|
44
|
-
* @param duration
|
|
52
|
+
* @param duration The duration to wait. Can be a number in milliseconds or a string like '2s', '100ms'.
|
|
45
53
|
* @returns A Promise that resolves after the specified duration.
|
|
46
54
|
*
|
|
47
55
|
* @example
|
|
48
56
|
* ```typescript
|
|
49
57
|
* await delay.by('1m'); // Wait for 1 minute
|
|
58
|
+
* await delay.by('2s'); // Wait for 2 seconds
|
|
50
59
|
* ```
|
|
51
60
|
*/
|
|
52
61
|
by: (duration) => new Promise((resolve) => setTimeout(resolve, (0, import_parse_duration.parseDuration)(duration))),
|
|
53
62
|
/**
|
|
54
|
-
*
|
|
63
|
+
* Pauses execution until the next animation frame.
|
|
55
64
|
*
|
|
56
|
-
* @returns A Promise that resolves with the
|
|
65
|
+
* @returns A Promise that resolves with the high-resolution timestamp of the next animation frame.
|
|
57
66
|
*
|
|
58
67
|
* @example
|
|
59
68
|
* ```typescript
|
|
60
|
-
* const timestamp = await delay.
|
|
69
|
+
* const timestamp = await delay.animationFrame();
|
|
70
|
+
* console.log(`Next frame at ${timestamp}`);
|
|
61
71
|
* ```
|
|
62
72
|
*/
|
|
63
|
-
|
|
73
|
+
animationFrame: () => new Promise((resolve) => requestAnimationFrame(resolve)),
|
|
64
74
|
/**
|
|
65
|
-
*
|
|
75
|
+
* Pauses execution until the browser is idle.
|
|
66
76
|
*
|
|
67
|
-
* @param timeout
|
|
68
|
-
* @returns A Promise that resolves with
|
|
77
|
+
* @param timeout An optional maximum duration to wait.
|
|
78
|
+
* @returns A Promise that resolves with an `IdleDeadline` object.
|
|
69
79
|
*
|
|
70
80
|
* @example
|
|
71
81
|
* ```typescript
|
|
72
|
-
* const deadline = await delay.
|
|
82
|
+
* const deadline = await delay.idleCallback({ timeout: 2000 });
|
|
83
|
+
* if (deadline.didTimeout) {
|
|
84
|
+
* console.log('Idle callback timed out.');
|
|
85
|
+
* }
|
|
73
86
|
* ```
|
|
74
87
|
*/
|
|
75
|
-
|
|
76
|
-
timeout: (0, import_parse_duration.parseDuration)(timeout)
|
|
77
|
-
})),
|
|
88
|
+
idleCallback: (options) => new Promise((resolve) => requestIdleCallback(resolve, options)),
|
|
78
89
|
/**
|
|
79
|
-
*
|
|
90
|
+
* Pauses execution until a specific DOM event is dispatched on an element.
|
|
80
91
|
*
|
|
81
|
-
* @param element
|
|
82
|
-
* @param eventName
|
|
83
|
-
* @
|
|
84
|
-
* @
|
|
92
|
+
* @param element The HTMLElement to listen on.
|
|
93
|
+
* @param eventName The name of the event to wait for.
|
|
94
|
+
* @param options Optional event listener options.
|
|
95
|
+
* @template T The event map type for the element.
|
|
96
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
85
97
|
*
|
|
86
98
|
* @example
|
|
87
99
|
* ```typescript
|
|
88
|
-
* const
|
|
100
|
+
* const button = document.getElementById('my-button');
|
|
101
|
+
* if (button) {
|
|
102
|
+
* const clickEvent = await delay.domEvent(button, 'click');
|
|
103
|
+
* console.log('Button clicked!', clickEvent);
|
|
104
|
+
* }
|
|
89
105
|
* ```
|
|
90
106
|
*/
|
|
91
|
-
|
|
92
|
-
(resolve) => element.addEventListener(eventName, resolve, {
|
|
107
|
+
domEvent: (element, eventName, options = { passive: true }) => new Promise(
|
|
108
|
+
(resolve) => element.addEventListener(eventName, resolve, {
|
|
109
|
+
...options,
|
|
110
|
+
once: true
|
|
111
|
+
})
|
|
93
112
|
),
|
|
94
113
|
/**
|
|
95
|
-
*
|
|
114
|
+
* Pauses execution until a specific event is dispatched on any event target.
|
|
96
115
|
*
|
|
97
|
-
* @param target
|
|
98
|
-
* @param eventName
|
|
99
|
-
* @
|
|
116
|
+
* @param target The event target (e.g., window, document, or a custom event emitter).
|
|
117
|
+
* @param eventName The name of the event to wait for.
|
|
118
|
+
* @param options Optional event listener options.
|
|
119
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
100
120
|
*
|
|
101
121
|
* @example
|
|
102
122
|
* ```typescript
|
|
103
|
-
* const
|
|
104
|
-
*
|
|
123
|
+
* const resizeEvent = await delay.event(window, 'resize');
|
|
124
|
+
* console.log('Window resized:', resizeEvent);
|
|
105
125
|
* ```
|
|
106
126
|
*/
|
|
107
|
-
|
|
108
|
-
(resolve) => target.addEventListener(eventName, resolve, {
|
|
127
|
+
event: (target, eventName, options = { passive: true }) => new Promise(
|
|
128
|
+
(resolve) => target.addEventListener(eventName, resolve, {
|
|
129
|
+
...options,
|
|
130
|
+
once: true
|
|
131
|
+
})
|
|
109
132
|
),
|
|
110
133
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* Uses `setImmediate` if available, falls back to `queueMicrotask`, and then to `setTimeout(0)`.
|
|
134
|
+
* Schedules a macrotask to run after the current event loop task completes.
|
|
135
|
+
* Uses `setTimeout(..., 0)`.
|
|
114
136
|
*
|
|
115
|
-
* @returns A Promise that resolves
|
|
137
|
+
* @returns A Promise that resolves when the macrotask is executed.
|
|
116
138
|
*
|
|
117
139
|
* @example
|
|
118
140
|
* ```typescript
|
|
119
|
-
*
|
|
141
|
+
* console.log('Start');
|
|
142
|
+
* await delay.nextMacrotask();
|
|
143
|
+
* console.log('End - after current task');
|
|
120
144
|
* ```
|
|
121
145
|
*/
|
|
122
|
-
|
|
123
|
-
if (typeof setImmediate !== "function") {
|
|
124
|
-
if (typeof queueMicrotask === "function") {
|
|
125
|
-
return delay.nextMicrotask();
|
|
126
|
-
}
|
|
127
|
-
return delay.by(0);
|
|
128
|
-
}
|
|
129
|
-
return new Promise((resolve) => setImmediate(resolve));
|
|
130
|
-
},
|
|
146
|
+
nextMacrotask: () => new Promise((resolve) => setTimeout(resolve, 0)),
|
|
131
147
|
/**
|
|
132
|
-
*
|
|
148
|
+
* Queues a microtask to run after the current task completes but before the next macrotask.
|
|
133
149
|
*
|
|
134
|
-
* @returns A Promise that resolves when the
|
|
150
|
+
* @returns A Promise that resolves when the microtask is executed.
|
|
135
151
|
*
|
|
136
152
|
* @example
|
|
137
153
|
* ```typescript
|
|
154
|
+
* console.log('Start');
|
|
138
155
|
* await delay.nextMicrotask();
|
|
156
|
+
* console.log('End - immediately after current task');
|
|
139
157
|
* ```
|
|
140
158
|
*/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return delay.immediate();
|
|
145
|
-
}
|
|
146
|
-
return delay.by(0);
|
|
147
|
-
}
|
|
148
|
-
return new Promise((resolve) => queueMicrotask(resolve));
|
|
149
|
-
}
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
160
|
+
nextMicrotask: () => Promise.resolve().then(() => {
|
|
161
|
+
})
|
|
150
162
|
};
|
|
151
163
|
// Annotate the CommonJS export names for ESM import in node:
|
|
152
164
|
0 && (module.exports = {
|
|
153
|
-
delay
|
|
165
|
+
delay,
|
|
166
|
+
requestAnimationFrame,
|
|
167
|
+
requestIdleCallback
|
|
154
168
|
});
|
|
155
169
|
//# sourceMappingURL=main.cjs.map
|
package/dist/main.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts", "../src/polyfill.ts"],
|
|
4
|
-
"sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration, type Duration} from '@alwatr/parse-duration';\n\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4B;AAC5B,4BAA2C;;;ACD3C,
|
|
4
|
+
"sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration, type Duration} from '@alwatr/parse-duration';\n\nimport {requestAnimationFrame, requestIdleCallback} from './polyfill.js';\n\nexport {requestAnimationFrame, requestIdleCallback};\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * A utility module to help manage asynchronous operations and waiting for events or timeouts.\n */\nexport const delay = {\n /**\n * Pauses execution for a specified duration.\n *\n * @param duration The duration to wait. Can be a number in milliseconds or a string like '2s', '100ms'.\n * @returns A Promise that resolves after the specified duration.\n *\n * @example\n * ```typescript\n * await delay.by('1m'); // Wait for 1 minute\n * await delay.by('2s'); // Wait for 2 seconds\n * ```\n */\n by: (duration: Duration): Promise<void> => new Promise((resolve) => setTimeout(resolve, parseDuration(duration))),\n\n /**\n * Pauses execution until the next animation frame.\n *\n * @returns A Promise that resolves with the high-resolution timestamp of the next animation frame.\n *\n * @example\n * ```typescript\n * const timestamp = await delay.animationFrame();\n * console.log(`Next frame at ${timestamp}`);\n * ```\n */\n animationFrame: (): Promise<DOMHighResTimeStamp> => new Promise((resolve) => requestAnimationFrame(resolve)),\n\n /**\n * Pauses execution until the browser is idle.\n *\n * @param timeout An optional maximum duration to wait.\n * @returns A Promise that resolves with an `IdleDeadline` object.\n *\n * @example\n * ```typescript\n * const deadline = await delay.idleCallback({ timeout: 2000 });\n * if (deadline.didTimeout) {\n * console.log('Idle callback timed out.');\n * }\n * ```\n */\n idleCallback: (options?: IdleRequestOptions): Promise<IdleDeadline> => new Promise((resolve) => requestIdleCallback(resolve, options)),\n\n /**\n * Pauses execution until a specific DOM event is dispatched on an element.\n *\n * @param element The HTMLElement to listen on.\n * @param eventName The name of the event to wait for.\n * @param options Optional event listener options.\n * @template T The event map type for the element.\n * @returns A Promise that resolves with the triggered event object.\n *\n * @example\n * ```typescript\n * const button = document.getElementById('my-button');\n * if (button) {\n * const clickEvent = await delay.domEvent(button, 'click');\n * console.log('Button clicked!', clickEvent);\n * }\n * ```\n */\n domEvent: <T extends keyof HTMLElementEventMap>(\n element: HTMLElement,\n eventName: T,\n options: AddEventListenerOptions = {passive: true},\n ): Promise<HTMLElementEventMap[T]> =>\n new Promise((resolve) =>\n element.addEventListener(eventName, resolve, {\n ...options,\n once: true,\n }),\n ),\n\n /**\n * Pauses execution until a specific event is dispatched on any event target.\n *\n * @param target The event target (e.g., window, document, or a custom event emitter).\n * @param eventName The name of the event to wait for.\n * @param options Optional event listener options.\n * @returns A Promise that resolves with the triggered event object.\n *\n * @example\n * ```typescript\n * const resizeEvent = await delay.event(window, 'resize');\n * console.log('Window resized:', resizeEvent);\n * ```\n */\n event: (target: EventTarget, eventName: string, options: AddEventListenerOptions = {passive: true}): Promise<Event> =>\n new Promise((resolve) =>\n target.addEventListener(eventName, resolve, {\n ...options,\n once: true,\n }),\n ),\n\n /**\n * Schedules a macrotask to run after the current event loop task completes.\n * Uses `setTimeout(..., 0)`.\n *\n * @returns A Promise that resolves when the macrotask is executed.\n *\n * @example\n * ```typescript\n * console.log('Start');\n * await delay.nextMacrotask();\n * console.log('End - after current task');\n * ```\n */\n nextMacrotask: (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0)),\n\n /**\n * Queues a microtask to run after the current task completes but before the next macrotask.\n *\n * @returns A Promise that resolves when the microtask is executed.\n *\n * @example\n * ```typescript\n * console.log('Start');\n * await delay.nextMicrotask();\n * console.log('End - immediately after current task');\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n nextMicrotask: (): Promise<void> => Promise.resolve().then(() => {}),\n} as const;\n", "import {getGlobalThis} from '@alwatr/global-this';\n\nconst globalThis = /* #__PURE__ */ getGlobalThis<DictionaryOpt<unknown>>();\n\n/**\n * Ensures compatibility for `requestAnimationFrame` by using the native API\n * available in `globalThis`. If it's not available, it falls back to a `setTimeout`\n * call that aims for a 60 frames per second refresh rate.\n *\n * @param callback The function to call when it's time to update your animation for the next repaint.\n * @returns A long integer value, the request ID, that uniquely identifies the entry in the callback list.\n */\nexport const requestAnimationFrame: (callback: FrameRequestCallback) => number =\n /* #__PURE__ */ globalThis.requestAnimationFrame?.bind(globalThis) ??\n /* #__PURE__ */ ((callback: FrameRequestCallback) => setTimeout(() => callback(performance.now()), 1000 / 60));\n\n/**\n * Ensures compatibility for `requestIdleCallback` by using the native API.\n * If unavailable, it falls back to a `setTimeout` that executes the callback\n * after a short delay, providing a mock `IdleDeadline` object.\n *\n * The mock `IdleDeadline` gives the task a 50ms budget to run.\n *\n * @param callback A reference to a function that should be called in the near future, when the event loop is idle.\n * @param options An optional object with configuration parameters.\n * @returns An ID which can be used to cancel the callback by calling `cancelIdleCallback()`.\n */\nexport const requestIdleCallback: (callback: (deadline: IdleDeadline) => void, options?: IdleRequestOptions) => number =\n /* #__PURE__ */ globalThis.requestIdleCallback?.bind(globalThis) ??\n /* #__PURE__ */ ((\n callback: (deadline: IdleDeadline) => void,\n // options is not used in the fallback but kept for API consistency\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: IdleRequestOptions,\n ) => {\n const startTime = Date.now();\n return setTimeout(() => {\n callback({\n didTimeout: !!options?.timeout,\n timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime)),\n });\n }, options?.timeout ?? 20);\n });\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA4B;AAC5B,4BAA2C;;;ACD3C,yBAA4B;AAE5B,IAAM,aAA6B,sDAAsC;AAUlE,IAAM,wBACK,2BAAW,uBAAuB,KAAK,UAAU,MAChD,CAAC,aAAmC,WAAW,MAAM,SAAS,YAAY,IAAI,CAAC,GAAG,MAAO,EAAE;AAavG,IAAM,sBACK,2BAAW,qBAAqB,KAAK,UAAU,MAC9C,CACf,UAGA,YACG;AACH,QAAM,YAAY,KAAK,IAAI;AAC3B,SAAO,WAAW,MAAM;AACtB,aAAS;AAAA,MACP,YAAY,CAAC,CAAC,SAAS;AAAA,MACvB,eAAe,MAAM,KAAK,IAAI,GAAG,MAAM,KAAK,IAAI,IAAI,UAAU;AAAA,IAChE,CAAC;AAAA,EACH,GAAG,SAAS,WAAW,EAAE;AAC3B;;;ADnCF,aAAc,qCAAc,IAAI,iBAAkB,OAAmB;AAK9D,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAanB,IAAI,CAAC,aAAsC,IAAI,QAAQ,CAAC,YAAY,WAAW,aAAS,qCAAc,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAahH,gBAAgB,MAAoC,IAAI,QAAQ,CAAC,YAAY,sBAAsB,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB3G,cAAc,CAAC,YAAwD,IAAI,QAAQ,CAAC,YAAY,oBAAoB,SAAS,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBrI,UAAU,CACR,SACA,WACA,UAAmC,EAAC,SAAS,KAAI,MAEjD,IAAI;AAAA,IAAQ,CAAC,YACX,QAAQ,iBAAiB,WAAW,SAAS;AAAA,MAC3C,GAAG;AAAA,MACH,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBF,OAAO,CAAC,QAAqB,WAAmB,UAAmC,EAAC,SAAS,KAAI,MAC/F,IAAI;AAAA,IAAQ,CAAC,YACX,OAAO,iBAAiB,WAAW,SAAS;AAAA,MAC1C,GAAG;AAAA,MACH,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeF,eAAe,MAAqB,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenF,eAAe,MAAqB,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAAA,EAAC,CAAC;AACrE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -1,92 +1,108 @@
|
|
|
1
1
|
import { type Duration } from '@alwatr/parse-duration';
|
|
2
|
+
import { requestAnimationFrame, requestIdleCallback } from './polyfill.js';
|
|
3
|
+
export { requestAnimationFrame, requestIdleCallback };
|
|
2
4
|
/**
|
|
3
5
|
* A utility module to help manage asynchronous operations and waiting for events or timeouts.
|
|
4
6
|
*/
|
|
5
7
|
export declare const delay: {
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
9
|
+
* Pauses execution for a specified duration.
|
|
8
10
|
*
|
|
9
|
-
* @param duration
|
|
11
|
+
* @param duration The duration to wait. Can be a number in milliseconds or a string like '2s', '100ms'.
|
|
10
12
|
* @returns A Promise that resolves after the specified duration.
|
|
11
13
|
*
|
|
12
14
|
* @example
|
|
13
15
|
* ```typescript
|
|
14
16
|
* await delay.by('1m'); // Wait for 1 minute
|
|
17
|
+
* await delay.by('2s'); // Wait for 2 seconds
|
|
15
18
|
* ```
|
|
16
19
|
*/
|
|
17
20
|
readonly by: (duration: Duration) => Promise<void>;
|
|
18
21
|
/**
|
|
19
|
-
*
|
|
22
|
+
* Pauses execution until the next animation frame.
|
|
20
23
|
*
|
|
21
|
-
* @returns A Promise that resolves with the
|
|
24
|
+
* @returns A Promise that resolves with the high-resolution timestamp of the next animation frame.
|
|
22
25
|
*
|
|
23
26
|
* @example
|
|
24
27
|
* ```typescript
|
|
25
|
-
* const timestamp = await delay.
|
|
28
|
+
* const timestamp = await delay.animationFrame();
|
|
29
|
+
* console.log(`Next frame at ${timestamp}`);
|
|
26
30
|
* ```
|
|
27
31
|
*/
|
|
28
|
-
readonly
|
|
32
|
+
readonly animationFrame: () => Promise<DOMHighResTimeStamp>;
|
|
29
33
|
/**
|
|
30
|
-
*
|
|
34
|
+
* Pauses execution until the browser is idle.
|
|
31
35
|
*
|
|
32
|
-
* @param timeout
|
|
33
|
-
* @returns A Promise that resolves with
|
|
36
|
+
* @param timeout An optional maximum duration to wait.
|
|
37
|
+
* @returns A Promise that resolves with an `IdleDeadline` object.
|
|
34
38
|
*
|
|
35
39
|
* @example
|
|
36
40
|
* ```typescript
|
|
37
|
-
* const deadline = await delay.
|
|
41
|
+
* const deadline = await delay.idleCallback({ timeout: 2000 });
|
|
42
|
+
* if (deadline.didTimeout) {
|
|
43
|
+
* console.log('Idle callback timed out.');
|
|
44
|
+
* }
|
|
38
45
|
* ```
|
|
39
46
|
*/
|
|
40
|
-
readonly
|
|
47
|
+
readonly idleCallback: (options?: IdleRequestOptions) => Promise<IdleDeadline>;
|
|
41
48
|
/**
|
|
42
|
-
*
|
|
49
|
+
* Pauses execution until a specific DOM event is dispatched on an element.
|
|
43
50
|
*
|
|
44
|
-
* @param element
|
|
45
|
-
* @param eventName
|
|
46
|
-
* @
|
|
47
|
-
* @
|
|
51
|
+
* @param element The HTMLElement to listen on.
|
|
52
|
+
* @param eventName The name of the event to wait for.
|
|
53
|
+
* @param options Optional event listener options.
|
|
54
|
+
* @template T The event map type for the element.
|
|
55
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
48
56
|
*
|
|
49
57
|
* @example
|
|
50
58
|
* ```typescript
|
|
51
|
-
* const
|
|
59
|
+
* const button = document.getElementById('my-button');
|
|
60
|
+
* if (button) {
|
|
61
|
+
* const clickEvent = await delay.domEvent(button, 'click');
|
|
62
|
+
* console.log('Button clicked!', clickEvent);
|
|
63
|
+
* }
|
|
52
64
|
* ```
|
|
53
65
|
*/
|
|
54
|
-
readonly
|
|
66
|
+
readonly domEvent: <T extends keyof HTMLElementEventMap>(element: HTMLElement, eventName: T, options?: AddEventListenerOptions) => Promise<HTMLElementEventMap[T]>;
|
|
55
67
|
/**
|
|
56
|
-
*
|
|
68
|
+
* Pauses execution until a specific event is dispatched on any event target.
|
|
57
69
|
*
|
|
58
|
-
* @param target
|
|
59
|
-
* @param eventName
|
|
60
|
-
* @
|
|
70
|
+
* @param target The event target (e.g., window, document, or a custom event emitter).
|
|
71
|
+
* @param eventName The name of the event to wait for.
|
|
72
|
+
* @param options Optional event listener options.
|
|
73
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
61
74
|
*
|
|
62
75
|
* @example
|
|
63
76
|
* ```typescript
|
|
64
|
-
* const
|
|
65
|
-
*
|
|
77
|
+
* const resizeEvent = await delay.event(window, 'resize');
|
|
78
|
+
* console.log('Window resized:', resizeEvent);
|
|
66
79
|
* ```
|
|
67
80
|
*/
|
|
68
|
-
readonly
|
|
81
|
+
readonly event: (target: EventTarget, eventName: string, options?: AddEventListenerOptions) => Promise<Event>;
|
|
69
82
|
/**
|
|
70
|
-
*
|
|
83
|
+
* Schedules a macrotask to run after the current event loop task completes.
|
|
84
|
+
* Uses `setTimeout(..., 0)`.
|
|
71
85
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* @returns A Promise that resolves immediately after yielding control to the event loop.
|
|
86
|
+
* @returns A Promise that resolves when the macrotask is executed.
|
|
75
87
|
*
|
|
76
88
|
* @example
|
|
77
89
|
* ```typescript
|
|
78
|
-
*
|
|
90
|
+
* console.log('Start');
|
|
91
|
+
* await delay.nextMacrotask();
|
|
92
|
+
* console.log('End - after current task');
|
|
79
93
|
* ```
|
|
80
94
|
*/
|
|
81
|
-
readonly
|
|
95
|
+
readonly nextMacrotask: () => Promise<void>;
|
|
82
96
|
/**
|
|
83
|
-
*
|
|
97
|
+
* Queues a microtask to run after the current task completes but before the next macrotask.
|
|
84
98
|
*
|
|
85
|
-
* @returns A Promise that resolves when the
|
|
99
|
+
* @returns A Promise that resolves when the microtask is executed.
|
|
86
100
|
*
|
|
87
101
|
* @example
|
|
88
102
|
* ```typescript
|
|
103
|
+
* console.log('Start');
|
|
89
104
|
* await delay.nextMicrotask();
|
|
105
|
+
* console.log('End - immediately after current task');
|
|
90
106
|
* ```
|
|
91
107
|
*/
|
|
92
108
|
readonly nextMicrotask: () => Promise<void>;
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAEzE,OAAO,EAAC,qBAAqB,EAAE,mBAAmB,EAAC,CAAC;AAIpD;;GAEG;AACH,eAAO,MAAM,KAAK;IAChB;;;;;;;;;;;OAWG;4BACY,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC;IAEvC;;;;;;;;;;OAUG;mCACiB,OAAO,CAAC,mBAAmB,CAAC;IAEhD;;;;;;;;;;;;;OAaG;sCACsB,kBAAkB,KAAG,OAAO,CAAC,YAAY,CAAC;IAEnE;;;;;;;;;;;;;;;;;OAiBG;wBACQ,CAAC,SAAS,MAAM,mBAAmB,WACnC,WAAW,aACT,CAAC,YACH,uBAAuB,KAC/B,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAQlC;;;;;;;;;;;;;OAaG;6BACa,WAAW,aAAa,MAAM,YAAW,uBAAuB,KAAqB,OAAO,CAAC,KAAK,CAAC;IAQnH;;;;;;;;;;;;OAYG;kCACgB,OAAO,CAAC,IAAI,CAAC;IAEhC;;;;;;;;;;;OAWG;kCAEgB,OAAO,CAAC,IAAI,CAAC;CACxB,CAAC"}
|
package/dist/main.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @alwatr/delay
|
|
1
|
+
/* @alwatr/delay v6.0.0 */
|
|
2
2
|
|
|
3
3
|
// src/main.ts
|
|
4
4
|
import { packageTracer } from "@alwatr/package-tracer";
|
|
@@ -6,126 +6,138 @@ import { parseDuration } from "@alwatr/parse-duration";
|
|
|
6
6
|
|
|
7
7
|
// src/polyfill.ts
|
|
8
8
|
import { getGlobalThis } from "@alwatr/global-this";
|
|
9
|
-
var
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
var globalThis = /* @__PURE__ */ getGlobalThis();
|
|
10
|
+
var requestAnimationFrame = /* @__PURE__ */ globalThis.requestAnimationFrame?.bind(globalThis) ?? ((callback) => setTimeout(() => callback(performance.now()), 1e3 / 60));
|
|
11
|
+
var requestIdleCallback = /* @__PURE__ */ globalThis.requestIdleCallback?.bind(globalThis) ?? ((callback, options) => {
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
return setTimeout(() => {
|
|
14
|
+
callback({
|
|
15
|
+
didTimeout: !!options?.timeout,
|
|
16
|
+
timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime))
|
|
17
|
+
});
|
|
18
|
+
}, options?.timeout ?? 20);
|
|
19
|
+
});
|
|
14
20
|
|
|
15
21
|
// src/main.ts
|
|
16
|
-
__dev_mode__: packageTracer.add("@alwatr/delay", "
|
|
22
|
+
__dev_mode__: packageTracer.add("@alwatr/delay", "6.0.0");
|
|
17
23
|
var delay = {
|
|
18
24
|
/**
|
|
19
|
-
*
|
|
25
|
+
* Pauses execution for a specified duration.
|
|
20
26
|
*
|
|
21
|
-
* @param duration
|
|
27
|
+
* @param duration The duration to wait. Can be a number in milliseconds or a string like '2s', '100ms'.
|
|
22
28
|
* @returns A Promise that resolves after the specified duration.
|
|
23
29
|
*
|
|
24
30
|
* @example
|
|
25
31
|
* ```typescript
|
|
26
32
|
* await delay.by('1m'); // Wait for 1 minute
|
|
33
|
+
* await delay.by('2s'); // Wait for 2 seconds
|
|
27
34
|
* ```
|
|
28
35
|
*/
|
|
29
36
|
by: (duration) => new Promise((resolve) => setTimeout(resolve, parseDuration(duration))),
|
|
30
37
|
/**
|
|
31
|
-
*
|
|
38
|
+
* Pauses execution until the next animation frame.
|
|
32
39
|
*
|
|
33
|
-
* @returns A Promise that resolves with the
|
|
40
|
+
* @returns A Promise that resolves with the high-resolution timestamp of the next animation frame.
|
|
34
41
|
*
|
|
35
42
|
* @example
|
|
36
43
|
* ```typescript
|
|
37
|
-
* const timestamp = await delay.
|
|
44
|
+
* const timestamp = await delay.animationFrame();
|
|
45
|
+
* console.log(`Next frame at ${timestamp}`);
|
|
38
46
|
* ```
|
|
39
47
|
*/
|
|
40
|
-
|
|
48
|
+
animationFrame: () => new Promise((resolve) => requestAnimationFrame(resolve)),
|
|
41
49
|
/**
|
|
42
|
-
*
|
|
50
|
+
* Pauses execution until the browser is idle.
|
|
43
51
|
*
|
|
44
|
-
* @param timeout
|
|
45
|
-
* @returns A Promise that resolves with
|
|
52
|
+
* @param timeout An optional maximum duration to wait.
|
|
53
|
+
* @returns A Promise that resolves with an `IdleDeadline` object.
|
|
46
54
|
*
|
|
47
55
|
* @example
|
|
48
56
|
* ```typescript
|
|
49
|
-
* const deadline = await delay.
|
|
57
|
+
* const deadline = await delay.idleCallback({ timeout: 2000 });
|
|
58
|
+
* if (deadline.didTimeout) {
|
|
59
|
+
* console.log('Idle callback timed out.');
|
|
60
|
+
* }
|
|
50
61
|
* ```
|
|
51
62
|
*/
|
|
52
|
-
|
|
53
|
-
timeout: parseDuration(timeout)
|
|
54
|
-
})),
|
|
63
|
+
idleCallback: (options) => new Promise((resolve) => requestIdleCallback(resolve, options)),
|
|
55
64
|
/**
|
|
56
|
-
*
|
|
65
|
+
* Pauses execution until a specific DOM event is dispatched on an element.
|
|
57
66
|
*
|
|
58
|
-
* @param element
|
|
59
|
-
* @param eventName
|
|
60
|
-
* @
|
|
61
|
-
* @
|
|
67
|
+
* @param element The HTMLElement to listen on.
|
|
68
|
+
* @param eventName The name of the event to wait for.
|
|
69
|
+
* @param options Optional event listener options.
|
|
70
|
+
* @template T The event map type for the element.
|
|
71
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
62
72
|
*
|
|
63
73
|
* @example
|
|
64
74
|
* ```typescript
|
|
65
|
-
* const
|
|
75
|
+
* const button = document.getElementById('my-button');
|
|
76
|
+
* if (button) {
|
|
77
|
+
* const clickEvent = await delay.domEvent(button, 'click');
|
|
78
|
+
* console.log('Button clicked!', clickEvent);
|
|
79
|
+
* }
|
|
66
80
|
* ```
|
|
67
81
|
*/
|
|
68
|
-
|
|
69
|
-
(resolve) => element.addEventListener(eventName, resolve, {
|
|
82
|
+
domEvent: (element, eventName, options = { passive: true }) => new Promise(
|
|
83
|
+
(resolve) => element.addEventListener(eventName, resolve, {
|
|
84
|
+
...options,
|
|
85
|
+
once: true
|
|
86
|
+
})
|
|
70
87
|
),
|
|
71
88
|
/**
|
|
72
|
-
*
|
|
89
|
+
* Pauses execution until a specific event is dispatched on any event target.
|
|
73
90
|
*
|
|
74
|
-
* @param target
|
|
75
|
-
* @param eventName
|
|
76
|
-
* @
|
|
91
|
+
* @param target The event target (e.g., window, document, or a custom event emitter).
|
|
92
|
+
* @param eventName The name of the event to wait for.
|
|
93
|
+
* @param options Optional event listener options.
|
|
94
|
+
* @returns A Promise that resolves with the triggered event object.
|
|
77
95
|
*
|
|
78
96
|
* @example
|
|
79
97
|
* ```typescript
|
|
80
|
-
* const
|
|
81
|
-
*
|
|
98
|
+
* const resizeEvent = await delay.event(window, 'resize');
|
|
99
|
+
* console.log('Window resized:', resizeEvent);
|
|
82
100
|
* ```
|
|
83
101
|
*/
|
|
84
|
-
|
|
85
|
-
(resolve) => target.addEventListener(eventName, resolve, {
|
|
102
|
+
event: (target, eventName, options = { passive: true }) => new Promise(
|
|
103
|
+
(resolve) => target.addEventListener(eventName, resolve, {
|
|
104
|
+
...options,
|
|
105
|
+
once: true
|
|
106
|
+
})
|
|
86
107
|
),
|
|
87
108
|
/**
|
|
88
|
-
*
|
|
109
|
+
* Schedules a macrotask to run after the current event loop task completes.
|
|
110
|
+
* Uses `setTimeout(..., 0)`.
|
|
89
111
|
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* @returns A Promise that resolves immediately after yielding control to the event loop.
|
|
112
|
+
* @returns A Promise that resolves when the macrotask is executed.
|
|
93
113
|
*
|
|
94
114
|
* @example
|
|
95
115
|
* ```typescript
|
|
96
|
-
*
|
|
116
|
+
* console.log('Start');
|
|
117
|
+
* await delay.nextMacrotask();
|
|
118
|
+
* console.log('End - after current task');
|
|
97
119
|
* ```
|
|
98
120
|
*/
|
|
99
|
-
|
|
100
|
-
if (typeof setImmediate !== "function") {
|
|
101
|
-
if (typeof queueMicrotask === "function") {
|
|
102
|
-
return delay.nextMicrotask();
|
|
103
|
-
}
|
|
104
|
-
return delay.by(0);
|
|
105
|
-
}
|
|
106
|
-
return new Promise((resolve) => setImmediate(resolve));
|
|
107
|
-
},
|
|
121
|
+
nextMacrotask: () => new Promise((resolve) => setTimeout(resolve, 0)),
|
|
108
122
|
/**
|
|
109
|
-
*
|
|
123
|
+
* Queues a microtask to run after the current task completes but before the next macrotask.
|
|
110
124
|
*
|
|
111
|
-
* @returns A Promise that resolves when the
|
|
125
|
+
* @returns A Promise that resolves when the microtask is executed.
|
|
112
126
|
*
|
|
113
127
|
* @example
|
|
114
128
|
* ```typescript
|
|
129
|
+
* console.log('Start');
|
|
115
130
|
* await delay.nextMicrotask();
|
|
131
|
+
* console.log('End - immediately after current task');
|
|
116
132
|
* ```
|
|
117
133
|
*/
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return delay.immediate();
|
|
122
|
-
}
|
|
123
|
-
return delay.by(0);
|
|
124
|
-
}
|
|
125
|
-
return new Promise((resolve) => queueMicrotask(resolve));
|
|
126
|
-
}
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
135
|
+
nextMicrotask: () => Promise.resolve().then(() => {
|
|
136
|
+
})
|
|
127
137
|
};
|
|
128
138
|
export {
|
|
129
|
-
delay
|
|
139
|
+
delay,
|
|
140
|
+
requestAnimationFrame,
|
|
141
|
+
requestIdleCallback
|
|
130
142
|
};
|
|
131
143
|
//# sourceMappingURL=main.mjs.map
|
package/dist/main.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts", "../src/polyfill.ts"],
|
|
4
|
-
"sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration, type Duration} from '@alwatr/parse-duration';\n\
|
|
5
|
-
"mappings": ";;;AAAA,SAAQ,qBAAoB;AAC5B,SAAQ,qBAAmC;;;ACD3C,SAAQ,
|
|
4
|
+
"sourcesContent": ["import {packageTracer} from '@alwatr/package-tracer';\nimport {parseDuration, type Duration} from '@alwatr/parse-duration';\n\nimport {requestAnimationFrame, requestIdleCallback} from './polyfill.js';\n\nexport {requestAnimationFrame, requestIdleCallback};\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * A utility module to help manage asynchronous operations and waiting for events or timeouts.\n */\nexport const delay = {\n /**\n * Pauses execution for a specified duration.\n *\n * @param duration The duration to wait. Can be a number in milliseconds or a string like '2s', '100ms'.\n * @returns A Promise that resolves after the specified duration.\n *\n * @example\n * ```typescript\n * await delay.by('1m'); // Wait for 1 minute\n * await delay.by('2s'); // Wait for 2 seconds\n * ```\n */\n by: (duration: Duration): Promise<void> => new Promise((resolve) => setTimeout(resolve, parseDuration(duration))),\n\n /**\n * Pauses execution until the next animation frame.\n *\n * @returns A Promise that resolves with the high-resolution timestamp of the next animation frame.\n *\n * @example\n * ```typescript\n * const timestamp = await delay.animationFrame();\n * console.log(`Next frame at ${timestamp}`);\n * ```\n */\n animationFrame: (): Promise<DOMHighResTimeStamp> => new Promise((resolve) => requestAnimationFrame(resolve)),\n\n /**\n * Pauses execution until the browser is idle.\n *\n * @param timeout An optional maximum duration to wait.\n * @returns A Promise that resolves with an `IdleDeadline` object.\n *\n * @example\n * ```typescript\n * const deadline = await delay.idleCallback({ timeout: 2000 });\n * if (deadline.didTimeout) {\n * console.log('Idle callback timed out.');\n * }\n * ```\n */\n idleCallback: (options?: IdleRequestOptions): Promise<IdleDeadline> => new Promise((resolve) => requestIdleCallback(resolve, options)),\n\n /**\n * Pauses execution until a specific DOM event is dispatched on an element.\n *\n * @param element The HTMLElement to listen on.\n * @param eventName The name of the event to wait for.\n * @param options Optional event listener options.\n * @template T The event map type for the element.\n * @returns A Promise that resolves with the triggered event object.\n *\n * @example\n * ```typescript\n * const button = document.getElementById('my-button');\n * if (button) {\n * const clickEvent = await delay.domEvent(button, 'click');\n * console.log('Button clicked!', clickEvent);\n * }\n * ```\n */\n domEvent: <T extends keyof HTMLElementEventMap>(\n element: HTMLElement,\n eventName: T,\n options: AddEventListenerOptions = {passive: true},\n ): Promise<HTMLElementEventMap[T]> =>\n new Promise((resolve) =>\n element.addEventListener(eventName, resolve, {\n ...options,\n once: true,\n }),\n ),\n\n /**\n * Pauses execution until a specific event is dispatched on any event target.\n *\n * @param target The event target (e.g., window, document, or a custom event emitter).\n * @param eventName The name of the event to wait for.\n * @param options Optional event listener options.\n * @returns A Promise that resolves with the triggered event object.\n *\n * @example\n * ```typescript\n * const resizeEvent = await delay.event(window, 'resize');\n * console.log('Window resized:', resizeEvent);\n * ```\n */\n event: (target: EventTarget, eventName: string, options: AddEventListenerOptions = {passive: true}): Promise<Event> =>\n new Promise((resolve) =>\n target.addEventListener(eventName, resolve, {\n ...options,\n once: true,\n }),\n ),\n\n /**\n * Schedules a macrotask to run after the current event loop task completes.\n * Uses `setTimeout(..., 0)`.\n *\n * @returns A Promise that resolves when the macrotask is executed.\n *\n * @example\n * ```typescript\n * console.log('Start');\n * await delay.nextMacrotask();\n * console.log('End - after current task');\n * ```\n */\n nextMacrotask: (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0)),\n\n /**\n * Queues a microtask to run after the current task completes but before the next macrotask.\n *\n * @returns A Promise that resolves when the microtask is executed.\n *\n * @example\n * ```typescript\n * console.log('Start');\n * await delay.nextMicrotask();\n * console.log('End - immediately after current task');\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n nextMicrotask: (): Promise<void> => Promise.resolve().then(() => {}),\n} as const;\n", "import {getGlobalThis} from '@alwatr/global-this';\n\nconst globalThis = /* #__PURE__ */ getGlobalThis<DictionaryOpt<unknown>>();\n\n/**\n * Ensures compatibility for `requestAnimationFrame` by using the native API\n * available in `globalThis`. If it's not available, it falls back to a `setTimeout`\n * call that aims for a 60 frames per second refresh rate.\n *\n * @param callback The function to call when it's time to update your animation for the next repaint.\n * @returns A long integer value, the request ID, that uniquely identifies the entry in the callback list.\n */\nexport const requestAnimationFrame: (callback: FrameRequestCallback) => number =\n /* #__PURE__ */ globalThis.requestAnimationFrame?.bind(globalThis) ??\n /* #__PURE__ */ ((callback: FrameRequestCallback) => setTimeout(() => callback(performance.now()), 1000 / 60));\n\n/**\n * Ensures compatibility for `requestIdleCallback` by using the native API.\n * If unavailable, it falls back to a `setTimeout` that executes the callback\n * after a short delay, providing a mock `IdleDeadline` object.\n *\n * The mock `IdleDeadline` gives the task a 50ms budget to run.\n *\n * @param callback A reference to a function that should be called in the near future, when the event loop is idle.\n * @param options An optional object with configuration parameters.\n * @returns An ID which can be used to cancel the callback by calling `cancelIdleCallback()`.\n */\nexport const requestIdleCallback: (callback: (deadline: IdleDeadline) => void, options?: IdleRequestOptions) => number =\n /* #__PURE__ */ globalThis.requestIdleCallback?.bind(globalThis) ??\n /* #__PURE__ */ ((\n callback: (deadline: IdleDeadline) => void,\n // options is not used in the fallback but kept for API consistency\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n options?: IdleRequestOptions,\n ) => {\n const startTime = Date.now();\n return setTimeout(() => {\n callback({\n didTimeout: !!options?.timeout,\n timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime)),\n });\n }, options?.timeout ?? 20);\n });\n"],
|
|
5
|
+
"mappings": ";;;AAAA,SAAQ,qBAAoB;AAC5B,SAAQ,qBAAmC;;;ACD3C,SAAQ,qBAAoB;AAE5B,IAAM,aAA6B,8BAAsC;AAUlE,IAAM,wBACK,2BAAW,uBAAuB,KAAK,UAAU,MAChD,CAAC,aAAmC,WAAW,MAAM,SAAS,YAAY,IAAI,CAAC,GAAG,MAAO,EAAE;AAavG,IAAM,sBACK,2BAAW,qBAAqB,KAAK,UAAU,MAC9C,CACf,UAGA,YACG;AACH,QAAM,YAAY,KAAK,IAAI;AAC3B,SAAO,WAAW,MAAM;AACtB,aAAS;AAAA,MACP,YAAY,CAAC,CAAC,SAAS;AAAA,MACvB,eAAe,MAAM,KAAK,IAAI,GAAG,MAAM,KAAK,IAAI,IAAI,UAAU;AAAA,IAChE,CAAC;AAAA,EACH,GAAG,SAAS,WAAW,EAAE;AAC3B;;;ADnCF,aAAc,eAAc,IAAI,iBAAkB,OAAmB;AAK9D,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAanB,IAAI,CAAC,aAAsC,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAahH,gBAAgB,MAAoC,IAAI,QAAQ,CAAC,YAAY,sBAAsB,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB3G,cAAc,CAAC,YAAwD,IAAI,QAAQ,CAAC,YAAY,oBAAoB,SAAS,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBrI,UAAU,CACR,SACA,WACA,UAAmC,EAAC,SAAS,KAAI,MAEjD,IAAI;AAAA,IAAQ,CAAC,YACX,QAAQ,iBAAiB,WAAW,SAAS;AAAA,MAC3C,GAAG;AAAA,MACH,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBF,OAAO,CAAC,QAAqB,WAAmB,UAAmC,EAAC,SAAS,KAAI,MAC/F,IAAI;AAAA,IAAQ,CAAC,YACX,OAAO,iBAAiB,WAAW,SAAS;AAAA,MAC1C,GAAG;AAAA,MACH,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeF,eAAe,MAAqB,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAenF,eAAe,MAAqB,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAAA,EAAC,CAAC;AACrE;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/polyfill.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Ensures compatibility for `requestAnimationFrame` by using the native API
|
|
3
|
+
* available in `globalThis`. If it's not available, it falls back to a `setTimeout`
|
|
4
|
+
* call that aims for a 60 frames per second refresh rate.
|
|
5
|
+
*
|
|
6
|
+
* @param callback The function to call when it's time to update your animation for the next repaint.
|
|
7
|
+
* @returns A long integer value, the request ID, that uniquely identifies the entry in the callback list.
|
|
8
|
+
*/
|
|
9
|
+
export declare const requestAnimationFrame: (callback: FrameRequestCallback) => number;
|
|
10
|
+
/**
|
|
11
|
+
* Ensures compatibility for `requestIdleCallback` by using the native API.
|
|
12
|
+
* If unavailable, it falls back to a `setTimeout` that executes the callback
|
|
13
|
+
* after a short delay, providing a mock `IdleDeadline` object.
|
|
14
|
+
*
|
|
15
|
+
* The mock `IdleDeadline` gives the task a 50ms budget to run.
|
|
16
|
+
*
|
|
17
|
+
* @param callback A reference to a function that should be called in the near future, when the event loop is idle.
|
|
18
|
+
* @param options An optional object with configuration parameters.
|
|
19
|
+
* @returns An ID which can be used to cancel the callback by calling `cancelIdleCallback()`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const requestIdleCallback: (callback: (deadline: IdleDeadline) => void, options?: IdleRequestOptions) => number;
|
|
5
22
|
//# sourceMappingURL=polyfill.d.ts.map
|
package/dist/polyfill.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,MAEwC,CAAC;AAEjH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,kBAAkB,KAAK,MAe5G,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwatr/delay",
|
|
3
3
|
"description": "Comprehensive toolkit for managing asynchronous operations.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "6.0.0",
|
|
5
5
|
"author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
|
|
6
6
|
"bugs": "https://github.com/Alwatr/nanolib/issues",
|
|
7
7
|
"dependencies": {
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
},
|
|
78
78
|
"type": "module",
|
|
79
79
|
"types": "./dist/main.d.ts",
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "5d7482af60778578d7adedf6b89a9f938e6cd776"
|
|
81
81
|
}
|