@hardlydifficult/poller 1.0.9 → 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 +84 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hardlydifficult/poller
|
|
2
2
|
|
|
3
|
-
A lightweight polling utility with debounced triggers, overlapping request handling, and deep equality change detection.
|
|
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,81 +13,122 @@ npm install @hardlydifficult/poller
|
|
|
13
13
|
```typescript
|
|
14
14
|
import { Poller } from "@hardlydifficult/poller";
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
return
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const onChange = (current: unknown, previous: unknown) => {
|
|
22
|
-
console.log("Data changed:", current);
|
|
16
|
+
const fetchUser = async () => {
|
|
17
|
+
const res = await fetch("https://api.example.com/user");
|
|
18
|
+
return res.json();
|
|
23
19
|
};
|
|
24
20
|
|
|
25
|
-
const poller = new Poller(
|
|
21
|
+
const poller = new Poller(
|
|
22
|
+
fetchUser,
|
|
23
|
+
(user, previousUser) => {
|
|
24
|
+
console.log("User changed:", user);
|
|
25
|
+
},
|
|
26
|
+
5000 // Poll every 5 seconds
|
|
27
|
+
);
|
|
26
28
|
|
|
27
29
|
await poller.start();
|
|
28
|
-
//
|
|
30
|
+
// Polling begins immediately and every 5 seconds
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
```
|
|
32
|
+
// Optionally, manually trigger a poll with debounce
|
|
33
|
+
poller.trigger(1000); // Fires after 1s of inactivity
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
// Stop polling when no longer needed
|
|
36
|
+
poller.stop();
|
|
37
|
+
```
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
## Polling with Change Detection
|
|
37
40
|
|
|
38
|
-
|
|
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.
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|--------------|-----------------------------------|----------------------------------------------|
|
|
42
|
-
| `fetchFn` | `() => Promise<T>` | Async function that fetches the latest data |
|
|
43
|
-
| `onChange` | `(current: T, previous: T | undefined) => void` | Callback invoked when data changes |
|
|
44
|
-
| `intervalMs` | `number` | Polling interval in milliseconds |
|
|
45
|
-
| `onError?` | `(error: unknown) => void` | Optional callback invoked on fetch errors |
|
|
43
|
+
### Constructor Parameters
|
|
46
44
|
|
|
47
|
-
|
|
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 |
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
### `start(): Promise<void>`
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
Begins polling immediately and at the configured interval.
|
|
52
55
|
|
|
53
56
|
```typescript
|
|
54
57
|
await poller.start();
|
|
55
|
-
//
|
|
58
|
+
// Polls once immediately, then every intervalMs ms
|
|
56
59
|
```
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
### `stop(): void`
|
|
59
62
|
|
|
60
|
-
Stops polling and clears
|
|
63
|
+
Stops polling and clears any pending debounced triggers.
|
|
61
64
|
|
|
62
65
|
```typescript
|
|
63
66
|
poller.stop();
|
|
64
|
-
//
|
|
67
|
+
// No further polls occur; timers cleared
|
|
65
68
|
```
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
### `trigger(debounceMs?: number): void`
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
Manually trigger a poll with debouncing to avoid excessive requests during rapid events.
|
|
70
73
|
|
|
71
74
|
```typescript
|
|
72
|
-
|
|
73
|
-
poller.trigger(
|
|
74
|
-
|
|
75
|
+
// Default debounce: 1000ms
|
|
76
|
+
poller.trigger();
|
|
77
|
+
|
|
78
|
+
// Custom debounce
|
|
79
|
+
poller.trigger(2000); // Fires after 2 seconds of no other triggers
|
|
75
80
|
```
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
## Debounced Manual Trigger
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
The `trigger()` method allows manually forcing a poll while debouncing multiple rapid calls:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
await poller.start();
|
|
88
|
+
poller.trigger(500); // Schedules a poll after 500ms
|
|
89
|
+
poller.trigger(500); // Resets debounce — only one poll fires
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Error Handling
|
|
93
|
+
|
|
94
|
+
Errors during polling do not halt the poller. They are optionally reported via `onError`, if provided.
|
|
82
95
|
|
|
83
96
|
```typescript
|
|
84
97
|
const poller = new Poller(
|
|
85
|
-
async () =>
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
(
|
|
98
|
+
async () => {
|
|
99
|
+
throw new Error("Network failure");
|
|
100
|
+
},
|
|
101
|
+
(data) => console.log(data),
|
|
102
|
+
2000,
|
|
103
|
+
(error) => console.error("Poll failed:", error)
|
|
89
104
|
);
|
|
105
|
+
await poller.start();
|
|
106
|
+
// Logs: Poll failed: Error: Network failure
|
|
107
|
+
// Continues polling after each error
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Overlapping Request Handling
|
|
90
111
|
|
|
112
|
+
The `Poller` skips new polls while a fetch is still in progress, preventing overlapping requests.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const fetchFn = async () => {
|
|
116
|
+
// Simulates slow network — never resolves before interval
|
|
117
|
+
await new Promise((resolve) => setTimeout(resolve, 6000));
|
|
118
|
+
return "data";
|
|
119
|
+
};
|
|
120
|
+
const poller = new Poller(fetchFn, () => {}, 1000);
|
|
91
121
|
await poller.start();
|
|
92
|
-
|
|
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);
|
|
93
134
|
```
|