time-queues 1.2.4 → 1.3.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 (49) hide show
  1. package/README.md +117 -36
  2. package/llms-full.txt +430 -0
  3. package/llms.txt +95 -0
  4. package/package.json +43 -12
  5. package/src/CancelTaskError.d.ts +2 -1
  6. package/src/CancelTaskError.js +2 -4
  7. package/src/Counter.d.ts +0 -1
  8. package/src/Counter.js +0 -2
  9. package/src/FrameQueue.d.ts +2 -2
  10. package/src/FrameQueue.js +0 -2
  11. package/src/IdleQueue.d.ts +2 -2
  12. package/src/IdleQueue.js +0 -2
  13. package/src/LimitedQueue.d.ts +104 -0
  14. package/src/LimitedQueue.js +78 -0
  15. package/src/ListQueue.d.ts +1 -6
  16. package/src/ListQueue.js +18 -3
  17. package/src/MicroTask.d.ts +7 -1
  18. package/src/MicroTask.js +47 -15
  19. package/src/MicroTaskQueue.d.ts +24 -20
  20. package/src/MicroTaskQueue.js +22 -7
  21. package/src/PageWatcher.d.ts +2 -2
  22. package/src/PageWatcher.js +0 -2
  23. package/src/Retainer.d.ts +4 -4
  24. package/src/Retainer.js +0 -2
  25. package/src/Scheduler.d.ts +23 -17
  26. package/src/Scheduler.js +1 -2
  27. package/src/Throttler.d.ts +7 -2
  28. package/src/Throttler.js +1 -2
  29. package/src/audit.js +0 -2
  30. package/src/batch.d.ts +16 -0
  31. package/src/batch.js +40 -0
  32. package/src/debounce.js +0 -2
  33. package/src/defer.d.ts +3 -4
  34. package/src/defer.js +0 -2
  35. package/src/index.d.ts +7 -2
  36. package/src/random-dist.d.ts +31 -0
  37. package/src/random-dist.js +27 -0
  38. package/src/random-sleep.d.ts +57 -0
  39. package/src/random-sleep.js +27 -0
  40. package/src/sample.d.ts +1 -1
  41. package/src/sample.js +0 -2
  42. package/src/sleep.d.ts +1 -1
  43. package/src/sleep.js +0 -2
  44. package/src/throttle.d.ts +2 -1
  45. package/src/throttle.js +0 -2
  46. package/src/when-dom-loaded.d.ts +4 -8
  47. package/src/when-dom-loaded.js +3 -9
  48. package/src/when-loaded.d.ts +4 -8
  49. package/src/when-loaded.js +3 -9
package/README.md CHANGED
@@ -3,17 +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, 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.
6
+ Lightweight library for asynchronous task scheduling and concurrency control in JavaScript. Works in browsers, Node.js, Deno, and Bun.
7
7
 
8
- 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.
8
+ ## Why time-queues?
9
9
 
10
- ## Key Features
10
+ Modern web apps need to schedule work without blocking the main thread, respect page lifecycle events, and limit concurrency — but the platform APIs are low-level and tedious to use correctly. `time-queues` wraps them in a small, composable toolkit:
11
11
 
12
- - **Efficient Task Scheduling**: Schedule tasks to run at specific times or after delays
13
- - **Browser Performance Optimization**: Execute tasks during idle periods or animation frames
14
- - **Page Lifecycle Management**: Respond intelligently to page visibility and focus changes
15
- - **Resource Management**: Control execution rates with throttling and debouncing
16
- - **Minimal Dependencies**: Relies only on [list-toolkit](https://www.npmjs.com/package/list-toolkit), a zero-dependency library
12
+ - **Schedule tasks** to run after a delay, at a specific time, or on a recurring interval
13
+ - **Optimize browser performance** by running work during idle periods or animation frames
14
+ - **React to page lifecycle** changes (hidden, frozen, terminated) automatically
15
+ - **Control concurrency** with throttling, debouncing, batching, and rate limiting
16
+ - **Manage resources** with reference-counted creation/destruction
17
+ - **Minimal footprint** — one dependency ([list-toolkit](https://www.npmjs.com/package/list-toolkit), zero-dep)
17
18
 
18
19
  ## Installation
19
20
 
@@ -21,57 +22,137 @@ The library provides elegant solutions for common timing and scheduling challeng
21
22
  npm install time-queues
22
23
  ```
23
24
 
24
- If you want to check out the source code, you can use the following command:
25
-
26
- ```sh
27
- git clone --recurse-submodules https://github.com/uhop/time-queues.git
28
- cd time-queues
29
- npm install
25
+ ## Quick Start
26
+
27
+ ```js
28
+ import sleep from 'time-queues/sleep.js';
29
+ import {Scheduler, repeat} from 'time-queues/Scheduler.js';
30
+ import {batch} from 'time-queues/batch.js';
31
+
32
+ // Simple delay
33
+ await sleep(1000);
34
+
35
+ // Run a task every 5 seconds
36
+ const scheduler = new Scheduler();
37
+ scheduler.enqueue(
38
+ repeat(({task, scheduler}) => {
39
+ console.log('tick');
40
+ }, 5000),
41
+ 5000
42
+ );
43
+
44
+ // Fetch 10 URLs, max 3 at a time
45
+ const results = await batch(
46
+ urls.map(url => () => fetch(url).then(r => r.json())),
47
+ 3
48
+ );
30
49
  ```
31
50
 
32
- ## Usage
51
+ See the [wiki](https://github.com/uhop/time-queues/wiki) for more use cases.
52
+
53
+ ## Documentation
54
+
55
+ The [project wiki](https://github.com/uhop/time-queues/wiki) has detailed docs for every component.
56
+
57
+ ### Queues
58
+
59
+ | Component | Purpose |
60
+ | --------------------------------------------------------------------- | --------------------------------------------------- |
61
+ | [Scheduler](https://github.com/uhop/time-queues/wiki/Scheduler) | Time-based task scheduling (delays, dates, repeats) |
62
+ | [IdleQueue](https://github.com/uhop/time-queues/wiki/IdleQueue) | Run tasks during browser idle periods |
63
+ | [FrameQueue](https://github.com/uhop/time-queues/wiki/FrameQueue) | Run tasks in animation frames |
64
+ | [LimitedQueue](https://github.com/uhop/time-queues/wiki/LimitedQueue) | Concurrency-controlled async queue |
65
+ | [PageWatcher](https://github.com/uhop/time-queues/wiki/PageWatcher) | React to page lifecycle changes |
66
+
67
+ ### Utilities
68
+
69
+ | Function | Purpose |
70
+ | ------------------------------------------------------------------- | --------------------------------------- |
71
+ | [sleep()](<https://github.com/uhop/time-queues/wiki/sleep()>) | Promise-based delay |
72
+ | [defer()](<https://github.com/uhop/time-queues/wiki/defer()>) | Execute on next tick |
73
+ | [throttle()](<https://github.com/uhop/time-queues/wiki/throttle()>) | Rate-limit a function (first call wins) |
74
+ | [debounce()](<https://github.com/uhop/time-queues/wiki/debounce()>) | Delay until input stabilizes |
75
+ | [sample()](<https://github.com/uhop/time-queues/wiki/sample()>) | Sample at regular intervals |
76
+ | [audit()](<https://github.com/uhop/time-queues/wiki/audit()>) | Collect then execute after delay |
77
+ | [batch()](<https://github.com/uhop/time-queues/wiki/batch()>) | Run async ops with concurrency limit |
78
+
79
+ ### Supporting Classes
80
+
81
+ | Component | Purpose |
82
+ | ------------------------------------------------------------------------- | ------------------------------- |
83
+ | [Throttler](https://github.com/uhop/time-queues/wiki/Throttler) | Key-based rate limiting |
84
+ | [Retainer](https://github.com/uhop/time-queues/wiki/Retainer) | Resource lifecycle management |
85
+ | [Counter](https://github.com/uhop/time-queues/wiki/Counter) | Track pending task counts |
86
+ | [MicroTask](https://github.com/uhop/time-queues/wiki/MicroTask) | Base task unit |
87
+ | [MicroTaskQueue](https://github.com/uhop/time-queues/wiki/MicroTaskQueue) | Base queue class |
88
+ | [ListQueue](https://github.com/uhop/time-queues/wiki/ListQueue) | List-based queue implementation |
33
89
 
34
- The full documentation is available in the project's [wiki](https://github.com/uhop/time-queues/wiki). Below is a summary of the most important parts of the documentation:
90
+ ### Random Utilities
35
91
 
36
- ### Resource Management
92
+ | Module | Purpose |
93
+ | --------------------------------------------------------------------- | ----------------------------------------------------- |
94
+ | [random-dist](https://github.com/uhop/time-queues/wiki/random-dist) | Random numbers (uniform, normal, exponential, Pareto) |
95
+ | [random-sleep](https://github.com/uhop/time-queues/wiki/random-sleep) | Randomized delays from various distributions |
37
96
 
38
- - [Scheduler](https://github.com/uhop/time-queues/wiki/Scheduler): Time-based task scheduling
39
- - [Retainer](https://github.com/uhop/time-queues/wiki/Retainer): Manage resource lifecycle
40
- - [Throttler](https://github.com/uhop/time-queues/wiki/Throttler): Control execution rate based on keys
41
- - [Counter](https://github.com/uhop/time-queues/wiki/Counter): Track the number of pending tasks asynchronously
97
+ ### Page Load Helpers
42
98
 
43
- ### Browser-Specific Components
99
+ | Function | Purpose |
100
+ | ----------------------------------------------------------------------------- | ---------------------------------- |
101
+ | [whenDomLoaded()](<https://github.com/uhop/time-queues/wiki/whenDomLoaded()>) | Run code when DOM is ready |
102
+ | [whenLoaded()](<https://github.com/uhop/time-queues/wiki/whenLoaded()>) | Run code when page is fully loaded |
44
103
 
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
104
+ ## Browser Notes
48
105
 
49
- ### Utility Functions
106
+ The library leverages these browser APIs where available:
50
107
 
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
108
+ - [requestIdleCallback()](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)
109
+ - [requestAnimationFrame()](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)
110
+ - [queueMicrotask()](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)
111
+ - [Page Lifecycle API](https://developer.chrome.com/docs/web-platform/page-lifecycle-api)
112
+
113
+ For background reading:
114
+
115
+ - [Background Tasks API](https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API)
116
+ - [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API)
117
+
118
+ ### Test web app
119
+
120
+ Run `npm start` and open [http://localhost:3000/tests/web/](http://localhost:3000/tests/web/) &mdash;
121
+ open the console, switch tabs, navigate away and back to see queues in action.
122
+ Source: [tests/web/test.js](https://github.com/uhop/time-queues/blob/main/tests/web/test.js).
123
+
124
+ ## AI Integration
125
+
126
+ This project ships [llms.txt](llms.txt) and [llms-full.txt](llms-full.txt) for AI agents and LLMs. Contributors and AI coding assistants should see [AGENTS.md](AGENTS.md) for project conventions.
127
+
128
+ ## Development
129
+
130
+ ```sh
131
+ git clone --recurse-submodules https://github.com/uhop/time-queues.git
132
+ cd time-queues
133
+ npm install
134
+ npm test
135
+ ```
57
136
 
58
137
  ## License
59
138
 
60
- This project is licensed under the BSD-3-Clause License.
139
+ BSD-3-Clause
61
140
 
62
141
  ## Release History
63
142
 
143
+ - 1.3.1 _Fixed `.d.ts` declarations, consolidated TS typing tests, improved documentation._
144
+ - 1.3.0 _Added `batch()`, `LimitedQueue`, random distributions and random sleep functions._
64
145
  - 1.2.4 _Updated dependencies._
65
146
  - 1.2.3 _Updated dependencies._
66
147
  - 1.2.2 _`Counter`: separated old waiter from new waiters before notifying them._
67
148
  - 1.2.1 _Minor release: updated formal TS dependencies in `index.d.ts`._
68
- - 1.2.0 _Added `Counter`. Updated dev dependencies._
69
- - 1.1.2 _Updated dev dependencies. No need to upgrade._
149
+ - 1.2.0 _Added `Counter`._
150
+ - 1.1.2 _Updated dev dependencies._
70
151
  - 1.1.1 _Updates to TS typings._
71
152
  - 1.1.0 _Added `Throttler`, `Retainer`, promise-based convenience time methods._
72
153
  - 1.0.5 _Technical release: updated deps, more tests._
73
154
  - 1.0.4 _Bug fixes and code simplifications._
74
155
  - 1.0.3 _Updated deps (`list-toolkit`) to fix a minor bug._
75
156
  - 1.0.2 _Updated deps (`list-toolkit`)._
76
- - 1.0.1 _Minor update in README. No need to upgrade._
157
+ - 1.0.1 _Minor update in README._
77
158
  - 1.0.0 _Initial release._
package/llms-full.txt ADDED
@@ -0,0 +1,430 @@
1
+ # time-queues
2
+
3
+ > Lightweight async task scheduling and concurrency control for JavaScript: schedulers, idle/frame/limited queues, throttle, debounce, batch, page lifecycle, random delays.
4
+
5
+ - NPM: https://npmjs.org/package/time-queues
6
+ - GitHub: https://github.com/uhop/time-queues
7
+ - Wiki: https://github.com/uhop/time-queues/wiki
8
+ - License: BSD-3-Clause
9
+ - Runtime: browsers, Node.js, Bun, Deno
10
+ - Module system: ESM (`"type": "module"`)
11
+ - TypeScript: built-in `.d.ts` declarations for all modules
12
+ - Dependency: [list-toolkit](https://npmjs.org/package/list-toolkit) (zero-dep)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install time-queues
18
+ ```
19
+
20
+ ## Quick start
21
+
22
+ ```js
23
+ import sleep from 'time-queues/sleep.js';
24
+ import {Scheduler, repeat} from 'time-queues/Scheduler.js';
25
+ import {batch} from 'time-queues/batch.js';
26
+
27
+ await sleep(1000);
28
+
29
+ const scheduler = new Scheduler();
30
+ scheduler.enqueue(repeat(({task, scheduler}) => {
31
+ console.log('tick');
32
+ }, 5000), 5000);
33
+
34
+ const results = await batch(
35
+ urls.map(url => () => fetch(url).then(r => r.json())),
36
+ 3
37
+ );
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ```
43
+ MicroTask (single task with promise support)
44
+ └─ Task (Scheduler-specific, adds delay/time)
45
+
46
+ MicroTaskQueue (abstract queue base)
47
+ ├─ Scheduler (time-based, uses min-heap)
48
+ └─ ListQueue (linked-list storage)
49
+ ├─ IdleQueue (requestIdleCallback)
50
+ ├─ FrameQueue (requestAnimationFrame)
51
+ ├─ LimitedQueue (concurrency control)
52
+ └─ PageWatcher (page lifecycle events)
53
+
54
+ Standalone: Counter, Throttler, Retainer, CancelTaskError
55
+ ```
56
+
57
+ All modules are ESM. Import as `import X from 'time-queues/<module>.js'`.
58
+
59
+ ## API Reference
60
+
61
+ ### CancelTaskError (`time-queues/CancelTaskError.js`)
62
+
63
+ Error subclass for task cancellation signals.
64
+
65
+ ```ts
66
+ class CancelTaskError extends Error {
67
+ constructor(message?: string, options?: ErrorOptions);
68
+ }
69
+ export default CancelTaskError;
70
+ ```
71
+
72
+ ### MicroTask (`time-queues/MicroTask.js`)
73
+
74
+ Base task unit with lazy promise creation.
75
+
76
+ ```ts
77
+ class MicroTask {
78
+ fn: () => unknown;
79
+ isCanceled: boolean;
80
+ get promise(): Promise<unknown> | null;
81
+ constructor(fn: () => unknown);
82
+ makePromise(): this;
83
+ resolve(value: unknown): this;
84
+ cancel(error?: Error): this;
85
+ }
86
+ export default MicroTask;
87
+ ```
88
+
89
+ ### MicroTaskQueue (`time-queues/MicroTaskQueue.js`)
90
+
91
+ Abstract queue base class.
92
+
93
+ ```ts
94
+ class MicroTaskQueue {
95
+ paused: boolean;
96
+ constructor(paused?: boolean);
97
+ get isEmpty(): boolean;
98
+ enqueue(fn: () => unknown): MicroTask;
99
+ dequeue(task: MicroTask): this;
100
+ schedule(fn: (() => unknown) | null | undefined, ...args: unknown[]): MicroTask;
101
+ clear(): this;
102
+ pause(): this;
103
+ resume(): this;
104
+ }
105
+ export default MicroTaskQueue;
106
+ ```
107
+
108
+ ### ListQueue (`time-queues/ListQueue.js`)
109
+
110
+ Linked-list queue implementation. Extends `MicroTaskQueue`.
111
+
112
+ ```ts
113
+ class ListQueue extends MicroTaskQueue {
114
+ paused: boolean;
115
+ stopQueue: (() => void) | null;
116
+ constructor(paused?: boolean);
117
+ get isEmpty(): boolean;
118
+ enqueue(fn: () => unknown): MicroTask;
119
+ dequeue(task: MicroTask): this;
120
+ schedule(fn: (() => unknown) | null | undefined): MicroTask;
121
+ clear(): this;
122
+ pause(): this;
123
+ resume(): this;
124
+ startQueue(): (() => void) | null; // override in subclasses
125
+ }
126
+ export type Task = MicroTask;
127
+ export default ListQueue;
128
+ ```
129
+
130
+ ### Scheduler (`time-queues/Scheduler.js`)
131
+
132
+ Time-based task scheduling with min-heap. Extends `MicroTaskQueue`.
133
+
134
+ ```ts
135
+ class Task extends MicroTask {
136
+ time: number;
137
+ delay: number;
138
+ constructor(delay: number | Date, fn: ({task: Task, scheduler: Scheduler}) => unknown);
139
+ }
140
+
141
+ class Scheduler extends MicroTaskQueue {
142
+ paused: boolean;
143
+ tolerance: number;
144
+ constructor(paused?: boolean, tolerance?: number);
145
+ get isEmpty(): boolean;
146
+ get nextTime(): number;
147
+ enqueue(fn: ({task: Task, scheduler: Scheduler}) => unknown, delay: number | Date): Task;
148
+ dequeue(task: Task): this;
149
+ schedule(fn: (({task: Task, scheduler: Scheduler}) => unknown) | null | undefined, delay: number | Date): Task;
150
+ clear(): this;
151
+ pause(): this;
152
+ resume(): this;
153
+ }
154
+
155
+ const repeat: (fn: ({task: Task, scheduler: Scheduler}) => void, delay: number | Date) => ({task: Task, scheduler: Scheduler}) => void;
156
+ const scheduler: Scheduler; // global instance
157
+ export default scheduler;
158
+ ```
159
+
160
+ Callback receives `{task, scheduler}` as a destructured object.
161
+
162
+ ### IdleQueue (`time-queues/IdleQueue.js`)
163
+
164
+ Run tasks during browser idle periods via `requestIdleCallback()`. Extends `ListQueue`.
165
+
166
+ ```ts
167
+ class IdleQueue extends ListQueue {
168
+ timeoutBatch: number | undefined;
169
+ options: IdleCallbackOptions | undefined;
170
+ constructor(paused?: boolean, timeoutBatchInMs?: number, options?: IdleCallbackOptions);
171
+ enqueue(fn: ({deadline: IdleDeadline, task: Task, queue: IdleQueue}) => unknown): Task;
172
+ schedule(fn: (({deadline: IdleDeadline, task: Task, queue: IdleQueue}) => unknown) | null | undefined): Task;
173
+ }
174
+
175
+ const idleQueue: IdleQueue; // global instance
176
+ const defer: (fn: ({deadline: IdleDeadline, task: Task, queue: IdleQueue}) => unknown) => Task;
177
+ export default IdleQueue;
178
+ ```
179
+
180
+ ### FrameQueue (`time-queues/FrameQueue.js`)
181
+
182
+ Run tasks in animation frames via `requestAnimationFrame()`. Extends `ListQueue`.
183
+
184
+ ```ts
185
+ class FrameQueue extends ListQueue {
186
+ batch: number | undefined;
187
+ constructor(paused?: boolean, batchInMs?: number);
188
+ enqueue(fn: ({timeStamp: number, task: Task, queue: FrameQueue}) => unknown): Task;
189
+ schedule(fn: (({timeStamp: number, task: Task, queue: FrameQueue}) => unknown) | null | undefined): Task;
190
+ }
191
+
192
+ const frameQueue: FrameQueue; // global instance
193
+ export default FrameQueue;
194
+ ```
195
+
196
+ ### LimitedQueue (`time-queues/LimitedQueue.js`)
197
+
198
+ Concurrency-controlled async queue. Extends `ListQueue`.
199
+
200
+ ```ts
201
+ class LimitedQueue extends ListQueue {
202
+ constructor(limit: number, paused?: boolean);
203
+ get taskLimit(): number;
204
+ set taskLimit(limit: number);
205
+ get activeTasks(): number;
206
+ get isIdle(): boolean;
207
+ waitForIdle(): Promise<void>;
208
+ enqueue(fn: () => unknown): Task;
209
+ schedule(fn: (() => unknown) | null | undefined): Task;
210
+ }
211
+ export { Task };
212
+ export default LimitedQueue;
213
+ ```
214
+
215
+ ### PageWatcher (`time-queues/PageWatcher.js`)
216
+
217
+ React to page lifecycle changes. Extends `ListQueue`.
218
+
219
+ ```ts
220
+ type PageState = 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated';
221
+
222
+ class PageWatcher extends ListQueue {
223
+ currentState: PageState;
224
+ constructor(started?: boolean);
225
+ enqueue(fn: (state: PageState, previousState: PageState, task: Task, queue: ListQueue) => void, initialize?: boolean): Task;
226
+ schedule(): never; // always throws
227
+ }
228
+
229
+ const watchStates: (queue: ListQueue, resumeStatesList?: PageState[]) => (state: PageState) => void;
230
+ const pageWatcher: PageWatcher; // global instance
231
+ export default PageWatcher;
232
+ ```
233
+
234
+ ### Counter (`time-queues/Counter.js`)
235
+
236
+ Numeric counter with async waiting.
237
+
238
+ ```ts
239
+ class Counter {
240
+ count: number;
241
+ constructor(initial?: number);
242
+ get value(): number;
243
+ set value(value: number);
244
+ increment(): void;
245
+ decrement(): void;
246
+ advance(amount?: number): void;
247
+ waitForZero(): Promise<number>;
248
+ waitFor(fn: (count: number) => boolean): Promise<number>;
249
+ clearWaiters(): void;
250
+ }
251
+ export default Counter;
252
+ ```
253
+
254
+ ### Throttler (`time-queues/Throttler.js`)
255
+
256
+ Key-based rate limiting with vacuum cleanup.
257
+
258
+ ```ts
259
+ type ThrottlerOptions = {
260
+ throttleTimeout?: number; // default: 1000
261
+ neverSeenTimeout?: number; // default: 0
262
+ vacuumPeriod?: number; // default: throttleTimeout * 3
263
+ };
264
+
265
+ class Throttler implements ThrottlerOptions {
266
+ throttleTimeout: number;
267
+ neverSeenTimeout: number;
268
+ vacuumPeriod: number;
269
+ lastSeen: Map<unknown, number>;
270
+ constructor(options?: ThrottlerOptions);
271
+ getLastSeen(key: unknown): number;
272
+ getDelay(key: unknown): number;
273
+ wait(key: unknown): Promise<void>;
274
+ get isVacuuming(): boolean;
275
+ startVacuum(): this;
276
+ stopVacuum(): this;
277
+ }
278
+ export default Throttler;
279
+ ```
280
+
281
+ ### Retainer (`time-queues/Retainer.js`)
282
+
283
+ Resource lifecycle management with reference counting.
284
+
285
+ ```ts
286
+ interface RetainerOptions<T = unknown> {
287
+ create: () => Promise<T> | T;
288
+ destroy: (value: T) => Promise<void> | void;
289
+ retentionPeriod: number;
290
+ }
291
+
292
+ class Retainer<T = unknown> implements RetainerOptions<T> {
293
+ counter: number;
294
+ value: T | null;
295
+ create: () => Promise<T> | T;
296
+ destroy: (value: T) => Promise<void> | void;
297
+ retentionPeriod: number;
298
+ constructor(options: RetainerOptions<T>);
299
+ async get(): Promise<T>;
300
+ async release(immediately?: boolean): Promise<this>;
301
+ }
302
+ export default Retainer;
303
+ ```
304
+
305
+ ### sleep (`time-queues/sleep.js`)
306
+
307
+ ```ts
308
+ function sleep(ms: number | Date): Promise<void>;
309
+ export default sleep;
310
+ ```
311
+
312
+ ### defer (`time-queues/defer.js`)
313
+
314
+ Next-tick execution via `requestIdleCallback` / `setImmediate` / `setTimeout`.
315
+
316
+ ```ts
317
+ function defer<A extends unknown[]>(fn: (...args: A) => void): (...args: A) => void;
318
+ function scheduleDefer<R>(fn: () => R): Promise<Awaited<R>>;
319
+ function scheduleDefer(fn: null | undefined): Promise<void>;
320
+ export default defer;
321
+ ```
322
+
323
+ ### throttle (`time-queues/throttle.js`)
324
+
325
+ Execute immediately, ignore calls until timeout expires. Uses first seen args.
326
+
327
+ ```ts
328
+ function throttle<A extends unknown[]>(fn: (...args: A) => void, ms: number): (...args: A) => void;
329
+ export default throttle;
330
+ ```
331
+
332
+ ### debounce (`time-queues/debounce.js`)
333
+
334
+ Delay until input stabilizes. Each call resets the timeout. Uses last seen args.
335
+
336
+ ```ts
337
+ function debounce<A extends unknown[]>(fn: (...args: A) => void, ms: number): (...args: A) => void;
338
+ export default debounce;
339
+ ```
340
+
341
+ ### sample (`time-queues/sample.js`)
342
+
343
+ Execute at regular intervals with last seen args. Intervals never reset and never stop.
344
+
345
+ ```ts
346
+ function sample<A extends unknown[]>(fn: (...args: A) => void, ms: number): (...args: A) => void;
347
+ export default sample;
348
+ ```
349
+
350
+ ### audit (`time-queues/audit.js`)
351
+
352
+ First call starts timeout, then executes with last seen args. Similar to throttle but uses last args.
353
+
354
+ ```ts
355
+ function audit<A extends unknown[]>(fn: (...args: A) => void, ms: number): (...args: A) => void;
356
+ export default audit;
357
+ ```
358
+
359
+ ### batch (`time-queues/batch.js`)
360
+
361
+ Run async operations with concurrency limit. Modeled after `Promise.all()`.
362
+
363
+ ```ts
364
+ function batch(
365
+ fns: ((() => PromiseLike<unknown>) | PromiseLike<unknown> | unknown)[],
366
+ limit?: number // default: 4
367
+ ): Promise<unknown[]>;
368
+ export default batch;
369
+ ```
370
+
371
+ ### random-dist (`time-queues/random-dist.js`)
372
+
373
+ Random number distributions.
374
+
375
+ ```ts
376
+ function uniform(min: number, max: number): number;
377
+ function normal(mean: number, stdDev: number, skewness?: number): number;
378
+ function expo(lambda: number): number;
379
+ function pareto(min: number, alpha: number): number;
380
+ ```
381
+
382
+ ### random-sleep (`time-queues/random-sleep.js`)
383
+
384
+ Randomized delays from various distributions. Each factory returns `() => Promise<void>`.
385
+
386
+ ```ts
387
+ type RandomSleepFunction = () => Promise<void>;
388
+
389
+ function randomUniformSleep(min: number, max: number): RandomSleepFunction;
390
+ function randomNormalSleep(mean: number, stdDev: number, skewness?: number): RandomSleepFunction;
391
+ function randomExpoSleep(rate: number, range: number, base?: number): RandomSleepFunction;
392
+ function randomParetoSleep(min: number, ratio?: number): RandomSleepFunction;
393
+ function randomSleep(max: number, min?: number): Promise<void>;
394
+ export default randomSleep;
395
+ ```
396
+
397
+ ### whenDomLoaded (`time-queues/when-dom-loaded.js`)
398
+
399
+ ```ts
400
+ function whenDomLoaded(fn: () => void): void;
401
+ function remove(fn: () => void): boolean;
402
+ function scheduleWhenDomLoaded<R>(fn: () => R): Promise<Awaited<R>>;
403
+ function scheduleWhenDomLoaded(fn?: null): Promise<void>;
404
+ export default whenDomLoaded;
405
+ ```
406
+
407
+ ### whenLoaded (`time-queues/when-loaded.js`)
408
+
409
+ ```ts
410
+ function whenLoaded(fn: () => void): void;
411
+ function remove(fn: () => void): boolean;
412
+ function scheduleWhenLoaded<R>(fn: () => R): Promise<Awaited<R>>;
413
+ function scheduleWhenLoaded(fn?: null): Promise<void>;
414
+ export default whenLoaded;
415
+ ```
416
+
417
+ ## Key concepts
418
+
419
+ - All modules are **ESM** with `import ... from 'time-queues/<module>.js'`.
420
+ - **Inheritance**: `MicroTaskQueue` → `ListQueue` → specialized queues. `Scheduler` extends `MicroTaskQueue` directly (uses min-heap, not linked list).
421
+ - **Lazy promises** — only created when `.makePromise()` is called or via `schedule()`.
422
+ - **Clean cancellation** — all tasks support cancellation via `CancelTaskError`.
423
+ - **Graceful degradation** — feature detection for browser APIs, works in Node.js/Bun/Deno.
424
+ - **Callback signatures** — queue callbacks receive a destructured context object: `({task, scheduler})` for Scheduler, `({deadline, task, queue})` for IdleQueue, `({timeStamp, task, queue})` for FrameQueue, `(state, prevState, task, queue)` for PageWatcher.
425
+
426
+ ## Links
427
+
428
+ - Docs: https://github.com/uhop/time-queues/wiki
429
+ - npm: https://www.npmjs.com/package/time-queues
430
+ - Summary: https://github.com/uhop/time-queues/blob/master/llms.txt