@hardlydifficult/poller 1.0.2 → 1.0.4

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 +124 -11
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hardlydifficult/poller
2
2
 
3
- Generic state-change poller. Polls a function at an interval and fires a callback when the result changes.
3
+ Polls async functions at configurable intervals and triggers callbacks only when the result changes—using deep equality detection via JSON serialization.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,7 +8,7 @@ Generic state-change poller. Polls a function at an interval and fires a callbac
8
8
  npm install @hardlydifficult/poller
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Quick Start
12
12
 
13
13
  ```typescript
14
14
  import { Poller } from "@hardlydifficult/poller";
@@ -28,26 +28,139 @@ poller.trigger(1000);
28
28
  poller.stop();
29
29
  ```
30
30
 
31
- ## API
31
+ ## Polling
32
32
 
33
- ### `new Poller<T>(fetchFn, onChange, intervalMs, onError?)`
33
+ The `Poller` class fetches data at a configurable interval and invokes a callback when the result changes. It fetches immediately on `start()`, then at the configured interval.
34
+
35
+ ```typescript
36
+ import { Poller } from "@hardlydifficult/poller";
37
+
38
+ const poller = new Poller(
39
+ async () => {
40
+ const response = await fetch("/api/status");
41
+ return response.json();
42
+ },
43
+ (current, previous) => {
44
+ console.log("Previous:", previous);
45
+ console.log("Current:", current);
46
+ },
47
+ 10000 // poll every 10 seconds
48
+ );
49
+
50
+ await poller.start();
51
+ // Fetches immediately, then every 10 seconds
52
+ ```
53
+
54
+ ### start()
55
+
56
+ Starts polling. Fetches immediately, then at the configured interval. Calling `start()` multiple times is safe (idempotent).
57
+
58
+ ```typescript
59
+ await poller.start(); // Fetches immediately
60
+ await poller.start(); // No-op, already running
61
+ ```
62
+
63
+ ### stop()
64
+
65
+ Stops polling and cleans up all timers.
66
+
67
+ ```typescript
68
+ poller.stop();
69
+ // No more polls will fire
70
+ ```
71
+
72
+ ## Change Detection
73
+
74
+ Changes are detected using JSON serialization for deep equality. Structurally identical objects are considered unchanged—even if they are different references.
75
+
76
+ ```typescript
77
+ const poller = new Poller(
78
+ async () => ({ count: 5, items: [1, 2, 3] }),
79
+ (current, previous) => {
80
+ // Only fires when the JSON representation changes
81
+ console.log("Changed from", previous, "to", current);
82
+ },
83
+ 5000
84
+ );
85
+
86
+ await poller.start();
87
+ ```
88
+
89
+ ## Manual Triggers
90
+
91
+ Call `trigger()` to manually poll immediately, with optional debouncing. Multiple rapid triggers are coalesced into a single poll.
92
+
93
+ ```typescript
94
+ const poller = new Poller(
95
+ async () => await fetchData(),
96
+ (current, previous) => console.log("Updated:", current),
97
+ 60000
98
+ );
99
+
100
+ await poller.start();
101
+
102
+ // Trigger a poll with 1000ms debounce (default)
103
+ poller.trigger();
104
+
105
+ // Trigger with custom debounce
106
+ poller.trigger(500);
107
+
108
+ // Multiple rapid triggers coalesce into one poll
109
+ poller.trigger(500);
110
+ poller.trigger(500);
111
+ poller.trigger(500); // Only one poll fires after 500ms
112
+ ```
113
+
114
+ ## Error Handling
115
+
116
+ Errors during fetch are passed to the optional `onError` callback. Polling continues regardless of errors.
117
+
118
+ ```typescript
119
+ const poller = new Poller(
120
+ async () => await fetchData(),
121
+ (current, previous) => console.log("Updated:", current),
122
+ 5000,
123
+ (error) => {
124
+ console.error("Fetch failed:", error);
125
+ // Polling continues automatically
126
+ }
127
+ );
128
+
129
+ await poller.start();
130
+ ```
131
+
132
+ ## API Reference
133
+
134
+ ### Constructor
135
+
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
+ ```
34
144
 
35
145
  | Parameter | Description |
36
- |-----------|-------------|
146
+ |---|---|
37
147
  | `fetchFn` | Async function that returns the current state |
38
148
  | `onChange` | Called with `(current, previous)` when state changes |
39
149
  | `intervalMs` | Polling interval in milliseconds |
40
150
  | `onError` | Optional error handler; polling continues on errors |
41
151
 
152
+ ### Methods
153
+
42
154
  | Method | Description |
43
- |--------|-------------|
155
+ |---|---|
44
156
  | `start()` | Start polling (fetches immediately, then at interval) |
45
157
  | `stop()` | Stop polling and clean up timers |
46
- | `trigger(debounceMs?)` | Manually trigger a poll with debounce (default 1000ms) |
158
+ | `trigger(debounceMs?)` | Manually trigger a poll with debounce (default `1000`ms) |
47
159
 
48
160
  ### Behavior
49
161
 
50
- - **Deep equality** -- uses JSON serialization to detect changes
51
- - **Overlap prevention** -- skips a poll if the previous fetch is still running
52
- - **Error resilience** -- continues polling after fetch errors
53
- - **Idempotent start** -- calling `start()` multiple times is safe
162
+ - **Deep equality** uses JSON serialization to detect structural changes
163
+ - **Overlap prevention** skips a poll if the previous fetch is still running
164
+ - **Error resilience** continues polling after fetch errors
165
+ - **Idempotent start** calling `start()` multiple times is safe
166
+ - **Debounced triggers** — multiple `trigger()` calls coalesce into one poll
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/poller",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [