@hardlydifficult/poller 1.0.8 → 1.0.9

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 +48 -99
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @hardlydifficult/poller
2
2
 
3
- A lightweight, generic polling utility with debounced triggers, overlapping request handling, and deep equality change detection.
3
+ A lightweight polling utility with debounced triggers, overlapping request handling, and deep equality change detection.
4
4
 
5
5
  ## Installation
6
6
 
@@ -13,132 +13,81 @@ npm install @hardlydifficult/poller
13
13
  ```typescript
14
14
  import { Poller } from "@hardlydifficult/poller";
15
15
 
16
- // Define a fetch function (e.g., API call)
17
- const fetchUser = async () => {
18
- const res = await fetch("https://api.example.com/user");
19
- return res.json();
16
+ const fetchFn = async () => {
17
+ const response = await fetch("https://api.example.com/data");
18
+ return response.json();
20
19
  };
21
20
 
22
- // Create and start the poller
23
- const poller = new Poller(
24
- fetchUser,
25
- (current, previous) => {
26
- console.log("User updated:", current);
27
- },
28
- 5000 // Poll every 5 seconds
29
- );
30
-
31
- await poller.start();
32
- // Polls every 5s, fires onChange only when JSON data changes
33
-
34
- // Manually trigger a debounced poll (e.g., after user action)
35
- poller.trigger(1000); // Waits 1s, then polls once
36
-
37
- // Stop polling when no longer needed
38
- poller.stop();
39
- ```
40
-
41
- ## Polling Lifecycle
42
-
43
- ### Start and Stop
21
+ const onChange = (current: unknown, previous: unknown) => {
22
+ console.log("Data changed:", current);
23
+ };
44
24
 
45
- - `start()`: Begins polling at the configured interval. Idempotent—safe to call multiple times.
46
- - `stop()`: Cancels timers and clears any pending debounced trigger. Safe to call multiple times.
25
+ const poller = new Poller(fetchFn, onChange, 5000);
47
26
 
48
- ```typescript
49
27
  await poller.start();
50
- await poller.start(); // No-op
28
+ // => Starts polling every 5 seconds, firing onChange on first fetch and any change
51
29
 
52
- poller.stop();
53
- poller.stop(); // No-op
30
+ poller.trigger(1000);
31
+ // => Triggers a debounced poll after 1 second (overriding any previous trigger call)
54
32
  ```
55
33
 
56
- ## Change Detection
57
-
58
- ### Deep Equality via JSON
59
-
60
- Change detection uses `JSON.stringify()` comparison, enabling structural equality checks for objects and arrays—even when references differ.
61
-
62
- ```typescript
63
- const fetchFn = async () => ({ items: [1, 2, 3] });
64
- const onChange = (current, previous) => {
65
- // Fires only when structure changes
66
- };
67
-
68
- const poller = new Poller(fetchFn, onChange, 1000);
69
- // Even if new object reference returned, onChange won’t fire unless JSON differs
70
- ```
34
+ ## Poller Class
71
35
 
72
- ### On Change Callback
36
+ A generic polling utility that periodically fetches data and invokes a callback when the result changes.
73
37
 
74
- ```typescript
75
- onChange(current: T, previous: T | undefined): void
76
- ```
38
+ ### Constructor
77
39
 
78
- - `current`: Most recently fetched value
79
- - `previous`: Prior value, or `undefined` on first poll
40
+ | Parameter | Type | Description |
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 |
80
46
 
81
- ## Error Handling
47
+ ### Methods
82
48
 
83
- ### Optional Error Callback
49
+ #### `start(): Promise<void>`
84
50
 
85
- Provide an `onError` handler to manage fetch failures; polling continues regardless.
51
+ Starts polling at the configured interval. Does nothing if already running.
86
52
 
87
53
  ```typescript
88
- const poller = new Poller(
89
- fetchFn,
90
- onChange,
91
- 5000,
92
- (error) => {
93
- console.warn("Polling error:", error);
94
- }
95
- );
54
+ await poller.start();
55
+ // => Begins polling; invokes onChange immediately on first fetch
96
56
  ```
97
57
 
98
- - Errors do not halt the polling interval.
99
- - If `onError` is omitted, errors are silently suppressed.
100
-
101
- ## Manual Triggering
58
+ #### `stop(): void`
102
59
 
103
- ### Debounced Triggers
104
-
105
- - `trigger(debounceMs?: number)`: Schedules a one-time poll after a debounce delay (default: 1000ms).
106
- - Multiple rapid calls cancel previous timeouts—only the last one fires.
60
+ Stops polling and clears all timers (including any pending debounced trigger).
107
61
 
108
62
  ```typescript
109
- poller.trigger(2000); // Polls in 2s
110
- poller.trigger(2000); // Cancelled, re-schedule to 2s from now
111
- poller.trigger(2000); // Cancelled again, final delay applies
63
+ poller.stop();
64
+ // => Immediately halts polling and cancels pending triggers
112
65
  ```
113
66
 
114
- - No-op if `poller` is not running.
115
-
116
- ## Overlap Handling
67
+ #### `trigger(debounceMs = 1000): void`
117
68
 
118
- - Concurrent fetches are skipped—only one in-flight request is allowed at a time.
119
- - Prevents resource waste and race conditions during slow network calls.
69
+ Triggers a debounced poll. Multiple rapid calls reset the debounce timer.
120
70
 
121
71
  ```typescript
122
- // Interval fires every 5s; if fetch takes 6s:
123
- // - Second interval fire is skipped
124
- // - Third interval fire executes after first completes
72
+ poller.trigger(500); // Debounce: 500 ms
73
+ poller.trigger(200); // Resets to 200 ms from now
74
+ // Only one poll fires after the last trigger delay
125
75
  ```
126
76
 
127
- ## API Reference
77
+ ### Behavior
128
78
 
129
- ### `Poller<T>`
79
+ - **Deep equality detection**: Uses `JSON.stringify` to detect structural changes, even with new object references.
80
+ - **Overlapping request handling**: Skips polls while a fetch is in progress.
81
+ - **Error resilience**: Continues polling on errors if `onError` is provided; otherwise, errors are silently ignored.
130
82
 
131
- | Parameter | Type | Description |
132
- |-----------|------|-------------|
133
- | `fetchFn` | `() => Promise<T>` | Async function to fetch data |
134
- | `onChange` | `(current: T, previous: T \| undefined) => void` | Callback on value change |
135
- | `intervalMs` | `number` | Polling interval in milliseconds |
136
- | `onError?` | `(error: unknown) => void` | Optional error handler |
137
-
138
- ### Methods
83
+ ```typescript
84
+ const poller = new Poller(
85
+ async () => fetch("https://api.example.com/status").then(r => r.json()),
86
+ (current, previous) => console.log("Status changed:", current),
87
+ 10000, // 10 seconds
88
+ (error) => console.error("Polling error:", error)
89
+ );
139
90
 
140
- | Method | Signature | Description |
141
- |--------|-----------|-------------|
142
- | `start` | `(): Promise<void>` | Begin polling immediately and then at `intervalMs` |
143
- | `stop` | `(): void` | Cancel all timers and pending triggers |
144
- | `trigger` | `(debounceMs?: number) => void` | Trigger a one-time poll after debounce delay |
91
+ await poller.start();
92
+ poller.trigger(500); // Manual override after 0.5s if triggered again
93
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardlydifficult/poller",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [