@hardlydifficult/poller 1.0.4 → 1.0.5

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 (2) hide show
  1. package/README.md +64 -26
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @hardlydifficult/poller
2
2
 
3
- Polls async functions at configurable intervals and triggers callbacks only when the result changesusing deep equality detection via JSON serialization.
3
+ A generic polling utility that periodically fetches data and invokes a callback only when the result changes, using JSON-based deep equality comparison.
4
4
 
5
- ## Install
5
+ ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @hardlydifficult/poller
@@ -13,6 +13,31 @@ npm install @hardlydifficult/poller
13
13
  ```typescript
14
14
  import { Poller } from "@hardlydifficult/poller";
15
15
 
16
+ // Create a poller that fetches mock API data every 5 seconds
17
+ const poller = new Poller(
18
+ async () => {
19
+ const response = await fetch("https://api.example.com/status");
20
+ return await response.json();
21
+ },
22
+ (current, previous) => {
23
+ console.log("Status changed:", current);
24
+ },
25
+ 5000,
26
+ (error) => {
27
+ console.error("Polling error:", error);
28
+ }
29
+ );
30
+
31
+ await poller.start(); // Begins polling immediately
32
+ // ... later
33
+ poller.stop(); // Stops polling
34
+ ```
35
+
36
+ ### Basic Usage
37
+
38
+ ```typescript
39
+ import { Poller } from "@hardlydifficult/poller";
40
+
16
41
  const poller = new Poller(
17
42
  async () => await fetchCurrentState(),
18
43
  (current, previous) => console.log("State changed!", current),
@@ -51,7 +76,7 @@ await poller.start();
51
76
  // Fetches immediately, then every 10 seconds
52
77
  ```
53
78
 
54
- ### start()
79
+ ### `start()`
55
80
 
56
81
  Starts polling. Fetches immediately, then at the configured interval. Calling `start()` multiple times is safe (idempotent).
57
82
 
@@ -60,7 +85,7 @@ await poller.start(); // Fetches immediately
60
85
  await poller.start(); // No-op, already running
61
86
  ```
62
87
 
63
- ### stop()
88
+ ### `stop()`
64
89
 
65
90
  Stops polling and cleans up all timers.
66
91
 
@@ -73,6 +98,9 @@ poller.stop();
73
98
 
74
99
  Changes are detected using JSON serialization for deep equality. Structurally identical objects are considered unchanged—even if they are different references.
75
100
 
101
+ - On first poll, `onChange(current, undefined)` is invoked.
102
+ - On subsequent polls, `onChange(current, previous)` is invoked only if the new value differs structurally.
103
+
76
104
  ```typescript
77
105
  const poller = new Poller(
78
106
  async () => ({ count: 5, items: [1, 2, 3] }),
@@ -90,6 +118,10 @@ await poller.start();
90
118
 
91
119
  Call `trigger()` to manually poll immediately, with optional debouncing. Multiple rapid triggers are coalesced into a single poll.
92
120
 
121
+ - Accepts a `debounceMs` parameter (default: `1000`).
122
+ - Multiple rapid calls reset the debounce timer — only the last trigger fires.
123
+ - No-op if the poller is not running.
124
+
93
125
  ```typescript
94
126
  const poller = new Poller(
95
127
  async () => await fetchData(),
@@ -113,7 +145,8 @@ poller.trigger(500); // Only one poll fires after 500ms
113
145
 
114
146
  ## Error Handling
115
147
 
116
- Errors during fetch are passed to the optional `onError` callback. Polling continues regardless of errors.
148
+ - Errors during fetch are caught and passed to the optional `onError` callback.
149
+ - Polling continues after errors — no automatic retry logic is applied.
117
150
 
118
151
  ```typescript
119
152
  const poller = new Poller(
@@ -129,33 +162,38 @@ const poller = new Poller(
129
162
  await poller.start();
130
163
  ```
131
164
 
132
- ## API Reference
165
+ ## Core Features
133
166
 
134
- ### Constructor
167
+ ### Polling Lifecycle
135
168
 
136
- ```typescript
137
- new Poller<T>(
138
- fetchFn: () => Promise<T>,
139
- onChange: (current: T, previous: T | undefined) => void,
140
- intervalMs: number,
141
- onError?: (error: unknown) => void
142
- )
143
- ```
169
+ The `Poller` manages its lifecycle with `start()` and `stop()` methods.
170
+
171
+ - `start()`: Begins polling immediately and then at the configured interval. Idempotent — calling it multiple times has no effect after the first call.
172
+ - `stop()`: Clears the polling timer and any pending debounced triggers. No-op if already stopped.
173
+
174
+ ### Concurrent Fetch Handling
175
+
176
+ Overlapping fetches (e.g., due to slow network) are automatically skipped:
177
+ - If `poll()` is already running when the interval fires, the next poll is skipped until the current one completes.
178
+
179
+ ## API Reference
180
+
181
+ ### `Poller<T>` Constructor
144
182
 
145
- | Parameter | Description |
146
- |---|---|
147
- | `fetchFn` | Async function that returns the current state |
148
- | `onChange` | Called with `(current, previous)` when state changes |
149
- | `intervalMs` | Polling interval in milliseconds |
150
- | `onError` | Optional error handler; polling continues on errors |
183
+ | Parameter | Type | Description |
184
+ |-------------|---------------------------------------|------------------------------------------|
185
+ | `fetchFn` | `() => Promise<T>` | Async function returning the current state |
186
+ | `onChange` | `(current: T, previous: T | undefined) => void` | Callback invoked on state changes |
187
+ | `intervalMs`| `number` | Polling interval in milliseconds |
188
+ | `onError?` | `(error: unknown) => void` | Optional callback for fetch errors |
151
189
 
152
190
  ### Methods
153
191
 
154
- | Method | Description |
155
- |---|---|
156
- | `start()` | Start polling (fetches immediately, then at interval) |
157
- | `stop()` | Stop polling and clean up timers |
158
- | `trigger(debounceMs?)` | Manually trigger a poll with debounce (default `1000`ms) |
192
+ | Method | Signature | Description |
193
+ |--------------|----------------------------------------|----------------------------------------------|
194
+ | `start()` | `(): Promise<void>` | Begins polling (immediate + interval-based) |
195
+ | `stop()` | `(): void` | Stops polling and clears timers |
196
+ | `trigger()` | `(debounceMs?: number) => void` | Triggers a debounced manual poll |
159
197
 
160
198
  ### Behavior
161
199
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/poller",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [