You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 16b953b
Browse filesBrowse the repository at this point in the historyBrowse files
| Backend status polling | Schedules |`@crup/react-timer-hook/schedules`|[Polling schedule](https://crup.github.io/react-timer-hook/recipes/intermediate/polling-schedule/)|
66
+
| Draft autosave or presence heartbeat | Schedules |`@crup/react-timer-hook/schedules`|[Autosave heartbeat](https://crup.github.io/react-timer-hook/recipes/intermediate/autosave-heartbeat/)|
63
67
| Polling that can close early | Schedules |`@crup/react-timer-hook/schedules`|[Poll and cancel](https://crup.github.io/react-timer-hook/recipes/intermediate/poll-and-cancel/)|
64
68
| Auction list with independent row controls | Timer group |`@crup/react-timer-hook/group`|[Timer group](https://crup.github.io/react-timer-hook/recipes/advanced/timer-group/)|
69
+
| Checkout holds with independent controls | Timer group |`@crup/react-timer-hook/group`|[Checkout holds](https://crup.github.io/react-timer-hook/recipes/advanced/checkout-holds/)|
65
70
| Upload/job dashboard with per-row polling | Timer group + schedules |`@crup/react-timer-hook/group`|[Per-item polling](https://crup.github.io/react-timer-hook/recipes/advanced/per-item-polling/)|
66
-
| Toast expiry or runtime item timers | Timer group |`@crup/react-timer-hook/group`|[Dynamic items](https://crup.github.io/react-timer-hook/recipes/advanced/dynamic-items/)|
71
+
| Toast expiry or runtime item timers | Timer group |`@crup/react-timer-hook/group`|[Toast auto-dismiss](https://crup.github.io/react-timer-hook/recipes/advanced/toast-auto-dismiss/)|
67
72
68
73
See the full use-case guide: https://crup.github.io/react-timer-hook/use-cases/
69
74
75
+
Design assumptions and runtime limits: https://crup.github.io/react-timer-hook/project/caveats/
|`updateIntervalMs`|`number`| No | Render/update cadence in milliseconds. Defaults to `1000`. This does not define elapsed time; elapsed time is calculated from timestamps. Use a smaller value like `100` or `20` when the UI needs finer updates. |
169
176
|`endWhen`|`(snapshot) => boolean`| No | Ends the lifecycle when it returns `true`. Use this for countdowns, timeouts, and custom stop conditions. |
170
177
|`onEnd`|`(snapshot, controls) => void \| Promise<void>`| No | Called once per generation when `endWhen` ends the lifecycle. `restart()` creates a new generation. |
171
-
|`onError`|`(error, snapshot, controls) => void`| No | Handles sync throws and async rejections from `onEnd`. |
178
+
|`onError`|`(error, snapshot, controls) => void`| No | Handles sync throws and async rejections from `onEnd`. Also used as the fallback for schedule callback failures when a schedule does not define `onError`. |
172
179
173
180
### `useScheduledTimer()` settings
174
181
@@ -193,6 +200,7 @@ Import from `@crup/react-timer-hook/schedules` when you need polling or schedule
193
200
|`leading`|`boolean`| No | Runs the schedule immediately when the timer starts or resumes into a new generation. Defaults to `false`. |
194
201
|`overlap`|`'skip' \| 'allow'`| No | Controls async overlap. Defaults to `skip`, so a pending callback prevents another run. |
195
202
|`callback`|`(snapshot, controls, context) => void \| Promise<void>`| Yes | Scheduled side effect. Receives timing context with `scheduledAt`, `firedAt`, `nextRunAt`, `overdueCount`, and `effectiveEveryMs`. |
203
+
|`onError`|`(error, snapshot, controls, context) => void`| No | Handles sync throws and async rejections from that schedule's `callback`. Falls back to the timer or item `onError` when omitted. |
196
204
197
205
### `useTimerGroup()` settings
198
206
@@ -212,7 +220,7 @@ Import from `@crup/react-timer-hook/group` when many keyed items need independen
212
220
|`autoStart`|`boolean`| No | Starts the item automatically when it is added or synced. Defaults to `false`. |
213
221
|`endWhen`|`(snapshot) => boolean`| No | Ends that item when it returns `true`. |
214
222
|`onEnd`|`(snapshot, controls) => void \| Promise<void>`| No | Called once per item generation when that item ends naturally. |
215
-
|`onError`|`(error, snapshot, controls) => void`| No | Handles sync throws and async rejections from that item's `onEnd`. |
223
+
|`onError`|`(error, snapshot, controls) => void`| No | Handles sync throws and async rejections from that item's `onEnd`. Also used as the fallback for that item's schedule callback failures. |
216
224
|`schedules`|`TimerSchedule[]`| No | Per-item schedules with the same contract as `useScheduledTimer()`. |
217
225
218
226
### Values and controls
@@ -246,9 +254,9 @@ The default import stays small. Add the other pieces only when that screen needs
246
254
247
255
| Piece | Import | Best for | Raw | Gzip | Brotli |
Copy file name to clipboardExpand all lines: docs-site/docs/api/types.mdx
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -59,11 +59,19 @@ type TimerSchedule = {
59
59
controls:TimerControls,
60
60
context:TimerScheduleContext,
61
61
) =>void|Promise<void>;
62
+
onError?: (
63
+
error:unknown,
64
+
snapshot:TimerSnapshot,
65
+
controls:TimerControls,
66
+
context:TimerScheduleContext,
67
+
) =>void;
62
68
};
63
69
```
64
70
65
71
`scheduledAt` is the intended fire time. `firedAt` is when the browser actually ran the callback. `overdueCount` reports how many schedule windows were missed before this callback because the browser, tab, or previous work delayed execution.
66
72
73
+
Schedule IDs must be unique within the same schedule list. If a schedule `callback` fails, schedule `onError` handles it. If schedule `onError` is omitted, the timer or timer-group item `onError` is used.
74
+
67
75
## Diagnostics
68
76
69
77
Diagnostics are opt-in. The package does not emit logs by default.
Copy file name to clipboardExpand all lines: docs-site/docs/api/use-scheduled-timer.mdx
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ type UseScheduledTimerOptions = UseTimerOptions & {
19
19
```
20
20
21
21
Schedules run while active and default to `overlap: 'skip'`.
22
-
`onError` comes from `UseTimerOptions` and receives sync throws or async rejections from `onEnd`.
22
+
`onError` comes from `UseTimerOptions` and receives sync throws or async rejections from `onEnd`. It is also the fallback for schedule callback errors when a schedule does not define its own `onError`.
The third callback argument contains `scheduledAt`, `firedAt`, `nextRunAt`, `overdueCount`, and `effectiveEveryMs`.
41
42
42
-
When the schedule cadence changes, the active scheduler recalculates the next timeout immediately. Changing only the callback keeps the current cadence and uses the latest callback on the next run.
43
+
When the schedule cadence changes, the active scheduler recalculates the next timeout after the render commits. Changing only the callback keeps the current cadence and uses the latest callback on the next run.
Copy file name to clipboardExpand all lines: docs-site/docs/api/use-timer-group.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ type TimerGroupItem = {
32
32
};
33
33
```
34
34
35
-
`onError` receives sync throws and async rejections from that item's `onEnd`.
35
+
`onError` receives sync throws and async rejections from that item's `onEnd`. It also handles item schedule callback failures when a schedule does not define its own `onError`.
36
36
37
37
When `items` is controlled by props, pass a new array/object when item definitions change. The store preserves state for existing IDs and syncs new callbacks, deadlines, and schedules without resetting the item generation.
0 commit comments