@crup/react-timer-hook 0.0.1-alpha.14 → 0.0.1-alpha.15
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 +24 -5
- package/dist/chunk-N626U6HM.js +1 -0
- package/dist/diagnostics.d.cts +2 -2
- package/dist/diagnostics.d.ts +2 -2
- package/dist/duration.d.cts +1 -1
- package/dist/duration.d.ts +1 -1
- package/dist/group.cjs +1 -1
- package/dist/group.d.cts +2 -2
- package/dist/group.d.ts +2 -2
- package/dist/group.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/schedules.cjs +1 -1
- package/dist/schedules.d.cts +2 -2
- package/dist/schedules.d.ts +2 -2
- package/dist/schedules.js +1 -1
- package/dist/{types-DK7omKO-.d.cts → types--o_xW2FP.d.cts} +2 -0
- package/dist/{types-DK7omKO-.d.ts → types--o_xW2FP.d.ts} +2 -0
- package/package.json +1 -1
- package/dist/chunk-RT4C7DWO.js +0 -1
package/README.md
CHANGED
|
@@ -20,11 +20,11 @@ Timers get messy when a product needs pause and resume, countdowns tied to serve
|
|
|
20
20
|
`@crup/react-timer-hook` keeps the default import small and lets you add only the pieces your screen needs:
|
|
21
21
|
|
|
22
22
|
- ⏱️ `useTimer()` from the root package for one lifecycle: stopwatch, countdown, clock, or custom flow.
|
|
23
|
-
- 🔋 Add
|
|
23
|
+
- 🔋 Add schedules, timer groups, duration helpers, and diagnostics only when a screen needs them.
|
|
24
24
|
- 🧭 `useTimerGroup()` from `/group` for many keyed lifecycles with one shared scheduler.
|
|
25
25
|
- 📡 `useScheduledTimer()` from `/schedules` for polling and timing context.
|
|
26
26
|
- 🧩 `durationParts()` from `/duration` for common display math.
|
|
27
|
-
- 🧪
|
|
27
|
+
- 🧪 Covered for rerenders, React Strict Mode, async callbacks, cleanup, and multi-timer screens.
|
|
28
28
|
- 🤖 AI-ready docs are available through hosted `llms.txt`, `llms-full.txt`, and an optional MCP docs helper.
|
|
29
29
|
|
|
30
30
|
## Install
|
|
@@ -51,6 +51,22 @@ Each recipe has a live playground and a focused code sample:
|
|
|
51
51
|
- Intermediate: [once-only onEnd](https://crup.github.io/react-timer-hook/recipes/intermediate/once-only-on-end/), [polling schedule](https://crup.github.io/react-timer-hook/recipes/intermediate/polling-schedule/), [poll and cancel](https://crup.github.io/react-timer-hook/recipes/intermediate/poll-and-cancel/), [backend event stop](https://crup.github.io/react-timer-hook/recipes/intermediate/backend-event-stop/), [diagnostics](https://crup.github.io/react-timer-hook/recipes/intermediate/debug-logs/)
|
|
52
52
|
- Advanced: [many display countdowns](https://crup.github.io/react-timer-hook/recipes/advanced/many-display-countdowns/), [timer group](https://crup.github.io/react-timer-hook/recipes/advanced/timer-group/), [group controls](https://crup.github.io/react-timer-hook/recipes/advanced/group-controls/), [per-item polling](https://crup.github.io/react-timer-hook/recipes/advanced/per-item-polling/), [dynamic items](https://crup.github.io/react-timer-hook/recipes/advanced/dynamic-items/)
|
|
53
53
|
|
|
54
|
+
## Use cases
|
|
55
|
+
|
|
56
|
+
| Product case | Use | Import | Recipe |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| Stopwatch, call timer, workout timer | Core | `@crup/react-timer-hook` | [Stopwatch](https://crup.github.io/react-timer-hook/recipes/basic/stopwatch/) |
|
|
59
|
+
| Wall clock or "last updated" display | Core | `@crup/react-timer-hook` | [Wall clock](https://crup.github.io/react-timer-hook/recipes/basic/wall-clock/) |
|
|
60
|
+
| Auction, reservation, or job deadline | Core | `@crup/react-timer-hook` | [Absolute countdown](https://crup.github.io/react-timer-hook/recipes/basic/absolute-countdown/) |
|
|
61
|
+
| Focus timer or checkout hold that pauses | Core + duration | `@crup/react-timer-hook` + `/duration` | [Pausable countdown](https://crup.github.io/react-timer-hook/recipes/basic/pausable-countdown/) |
|
|
62
|
+
| Backend status polling | Schedules | `@crup/react-timer-hook/schedules` | [Polling schedule](https://crup.github.io/react-timer-hook/recipes/intermediate/polling-schedule/) |
|
|
63
|
+
| 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
|
+
| 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/) |
|
|
65
|
+
| 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/) |
|
|
67
|
+
|
|
68
|
+
See the full use-case guide: https://crup.github.io/react-timer-hook/use-cases/
|
|
69
|
+
|
|
54
70
|
## Quick examples
|
|
55
71
|
|
|
56
72
|
### Stopwatch
|
|
@@ -152,6 +168,7 @@ const timers = useTimerGroup({
|
|
|
152
168
|
| `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. |
|
|
153
169
|
| `endWhen` | `(snapshot) => boolean` | No | Ends the lifecycle when it returns `true`. Use this for countdowns, timeouts, and custom stop conditions. |
|
|
154
170
|
| `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`. |
|
|
155
172
|
|
|
156
173
|
### `useScheduledTimer()` settings
|
|
157
174
|
|
|
@@ -163,6 +180,7 @@ Import from `@crup/react-timer-hook/schedules` when you need polling or schedule
|
|
|
163
180
|
| `updateIntervalMs` | `number` | No | Render/update cadence in milliseconds. Defaults to `1000`. Scheduled callbacks can run on their own cadence. |
|
|
164
181
|
| `endWhen` | `(snapshot) => boolean` | No | Ends the lifecycle when it returns `true`. |
|
|
165
182
|
| `onEnd` | `(snapshot, controls) => void \| Promise<void>` | No | Called once per generation when `endWhen` ends the lifecycle. |
|
|
183
|
+
| `onError` | `(error, snapshot, controls) => void` | No | Handles sync throws and async rejections from `onEnd`. |
|
|
166
184
|
| `schedules` | `TimerSchedule[]` | No | Scheduled side effects that run while the timer is active. Async overlap defaults to `skip`. |
|
|
167
185
|
| `diagnostics` | `TimerDiagnostics` | No | Optional lifecycle and schedule events. No logs are emitted unless you pass a logger. |
|
|
168
186
|
|
|
@@ -194,6 +212,7 @@ Import from `@crup/react-timer-hook/group` when many keyed items need independen
|
|
|
194
212
|
| `autoStart` | `boolean` | No | Starts the item automatically when it is added or synced. Defaults to `false`. |
|
|
195
213
|
| `endWhen` | `(snapshot) => boolean` | No | Ends that item when it returns `true`. |
|
|
196
214
|
| `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`. |
|
|
197
216
|
| `schedules` | `TimerSchedule[]` | No | Per-item schedules with the same contract as `useScheduledTimer()`. |
|
|
198
217
|
|
|
199
218
|
### Values and controls
|
|
@@ -227,9 +246,9 @@ The default import stays small. Add the other pieces only when that screen needs
|
|
|
227
246
|
|
|
228
247
|
| Piece | Import | Best for | Raw | Gzip | Brotli |
|
|
229
248
|
| --- | --- | --- | ---: | ---: | ---: |
|
|
230
|
-
| ⏱️ Core | `@crup/react-timer-hook` | Stopwatch, countdown, clock, custom lifecycle | 3.
|
|
231
|
-
| 🧭 Timer group | `@crup/react-timer-hook/group` | Many independent row/item timers | 9.
|
|
232
|
-
| 📡 Schedules | `@crup/react-timer-hook/schedules` | Polling, cadence callbacks, overdue timing context | 7.
|
|
249
|
+
| ⏱️ Core | `@crup/react-timer-hook` | Stopwatch, countdown, clock, custom lifecycle | 3.96 kB | 1.37 kB | 1.25 kB |
|
|
250
|
+
| 🧭 Timer group | `@crup/react-timer-hook/group` | Many independent row/item timers | 9.91 kB | 3.51 kB | 3.20 kB |
|
|
251
|
+
| 📡 Schedules | `@crup/react-timer-hook/schedules` | Polling, cadence callbacks, overdue timing context | 7.62 kB | 2.67 kB | 2.46 kB |
|
|
233
252
|
| 🧩 Duration | `@crup/react-timer-hook/duration` | `days`, `hours`, `minutes`, `seconds`, `milliseconds` | 318 B | 224 B | 192 B |
|
|
234
253
|
| 🔎 Diagnostics | `@crup/react-timer-hook/diagnostics` | Optional lifecycle and schedule event logging | 105 B | 115 B | 90 B |
|
|
235
254
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as p,d as c,k as f}from"./chunk-I3PNNG3I.js";function y(e){return e?typeof e=="function"?{enabled:!0,includeTicks:!1,logger:e}:{enabled:e.enabled!==!1,includeTicks:e.includeTicks??!1,label:e.label,logger:e.logger}:{enabled:!1,includeTicks:!1}}function v(e,n){let t=y(e);!t.enabled||!t.logger||n.type==="timer:tick"&&!t.includeTicks||t.logger({...n,label:n.label??t.label})}function k(e,n){return{generation:n,tick:e.tick,now:e.now,elapsedMilliseconds:e.elapsedMilliseconds,status:e.status}}function b(){return{lastRunAt:null,pendingCount:0,leadingGeneration:null}}function E({schedules:e=[],states:n,snapshot:t,generation:o,controls:r,activation:i=!1,isLive:l,onEvent:d}){let u=new Set;e.forEach((s,C)=>{let m=s.id??String(C);u.add(m);let a=n.get(m);if(a||(a=b(),n.set(m,a)),i&&s.leading&&a.leadingGeneration!==o){a.leadingGeneration=o,g(s,m,a,t,o,r,S(s,m,t.now,t.now,0),l,d);return}a.lastRunAt===null&&(a.lastRunAt=t.now);let T=Math.floor((t.now-a.lastRunAt)/s.everyMs);if(T>=1){let h=a.lastRunAt+T*s.everyMs;g(s,m,a,t,o,r,S(s,m,h,t.now,T-1),l,d)}});for(let s of n.keys())u.has(s)||n.delete(s)}function I(e,n,t,o){let r=o;return e?.forEach((i,l)=>{let d=i.id??String(l),s=n.get(d)?.lastRunAt??t;r=Math.min(r,Math.max(1,s+i.everyMs-t))}),r}function M(e,n,t,o){let r=new Set;e?.forEach((i,l)=>{let d=i.id??String(l);r.add(d),n.has(d)||n.set(d,{lastRunAt:o?t:null,pendingCount:0,leadingGeneration:null})});for(let i of n.keys())r.has(i)||n.delete(i)}function R(e){return(e??[]).map((n,t)=>`${n.id??t}:${n.everyMs}:${n.leading??!1}:${n.overlap??"skip"}`).join(",")}function S(e,n,t,o,r){return{scheduleId:e.id??n,scheduledAt:t,firedAt:o,nextRunAt:t+e.everyMs,overdueCount:r,effectiveEveryMs:e.everyMs}}function g(e,n,t,o,r,i,l,d,u){if(t.pendingCount>0&&(e.overlap??"skip")==="skip"){t.lastRunAt=l.scheduledAt,u?.({type:"schedule:skip",context:l,reason:"overlap"});return}t.lastRunAt=l.scheduledAt,t.pendingCount+=1,u?.({type:"schedule:start",context:l}),Promise.resolve().then(()=>e.callback(o,i,l)).then(()=>u?.({type:"schedule:end",context:l}),s=>u?.({type:"schedule:error",context:l,error:s})).finally(()=>{d(r)&&(t.pendingCount=Math.max(0,t.pendingCount-1))})}function G(e,n){return{state:p(n),definition:e,endCalledGeneration:null}}function P(e){e.endCalledGeneration=null}function O(e,n){return c(e.state,n)}function $(e,n,t,o){let r=c(e.state,n);if(!e.definition.endWhen?.(r)||!f(e.state,n))return null;let i=c(e.state,n);return x(e,i,t,o),i}function x(e,n,t,o){let r=e.state.generation;if(e.endCalledGeneration!==r){e.endCalledGeneration=r;try{let i=e.definition.onEnd?.(n,t);i&&o&&Promise.resolve(i).catch(l=>o?.(l,n,r))}catch(i){if(o){o(i,n,r);return}throw i}}}export{v as a,k as b,E as c,I as d,M as e,R as f,G as g,P as h,O as i,$ as j};
|
package/dist/diagnostics.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as TimerDiagnostics } from './types
|
|
2
|
-
export { j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger } from './types
|
|
1
|
+
import { i as TimerDiagnostics } from './types--o_xW2FP.cjs';
|
|
2
|
+
export { j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger } from './types--o_xW2FP.cjs';
|
|
3
3
|
|
|
4
4
|
declare function consoleTimerDiagnostics(options?: {
|
|
5
5
|
includeTicks?: boolean;
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as TimerDiagnostics } from './types
|
|
2
|
-
export { j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger } from './types
|
|
1
|
+
import { i as TimerDiagnostics } from './types--o_xW2FP.js';
|
|
2
|
+
export { j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger } from './types--o_xW2FP.js';
|
|
3
3
|
|
|
4
4
|
declare function consoleTimerDiagnostics(options?: {
|
|
5
5
|
includeTicks?: boolean;
|
package/dist/duration.d.cts
CHANGED
package/dist/duration.d.ts
CHANGED
package/dist/group.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var F=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var i in t)F(e,i,{get:t[i],enumerable:!0})},ye=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Se(t))!ge.call(e,a)&&a!==i&&F(e,a,{get:()=>t[a],enumerable:!(s=Te(t,a))||s.enumerable});return e};var we=e=>ye(F({},"__esModule",{value:!0}),e);var ke={};he(ke,{useTimerGroup:()=>ae});module.exports=we(ke);var I=require("react");function p(){let e=Date.now(),t=typeof performance<"u"&&typeof performance.now=="function"?performance.now():e;return{wallNow:e,monotonicNow:t}}function H(e,t){if(!Number.isFinite(e)||e<=0)throw new RangeError(`${t} must be a finite number greater than 0`)}function be(e){return e?typeof e=="function"?{enabled:!0,includeTicks:!1,logger:e}:{enabled:e.enabled!==!1,includeTicks:e.includeTicks??!1,label:e.label,logger:e.logger}:{enabled:!1,includeTicks:!1}}function A(e,t){let i=be(e);!i.enabled||!i.logger||t.type==="timer:tick"&&!i.includeTicks||i.logger({...t,label:t.label??i.label})}function x(e,t){return{generation:t,tick:e.tick,now:e.now,elapsedMilliseconds:e.elapsedMilliseconds,status:e.status}}function Ce(){return{lastRunAt:null,pendingCount:0,leadingGeneration:null}}function V({schedules:e=[],states:t,snapshot:i,generation:s,controls:a,activation:u=!1,isLive:c,onEvent:T}){let d=new Set;e.forEach((m,g)=>{let b=m.id??String(g);d.add(b);let S=t.get(b);if(S||(S=Ce(),t.set(b,S)),u&&m.leading&&S.leadingGeneration!==s){S.leadingGeneration=s,Q(m,b,S,i,s,a,J(m,b,i.now,i.now,0),c,T);return}S.lastRunAt===null&&(S.lastRunAt=i.now);let v=Math.floor((i.now-S.lastRunAt)/m.everyMs);if(v>=1){let h=S.lastRunAt+v*m.everyMs;Q(m,b,S,i,s,a,J(m,b,h,i.now,v-1),c,T)}});for(let m of t.keys())d.has(m)||t.delete(m)}function X(e,t,i,s){let a=s;return e?.forEach((u,c)=>{let T=u.id??String(c),m=t.get(T)?.lastRunAt??i;a=Math.min(a,Math.max(1,m+u.everyMs-i))}),a}function Y(e,t,i,s){let a=new Set;e?.forEach((u,c)=>{let T=u.id??String(c);a.add(T),t.has(T)||t.set(T,{lastRunAt:s?i:null,pendingCount:0,leadingGeneration:null})});for(let u of t.keys())a.has(u)||t.delete(u)}function J(e,t,i,s,a){return{scheduleId:e.id??t,scheduledAt:i,firedAt:s,nextRunAt:i+e.everyMs,overdueCount:a,effectiveEveryMs:e.everyMs}}function Q(e,t,i,s,a,u,c,T,d){if(i.pendingCount>0&&(e.overlap??"skip")==="skip"){i.lastRunAt=c.scheduledAt,d?.({type:"schedule:skip",context:c,reason:"overlap"});return}i.lastRunAt=c.scheduledAt,i.pendingCount+=1,d?.({type:"schedule:start",context:c}),Promise.resolve().then(()=>e.callback(s,u,c)).then(()=>d?.({type:"schedule:end",context:c}),m=>d?.({type:"schedule:error",context:c,error:m})).finally(()=>{T(a)&&(i.pendingCount=Math.max(0,i.pendingCount-1))})}function Z(e){return{status:"idle",generation:0,tick:0,startedAt:null,pausedAt:null,endedAt:null,cancelledAt:null,cancelReason:null,baseElapsedMilliseconds:0,activeStartedAtMonotonic:null,now:e.wallNow}}function G(e,t){return e.status!=="running"||e.activeStartedAtMonotonic===null?e.baseElapsedMilliseconds:Math.max(0,e.baseElapsedMilliseconds+t.monotonicNow-e.activeStartedAtMonotonic)}function E(e,t){let i=G(e,t);return{status:e.status,now:t.wallNow,tick:e.tick,startedAt:e.startedAt,pausedAt:e.pausedAt,endedAt:e.endedAt,cancelledAt:e.cancelledAt,cancelReason:e.cancelReason,elapsedMilliseconds:i,isIdle:e.status==="idle",isRunning:e.status==="running",isPaused:e.status==="paused",isEnded:e.status==="ended",isCancelled:e.status==="cancelled"}}function M(e,t){return e.status!=="idle"?!1:(e.status="running",e.startedAt=t.wallNow,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function _(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=G(e,t),e.activeStartedAtMonotonic=null,e.status="paused",e.pausedAt=t.wallNow,e.now=t.wallNow,!0)}function ee(e,t){return e.status!=="paused"?!1:(e.status="running",e.pausedAt=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function L(e,t,i={}){return e.generation+=1,e.tick=0,e.status=i.autoStart?"running":"idle",e.startedAt=i.autoStart?t.wallNow:null,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.baseElapsedMilliseconds=0,e.activeStartedAtMonotonic=i.autoStart?t.monotonicNow:null,e.now=t.wallNow,!0}function te(e,t){return L(e,t,{autoStart:!0})}function ne(e,t,i){return e.status==="ended"||e.status==="cancelled"?!1:(e.baseElapsedMilliseconds=G(e,t),e.activeStartedAtMonotonic=null,e.status="cancelled",e.cancelledAt=t.wallNow,e.cancelReason=i??null,e.now=t.wallNow,!0)}function re(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=G(e,t),e.activeStartedAtMonotonic=null,e.status="ended",e.endedAt=t.wallNow,e.now=t.wallNow,!0)}function oe(e,t){return e.status!=="running"?!1:(e.tick+=1,e.now=t.wallNow,!0)}function ie(e,t){return{state:Z(t),definition:e,endCalledGeneration:null}}function j(e){e.endCalledGeneration=null}function w(e,t){return E(e.state,t)}function se(e,t,i,s){let a=E(e.state,t);if(!e.definition.endWhen?.(a)||!re(e.state,t))return null;let u=E(e.state,t);return Ie(e,u,i,s),u}function Ie(e,t,i,s){let a=e.state.generation;if(e.endCalledGeneration!==a){e.endCalledGeneration=a;try{let u=e.definition.onEnd?.(t,i);u&&s&&Promise.resolve(u).catch(c=>s?.(c,t,a))}catch(u){if(s){s(u,t,a);return}throw u}}}function ae(e={}){let t=(0,I.useRef)(null);return t.current===null&&(t.current=ve(e)),t.current.setOptions(e),(0,I.useEffect)(()=>{let s=t.current;return()=>s.destroy()},[]),(0,I.useEffect)(()=>{t.current.sync()},[e.diagnostics,e.items,e.updateIntervalMs]),{...(0,I.useSyncExternalStore)(t.current.subscribe,t.current.getSnapshot,t.current.getSnapshot),get:t.current.getTimer,...t.current.controls}}function ve(e){let t=e;K(t);let i=new Set,s=new Map,a=le(s,p().wallNow),u=null,c=R(t),T=!0,d=(n=p())=>{a=le(s,n.wallNow),i.forEach(r=>r())},m=()=>{u!==null&&(clearTimeout(u),u=null)},g=(n,r,o,l={})=>{A(t.diagnostics,{type:n,scope:"timer-group",timerId:r?.id,...x(o,r?.state.generation??0),...l})},b=n=>(r,o,l)=>{A(t.diagnostics,{type:"callback:error",scope:"timer-group",timerId:n.id,error:r,...x(o,l)})},S=(n,r,o)=>l=>{A(t.diagnostics,{type:l.type,scope:"timer-group",timerId:n.id,...l.context,..."reason"in l?{reason:l.reason}:{},..."error"in l?{error:l.error}:{},...x(r,o)})},v=n=>({start:()=>N(n),pause:()=>D(n),resume:()=>P(n),reset:r=>O(n,r),restart:()=>$(n),cancel:r=>U(n,r)}),h=(n,r=p(),o=!1)=>{if(n.state.status!=="running")return!1;let l=v(n.id),f=se(n,r,l,b(n));if(f)return g("timer:end",n,f),!0;let C=w(n,r);return V({schedules:n.definition.schedules,states:n.schedules,snapshot:C,generation:n.state.generation,controls:l,activation:o,isLive:z=>s.get(n.id)?.state.generation===z,onEvent:S(n,C,n.state.generation)}),!1},y=()=>{m();let n=Array.from(s.values()).filter(l=>l.state.status==="running");if(n.length===0)return;let r=p(),o=t.updateIntervalMs??1e3;for(let l of n)o=Math.min(o,X(l.definition.schedules,l.schedules,r.wallNow,o));g("scheduler:start",n[0],w(n[0],r)),u=setTimeout(()=>{let l=p();for(let f of s.values()){if(f.state.status!=="running")continue;oe(f.state,l);let C=w(f,l);g("timer:tick",f,C),h(f,l)}d(l),y()},o)},q=n=>{let r=s.get(n.id);if(r)return r.definition=n,k(r,p().wallNow),{item:r,added:!1};let o=p(),l={...ie(n,o),id:n.id,schedules:new Map};return s.set(n.id,l),k(l,o.wallNow),n.autoStart&&(M(l.state,o),h(l,o,!0)),{item:l,added:!0}},B=()=>{K(t);let n=T;T=!1;let r=new Set,o=!1,l=p();if(t.items){for(let f of t.items){r.add(f.id);let{item:C,added:z}=q(f);o=o||z,f.autoStart&&C.state.status==="idle"&&M(C.state,l)&&(o=!0,o=h(C,l,!0)||o),o=h(C,l)||o}for(let f of s.keys())r.has(f)||(s.delete(f),o=!0)}o&&d(l),(o||n)&&y()},ue=n=>{if(W([n]),s.has(n.id))throw new Error(`Timer item "${n.id}" already exists`);q(n),c=R(t),d(),y()},ce=(n,r)=>{let o=s.get(n);if(!o)return;let l={...o.definition,...r,id:n};W([l]),o.definition=l,k(o,p().wallNow),h(o),c=R(t),d(),y()},de=n=>{s.delete(n)&&(d(),y())},me=()=>{s.clear(),m(),d()},N=n=>{let r=s.get(n);if(!r)return;let o=p();M(r.state,o)&&(g("timer:start",r,w(r,o)),h(r,o,!0),d(o),y())},D=n=>{let r=s.get(n);if(!r)return;let o=p();_(r.state,o)&&(g("timer:pause",r,w(r,o)),d(o),y())},P=n=>{let r=s.get(n);if(!r)return;let o=p();ee(r.state,o)&&(g("timer:resume",r,w(r,o)),h(r,o,!0),d(o),y())},O=(n,r={})=>{let o=s.get(n);if(!o)return;let l=p();L(o.state,l,r),o.schedules.clear(),k(o,l.wallNow),j(o),g("timer:reset",o,w(o,l)),h(o,l,r.autoStart),d(l),y()},$=n=>{let r=s.get(n);if(!r)return;let o=p();te(r.state,o),r.schedules.clear(),k(r,o.wallNow),j(r),g("timer:restart",r,w(r,o)),h(r,o,!0),d(o),y()},U=(n,r)=>{let o=s.get(n);if(!o)return;let l=p();ne(o.state,l,r)&&(g("timer:cancel",o,w(o,l),{reason:r}),d(l),y())},pe=n=>{let r=s.get(n);return r?w(r,p()):void 0},fe={add:ue,update:ce,remove:de,clear:me,start:N,pause:D,resume:P,reset:O,restart:$,cancel:U,startAll:()=>Array.from(s.keys()).forEach(N),pauseAll:()=>Array.from(s.keys()).forEach(D),resumeAll:()=>Array.from(s.keys()).forEach(P),resetAll:n=>Array.from(s.keys()).forEach(r=>O(r,n)),restartAll:()=>Array.from(s.keys()).forEach($),cancelAll:n=>Array.from(s.keys()).forEach(r=>U(r,n))};return B(),{controls:fe,destroy:m,getSnapshot:()=>a,getTimer:pe,setOptions:n=>{K(n);let r=R(n);r!==c&&(c=r,T=!0),t=n},subscribe:n=>(i.add(n),()=>i.delete(n)),sync:B}}function le(e,t){return{now:t,size:e.size,ids:Array.from(e.keys())}}function k(e,t){Y(e.definition.schedules,e.schedules,t,e.state.status==="running")}function R(e){return[e.updateIntervalMs??1e3,...(e.items??[]).map(t=>{let i=t.schedules?.map((s,a)=>`${s.id??a}:${s.everyMs}:${s.leading??!1}:${s.overlap??"skip"}`).join(",");return`${t.id}:${t.autoStart??!1}:${i??""}`})].join("|")}function K(e){H(e.updateIntervalMs??1e3,"updateIntervalMs"),W(e.items)}function W(e){let t=new Set;e?.forEach(i=>{if(!i.id)throw new Error("Timer item id is required");if(t.has(i.id))throw new Error(`Duplicate timer item id "${i.id}"`);t.add(i.id),i.schedules?.forEach(s=>H(s.everyMs,"schedule.everyMs"))})}0&&(module.exports={useTimerGroup});
|
|
1
|
+
"use strict";var F=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var we=Object.prototype.hasOwnProperty;var be=(e,t)=>{for(var i in t)F(e,i,{get:t[i],enumerable:!0})},Ce=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ye(t))!we.call(e,a)&&a!==i&&F(e,a,{get:()=>t[a],enumerable:!(s=he(t,a))||s.enumerable});return e};var Ie=e=>Ce(F({},"__esModule",{value:!0}),e);var Ge={};be(Ge,{useTimerGroup:()=>ce});module.exports=Ie(Ge);var v=require("react");function f(){let e=Date.now(),t=typeof performance<"u"&&typeof performance.now=="function"?performance.now():e;return{wallNow:e,monotonicNow:t}}function H(e,t){if(!Number.isFinite(e)||e<=0)throw new RangeError(`${t} must be a finite number greater than 0`)}function ve(e){return e?typeof e=="function"?{enabled:!0,includeTicks:!1,logger:e}:{enabled:e.enabled!==!1,includeTicks:e.includeTicks??!1,label:e.label,logger:e.logger}:{enabled:!1,includeTicks:!1}}function x(e,t){let i=ve(e);!i.enabled||!i.logger||t.type==="timer:tick"&&!i.includeTicks||i.logger({...t,label:t.label??i.label})}function G(e,t){return{generation:t,tick:e.tick,now:e.now,elapsedMilliseconds:e.elapsedMilliseconds,status:e.status}}function ke(){return{lastRunAt:null,pendingCount:0,leadingGeneration:null}}function Y({schedules:e=[],states:t,snapshot:i,generation:s,controls:a,activation:u=!1,isLive:m,onEvent:d}){let y=new Set;e.forEach((c,D)=>{let b=c.id??String(D);y.add(b);let S=t.get(b);if(S||(S=ke(),t.set(b,S)),u&&c.leading&&S.leadingGeneration!==s){S.leadingGeneration=s,X(c,b,S,i,s,a,V(c,b,i.now,i.now,0),m,d);return}S.lastRunAt===null&&(S.lastRunAt=i.now);let g=Math.floor((i.now-S.lastRunAt)/c.everyMs);if(g>=1){let h=S.lastRunAt+g*c.everyMs;X(c,b,S,i,s,a,V(c,b,h,i.now,g-1),m,d)}});for(let c of t.keys())y.has(c)||t.delete(c)}function Z(e,t,i,s){let a=s;return e?.forEach((u,m)=>{let d=u.id??String(m),c=t.get(d)?.lastRunAt??i;a=Math.min(a,Math.max(1,c+u.everyMs-i))}),a}function _(e,t,i,s){let a=new Set;e?.forEach((u,m)=>{let d=u.id??String(m);a.add(d),t.has(d)||t.set(d,{lastRunAt:s?i:null,pendingCount:0,leadingGeneration:null})});for(let u of t.keys())a.has(u)||t.delete(u)}function ee(e){return(e??[]).map((t,i)=>`${t.id??i}:${t.everyMs}:${t.leading??!1}:${t.overlap??"skip"}`).join(",")}function V(e,t,i,s,a){return{scheduleId:e.id??t,scheduledAt:i,firedAt:s,nextRunAt:i+e.everyMs,overdueCount:a,effectiveEveryMs:e.everyMs}}function X(e,t,i,s,a,u,m,d,y){if(i.pendingCount>0&&(e.overlap??"skip")==="skip"){i.lastRunAt=m.scheduledAt,y?.({type:"schedule:skip",context:m,reason:"overlap"});return}i.lastRunAt=m.scheduledAt,i.pendingCount+=1,y?.({type:"schedule:start",context:m}),Promise.resolve().then(()=>e.callback(s,u,m)).then(()=>y?.({type:"schedule:end",context:m}),c=>y?.({type:"schedule:error",context:m,error:c})).finally(()=>{d(a)&&(i.pendingCount=Math.max(0,i.pendingCount-1))})}function te(e){return{status:"idle",generation:0,tick:0,startedAt:null,pausedAt:null,endedAt:null,cancelledAt:null,cancelReason:null,baseElapsedMilliseconds:0,activeStartedAtMonotonic:null,now:e.wallNow}}function E(e,t){return e.status!=="running"||e.activeStartedAtMonotonic===null?e.baseElapsedMilliseconds:Math.max(0,e.baseElapsedMilliseconds+t.monotonicNow-e.activeStartedAtMonotonic)}function R(e,t){let i=E(e,t);return{status:e.status,now:t.wallNow,tick:e.tick,startedAt:e.startedAt,pausedAt:e.pausedAt,endedAt:e.endedAt,cancelledAt:e.cancelledAt,cancelReason:e.cancelReason,elapsedMilliseconds:i,isIdle:e.status==="idle",isRunning:e.status==="running",isPaused:e.status==="paused",isEnded:e.status==="ended",isCancelled:e.status==="cancelled"}}function M(e,t){return e.status!=="idle"?!1:(e.status="running",e.startedAt=t.wallNow,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function ne(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=E(e,t),e.activeStartedAtMonotonic=null,e.status="paused",e.pausedAt=t.wallNow,e.now=t.wallNow,!0)}function re(e,t){return e.status!=="paused"?!1:(e.status="running",e.pausedAt=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function j(e,t,i={}){return e.generation+=1,e.tick=0,e.status=i.autoStart?"running":"idle",e.startedAt=i.autoStart?t.wallNow:null,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.baseElapsedMilliseconds=0,e.activeStartedAtMonotonic=i.autoStart?t.monotonicNow:null,e.now=t.wallNow,!0}function oe(e,t){return j(e,t,{autoStart:!0})}function ie(e,t,i){return e.status==="ended"||e.status==="cancelled"?!1:(e.baseElapsedMilliseconds=E(e,t),e.activeStartedAtMonotonic=null,e.status="cancelled",e.cancelledAt=t.wallNow,e.cancelReason=i??null,e.now=t.wallNow,!0)}function se(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=E(e,t),e.activeStartedAtMonotonic=null,e.status="ended",e.endedAt=t.wallNow,e.now=t.wallNow,!0)}function le(e,t){return e.status!=="running"?!1:(e.tick+=1,e.now=t.wallNow,!0)}function ae(e,t){return{state:te(t),definition:e,endCalledGeneration:null}}function K(e){e.endCalledGeneration=null}function w(e,t){return R(e.state,t)}function ue(e,t,i,s){let a=R(e.state,t);if(!e.definition.endWhen?.(a)||!se(e.state,t))return null;let u=R(e.state,t);return Ae(e,u,i,s),u}function Ae(e,t,i,s){let a=e.state.generation;if(e.endCalledGeneration!==a){e.endCalledGeneration=a;try{let u=e.definition.onEnd?.(t,i);u&&s&&Promise.resolve(u).catch(m=>s?.(m,t,a))}catch(u){if(s){s(u,t,a);return}throw u}}}function ce(e={}){let t=(0,v.useRef)(null);return t.current===null&&(t.current=xe(e)),t.current.setOptions(e),(0,v.useEffect)(()=>{let s=t.current;return()=>s.destroy()},[]),{...(0,v.useSyncExternalStore)(t.current.subscribe,t.current.getSnapshot,t.current.getSnapshot),get:t.current.getTimer,...t.current.controls}}function xe(e){let t=e;q(t);let i=new Set,s=new Map,a=W(s,f().wallNow),u=null,m=N(t),d=(n=f())=>{a=W(s,n.wallNow),i.forEach(r=>r())},y=()=>{u!==null&&(clearTimeout(u),u=null)},c=(n,r,o,l={})=>{x(t.diagnostics,{type:n,scope:"timer-group",timerId:r?.id,...G(o,r?.state.generation??0),...l})},D=n=>(r,o,l)=>{n.definition.onError?.(r,o,S(n.id)),x(t.diagnostics,{type:"callback:error",scope:"timer-group",timerId:n.id,error:r,...G(o,l)})},b=(n,r,o)=>l=>{x(t.diagnostics,{type:l.type,scope:"timer-group",timerId:n.id,...l.context,..."reason"in l?{reason:l.reason}:{},..."error"in l?{error:l.error}:{},...G(r,o)})},S=n=>({start:()=>P(n),pause:()=>O(n),resume:()=>$(n),reset:r=>U(n,r),restart:()=>z(n),cancel:r=>L(n,r)}),g=(n,r=f(),o=!1)=>{if(n.state.status!=="running")return!1;let l=S(n.id),T=ue(n,r,l,D(n));if(T)return c("timer:end",n,T),!0;let p=w(n,r);return Y({schedules:n.definition.schedules,states:n.schedules,snapshot:p,generation:n.state.generation,controls:l,activation:o,isLive:C=>s.get(n.id)?.state.generation===C,onEvent:b(n,p,n.state.generation)}),!1},h=(n=!0)=>{y();let r=Array.from(s.values()).filter(T=>T.state.status==="running");if(r.length===0)return;let o=f(),l=t.updateIntervalMs??1e3;for(let T of r)l=Math.min(l,Z(T.definition.schedules,T.schedules,o.wallNow,l));n&&c("scheduler:start",r[0],w(r[0],o)),u=setTimeout(()=>{let T=f();for(let p of s.values()){if(p.state.status!=="running")continue;le(p.state,T);let C=w(p,T);c("timer:tick",p,C),g(p,T)}d(T),h()},l)},J=n=>{let r=s.get(n.id);if(r)return r.definition=n,k(r,f().wallNow),{item:r,added:!1};let o=f(),l={...ae(n,o),id:n.id,schedules:new Map};return s.set(n.id,l),k(l,o.wallNow),{item:l,added:!0}},Q=(n={})=>{let r=n.notify??!0,o=n.process??!0,l=n.reschedule??!0;q(t);let T=new Set,p=!1,C=f();if(t.items){for(let I of t.items){T.add(I.id);let{item:A,added:ge}=J(I);p=p||ge,I.autoStart&&A.state.status==="idle"&&M(A.state,C)&&(p=!0,o&&(p=g(A,C,!0)||p)),o&&(p=g(A,C)||p)}for(let I of s.keys())T.has(I)||(s.delete(I),p=!0)}p&&(r?d(C):a=W(s,C.wallNow)),(p||l)&&h(r)},de=n=>{if(B([n]),s.has(n.id))throw new Error(`Timer item "${n.id}" already exists`);let{item:r}=J(n),o=f();n.autoStart&&M(r.state,o)&&g(r,o,!0),m=N(t),d(o),h()},me=(n,r)=>{let o=s.get(n);if(!o)return;let l={...o.definition,...r,id:n};B([l]),o.definition=l,k(o,f().wallNow),g(o),m=N(t),d(),h()},pe=n=>{s.delete(n)&&(d(),h())},fe=()=>{s.clear(),y(),d()},P=n=>{let r=s.get(n);if(!r)return;let o=f();M(r.state,o)&&(c("timer:start",r,w(r,o)),g(r,o,!0),d(o),h())},O=n=>{let r=s.get(n);if(!r)return;let o=f();ne(r.state,o)&&(c("timer:pause",r,w(r,o)),d(o),h())},$=n=>{let r=s.get(n);if(!r)return;let o=f();re(r.state,o)&&(c("timer:resume",r,w(r,o)),g(r,o,!0),d(o),h())},U=(n,r={})=>{let o=s.get(n);if(!o)return;let l=f();j(o.state,l,r),o.schedules.clear(),k(o,l.wallNow),K(o),c("timer:reset",o,w(o,l)),g(o,l,r.autoStart),d(l),h()},z=n=>{let r=s.get(n);if(!r)return;let o=f();oe(r.state,o),r.schedules.clear(),k(r,o.wallNow),K(r),c("timer:restart",r,w(r,o)),g(r,o,!0),d(o),h()},L=(n,r)=>{let o=s.get(n);if(!o)return;let l=f();ie(o.state,l,r)&&(c("timer:cancel",o,w(o,l),{reason:r}),d(l),h())},Te=n=>{let r=s.get(n);return r?w(r,f()):void 0},Se={add:de,update:me,remove:pe,clear:fe,start:P,pause:O,resume:$,reset:U,restart:z,cancel:L,startAll:()=>Array.from(s.keys()).forEach(P),pauseAll:()=>Array.from(s.keys()).forEach(O),resumeAll:()=>Array.from(s.keys()).forEach($),resetAll:n=>Array.from(s.keys()).forEach(r=>U(r,n)),restartAll:()=>Array.from(s.keys()).forEach(z),cancelAll:n=>Array.from(s.keys()).forEach(r=>L(r,n))};return Q(),{controls:Se,destroy:y,getSnapshot:()=>a,getTimer:Te,setOptions:n=>{q(n);let r=N(n),o=r!==m,l=n.items!==t.items||o;t=n,l&&(m=r,Q({notify:!1,process:!1,reschedule:o}))},subscribe:n=>(i.add(n),()=>i.delete(n))}}function W(e,t){return{now:t,size:e.size,ids:Array.from(e.keys())}}function k(e,t){_(e.definition.schedules,e.schedules,t,e.state.status==="running")}function N(e){return[e.updateIntervalMs??1e3,...(e.items??[]).map(t=>{let i=ee(t.schedules);return`${t.id}:${t.autoStart??!1}:${i??""}`})].join("|")}function q(e){H(e.updateIntervalMs??1e3,"updateIntervalMs"),B(e.items)}function B(e){let t=new Set;e?.forEach(i=>{if(!i.id)throw new Error("Timer item id is required");if(t.has(i.id))throw new Error(`Duplicate timer item id "${i.id}"`);t.add(i.id),i.schedules?.forEach(s=>H(s.everyMs,"schedule.everyMs"))})}0&&(module.exports={useTimerGroup});
|
package/dist/group.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as UseTimerGroupOptions, e as TimerGroupResult } from './types
|
|
2
|
-
export { f as TimerGroupItem, g as TimerGroupItemControls } from './types
|
|
1
|
+
import { d as UseTimerGroupOptions, e as TimerGroupResult } from './types--o_xW2FP.cjs';
|
|
2
|
+
export { f as TimerGroupItem, g as TimerGroupItemControls } from './types--o_xW2FP.cjs';
|
|
3
3
|
|
|
4
4
|
declare function useTimerGroup(options?: UseTimerGroupOptions): TimerGroupResult;
|
|
5
5
|
|
package/dist/group.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as UseTimerGroupOptions, e as TimerGroupResult } from './types
|
|
2
|
-
export { f as TimerGroupItem, g as TimerGroupItemControls } from './types
|
|
1
|
+
import { d as UseTimerGroupOptions, e as TimerGroupResult } from './types--o_xW2FP.js';
|
|
2
|
+
export { f as TimerGroupItem, g as TimerGroupItemControls } from './types--o_xW2FP.js';
|
|
3
3
|
|
|
4
4
|
declare function useTimerGroup(options?: UseTimerGroupOptions): TimerGroupResult;
|
|
5
5
|
|
package/dist/group.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as k,b as v,c as V,d as W,e as X,f as Y,g as Z,h as U,i as p,j as _}from"./chunk-N626U6HM.js";import{a,b as P,e as w,f as F,g as B,h as H,i as J,j as K,l as Q}from"./chunk-I3PNNG3I.js";import{useEffect as ce,useRef as le,useSyncExternalStore as me}from"react";function de(i={}){let o=le(null);return o.current===null&&(o.current=pe(i)),o.current.setOptions(i),ce(()=>{let n=o.current;return()=>n.destroy()},[]),{...me(o.current.subscribe,o.current.getSnapshot,o.current.getSnapshot),get:o.current.getTimer,...o.current.controls}}function pe(i){let o=i;z(o);let l=new Set,n=new Map,b=D(n,a().wallNow),y=null,I=E(o),m=(e=a())=>{b=D(n,e.wallNow),l.forEach(t=>t())},A=()=>{y!==null&&(clearTimeout(y),y=null)},f=(e,t,r,s={})=>{k(o.diagnostics,{type:e,scope:"timer-group",timerId:t?.id,...v(r,t?.state.generation??0),...s})},ee=e=>(t,r,s)=>{e.definition.onError?.(t,r,L(e.id)),k(o.diagnostics,{type:"callback:error",scope:"timer-group",timerId:e.id,error:t,...v(r,s)})},te=(e,t,r)=>s=>{k(o.diagnostics,{type:s.type,scope:"timer-group",timerId:e.id,...s.context,..."reason"in s?{reason:s.reason}:{},..."error"in s?{error:s.error}:{},...v(t,r)})},L=e=>({start:()=>N(e),pause:()=>R(e),resume:()=>M(e),reset:t=>x(e,t),restart:()=>C(e),cancel:t=>O(e,t)}),g=(e,t=a(),r=!1)=>{if(e.state.status!=="running")return!1;let s=L(e.id),c=_(e,t,s,ee(e));if(c)return f("timer:end",e,c),!0;let u=p(e,t);return V({schedules:e.definition.schedules,states:e.schedules,snapshot:u,generation:e.state.generation,controls:s,activation:r,isLive:h=>n.get(e.id)?.state.generation===h,onEvent:te(e,u,e.state.generation)}),!1},d=(e=!0)=>{A();let t=Array.from(n.values()).filter(c=>c.state.status==="running");if(t.length===0)return;let r=a(),s=o.updateIntervalMs??1e3;for(let c of t)s=Math.min(s,W(c.definition.schedules,c.schedules,r.wallNow,s));e&&f("scheduler:start",t[0],p(t[0],r)),y=setTimeout(()=>{let c=a();for(let u of n.values()){if(u.state.status!=="running")continue;Q(u.state,c);let h=p(u,c);f("timer:tick",u,h),g(u,c)}m(c),d()},s)},j=e=>{let t=n.get(e.id);if(t)return t.definition=e,S(t,a().wallNow),{item:t,added:!1};let r=a(),s={...Z(e,r),id:e.id,schedules:new Map};return n.set(e.id,s),S(s,r.wallNow),{item:s,added:!0}},q=(e={})=>{let t=e.notify??!0,r=e.process??!0,s=e.reschedule??!0;z(o);let c=new Set,u=!1,h=a();if(o.items){for(let T of o.items){c.add(T.id);let{item:G,added:ae}=j(T);u=u||ae,T.autoStart&&G.state.status==="idle"&&w(G.state,h)&&(u=!0,r&&(u=g(G,h,!0)||u)),r&&(u=g(G,h)||u)}for(let T of n.keys())c.has(T)||(n.delete(T),u=!0)}u&&(t?m(h):b=D(n,h.wallNow)),(u||s)&&d(t)},re=e=>{if($([e]),n.has(e.id))throw new Error(`Timer item "${e.id}" already exists`);let{item:t}=j(e),r=a();e.autoStart&&w(t.state,r)&&g(t,r,!0),I=E(o),m(r),d()},se=(e,t)=>{let r=n.get(e);if(!r)return;let s={...r.definition,...t,id:e};$([s]),r.definition=s,S(r,a().wallNow),g(r),I=E(o),m(),d()},oe=e=>{n.delete(e)&&(m(),d())},ne=()=>{n.clear(),A(),m()},N=e=>{let t=n.get(e);if(!t)return;let r=a();w(t.state,r)&&(f("timer:start",t,p(t,r)),g(t,r,!0),m(r),d())},R=e=>{let t=n.get(e);if(!t)return;let r=a();F(t.state,r)&&(f("timer:pause",t,p(t,r)),m(r),d())},M=e=>{let t=n.get(e);if(!t)return;let r=a();B(t.state,r)&&(f("timer:resume",t,p(t,r)),g(t,r,!0),m(r),d())},x=(e,t={})=>{let r=n.get(e);if(!r)return;let s=a();H(r.state,s,t),r.schedules.clear(),S(r,s.wallNow),U(r),f("timer:reset",r,p(r,s)),g(r,s,t.autoStart),m(s),d()},C=e=>{let t=n.get(e);if(!t)return;let r=a();J(t.state,r),t.schedules.clear(),S(t,r.wallNow),U(t),f("timer:restart",t,p(t,r)),g(t,r,!0),m(r),d()},O=(e,t)=>{let r=n.get(e);if(!r)return;let s=a();K(r.state,s,t)&&(f("timer:cancel",r,p(r,s),{reason:t}),m(s),d())},ie=e=>{let t=n.get(e);return t?p(t,a()):void 0},ue={add:re,update:se,remove:oe,clear:ne,start:N,pause:R,resume:M,reset:x,restart:C,cancel:O,startAll:()=>Array.from(n.keys()).forEach(N),pauseAll:()=>Array.from(n.keys()).forEach(R),resumeAll:()=>Array.from(n.keys()).forEach(M),resetAll:e=>Array.from(n.keys()).forEach(t=>x(t,e)),restartAll:()=>Array.from(n.keys()).forEach(C),cancelAll:e=>Array.from(n.keys()).forEach(t=>O(t,e))};return q(),{controls:ue,destroy:A,getSnapshot:()=>b,getTimer:ie,setOptions:e=>{z(e);let t=E(e),r=t!==I,s=e.items!==o.items||r;o=e,s&&(I=t,q({notify:!1,process:!1,reschedule:r}))},subscribe:e=>(l.add(e),()=>l.delete(e))}}function D(i,o){return{now:o,size:i.size,ids:Array.from(i.keys())}}function S(i,o){X(i.definition.schedules,i.schedules,o,i.state.status==="running")}function E(i){return[i.updateIntervalMs??1e3,...(i.items??[]).map(o=>{let l=Y(o.schedules);return`${o.id}:${o.autoStart??!1}:${l??""}`})].join("|")}function z(i){P(i.updateIntervalMs??1e3,"updateIntervalMs"),$(i.items)}function $(i){let o=new Set;i?.forEach(l=>{if(!l.id)throw new Error("Timer item id is required");if(o.has(l.id))throw new Error(`Duplicate timer item id "${l.id}"`);o.add(l.id),l.schedules?.forEach(n=>P(n.everyMs,"schedule.everyMs"))})}export{de as useTimerGroup};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var A=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var F=(e,t)=>{for(var o in t)A(e,o,{get:t[o],enumerable:!0})},D=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of P(t))!U.call(e,i)&&i!==o&&A(e,i,{get:()=>t[i],enumerable:!(r=O(t,i))||r.enumerable});return e};var G=e=>D(A({},"__esModule",{value:!0}),e);var $={};F($,{useTimer:()=>k});module.exports=G($);var m=require("react");function a(){let e=Date.now(),t=typeof performance<"u"&&typeof performance.now=="function"?performance.now():e;return{wallNow:e,monotonicNow:t}}function g(e,t){if(!Number.isFinite(e)||e<=0)throw new RangeError(`${t} must be a finite number greater than 0`)}function M(e){return{status:"idle",generation:0,tick:0,startedAt:null,pausedAt:null,endedAt:null,cancelledAt:null,cancelReason:null,baseElapsedMilliseconds:0,activeStartedAtMonotonic:null,now:e.wallNow}}function w(e,t){return e.status!=="running"||e.activeStartedAtMonotonic===null?e.baseElapsedMilliseconds:Math.max(0,e.baseElapsedMilliseconds+t.monotonicNow-e.activeStartedAtMonotonic)}function f(e,t){let o=w(e,t);return{status:e.status,now:t.wallNow,tick:e.tick,startedAt:e.startedAt,pausedAt:e.pausedAt,endedAt:e.endedAt,cancelledAt:e.cancelledAt,cancelReason:e.cancelReason,elapsedMilliseconds:o,isIdle:e.status==="idle",isRunning:e.status==="running",isPaused:e.status==="paused",isEnded:e.status==="ended",isCancelled:e.status==="cancelled"}}function h(e,t){return e.status!=="idle"?!1:(e.status="running",e.startedAt=t.wallNow,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function v(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=w(e,t),e.activeStartedAtMonotonic=null,e.status="paused",e.pausedAt=t.wallNow,e.now=t.wallNow,!0)}function C(e,t){return e.status!=="paused"?!1:(e.status="running",e.pausedAt=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function R(e,t,o={}){return e.generation+=1,e.tick=0,e.status=o.autoStart?"running":"idle",e.startedAt=o.autoStart?t.wallNow:null,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.baseElapsedMilliseconds=0,e.activeStartedAtMonotonic=o.autoStart?t.monotonicNow:null,e.now=t.wallNow,!0}function N(e,t){return R(e,t,{autoStart:!0})}function y(e,t,o){return e.status==="ended"||e.status==="cancelled"?!1:(e.baseElapsedMilliseconds=w(e,t),e.activeStartedAtMonotonic=null,e.status="cancelled",e.cancelledAt=t.wallNow,e.cancelReason=o??null,e.now=t.wallNow,!0)}function I(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=w(e,t),e.activeStartedAtMonotonic=null,e.status="ended",e.endedAt=t.wallNow,e.now=t.wallNow,!0)}function E(e,t){return e.status!=="running"?!1:(e.tick+=1,e.now=t.wallNow,!0)}function k(e={}){let t=(0,m.useRef)(null);return t.current===null&&(t.current=W(e)),t.current.setOptions(e),(0,m.useEffect)(()=>{let r=t.current;return e.autoStart&&r.controls.start(),()=>r.destroy()},[]),{...(0,m.useSyncExternalStore)(t.current.subscribe,t.current.getSnapshot,t.current.getSnapshot),...t.current.controls}}function W(e){let t=e;g(t.updateIntervalMs??1e3,"updateIntervalMs");let o=new Set,r=M(a()),i=f(r,a()),S=null,T=null,u=(n=a())=>{i=f(r,n),o.forEach(l=>l())},s=()=>{S!==null&&(clearTimeout(S),S=null)},x=n=>{if(T===r.generation)return;T=r.generation;let l=d=>{if(t.onError){t.onError(d,n,b);return}setTimeout(()=>{throw d},0)};try{Promise.resolve(t.onEnd?.(n,b)).catch(d=>{l(d)})}catch(d){l(d)}},p=n=>{let l=f(r,n);return!t.endWhen?.(l)||!I(r,n)?!1:(s(),u(n),x(f(r,n)),!0)},c=()=>{s(),r.status==="running"&&(S=setTimeout(()=>{if(r.status!=="running")return;let n=a();E(r,n),!p(n)&&(u(n),c())},t.updateIntervalMs??1e3))},b={start:()=>{let n=a();if(!h(r,n)){r.status==="running"&&c();return}u(n),p(n)||c()},pause:()=>{let n=a();v(r,n)&&(s(),u(n))},resume:()=>{let n=a();C(r,n)&&(u(n),p(n)||c())},reset:(n={})=>{let l=a();s(),R(r,l,n),T=null,u(l),n.autoStart&&!p(l)&&c()},restart:()=>{let n=a();s(),N(r,n),T=null,u(n),p(n)||c()},cancel:n=>{let l=a();y(r,l,n)&&(s(),u(l))}};return{controls:b,destroy:s,getSnapshot:()=>i,setOptions:n=>{g(n.updateIntervalMs??1e3,"updateIntervalMs"),t=n},subscribe:n=>(o.add(n),()=>o.delete(n))}}0&&(module.exports={useTimer});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UseTimerOptions, T as TimerSnapshot, a as TimerControls } from './types
|
|
2
|
-
export { b as TimerEndPredicate, c as TimerStatus } from './types
|
|
1
|
+
import { U as UseTimerOptions, T as TimerSnapshot, a as TimerControls } from './types--o_xW2FP.cjs';
|
|
2
|
+
export { b as TimerEndPredicate, c as TimerStatus } from './types--o_xW2FP.cjs';
|
|
3
3
|
|
|
4
4
|
declare function useTimer(options?: UseTimerOptions): TimerSnapshot & TimerControls;
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UseTimerOptions, T as TimerSnapshot, a as TimerControls } from './types
|
|
2
|
-
export { b as TimerEndPredicate, c as TimerStatus } from './types
|
|
1
|
+
import { U as UseTimerOptions, T as TimerSnapshot, a as TimerControls } from './types--o_xW2FP.js';
|
|
2
|
+
export { b as TimerEndPredicate, c as TimerStatus } from './types--o_xW2FP.js';
|
|
3
3
|
|
|
4
4
|
declare function useTimer(options?: UseTimerOptions): TimerSnapshot & TimerControls;
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as o,b as d,c as y,d as m,e as v,f as g,g as E,h as b,i as k,j as C,k as I,l as O}from"./chunk-I3PNNG3I.js";import{useEffect as U,useRef as R,useSyncExternalStore as w}from"react";function x(c={}){let r=R(null);return r.current===null&&(r.current=P(c)),r.current.setOptions(c),U(()=>{let e=r.current;return c.autoStart&&e.controls.start(),()=>e.destroy()},[]),{...w(r.current.subscribe,r.current.getSnapshot,r.current.getSnapshot),...r.current.controls}}function P(c){let r=c;d(r.updateIntervalMs??1e3,"updateIntervalMs");let p=new Set,e=y(o()),h=m(e,o()),T=null,f=null,s=(t=o())=>{h=m(e,t),p.forEach(n=>n())},i=()=>{T!==null&&(clearTimeout(T),T=null)},M=t=>{if(f===e.generation)return;f=e.generation;let n=u=>{if(r.onError){r.onError(u,t,S);return}setTimeout(()=>{throw u},0)};try{Promise.resolve(r.onEnd?.(t,S)).catch(u=>{n(u)})}catch(u){n(u)}},l=t=>{let n=m(e,t);return!r.endWhen?.(n)||!I(e,t)?!1:(i(),s(t),M(m(e,t)),!0)},a=()=>{i(),e.status==="running"&&(T=setTimeout(()=>{if(e.status!=="running")return;let t=o();O(e,t),!l(t)&&(s(t),a())},r.updateIntervalMs??1e3))},S={start:()=>{let t=o();if(!v(e,t)){e.status==="running"&&a();return}s(t),l(t)||a()},pause:()=>{let t=o();g(e,t)&&(i(),s(t))},resume:()=>{let t=o();E(e,t)&&(s(t),l(t)||a())},reset:(t={})=>{let n=o();i(),b(e,n,t),f=null,s(n),t.autoStart&&!l(n)&&a()},restart:()=>{let t=o();i(),k(e,t),f=null,s(t),l(t)||a()},cancel:t=>{let n=o();C(e,n,t)&&(i(),s(n))}};return{controls:S,destroy:i,getSnapshot:()=>h,setOptions:t=>{d(t.updateIntervalMs??1e3,"updateIntervalMs"),r=t},subscribe:t=>(p.add(t),()=>p.delete(t))}}export{x as useTimer};
|
package/dist/schedules.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var M=Object.defineProperty;var X=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var _=(e,t)=>{for(var r in t)M(e,r,{get:t[r],enumerable:!0})},ee=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Y(t))!Z.call(e,i)&&i!==r&&M(e,i,{get:()=>t[i],enumerable:!(n=X(t,i))||n.enumerable});return e};var te=e=>ee(M({},"__esModule",{value:!0}),e);var le={};_(le,{useScheduledTimer:()=>Q});module.exports=te(le);var C=require("react");function m(){let e=Date.now(),t=typeof performance<"u"&&typeof performance.now=="function"?performance.now():e;return{wallNow:e,monotonicNow:t}}function E(e,t){if(!Number.isFinite(e)||e<=0)throw new RangeError(`${t} must be a finite number greater than 0`)}function ne(e){return e?typeof e=="function"?{enabled:!0,includeTicks:!1,logger:e}:{enabled:e.enabled!==!1,includeTicks:e.includeTicks??!1,label:e.label,logger:e.logger}:{enabled:!1,includeTicks:!1}}function v(e,t){let r=ne(e);!r.enabled||!r.logger||t.type==="timer:tick"&&!r.includeTicks||r.logger({...t,label:t.label??r.label})}function x(e,t){return{generation:t,tick:e.tick,now:e.now,elapsedMilliseconds:e.elapsedMilliseconds,status:e.status}}function re(){return{lastRunAt:null,pendingCount:0,leadingGeneration:null}}function P({schedules:e=[],states:t,snapshot:r,generation:n,controls:i,activation:s=!1,isLive:u,onEvent:p}){let d=new Set;e.forEach((a,f)=>{let h=a.id??String(f);d.add(h);let T=t.get(h);if(T||(T=re(),t.set(h,T)),s&&a.leading&&T.leadingGeneration!==n){T.leadingGeneration=n,G(a,h,T,r,n,i,N(a,h,r.now,r.now,0),u,p);return}T.lastRunAt===null&&(T.lastRunAt=r.now);let g=Math.floor((r.now-T.lastRunAt)/a.everyMs);if(g>=1){let b=T.lastRunAt+g*a.everyMs;G(a,h,T,r,n,i,N(a,h,b,r.now,g-1),u,p)}});for(let a of t.keys())d.has(a)||t.delete(a)}function O(e,t,r,n){let i=n;return e?.forEach((s,u)=>{let p=s.id??String(u),a=t.get(p)?.lastRunAt??r;i=Math.min(i,Math.max(1,a+s.everyMs-r))}),i}function U(e,t,r,n){let i=new Set;e?.forEach((s,u)=>{let p=s.id??String(u);i.add(p),t.has(p)||t.set(p,{lastRunAt:n?r:null,pendingCount:0,leadingGeneration:null})});for(let s of t.keys())i.has(s)||t.delete(s)}function I(e){return(e??[]).map((t,r)=>`${t.id??r}:${t.everyMs}:${t.leading??!1}:${t.overlap??"skip"}`).join(",")}function N(e,t,r,n,i){return{scheduleId:e.id??t,scheduledAt:r,firedAt:n,nextRunAt:r+e.everyMs,overdueCount:i,effectiveEveryMs:e.everyMs}}function G(e,t,r,n,i,s,u,p,d){if(r.pendingCount>0&&(e.overlap??"skip")==="skip"){r.lastRunAt=u.scheduledAt,d?.({type:"schedule:skip",context:u,reason:"overlap"});return}r.lastRunAt=u.scheduledAt,r.pendingCount+=1,d?.({type:"schedule:start",context:u}),Promise.resolve().then(()=>e.callback(n,s,u)).then(()=>d?.({type:"schedule:end",context:u}),a=>d?.({type:"schedule:error",context:u,error:a})).finally(()=>{p(i)&&(r.pendingCount=Math.max(0,r.pendingCount-1))})}function $(e){return{status:"idle",generation:0,tick:0,startedAt:null,pausedAt:null,endedAt:null,cancelledAt:null,cancelReason:null,baseElapsedMilliseconds:0,activeStartedAtMonotonic:null,now:e.wallNow}}function k(e,t){return e.status!=="running"||e.activeStartedAtMonotonic===null?e.baseElapsedMilliseconds:Math.max(0,e.baseElapsedMilliseconds+t.monotonicNow-e.activeStartedAtMonotonic)}function A(e,t){let r=k(e,t);return{status:e.status,now:t.wallNow,tick:e.tick,startedAt:e.startedAt,pausedAt:e.pausedAt,endedAt:e.endedAt,cancelledAt:e.cancelledAt,cancelReason:e.cancelReason,elapsedMilliseconds:r,isIdle:e.status==="idle",isRunning:e.status==="running",isPaused:e.status==="paused",isEnded:e.status==="ended",isCancelled:e.status==="cancelled"}}function L(e,t){return e.status!=="idle"?!1:(e.status="running",e.startedAt=t.wallNow,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function F(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=k(e,t),e.activeStartedAtMonotonic=null,e.status="paused",e.pausedAt=t.wallNow,e.now=t.wallNow,!0)}function H(e,t){return e.status!=="paused"?!1:(e.status="running",e.pausedAt=null,e.activeStartedAtMonotonic=t.monotonicNow,e.now=t.wallNow,!0)}function R(e,t,r={}){return e.generation+=1,e.tick=0,e.status=r.autoStart?"running":"idle",e.startedAt=r.autoStart?t.wallNow:null,e.pausedAt=null,e.endedAt=null,e.cancelledAt=null,e.cancelReason=null,e.baseElapsedMilliseconds=0,e.activeStartedAtMonotonic=r.autoStart?t.monotonicNow:null,e.now=t.wallNow,!0}function K(e,t){return R(e,t,{autoStart:!0})}function W(e,t,r){return e.status==="ended"||e.status==="cancelled"?!1:(e.baseElapsedMilliseconds=k(e,t),e.activeStartedAtMonotonic=null,e.status="cancelled",e.cancelledAt=t.wallNow,e.cancelReason=r??null,e.now=t.wallNow,!0)}function j(e,t){return e.status!=="running"?!1:(e.baseElapsedMilliseconds=k(e,t),e.activeStartedAtMonotonic=null,e.status="ended",e.endedAt=t.wallNow,e.now=t.wallNow,!0)}function q(e,t){return e.status!=="running"?!1:(e.tick+=1,e.now=t.wallNow,!0)}function z(e,t){return{state:$(t),definition:e,endCalledGeneration:null}}function D(e){e.endCalledGeneration=null}function S(e,t){return A(e.state,t)}function B(e,t,r,n){let i=A(e.state,t);if(!e.definition.endWhen?.(i)||!j(e.state,t))return null;let s=A(e.state,t);return oe(e,s,r,n),s}function oe(e,t,r,n){let i=e.state.generation;if(e.endCalledGeneration!==i){e.endCalledGeneration=i;try{let s=e.definition.onEnd?.(t,r);s&&n&&Promise.resolve(s).catch(u=>n?.(u,t,i))}catch(s){if(n){n(s,t,i);return}throw s}}}function Q(e={}){let t=(0,C.useRef)(null);return t.current===null&&(t.current=ie(e)),t.current.setOptions(e),(0,C.useEffect)(()=>{let n=t.current;return e.autoStart&&n.controls.start(),()=>n.destroy()},[]),{...(0,C.useSyncExternalStore)(t.current.subscribe,t.current.getSnapshot,t.current.getSnapshot),...t.current.controls}}function ie(e){let t=e;J(t);let r=new Set,n=z(t,m()),i=new Map,s=S(n,m()),u=null,p=I(t.schedules),d=(o=m())=>{s=S(n,o),r.forEach(l=>l())},a=()=>{u!==null&&(clearTimeout(u),u=null)},f=(o,l,c={})=>{v(t.diagnostics,{type:o,scope:"timer",...x(l,n.state.generation),...c})},h=(o,l,c)=>{t.onError?.(o,l,y),v(t.diagnostics,{type:"callback:error",scope:"timer",error:o,...x(l,c)})},T=(o,l)=>c=>{v(t.diagnostics,{type:c.type,scope:"timer",...c.context,..."reason"in c?{reason:c.reason}:{},..."error"in c?{error:c.error}:{},...x(o,l)})},g=(o=m(),l=!1)=>{if(n.state.status!=="running")return!1;let c=B(n,o,y,h);if(c)return a(),f("timer:end",c),d(o),!0;let w=S(n,o);return P({schedules:t.schedules,states:i,snapshot:w,generation:n.state.generation,controls:y,activation:l,isLive:V=>n.state.generation===V,onEvent:T(w,n.state.generation)}),!1},b=(o=!0)=>{if(a(),n.state.status!=="running")return;let l=O(t.schedules,i,m().wallNow,t.updateIntervalMs??1e3);o&&f("scheduler:start",S(n,m())),u=setTimeout(()=>{if(n.state.status!=="running")return;let c=m();q(n.state,c);let w=S(n,c);f("timer:tick",w),g(c)||(d(c),b())},l)},y={start:()=>{let o=m();if(!L(n.state,o)){n.state.status==="running"&&b();return}f("timer:start",S(n,o)),g(o,!0),d(o),b()},pause:()=>{let o=m();F(n.state,o)&&(a(),f("timer:pause",S(n,o)),d(o))},resume:()=>{let o=m();H(n.state,o)&&(f("timer:resume",S(n,o)),g(o,!0),d(o),b())},reset:(o={})=>{let l=m();a(),R(n.state,l,o),i.clear(),D(n),f("timer:reset",S(n,l)),g(l,o.autoStart),d(l),b()},restart:()=>{let o=m();a(),K(n.state,o),i.clear(),D(n),f("timer:restart",S(n,o)),g(o,!0),d(o),b()},cancel:o=>{let l=m();W(n.state,l,o)&&(a(),f("timer:cancel",S(n,l),{reason:o}),d(l))}};return{controls:y,destroy:a,getSnapshot:()=>s,setOptions:o=>{J(o);let l=I(o.schedules),c=l!==p;t=o,n.definition=o,c&&(p=l,U(t.schedules,i,m().wallNow,n.state.status==="running"),b(!1))},subscribe:o=>(r.add(o),()=>r.delete(o))}}function J(e){E(e.updateIntervalMs??1e3,"updateIntervalMs"),e.schedules?.forEach(t=>E(t.everyMs,"schedule.everyMs"))}0&&(module.exports={useScheduledTimer});
|
package/dist/schedules.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as UseScheduledTimerOptions, T as TimerSnapshot, a as TimerControls } from './types
|
|
2
|
-
export { i as TimerDiagnostics, j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger, l as TimerSchedule, m as TimerScheduleContext } from './types
|
|
1
|
+
import { h as UseScheduledTimerOptions, T as TimerSnapshot, a as TimerControls } from './types--o_xW2FP.cjs';
|
|
2
|
+
export { i as TimerDiagnostics, j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger, l as TimerSchedule, m as TimerScheduleContext } from './types--o_xW2FP.cjs';
|
|
3
3
|
|
|
4
4
|
declare function useScheduledTimer(options?: UseScheduledTimerOptions): TimerSnapshot & TimerControls;
|
|
5
5
|
|
package/dist/schedules.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as UseScheduledTimerOptions, T as TimerSnapshot, a as TimerControls } from './types
|
|
2
|
-
export { i as TimerDiagnostics, j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger, l as TimerSchedule, m as TimerScheduleContext } from './types
|
|
1
|
+
import { h as UseScheduledTimerOptions, T as TimerSnapshot, a as TimerControls } from './types--o_xW2FP.js';
|
|
2
|
+
export { i as TimerDiagnostics, j as TimerDiagnosticsEvent, k as TimerDiagnosticsLogger, l as TimerSchedule, m as TimerScheduleContext } from './types--o_xW2FP.js';
|
|
3
3
|
|
|
4
4
|
declare function useScheduledTimer(options?: UseScheduledTimerOptions): TimerSnapshot & TimerControls;
|
|
5
5
|
|
package/dist/schedules.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as g,b as y,c as N,d as P,e as R,f as E,g as L,h as b,i,j as F}from"./chunk-N626U6HM.js";import{a as o,b as v,e as C,f as D,g as w,h as O,i as U,j as M,l as x}from"./chunk-I3PNNG3I.js";import{useEffect as A,useRef as B,useSyncExternalStore as H}from"react";function J(a={}){let s=B(null);return s.current===null&&(s.current=K(a)),s.current.setOptions(a),A(()=>{let t=s.current;return a.autoStart&&t.controls.start(),()=>t.destroy()},[]),{...H(s.current.subscribe,s.current.getSnapshot,s.current.getSnapshot),...s.current.controls}}function K(a){let s=a;G(s);let S=new Set,t=L(s,o()),d=new Map,k=i(t,o()),h=null,I=E(s.schedules),u=(e=o())=>{k=i(t,e),S.forEach(r=>r())},l=()=>{h!==null&&(clearTimeout(h),h=null)},c=(e,r,n={})=>{g(s.diagnostics,{type:e,scope:"timer",...y(r,t.state.generation),...n})},j=(e,r,n)=>{s.onError?.(e,r,T),g(s.diagnostics,{type:"callback:error",scope:"timer",error:e,...y(r,n)})},q=(e,r)=>n=>{g(s.diagnostics,{type:n.type,scope:"timer",...n.context,..."reason"in n?{reason:n.reason}:{},..."error"in n?{error:n.error}:{},...y(e,r)})},p=(e=o(),r=!1)=>{if(t.state.status!=="running")return!1;let n=F(t,e,T,j);if(n)return l(),c("timer:end",n),u(e),!0;let f=i(t,e);return N({schedules:s.schedules,states:d,snapshot:f,generation:t.state.generation,controls:T,activation:r,isLive:z=>t.state.generation===z,onEvent:q(f,t.state.generation)}),!1},m=(e=!0)=>{if(l(),t.state.status!=="running")return;let r=P(s.schedules,d,o().wallNow,s.updateIntervalMs??1e3);e&&c("scheduler:start",i(t,o())),h=setTimeout(()=>{if(t.state.status!=="running")return;let n=o();x(t.state,n);let f=i(t,n);c("timer:tick",f),p(n)||(u(n),m())},r)},T={start:()=>{let e=o();if(!C(t.state,e)){t.state.status==="running"&&m();return}c("timer:start",i(t,e)),p(e,!0),u(e),m()},pause:()=>{let e=o();D(t.state,e)&&(l(),c("timer:pause",i(t,e)),u(e))},resume:()=>{let e=o();w(t.state,e)&&(c("timer:resume",i(t,e)),p(e,!0),u(e),m())},reset:(e={})=>{let r=o();l(),O(t.state,r,e),d.clear(),b(t),c("timer:reset",i(t,r)),p(r,e.autoStart),u(r),m()},restart:()=>{let e=o();l(),U(t.state,e),d.clear(),b(t),c("timer:restart",i(t,e)),p(e,!0),u(e),m()},cancel:e=>{let r=o();M(t.state,r,e)&&(l(),c("timer:cancel",i(t,r),{reason:e}),u(r))}};return{controls:T,destroy:l,getSnapshot:()=>k,setOptions:e=>{G(e);let r=E(e.schedules),n=r!==I;s=e,t.definition=e,n&&(I=r,R(s.schedules,d,o().wallNow,t.state.status==="running"),m(!1))},subscribe:e=>(S.add(e),()=>S.delete(e))}}function G(a){v(a.updateIntervalMs??1e3,"updateIntervalMs"),a.schedules?.forEach(s=>v(s.everyMs,"schedule.everyMs"))}export{J as useScheduledTimer};
|
|
@@ -82,6 +82,7 @@ type UseTimerOptions = {
|
|
|
82
82
|
updateIntervalMs?: number;
|
|
83
83
|
endWhen?: TimerEndPredicate;
|
|
84
84
|
onEnd?: (snapshot: TimerSnapshot, controls: TimerControls) => void | Promise<void>;
|
|
85
|
+
onError?: (error: unknown, snapshot: TimerSnapshot, controls: TimerControls) => void;
|
|
85
86
|
};
|
|
86
87
|
type UseScheduledTimerOptions = UseTimerOptions & {
|
|
87
88
|
schedules?: TimerSchedule[];
|
|
@@ -93,6 +94,7 @@ type TimerGroupItem = {
|
|
|
93
94
|
autoStart?: boolean;
|
|
94
95
|
endWhen?: TimerEndPredicate;
|
|
95
96
|
onEnd?: (snapshot: TimerSnapshot, controls: TimerGroupItemControls) => void | Promise<void>;
|
|
97
|
+
onError?: (error: unknown, snapshot: TimerSnapshot, controls: TimerGroupItemControls) => void;
|
|
96
98
|
schedules?: TimerSchedule[];
|
|
97
99
|
};
|
|
98
100
|
type UseTimerGroupOptions = {
|
|
@@ -82,6 +82,7 @@ type UseTimerOptions = {
|
|
|
82
82
|
updateIntervalMs?: number;
|
|
83
83
|
endWhen?: TimerEndPredicate;
|
|
84
84
|
onEnd?: (snapshot: TimerSnapshot, controls: TimerControls) => void | Promise<void>;
|
|
85
|
+
onError?: (error: unknown, snapshot: TimerSnapshot, controls: TimerControls) => void;
|
|
85
86
|
};
|
|
86
87
|
type UseScheduledTimerOptions = UseTimerOptions & {
|
|
87
88
|
schedules?: TimerSchedule[];
|
|
@@ -93,6 +94,7 @@ type TimerGroupItem = {
|
|
|
93
94
|
autoStart?: boolean;
|
|
94
95
|
endWhen?: TimerEndPredicate;
|
|
95
96
|
onEnd?: (snapshot: TimerSnapshot, controls: TimerGroupItemControls) => void | Promise<void>;
|
|
97
|
+
onError?: (error: unknown, snapshot: TimerSnapshot, controls: TimerGroupItemControls) => void;
|
|
96
98
|
schedules?: TimerSchedule[];
|
|
97
99
|
};
|
|
98
100
|
type UseTimerGroupOptions = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crup/react-timer-hook",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.15",
|
|
4
4
|
"description": "A lightweight React hooks library for building timers, stopwatches, and real-time clocks with minimal boilerplate.",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
package/dist/chunk-RT4C7DWO.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as f,d as c,k as p}from"./chunk-I3PNNG3I.js";function y(e){return e?typeof e=="function"?{enabled:!0,includeTicks:!1,logger:e}:{enabled:e.enabled!==!1,includeTicks:e.includeTicks??!1,label:e.label,logger:e.logger}:{enabled:!1,includeTicks:!1}}function v(e,n){let t=y(e);!t.enabled||!t.logger||n.type==="timer:tick"&&!t.includeTicks||t.logger({...n,label:n.label??t.label})}function k(e,n){return{generation:n,tick:e.tick,now:e.now,elapsedMilliseconds:e.elapsedMilliseconds,status:e.status}}function b(){return{lastRunAt:null,pendingCount:0,leadingGeneration:null}}function E({schedules:e=[],states:n,snapshot:t,generation:i,controls:r,activation:o=!1,isLive:l,onEvent:d}){let u=new Set;e.forEach((s,C)=>{let m=s.id??String(C);u.add(m);let a=n.get(m);if(a||(a=b(),n.set(m,a)),o&&s.leading&&a.leadingGeneration!==i){a.leadingGeneration=i,g(s,m,a,t,i,r,S(s,m,t.now,t.now,0),l,d);return}a.lastRunAt===null&&(a.lastRunAt=t.now);let T=Math.floor((t.now-a.lastRunAt)/s.everyMs);if(T>=1){let h=a.lastRunAt+T*s.everyMs;g(s,m,a,t,i,r,S(s,m,h,t.now,T-1),l,d)}});for(let s of n.keys())u.has(s)||n.delete(s)}function I(e,n,t,i){let r=i;return e?.forEach((o,l)=>{let d=o.id??String(l),s=n.get(d)?.lastRunAt??t;r=Math.min(r,Math.max(1,s+o.everyMs-t))}),r}function M(e,n,t,i){let r=new Set;e?.forEach((o,l)=>{let d=o.id??String(l);r.add(d),n.has(d)||n.set(d,{lastRunAt:i?t:null,pendingCount:0,leadingGeneration:null})});for(let o of n.keys())r.has(o)||n.delete(o)}function S(e,n,t,i,r){return{scheduleId:e.id??n,scheduledAt:t,firedAt:i,nextRunAt:t+e.everyMs,overdueCount:r,effectiveEveryMs:e.everyMs}}function g(e,n,t,i,r,o,l,d,u){if(t.pendingCount>0&&(e.overlap??"skip")==="skip"){t.lastRunAt=l.scheduledAt,u?.({type:"schedule:skip",context:l,reason:"overlap"});return}t.lastRunAt=l.scheduledAt,t.pendingCount+=1,u?.({type:"schedule:start",context:l}),Promise.resolve().then(()=>e.callback(i,o,l)).then(()=>u?.({type:"schedule:end",context:l}),s=>u?.({type:"schedule:error",context:l,error:s})).finally(()=>{d(r)&&(t.pendingCount=Math.max(0,t.pendingCount-1))})}function w(e,n){return{state:f(n),definition:e,endCalledGeneration:null}}function G(e){e.endCalledGeneration=null}function P(e,n){return c(e.state,n)}function O(e,n,t,i){let r=c(e.state,n);if(!e.definition.endWhen?.(r)||!p(e.state,n))return null;let o=c(e.state,n);return x(e,o,t,i),o}function x(e,n,t,i){let r=e.state.generation;if(e.endCalledGeneration!==r){e.endCalledGeneration=r;try{let o=e.definition.onEnd?.(n,t);o&&i&&Promise.resolve(o).catch(l=>i?.(l,n,r))}catch(o){if(i){i(o,n,r);return}throw o}}}export{v as a,k as b,E as c,I as d,M as e,w as f,G as g,P as h,O as i};
|