@hardlydifficult/poller 1.0.10 → 1.0.11
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 +60 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hardlydifficult/poller
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A lightweight polling utility with debounced manual triggers, overlapping request handling, and deep equality change detection.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -13,51 +13,73 @@ npm install @hardlydifficult/poller
|
|
|
13
13
|
```typescript
|
|
14
14
|
import { Poller } from "@hardlydifficult/poller";
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
return
|
|
16
|
+
const fetchUser = async () => {
|
|
17
|
+
const res = await fetch("https://api.example.com/user");
|
|
18
|
+
return res.json();
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const poller = new Poller(
|
|
22
|
-
|
|
23
|
-
(
|
|
24
|
-
|
|
22
|
+
fetchUser,
|
|
23
|
+
(user, previousUser) => {
|
|
24
|
+
console.log("User changed:", user);
|
|
25
|
+
},
|
|
26
|
+
5000 // Poll every 5 seconds
|
|
25
27
|
);
|
|
26
28
|
|
|
27
29
|
await poller.start();
|
|
28
|
-
//
|
|
30
|
+
// Polling begins immediately and every 5 seconds
|
|
31
|
+
|
|
32
|
+
// Optionally, manually trigger a poll with debounce
|
|
33
|
+
poller.trigger(1000); // Fires after 1s of inactivity
|
|
29
34
|
|
|
30
|
-
//
|
|
35
|
+
// Stop polling when no longer needed
|
|
31
36
|
poller.stop();
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
## Polling with Change Detection
|
|
35
40
|
|
|
36
|
-
The `Poller` class
|
|
41
|
+
The `Poller` class periodically fetches data using a user-provided async function and invokes a callback only when the result changes. Change detection uses deep equality via `JSON.stringify`, ensuring structurally identical values (even with different object references) do not trigger redundant callbacks.
|
|
37
42
|
|
|
38
43
|
### Constructor Parameters
|
|
39
44
|
|
|
40
|
-
| Parameter
|
|
41
|
-
|
|
42
|
-
| `fetchFn`
|
|
43
|
-
| `onChange`
|
|
44
|
-
| `intervalMs
|
|
45
|
-
| `onError?`
|
|
45
|
+
| Parameter | Type | Description |
|
|
46
|
+
|------|--|---------|
|
|
47
|
+
| `fetchFn` | `() => Promise<T>` | Async function that fetches the data to poll |
|
|
48
|
+
| `onChange` | `(current: T, previous: T \| undefined) => void` | Callback invoked when data changes (using deep equality) |
|
|
49
|
+
| `intervalMs` | `number` | Polling interval in milliseconds |
|
|
50
|
+
| `onError?` | `(error: unknown) => void` | Optional callback for fetch errors |
|
|
46
51
|
|
|
47
|
-
###
|
|
52
|
+
### `start(): Promise<void>`
|
|
53
|
+
|
|
54
|
+
Begins polling immediately and at the configured interval.
|
|
48
55
|
|
|
49
56
|
```typescript
|
|
50
|
-
// Start polling (idempotent — safe to call multiple times)
|
|
51
57
|
await poller.start();
|
|
58
|
+
// Polls once immediately, then every intervalMs ms
|
|
59
|
+
```
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
### `stop(): void`
|
|
62
|
+
|
|
63
|
+
Stops polling and clears any pending debounced triggers.
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
54
66
|
poller.stop();
|
|
67
|
+
// No further polls occur; timers cleared
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### `trigger(debounceMs?: number): void`
|
|
55
71
|
|
|
56
|
-
|
|
57
|
-
|
|
72
|
+
Manually trigger a poll with debouncing to avoid excessive requests during rapid events.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// Default debounce: 1000ms
|
|
76
|
+
poller.trigger();
|
|
77
|
+
|
|
78
|
+
// Custom debounce
|
|
79
|
+
poller.trigger(2000); // Fires after 2 seconds of no other triggers
|
|
58
80
|
```
|
|
59
81
|
|
|
60
|
-
|
|
82
|
+
## Debounced Manual Trigger
|
|
61
83
|
|
|
62
84
|
The `trigger()` method allows manually forcing a poll while debouncing multiple rapid calls:
|
|
63
85
|
|
|
@@ -67,7 +89,7 @@ poller.trigger(500); // Schedules a poll after 500ms
|
|
|
67
89
|
poller.trigger(500); // Resets debounce — only one poll fires
|
|
68
90
|
```
|
|
69
91
|
|
|
70
|
-
|
|
92
|
+
## Error Handling
|
|
71
93
|
|
|
72
94
|
Errors during polling do not halt the poller. They are optionally reported via `onError`, if provided.
|
|
73
95
|
|
|
@@ -90,11 +112,23 @@ await poller.start();
|
|
|
90
112
|
The `Poller` skips new polls while a fetch is still in progress, preventing overlapping requests.
|
|
91
113
|
|
|
92
114
|
```typescript
|
|
93
|
-
const fetchFn =
|
|
115
|
+
const fetchFn = async () => {
|
|
94
116
|
// Simulates slow network — never resolves before interval
|
|
95
|
-
|
|
96
|
-
|
|
117
|
+
await new Promise((resolve) => setTimeout(resolve, 6000));
|
|
118
|
+
return "data";
|
|
119
|
+
};
|
|
97
120
|
const poller = new Poller(fetchFn, () => {}, 1000);
|
|
98
121
|
await poller.start();
|
|
99
122
|
// Only one fetch runs at a time — subsequent intervals are skipped until it completes
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Deep Equality Detection
|
|
126
|
+
|
|
127
|
+
The `Poller` uses `JSON.stringify` to compare current and previous values, enabling detection of structural changes in objects and arrays.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const fetchCount = async () => ({ value: 1 });
|
|
131
|
+
const poller = new Poller(fetchCount, (curr, prev) => {
|
|
132
|
+
// Fires only when value changes
|
|
133
|
+
}, 1000);
|
|
100
134
|
```
|