time-queues 1.0.4 → 1.1.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/README.md +27 -294
- package/package.json +16 -4
- package/src/FrameQueue.d.ts +71 -0
- package/src/FrameQueue.js +2 -0
- package/src/IdleQueue.d.ts +83 -0
- package/src/IdleQueue.js +2 -0
- package/src/ListQueue.d.ts +77 -0
- package/src/ListQueue.js +3 -1
- package/src/MicroTask.d.ts +17 -0
- package/src/MicroTask.js +2 -0
- package/src/MicroTaskQueue.d.ts +63 -0
- package/src/MicroTaskQueue.js +2 -0
- package/src/PageWatcher.d.ts +82 -0
- package/src/PageWatcher.js +2 -0
- package/src/Retainer.d.ts +47 -0
- package/src/Retainer.js +48 -0
- package/src/Scheduler.d.ts +94 -0
- package/src/Scheduler.js +11 -3
- package/src/Throttler.d.ts +79 -0
- package/src/Throttler.js +71 -0
- package/src/audit.d.ts +15 -0
- package/src/audit.js +20 -0
- package/src/debounce.d.ts +14 -0
- package/src/debounce.js +16 -0
- package/src/defer.d.ts +13 -0
- package/src/defer.js +2 -0
- package/src/sample.d.ts +17 -0
- package/src/sample.js +25 -0
- package/src/sleep.d.ts +9 -0
- package/src/sleep.js +13 -0
- package/src/throttle.d.ts +15 -0
- package/src/throttle.js +14 -0
- package/src/when-dom-loaded.d.ts +17 -0
- package/src/when-dom-loaded.js +4 -2
- package/src/when-loaded.d.ts +17 -0
- package/src/when-loaded.js +4 -2
package/README.md
CHANGED
|
@@ -3,45 +3,18 @@
|
|
|
3
3
|
[npm-img]: https://img.shields.io/npm/v/time-queues.svg
|
|
4
4
|
[npm-url]: https://npmjs.org/package/time-queues
|
|
5
5
|
|
|
6
|
-
`time-queues` is an efficient library for organizing asynchronous multitasking and scheduled tasks.
|
|
7
|
-
It can be used in a browser and in server-side environments like `Node`, `Deno` and `Bun`.
|
|
8
|
-
It depends only on [list-toolkit](https://github.com/uhop/list-toolkit), which is a no-dependency library for efficient task queues.
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
`time-queues` is an efficient, lightweight library for organizing asynchronous multitasking and scheduled tasks in JavaScript applications. It works seamlessly in browsers and server-side environments like Node.js, Deno, and Bun.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
* **Scheduler**: a `MinHeap`-based task queue that schedules time-based tasks in the future.
|
|
14
|
-
* **repeat()**: a function that creates a repeatable task.
|
|
15
|
-
* **defer()**: a function that executes a task at a later time in the next tick.
|
|
16
|
-
* Browsers:
|
|
17
|
-
* Efficient multitasking:
|
|
18
|
-
* **IdleQueue**: a task queue that executes tasks in the next idle period.
|
|
19
|
-
* Based on [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback).
|
|
20
|
-
* **defer()**: a function that executes a task at a later time in the next idle period.
|
|
21
|
-
* **FrameQueue**: a task queue that executes tasks in the next frame.
|
|
22
|
-
* Based on [requestAnimationFrame()](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
|
|
23
|
-
* Page state management:
|
|
24
|
-
* **PageWatcher**: a task queue that executes tasks when the page state changes.
|
|
25
|
-
* **watchStates()**: a helper that pauses and resumes queues when the page state changes.
|
|
26
|
-
* **whenDomLoaded()**: a helper that executes tasks when the DOM is loaded.
|
|
27
|
-
* **whenLoaded()**: a helper that executes tasks when the page is loaded.
|
|
9
|
+
The library provides elegant solutions for common timing and scheduling challenges, helping developers create responsive, efficient applications that follow best practices for resource management and user experience.
|
|
28
10
|
|
|
29
|
-
|
|
11
|
+
## Key Features
|
|
30
12
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
There are many articles on the subject that detail how to leverage the APIs writing efficient applications.
|
|
38
|
-
Some of them are:
|
|
39
|
-
|
|
40
|
-
* [Background Tasks API](https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API)
|
|
41
|
-
* [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)
|
|
42
|
-
* [Page Lifecycle API](https://developer.chrome.com/docs/web-platform/page-lifecycle-api)
|
|
43
|
-
|
|
44
|
-
This package eliminates the need to write code that you'll write anyway following best practices.
|
|
13
|
+
- **Efficient Task Scheduling**: Schedule tasks to run at specific times or after delays
|
|
14
|
+
- **Browser Performance Optimization**: Execute tasks during idle periods or animation frames
|
|
15
|
+
- **Page Lifecycle Management**: Respond intelligently to page visibility and focus changes
|
|
16
|
+
- **Resource Management**: Control execution rates with throttling and debouncing
|
|
17
|
+
- **Minimal Dependencies**: Relies only on [list-toolkit](https://www.npmjs.com/package/list-toolkit), a zero-dependency library
|
|
45
18
|
|
|
46
19
|
## Installation
|
|
47
20
|
|
|
@@ -52,277 +25,35 @@ npm install time-queues
|
|
|
52
25
|
If you want to check out the source code, you can use the following command:
|
|
53
26
|
|
|
54
27
|
```sh
|
|
55
|
-
git clone https://github.com/uhop/time-queues.git
|
|
28
|
+
git clone --recurse-submodules https://github.com/uhop/time-queues.git
|
|
56
29
|
cd time-queues
|
|
57
30
|
npm install
|
|
58
31
|
```
|
|
59
32
|
|
|
60
|
-
Don't forget to look at a test web application that uses the library. For that you should start a server:
|
|
61
|
-
|
|
62
|
-
```sh
|
|
63
|
-
npm start
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
And navigate to [http://localhost:3000/tests/web/](http://localhost:3000/tests/web/) —
|
|
67
|
-
don't forget to open the console and play around: switch tabs, make other window active,
|
|
68
|
-
navigate away and come back, and so on.
|
|
69
|
-
See how queues work in [tests/web/test.js](https://github.com/uhop/time-queues/blob/main/tests/web/test.js).
|
|
70
|
-
|
|
71
33
|
## Usage
|
|
72
34
|
|
|
73
|
-
The full documentation is available in the project's [wiki](https://github.com/uhop/time-queues/wiki). Below is
|
|
74
|
-
|
|
75
|
-
### ListQueue
|
|
76
|
-
|
|
77
|
-
`ListQueue` is a list-based task queue that executes tasks in the order they were added.
|
|
78
|
-
It serves as a base class for other task queues. The following methods are available:
|
|
79
|
-
|
|
80
|
-
| Method | Description |
|
|
81
|
-
|:---|:---|
|
|
82
|
-
| `ListQueue(paused)` | Create a new list queue (paused optionally). |
|
|
83
|
-
| `isEmpty` | Check if the list queue is empty. |
|
|
84
|
-
| `pause()` | Pause the list queue. |
|
|
85
|
-
| `resume()` | Resume the list queue. |
|
|
86
|
-
| `enqueue(fn)` | Schedule a function to be executed. Returns the task. |
|
|
87
|
-
| `dequeue(task)` | Remove a task from the list queue. |
|
|
88
|
-
| `clear()` | Remove all tasks from the list queue. |
|
|
89
|
-
|
|
90
|
-
Subclasses should implement `startQueue()`.
|
|
35
|
+
The full documentation is available in the project's [wiki](https://github.com/uhop/time-queues/wiki). Below is the most important parts of the documentation:
|
|
91
36
|
|
|
92
|
-
###
|
|
37
|
+
### Resource Management
|
|
93
38
|
|
|
94
|
-
|
|
95
|
-
|
|
39
|
+
- [Scheduler](https://github.com/uhop/time-queues/wiki/Scheduler): Time-based task scheduling
|
|
40
|
+
- [Retainer](https://github.com/uhop/time-queues/wiki/Retainer): Manage resource lifecycle
|
|
41
|
+
- [Throttler](https://github.com/uhop/time-queues/wiki/Throttler): Control execution rate based on keys
|
|
96
42
|
|
|
97
|
-
|
|
98
|
-
The following additional methods are available:
|
|
43
|
+
### Browser-Specific Components
|
|
99
44
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
| `nextTime` | Get the next scheduled time or 'Infinity` if the scheduler is empty. |
|
|
104
|
-
| `enqueue(fn, time)` | Schedule a function to be executed at a later time. Returns the task. `time` can be a date or a number in milliseconds from now. |
|
|
105
|
-
|
|
106
|
-
Scheduled functions are called once with the following arguments:
|
|
107
|
-
|
|
108
|
-
* `fn(task, scheduler)`, where:
|
|
109
|
-
* `fn` — the scheduled function.
|
|
110
|
-
* `task` — the task object that corresponds to the scheduled function.
|
|
111
|
-
* `scheduler` — the scheduler object.
|
|
112
|
-
|
|
113
|
-
The return value is ignored.
|
|
114
|
-
|
|
115
|
-
The module provides a singleton ready to be used:
|
|
116
|
-
|
|
117
|
-
```js
|
|
118
|
-
import scheduler, {repeat} from 'time-queues/Scheduler.js';
|
|
119
|
-
|
|
120
|
-
// schedule a task
|
|
121
|
-
const task = scheduler.enqueue(() => console.log('The first task'), 1000);
|
|
122
|
-
|
|
123
|
-
// run a task every second
|
|
124
|
-
const hello = () => {
|
|
125
|
-
console.log('Hello, world!');
|
|
126
|
-
scheduler.enqueue(hello, 1000);
|
|
127
|
-
};
|
|
128
|
-
scheduler.enqueue(hello, 1000);
|
|
129
|
-
|
|
130
|
-
// pause the scheduler
|
|
131
|
-
scheduler.pause();
|
|
132
|
-
|
|
133
|
-
// remove the first task
|
|
134
|
-
scheduler.dequeue(task);
|
|
135
|
-
|
|
136
|
-
// remove all tasks
|
|
137
|
-
scheduler.clear();
|
|
138
|
-
```
|
|
45
|
+
- [IdleQueue](https://github.com/uhop/time-queues/wiki/IdleQueue): Execute tasks during browser idle periods
|
|
46
|
+
- [FrameQueue](https://github.com/uhop/time-queues/wiki/FrameQueue): Execute tasks during animation frames
|
|
47
|
+
- [PageWatcher](https://github.com/uhop/time-queues/wiki/PageWatcher): Monitor and respond to page lifecycle changes
|
|
139
48
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
The module provides a helper function `repeat()` that creates a repeatable task:
|
|
143
|
-
|
|
144
|
-
* `repeat(fn, interval)`, where:
|
|
145
|
-
* `fn` — the scheduled function.
|
|
146
|
-
* `interval` — the interval in milliseconds. If not specified the corresponding task delay is used.
|
|
147
|
-
|
|
148
|
-
We can rewrite the above example using `repeat()`:
|
|
149
|
-
|
|
150
|
-
```js
|
|
151
|
-
// run a task every second
|
|
152
|
-
scheduler.enqueue(repeat(() => console.log('Hello, world!'), 1000));
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### defer()
|
|
156
|
-
|
|
157
|
-
`defer(fn)` is a function that executes an argument function at a later time in the next tick.
|
|
158
|
-
|
|
159
|
-
Deferred functions are called with no arguments. The return value is ignored.
|
|
160
|
-
|
|
161
|
-
```js
|
|
162
|
-
import defer from 'time-queues/defer.js';
|
|
163
|
-
|
|
164
|
-
// run a task in the next tick
|
|
165
|
-
defer(() => console.log('Goodbye, world!'));
|
|
166
|
-
|
|
167
|
-
// run code now
|
|
168
|
-
console.log('Hello, world!');
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### IdleQueue
|
|
172
|
-
|
|
173
|
-
`IdleQueue` is a task queue that executes tasks in the next idle period. It implements `ListQueue` and is based on [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback).
|
|
174
|
-
|
|
175
|
-
Efficient web applications should use `IdleQueue` to schedule computations required to prepare data and
|
|
176
|
-
even create necessary DOM elements.
|
|
177
|
-
See [Background Tasks API](https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API) for more information.
|
|
178
|
-
|
|
179
|
-
Queued functions are called once with the following arguments:
|
|
180
|
-
|
|
181
|
-
* `fn(deadline, task, idleQueue)`, where:
|
|
182
|
-
* `fn` — the scheduled function.
|
|
183
|
-
* `deadline` — the deadline object. See [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) for more information.
|
|
184
|
-
* `task` — the task object that corresponds to the scheduled function.
|
|
185
|
-
* `idleQueue` — the idle queue object.
|
|
186
|
-
|
|
187
|
-
The return value is ignored.
|
|
188
|
-
|
|
189
|
-
The module provides a singleton ready to be used:
|
|
190
|
-
|
|
191
|
-
```js
|
|
192
|
-
import idleQueue from 'time-queues/IdleQueue.js';
|
|
193
|
-
import frameQueue from 'time-queues/FrameQueue.js';
|
|
194
|
-
|
|
195
|
-
idleQueue.enqueue(() => {
|
|
196
|
-
// prepare our data and generate DOM
|
|
197
|
-
const div = document.createElement('div');
|
|
198
|
-
div.appendChild(document.createTextNode('Hello, world!'));
|
|
199
|
-
// now update the DOM in the next frame
|
|
200
|
-
frameQueue.enqueue(() => document.body.appendChild(div));
|
|
201
|
-
});
|
|
202
|
-
```
|
|
49
|
+
### Utility Functions
|
|
203
50
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
Queued functions are called once with the following arguments:
|
|
212
|
-
|
|
213
|
-
* `fn(timeStamp, task, frameQueue)`, where:
|
|
214
|
-
* `fn` — the scheduled function.
|
|
215
|
-
* `timeStamp` — the timestamp object. See [requestAnimationFrame()](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) for more information.
|
|
216
|
-
* `task` — the task object that corresponds to the scheduled function.
|
|
217
|
-
* `frameQueue` — the frame queue object.
|
|
218
|
-
|
|
219
|
-
The return value is ignored.
|
|
220
|
-
|
|
221
|
-
The module provides a singleton ready to be used. See the code snippet `IdleQueue` above for more information.
|
|
222
|
-
|
|
223
|
-
### PageWatcher
|
|
224
|
-
|
|
225
|
-
`PageWatcher` is a task queue that executes tasks when the page state changes. It is based on [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API).
|
|
226
|
-
You can find more information in [Page Lifecycle API](https://developer.chrome.com/docs/web-platform/page-lifecycle-api).
|
|
227
|
-
|
|
228
|
-
Efficient web applications should use `PageWatcher` to watch for page visibility changes and react accordingly, for example, by suspending updates in the hidden state.
|
|
229
|
-
|
|
230
|
-
`PageWatcher` implements `ListQueue`. The following additional/changed methods are available:
|
|
231
|
-
|
|
232
|
-
| Method | Description |
|
|
233
|
-
|:---|:---|
|
|
234
|
-
| `PageWatcher(started)` | Create a new page watcher (started optionally). |
|
|
235
|
-
| `currentState` | Get the current page state (see below). |
|
|
236
|
-
| `enqueue(fn, initialize)` | Schedule a function to be executed. Returns the task. If `initialize` is truthy, the function will be queued and called immediately with the current state. |
|
|
237
|
-
|
|
238
|
-
A page state can be one of the following strings:
|
|
239
|
-
|
|
240
|
-
* `active` — the page is a current window, it is visible and the user can interact with it.
|
|
241
|
-
* `passive` — the page is not a current window, it is visible, but the user cannot interact with it.
|
|
242
|
-
* `hidden` — the page is not visible.
|
|
243
|
-
* `frozen` — the page is suspended, no timers nor fetch callbacks can be executed.
|
|
244
|
-
* `terminated` — the page is terminated, no new tasks can be started.
|
|
245
|
-
|
|
246
|
-
Queued functions are called on every state change with the following arguments:
|
|
247
|
-
|
|
248
|
-
* `fn(state, previousState, task, pageWatcher)`, where:
|
|
249
|
-
* 'fn` — the scheduled function.
|
|
250
|
-
* `state` — the new page state.
|
|
251
|
-
* `previousState` — the previous page state.
|
|
252
|
-
* `task` — the task object that corresponds to the scheduled function.
|
|
253
|
-
* `pageWatcher` — the page watcher object.
|
|
254
|
-
|
|
255
|
-
The return value is ignored.
|
|
256
|
-
|
|
257
|
-
The module provides a singleton ready to be used.
|
|
258
|
-
|
|
259
|
-
```js
|
|
260
|
-
import pageWatcher from 'time-queues/PageWatcher.js';
|
|
261
|
-
|
|
262
|
-
pageWatcher.enqueue(state => console.log('state:', state), true);
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
#### watchStates()
|
|
266
|
-
|
|
267
|
-
`watchStates()` is a helper that pauses and resumes queues when the page state changes.
|
|
268
|
-
It can be added to a `PageWatcher` object controlling a `Scheduler` object or any other queue
|
|
269
|
-
to pause it depending on a page state.
|
|
270
|
-
|
|
271
|
-
The function signature is:
|
|
272
|
-
|
|
273
|
-
* `watchStates(queue, resumeStatesList = ['active'])`, where:
|
|
274
|
-
* `queue` — the queue object to be controlled.
|
|
275
|
-
* `resumeStatesList` — the iterable of page states to `resume()`. All other states will pause the queue. Defaults to 'active'.
|
|
276
|
-
|
|
277
|
-
The return value is a function that is suitable for `PageWatcher.enqueue()`.
|
|
278
|
-
|
|
279
|
-
```js
|
|
280
|
-
import pageWatcher, {watchStates} from 'time-queues/PageWatcher.js';
|
|
281
|
-
import scheduler from 'time-queues/Scheduler.js';
|
|
282
|
-
|
|
283
|
-
// do not process time-based tasks when the page is not visible
|
|
284
|
-
pageWatcher.enqueue(watchStates(scheduler, ['active', 'passive']), true);
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### whenDomLoaded()
|
|
288
|
-
|
|
289
|
-
`whenDomLoaded()` is a helper that executes a function when the DOM is loaded.
|
|
290
|
-
If the DOM is already loaded, the function will be executed with `queueMicrotask()`.
|
|
291
|
-
Otherwise it'll be queued and executed when the DOM is loaded.
|
|
292
|
-
See [DOMContentLoaded](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event) for more information.
|
|
293
|
-
|
|
294
|
-
The function signature is:
|
|
295
|
-
|
|
296
|
-
* `whenDomLoaded(fn)`, where:
|
|
297
|
-
* `fn` — the function to be executed when the DOM is loaded.
|
|
298
|
-
|
|
299
|
-
It will be called with no arguments. The return value is ignored.
|
|
300
|
-
|
|
301
|
-
```js
|
|
302
|
-
import whenDomLoaded from 'time-queues/whenDomLoaded.js';
|
|
303
|
-
|
|
304
|
-
whenDomLoaded(() => console.log('The DOM is loaded'));
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### whenLoaded()
|
|
308
|
-
|
|
309
|
-
`whenLoaded()` is a helper that executes a function when the page is fully loaded.
|
|
310
|
-
If the page is already loaded, the function will be executed with `queueMicrotask()`.
|
|
311
|
-
Otherwise it'll be queued and executed when the page is loaded.
|
|
312
|
-
See [load](https://developer.mozilla.org/en-US/docs/Web/Events/load) for more information.
|
|
313
|
-
|
|
314
|
-
The function signature is:
|
|
315
|
-
|
|
316
|
-
* `whenLoaded(fn)`, where:
|
|
317
|
-
* `fn` — the function to be executed when the page is loaded.
|
|
318
|
-
|
|
319
|
-
It will be called with no arguments. The return value is ignored.
|
|
320
|
-
|
|
321
|
-
```js
|
|
322
|
-
import whenLoaded from 'time-queues/whenLoaded.js';
|
|
323
|
-
|
|
324
|
-
whenLoaded(() => console.log('The page is loaded'));
|
|
325
|
-
```
|
|
51
|
+
- [defer()](<https://github.com/uhop/time-queues/wiki/defer()>): Execute tasks in the next tick
|
|
52
|
+
- [sleep()](<https://github.com/uhop/time-queues/wiki/sleep()>): Promise-based delay function
|
|
53
|
+
- [throttle()](<https://github.com/uhop/time-queues/wiki/throttle()>): Limit function execution rate
|
|
54
|
+
- [debounce()](<https://github.com/uhop/time-queues/wiki/debounce()>): Delay function execution until input stabilizes
|
|
55
|
+
- [sample()](<https://github.com/uhop/time-queues/wiki/sample()>): Execute function at regular intervals
|
|
56
|
+
- [audit()](<https://github.com/uhop/time-queues/wiki/audit()>): Execute function after specified delay
|
|
326
57
|
|
|
327
58
|
## License
|
|
328
59
|
|
|
@@ -330,6 +61,8 @@ This project is licensed under the BSD-3-Clause License.
|
|
|
330
61
|
|
|
331
62
|
## Release History
|
|
332
63
|
|
|
64
|
+
* 1.1.0 *Added `Throttler`, `Retainer`, promise-based convenience time methods.*
|
|
65
|
+
* 1.0.5 *Technical release: updated deps, more tests.*
|
|
333
66
|
* 1.0.4 *Bug fixes and code simplifications.*
|
|
334
67
|
* 1.0.3 *Updated deps (`list-toolkit`) to fix a minor bug.*
|
|
335
68
|
* 1.0.2 *Updated deps (`list-toolkit`).*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "time-queues",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Time queues to organize multitasking and scheduled tasks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
"test:bun": "tape6-bun --flags FO",
|
|
12
12
|
"test:deno-original": "tape6-deno --flags FO",
|
|
13
13
|
"test:deno": "deno run -A `tape6-runner main` --flags FO",
|
|
14
|
+
"test:proc": "tape6-proc --flags FO",
|
|
15
|
+
"test:proc:bun": "bun run `npx tape6-proc --self` --flags FO",
|
|
16
|
+
"test:proc:deno": "deno run -A `npx tape6-proc --self` --flags FO --runFileArgs -A",
|
|
17
|
+
"ts-check": "tsc --noEmit",
|
|
18
|
+
"lint": "prettier --check src/ tests/ wiki/",
|
|
19
|
+
"lint:fix": "prettier --write src/ tests/ wiki/",
|
|
14
20
|
"start": "tape6-server --trace"
|
|
15
21
|
},
|
|
16
22
|
"repository": {
|
|
@@ -30,7 +36,9 @@
|
|
|
30
36
|
},
|
|
31
37
|
"homepage": "https://github.com/uhop/time-queues#readme",
|
|
32
38
|
"files": [
|
|
33
|
-
"/src"
|
|
39
|
+
"/src",
|
|
40
|
+
"LICENSE",
|
|
41
|
+
"README.md"
|
|
34
42
|
],
|
|
35
43
|
"tape6": {
|
|
36
44
|
"tests": [
|
|
@@ -39,14 +47,18 @@
|
|
|
39
47
|
"importmap": {
|
|
40
48
|
"imports": {
|
|
41
49
|
"tape-six": "/node_modules/tape-six/index.js",
|
|
50
|
+
"list-toolkit/": "/node_modules/list-toolkit/src/",
|
|
42
51
|
"time-queues/": "/src/"
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
},
|
|
46
55
|
"devDependencies": {
|
|
47
|
-
"
|
|
56
|
+
"@types/node": "^22.13.10",
|
|
57
|
+
"tape-six": "^1.0.3",
|
|
58
|
+
"tape-six-proc": "^1.0.1",
|
|
59
|
+
"typescript": "^5.8.2"
|
|
48
60
|
},
|
|
49
61
|
"dependencies": {
|
|
50
|
-
"list-toolkit": "^2.
|
|
62
|
+
"list-toolkit": "^2.2.1"
|
|
51
63
|
}
|
|
52
64
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {ListQueue, Task} from './ListQueue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A queue based on [requestAnimationFrame()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame).
|
|
5
|
+
* Used in an animation loop or for drawing updates.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FrameQueue extends ListQueue {
|
|
8
|
+
/**
|
|
9
|
+
* The batch size in milliseconds for running tasks.
|
|
10
|
+
* If `undefined`, all tasks are run in a single frame.
|
|
11
|
+
*/
|
|
12
|
+
batch: number | undefined;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new frame queue.
|
|
16
|
+
* @param paused Whether the queue should start paused.
|
|
17
|
+
* @param batchInMs The batch size in milliseconds.
|
|
18
|
+
*/
|
|
19
|
+
constructor(paused: boolean = false, batchInMs?: number);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether the queue is empty.
|
|
23
|
+
*/
|
|
24
|
+
get isEmpty(): boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Enqueues a task.
|
|
28
|
+
* @param fn The function to execute.
|
|
29
|
+
* @returns The task object.
|
|
30
|
+
*/
|
|
31
|
+
enqueue(fn: (timeStamp: number, task: Task, queue: FrameQueue) => void): Task;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Dequeues a task.
|
|
35
|
+
* @param task The task to dequeue.
|
|
36
|
+
* @returns The queue.
|
|
37
|
+
*/
|
|
38
|
+
dequeue(task: Task): this;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Clears the queue.
|
|
42
|
+
* @returns The queue.
|
|
43
|
+
*/
|
|
44
|
+
clear(): this;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Pauses the queue.
|
|
48
|
+
* @returns The queue.
|
|
49
|
+
*/
|
|
50
|
+
pause(): this;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Resumes the queue.
|
|
54
|
+
* @returns The queue.
|
|
55
|
+
*/
|
|
56
|
+
resume(): this;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Starts the queue.
|
|
60
|
+
* It is used internally by `resume()`.
|
|
61
|
+
* @returns The function that stops the queue.
|
|
62
|
+
*/
|
|
63
|
+
startQueue(): (() => void) | null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* The default frame queue usually used as a global queue.
|
|
68
|
+
*/
|
|
69
|
+
export const frameQueue: FrameQueue;
|
|
70
|
+
|
|
71
|
+
export default FrameQueue;
|
package/src/FrameQueue.js
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {ListQueue, Task} from './ListQueue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A queue based on [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback).
|
|
5
|
+
* Used for background tasks.
|
|
6
|
+
*/
|
|
7
|
+
export declare class IdleQueue extends ListQueue {
|
|
8
|
+
/**
|
|
9
|
+
* The timeout batch size in milliseconds for running tasks.
|
|
10
|
+
* If `undefined`, all tasks are run in a single idle period.
|
|
11
|
+
* This timeout is used only when `deadline.didTimeout` passed by `requestIdleCallback()` is `true`.
|
|
12
|
+
*/
|
|
13
|
+
timeoutBatch: number | undefined;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The options passed to `requestIdleCallback()`.
|
|
17
|
+
*/
|
|
18
|
+
options: IdleCallbackOptions | undefined;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new idle queue.
|
|
22
|
+
* @param paused Whether the queue should start paused.
|
|
23
|
+
* @param timeoutBatchInMs The timeout batch size in milliseconds.
|
|
24
|
+
* @param options The options passed to `requestIdleCallback()`.
|
|
25
|
+
*/
|
|
26
|
+
constructor(paused: boolean = false, timeoutBatchInMs?: number, options?: IdleCallbackOptions);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether the queue is empty.
|
|
30
|
+
*/
|
|
31
|
+
get isEmpty(): boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Enqueues a task.
|
|
35
|
+
* @param fn The function to execute.
|
|
36
|
+
* @returns The task object.
|
|
37
|
+
*/
|
|
38
|
+
enqueue(fn: (deadline: IdleDeadline, task: Task, queue: IdleQueue) => void): Task;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Dequeues a task.
|
|
42
|
+
* @param task The task to dequeue.
|
|
43
|
+
* @returns The queue.
|
|
44
|
+
*/
|
|
45
|
+
dequeue(task: Task): this;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Clears the queue.
|
|
49
|
+
* @returns The queue.
|
|
50
|
+
*/
|
|
51
|
+
clear(): this;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Pauses the queue.
|
|
55
|
+
* @returns The queue.
|
|
56
|
+
*/
|
|
57
|
+
pause(): this;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Resumes the queue.
|
|
61
|
+
* @returns The queue.
|
|
62
|
+
*/
|
|
63
|
+
resume(): this;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Starts the queue.
|
|
67
|
+
* It is used internally by `resume()`.
|
|
68
|
+
* @returns The function that stops the queue.
|
|
69
|
+
*/
|
|
70
|
+
startQueue(): (() => void) | null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The default idle queue usually used as a global queue.
|
|
75
|
+
*/
|
|
76
|
+
export const idleQueue: IdleQueue;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A function that schedules a task to run in the next idle period.
|
|
80
|
+
*/
|
|
81
|
+
export const defer: (fn: (deadline: IdleDeadline, task: Task, queue: IdleQueue) => void) => Task;
|
|
82
|
+
|
|
83
|
+
export default IdleQueue;
|
package/src/IdleQueue.js
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {MicroTask} from './MicroTask';
|
|
2
|
+
import {List} from 'list-toolkit';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A list-based queue of microtasks that will be executed when scheduled.
|
|
6
|
+
* It is a base class for other list-based task queues.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ListQueue extends MicroTaskQueue {
|
|
9
|
+
/**
|
|
10
|
+
* The list of tasks.
|
|
11
|
+
*/
|
|
12
|
+
list: List<MicroTask>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The function that stops the queue.
|
|
16
|
+
* It is used internally by `pause()` and `resume()`.
|
|
17
|
+
*/
|
|
18
|
+
stopQueue: (() => void) | null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new list queue.
|
|
22
|
+
* @param paused Whether the queue should start paused.
|
|
23
|
+
*/
|
|
24
|
+
constructor(paused: boolean);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Whether the queue is empty.
|
|
28
|
+
*/
|
|
29
|
+
get isEmpty(): boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Enqueues a microtask.
|
|
33
|
+
* @param fn The function to execute when the microtask is scheduled.
|
|
34
|
+
* @returns The enqueued microtask.
|
|
35
|
+
*/
|
|
36
|
+
enqueue(fn: () => void): MicroTask;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Dequeues a microtask.
|
|
40
|
+
* @param task The microtask to dequeue.
|
|
41
|
+
* @returns The queue.
|
|
42
|
+
*/
|
|
43
|
+
dequeue(task: MicroTask): this;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Clears the queue.
|
|
47
|
+
* @returns The queue.
|
|
48
|
+
*/
|
|
49
|
+
clear(): this;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Pauses the queue.
|
|
53
|
+
* @returns The queue.
|
|
54
|
+
*/
|
|
55
|
+
pause(): this;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resumes the queue.
|
|
59
|
+
* @returns The queue.
|
|
60
|
+
*/
|
|
61
|
+
resume(): this;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Starts the queue.
|
|
65
|
+
* It is used internally by `resume()`.
|
|
66
|
+
* It is meant to be overridden in subclasses.
|
|
67
|
+
* @returns The function that stops the queue.
|
|
68
|
+
*/
|
|
69
|
+
startQueue(): (() => void) | null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A task for list queues.
|
|
74
|
+
*/
|
|
75
|
+
export declare type Task = MicroTask;
|
|
76
|
+
|
|
77
|
+
export default ListQueue;
|
package/src/ListQueue.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// @ts-self-types="./ListQueue.d.ts"
|
|
2
|
+
|
|
1
3
|
'use strict';
|
|
2
4
|
|
|
3
5
|
import List from 'list-toolkit/list.js';
|
|
@@ -40,7 +42,7 @@ export class ListQueue extends MicroTaskQueue {
|
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
dequeue(task) {
|
|
43
|
-
|
|
45
|
+
this.list.removeNode(task);
|
|
44
46
|
if (!this.paused && this.list.isEmpty && this.stopQueue)
|
|
45
47
|
this.stopQueue = (this.stopQueue(), null);
|
|
46
48
|
return this;
|