@timekeeper-countdown/core 0.2.0 → 0.3.0

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 CHANGED
@@ -21,7 +21,7 @@ The published bundle is pure ESM. When targeting CommonJS environments use a bun
21
21
 
22
22
  Supported runtimes:
23
23
 
24
- - Node.js 18+
24
+ - Node.js 22+
25
25
  - Modern browsers (ES2022 modules)
26
26
 
27
27
  ---
@@ -55,7 +55,7 @@ countdown.start(); // Begin the countdown
55
55
  `Countdown` wraps the lower-level engine and returns convenient methods:
56
56
 
57
57
  ```ts
58
- countdown.start(); // boolean (false when invalid transition)
58
+ countdown.start(); // void (the low-level CountdownEngine returns boolean)
59
59
  countdown.pause();
60
60
  countdown.resume();
61
61
  countdown.reset(nextInitialSeconds?);
@@ -93,9 +93,12 @@ engine.start();
93
93
  `CountdownEngine` exposes fine-grained control:
94
94
 
95
95
  - `start`, `pause`, `resume`, `reset(nextInitialSeconds?)`, `stop`, `setSeconds(value)`, `destroy`
96
+ - The constructor, `reset(value)`, and `setSeconds(value)` require a non-negative integer (≤ `Number.MAX_SAFE_INTEGER`) and **throw** on an invalid value (negative, non-integer, `NaN`, or `Infinity`).
96
97
  - `getSnapshot()` returns the latest snapshot.
97
98
  - `subscribe(listener)` emits the current snapshot immediately and on every tick.
98
99
 
100
+ Exceptions thrown by your own callbacks — `onSnapshot`, `onStateChange`, and `subscribe` listeners — are **swallowed** (fail-soft): one throwing listener never crashes the timer or stops the other listeners. These callback errors are **not** delivered to `onError`; `onError` is reserved for internal/timer errors only.
101
+
99
102
  Snapshot structure:
100
103
 
101
104
  ```ts
@@ -339,6 +342,10 @@ const provider = {
339
342
  CountdownEngine(60, { timeProvider: provider });
340
343
  ```
341
344
 
345
+ Constructing with an invalid `timeProvider` — anything that is neither a function nor an object exposing a `now(): number` method — **throws** at construction (and that error propagates from `useCountdown`'s effect).
346
+
347
+ Every time provider — the default one and any custom provider you supply — is wrapped in a finite, non-decreasing guard, so a `NaN`/`Infinity`/backward clock reading (from NTP, DST, or sleep-wake, or a buggy custom provider) is repaired to the last good value, and remaining seconds is always clamped to `[0, initialValue]`. A provider whose `now()` *throws* is not repaired; the error routes to `onError` instead.
348
+
342
349
  ---
343
350
 
344
351
  ## TypeScript Support
@@ -366,15 +373,9 @@ import type {
366
373
 
367
374
  ## Contributing
368
375
 
369
- Issues and pull requests are welcome. Please review the [repository guidelines](https://github.com/eagle-head/timekeeper-countdown/blob/main/AGENTS.md) for more details and run:
370
-
371
- ```bash
372
- npm run lint --workspaces
373
- npm run test --workspaces
374
- npm run typecheck --workspaces
375
- ```
376
+ We welcome contributions! Please read our [Contributing Guide](https://github.com/eagle-head/timekeeper-countdown/blob/main/CONTRIBUTING.md) to get started.
376
377
 
377
- before submitting changes.
378
+ By participating in this project, you agree to abide by our [Code of Conduct](https://github.com/eagle-head/timekeeper-countdown/blob/main/CODE_OF_CONDUCT.md).
378
379
 
379
380
  ---
380
381
 
@@ -16,6 +16,33 @@ declare const TimerState: Readonly<{
16
16
  }>;
17
17
  type TimerState = (typeof TimerState)[keyof typeof TimerState];
18
18
 
19
+ /**
20
+ * A countdown duration broken down into calendar-style units.
21
+ *
22
+ * The unit ladder is fixed-length and internally consistent — a year is
23
+ * {@link SECONDS_PER_YEAR} (365 days), a week is {@link SECONDS_PER_WEEK}
24
+ * (7 days), and so on. Because the breakdown is computed by successive
25
+ * subtraction over that single ladder (not independent modular arithmetic),
26
+ * the parts always reconstruct the total exactly:
27
+ *
28
+ * ```
29
+ * years*SECONDS_PER_YEAR + weeks*SECONDS_PER_WEEK + days*SECONDS_PER_DAY +
30
+ * hours*SECONDS_PER_HOUR + minutes*SECONDS_PER_MINUTE + seconds === totalSeconds
31
+ * ```
32
+ *
33
+ * Field ranges:
34
+ * - `years` — 0+ (unbounded; one year is 365 days)
35
+ * - `weeks` — 0–52 (one week is 7 days, so the 365-day remainder reaches 52 weeks)
36
+ * - `days` — 0–6
37
+ * - `hours` — 0–23
38
+ * - `minutes` / `seconds` — 0–59
39
+ *
40
+ * The `total*` fields are cumulative floors of the whole duration, NOT modular
41
+ * remainders of the calendar ladder:
42
+ * - `totalDays` — `Math.floor(totalSeconds / SECONDS_PER_DAY)`
43
+ * - `totalHours` — `Math.floor(totalSeconds / SECONDS_PER_HOUR)`
44
+ * - `totalMinutes` — `Math.floor(totalSeconds / SECONDS_PER_MINUTE)`
45
+ */
19
46
  interface CountdownParts {
20
47
  years: number;
21
48
  weeks: number;
@@ -27,6 +54,7 @@ interface CountdownParts {
27
54
  totalHours: number;
28
55
  totalMinutes: number;
29
56
  }
57
+
30
58
  interface CountdownSnapshot {
31
59
  initialSeconds: number;
32
60
  totalSeconds: number;
@@ -16,6 +16,33 @@ declare const TimerState: Readonly<{
16
16
  }>;
17
17
  type TimerState = (typeof TimerState)[keyof typeof TimerState];
18
18
 
19
+ /**
20
+ * A countdown duration broken down into calendar-style units.
21
+ *
22
+ * The unit ladder is fixed-length and internally consistent — a year is
23
+ * {@link SECONDS_PER_YEAR} (365 days), a week is {@link SECONDS_PER_WEEK}
24
+ * (7 days), and so on. Because the breakdown is computed by successive
25
+ * subtraction over that single ladder (not independent modular arithmetic),
26
+ * the parts always reconstruct the total exactly:
27
+ *
28
+ * ```
29
+ * years*SECONDS_PER_YEAR + weeks*SECONDS_PER_WEEK + days*SECONDS_PER_DAY +
30
+ * hours*SECONDS_PER_HOUR + minutes*SECONDS_PER_MINUTE + seconds === totalSeconds
31
+ * ```
32
+ *
33
+ * Field ranges:
34
+ * - `years` — 0+ (unbounded; one year is 365 days)
35
+ * - `weeks` — 0–52 (one week is 7 days, so the 365-day remainder reaches 52 weeks)
36
+ * - `days` — 0–6
37
+ * - `hours` — 0–23
38
+ * - `minutes` / `seconds` — 0–59
39
+ *
40
+ * The `total*` fields are cumulative floors of the whole duration, NOT modular
41
+ * remainders of the calendar ladder:
42
+ * - `totalDays` — `Math.floor(totalSeconds / SECONDS_PER_DAY)`
43
+ * - `totalHours` — `Math.floor(totalSeconds / SECONDS_PER_HOUR)`
44
+ * - `totalMinutes` — `Math.floor(totalSeconds / SECONDS_PER_MINUTE)`
45
+ */
19
46
  interface CountdownParts {
20
47
  years: number;
21
48
  weeks: number;
@@ -27,6 +54,7 @@ interface CountdownParts {
27
54
  totalHours: number;
28
55
  totalMinutes: number;
29
56
  }
57
+
30
58
  interface CountdownSnapshot {
31
59
  initialSeconds: number;
32
60
  totalSeconds: number;
package/dist/format.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';function f(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function i(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function o(t,a=2){return !Number.isFinite(t)||t<0?"0".repeat(a):Math.floor(t).toString().padStart(a,"0")}function s(t){return Math.floor(t/60)}function c(t){return s(t)%60}function d(t){return Math.floor(t/3600)%24}function g(t){return Math.floor(t/86400)%7}function p(t){return Math.floor(t/604800)%52}function S(t){return Math.floor(t/31536e3)}function m(){let t=r=>i(f(r));return {formatTime:r=>{let n=t(r);return {minutes:o(s(n)),seconds:o(n%60)}},formatMinutes:r=>{let n=t(r);return o(c(n))},formatSeconds:r=>{let n=t(r);return o(n%60)},formatHours:r=>{let n=t(r);return o(d(n))},formatDays:r=>{let n=t(r);return o(g(n))},formatWeeks:r=>{let n=t(r);return o(p(n))},formatYears:r=>{let n=t(r);return o(S(n))}}}var e=m();function l(t){return e.formatTime(t)}function E(t){return e.formatMinutes(t)}function T(t){return e.formatSeconds(t)}function x(t){return e.formatHours(t)}function F(t){return e.formatDays(t)}function b(t){return e.formatWeeks(t)}function _(t){return e.formatYears(t)}exports.Formatter=m;exports.defaultFormatter=e;exports.formatDays=F;exports.formatHours=x;exports.formatMinutes=E;exports.formatSeconds=T;exports.formatTime=l;exports.formatWeeks=b;exports.formatYears=_;
1
+ 'use strict';function l(t){let a=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,o=a,s=Math.floor(o/31536e3);o-=s*31536e3;let m=Math.floor(o/604800);o-=m*604800;let u=Math.floor(o/86400);o-=u*86400;let f=Math.floor(o/3600);o-=f*3600;let i=Math.floor(o/60);return o-=i*60,{years:s,weeks:m,days:u,hours:f,minutes:i,seconds:o,totalDays:Math.floor(a/86400),totalHours:Math.floor(a/3600),totalMinutes:Math.floor(a/60)}}function S(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function F(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function n(t,a=2){return t.toString().padStart(a,"0")}function x(){let t=r=>l(S(F(r)));return {formatTime:r=>{let c=t(r);return {minutes:n(c.totalMinutes),seconds:n(c.seconds)}},formatMinutes:r=>n(t(r).minutes),formatSeconds:r=>n(t(r).seconds),formatHours:r=>n(t(r).hours),formatDays:r=>n(t(r).days),formatWeeks:r=>n(t(r).weeks),formatYears:r=>n(t(r).years)}}var e=x();function M(t){return e.formatTime(t)}function h(t){return e.formatMinutes(t)}function y(t){return e.formatSeconds(t)}function E(t){return e.formatHours(t)}function k(t){return e.formatDays(t)}function C(t){return e.formatWeeks(t)}function w(t){return e.formatYears(t)}exports.Formatter=x;exports.defaultFormatter=e;exports.formatDays=k;exports.formatHours=E;exports.formatMinutes=h;exports.formatSeconds=y;exports.formatTime=M;exports.formatWeeks=C;exports.formatYears=w;
package/dist/format.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CountdownSnapshot } from './countdown-engine-qnWxt-ed.cjs';
1
+ import { C as CountdownSnapshot } from './countdown-engine-DEKF_8iT.cjs';
2
2
 
3
3
  type FormatTarget = number | Pick<CountdownSnapshot, 'totalSeconds'> | null | undefined;
4
4
  declare function Formatter(): {
package/dist/format.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as CountdownSnapshot } from './countdown-engine-qnWxt-ed.js';
1
+ import { C as CountdownSnapshot } from './countdown-engine-DEKF_8iT.js';
2
2
 
3
3
  type FormatTarget = number | Pick<CountdownSnapshot, 'totalSeconds'> | null | undefined;
4
4
  declare function Formatter(): {
package/dist/format.js CHANGED
@@ -1 +1 @@
1
- function f(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function i(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function o(t,a=2){return !Number.isFinite(t)||t<0?"0".repeat(a):Math.floor(t).toString().padStart(a,"0")}function s(t){return Math.floor(t/60)}function c(t){return s(t)%60}function d(t){return Math.floor(t/3600)%24}function g(t){return Math.floor(t/86400)%7}function p(t){return Math.floor(t/604800)%52}function S(t){return Math.floor(t/31536e3)}function m(){let t=r=>i(f(r));return {formatTime:r=>{let n=t(r);return {minutes:o(s(n)),seconds:o(n%60)}},formatMinutes:r=>{let n=t(r);return o(c(n))},formatSeconds:r=>{let n=t(r);return o(n%60)},formatHours:r=>{let n=t(r);return o(d(n))},formatDays:r=>{let n=t(r);return o(g(n))},formatWeeks:r=>{let n=t(r);return o(p(n))},formatYears:r=>{let n=t(r);return o(S(n))}}}var e=m();function l(t){return e.formatTime(t)}function E(t){return e.formatMinutes(t)}function T(t){return e.formatSeconds(t)}function x(t){return e.formatHours(t)}function F(t){return e.formatDays(t)}function b(t){return e.formatWeeks(t)}function _(t){return e.formatYears(t)}export{m as Formatter,e as defaultFormatter,F as formatDays,x as formatHours,E as formatMinutes,T as formatSeconds,l as formatTime,b as formatWeeks,_ as formatYears};
1
+ function l(t){let a=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,o=a,s=Math.floor(o/31536e3);o-=s*31536e3;let m=Math.floor(o/604800);o-=m*604800;let u=Math.floor(o/86400);o-=u*86400;let f=Math.floor(o/3600);o-=f*3600;let i=Math.floor(o/60);return o-=i*60,{years:s,weeks:m,days:u,hours:f,minutes:i,seconds:o,totalDays:Math.floor(a/86400),totalHours:Math.floor(a/3600),totalMinutes:Math.floor(a/60)}}function S(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function F(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function n(t,a=2){return t.toString().padStart(a,"0")}function x(){let t=r=>l(S(F(r)));return {formatTime:r=>{let c=t(r);return {minutes:n(c.totalMinutes),seconds:n(c.seconds)}},formatMinutes:r=>n(t(r).minutes),formatSeconds:r=>n(t(r).seconds),formatHours:r=>n(t(r).hours),formatDays:r=>n(t(r).days),formatWeeks:r=>n(t(r).weeks),formatYears:r=>n(t(r).years)}}var e=x();function M(t){return e.formatTime(t)}function h(t){return e.formatMinutes(t)}function y(t){return e.formatSeconds(t)}function E(t){return e.formatHours(t)}function k(t){return e.formatDays(t)}function C(t){return e.formatWeeks(t)}function w(t){return e.formatYears(t)}export{x as Formatter,e as defaultFormatter,k as formatDays,E as formatHours,h as formatMinutes,y as formatSeconds,M as formatTime,C as formatWeeks,w as formatYears};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';function Y(){return {now:()=>performance.now(),isHighResolution:true,type:"performance"}}function W(){return {now:()=>Date.now(),isHighResolution:false,type:"date"}}function w(){let t,e=W();function s(){try{if(typeof performance<"u"&&typeof performance.now=="function"){let n=performance.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0&&n<=Number.MAX_SAFE_INTEGER){t=Y();return}}throw new Error("performance.now() not available or invalid")}catch{t=e;}}return s(),{now:()=>{try{let n=t.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0&&n<=Number.MAX_SAFE_INTEGER)return n;throw new Error("Invalid time value returned")}catch{t!==e&&(t=e);try{let n=e.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0)return n}catch{}return 0}},get isHighResolution(){return t.isHighResolution},get type(){return t.type}}}w();var L=10,V=100;function D(t,e,s={}){if(typeof t!="number"||!Number.isFinite(t))throw new Error("initialSeconds must be a finite number");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");let n=Math.floor(Math.max(0,t)),m=null,i=null,u=0,c=n,r=n,a=Math.max(L,Math.floor(s.tickIntervalMs??V)),b=w(),d=s.timeProvider??(()=>b.now()),p=()=>setInterval(()=>{try{if(i===null)return;let E=d()-i-u,x=Math.floor(E/1e3),o=Math.max(0,r-x);n=o,o!==c&&(c=o,e.onTick(o)),o===0&&(l(),e.onComplete());}catch(S){l(),e.onError(S instanceof Error?S:new Error(String(S)));}},a),P=()=>{if(m||n<=0)return false;try{if(i!==null&&n<r){let S=(r-n)*1e3;u=d()-i-S;}else i=d(),u=0,c=n;return m=p(),!0}catch(S){return e.onError(S instanceof Error?S:new Error(String(S))),false}},l=()=>{m&&(clearInterval(m),m=null);},g=()=>{l(),n=r,i=null,u=0,c=r;},v=S=>{if(typeof S!="number"||!Number.isFinite(S))return;let E=Math.floor(Math.max(0,Math.min(S,Number.MAX_SAFE_INTEGER)));n=E,i=null,u=0,c=E;};return {start:P,stop:l,reset:g,setSeconds:v,setInitialValue:S=>{if(typeof S!="number"||!Number.isFinite(S))return;let E=Math.floor(Math.max(0,Math.min(S,Number.MAX_SAFE_INTEGER)));r=E,v(E);},getTotalSeconds:()=>n,getInitialValue:()=>r,isRunning:()=>m!==null,destroy:()=>{l(),n=0,i=null,u=0;}}}var f=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"}),M={[f.IDLE]:{start:f.RUNNING},[f.RUNNING]:{pause:f.PAUSED,reset:f.IDLE,stop:f.STOPPED,complete:f.STOPPED},[f.PAUSED]:{resume:f.RUNNING,reset:f.IDLE,stop:f.STOPPED},[f.STOPPED]:{reset:f.IDLE}};function _(t){if(t!==void 0){if(typeof t!="object"||t===null)throw new Error("events must be an object");if(t.onStateChange!==void 0&&typeof t.onStateChange!="function")throw new Error("events.onStateChange must be a function")}let e=f.IDLE;function s(b){let d=M[e]?.[b];if(!d)return false;e=d;try{t?.onStateChange?.(d);}catch{}return true}function n(){return s("start")}function m(){return s("resume")}function i(){return s("pause")}function u(){return s("reset")}function c(){return s("stop")}function r(){return s("complete")}function a(){e===f.IDLE||e===f.STOPPED||s("stop");}return {start:n,resume:m,pause:i,reset:u,stop:c,complete:r,getCurrentState:()=>e,canStart:()=>!!M[e]?.start,canResume:()=>!!M[e]?.resume,canPause:()=>!!M[e]?.pause,isRunning:()=>e===f.RUNNING,destroy:a}}function O(t){if(typeof t!="number"||!Number.isFinite(t)||!Number.isInteger(t))throw new Error("initialSeconds must be a finite, non-negative integer");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");return t}function J(t){if(!t){let e=w();return ()=>e.now()}if(typeof t=="function")return t;if(typeof t.now=="function"){let e=t;return ()=>e.now()}throw new Error("timeProvider must implement a now(): number method")}function Q(t){let e=Math.max(0,Math.floor(t)),s=Math.floor(e/31536e3),n=Math.floor(e/604800)%52,m=Math.floor(e/86400)%7,i=Math.floor(e/3600)%24,u=Math.floor(e/60)%60,c=e%60,r=Math.floor(e/86400),a=Math.floor(e/3600),b=Math.floor(e/60);return {years:s,weeks:n,days:m,hours:i,minutes:u,seconds:c,totalDays:r,totalHours:a,totalMinutes:b}}function y(t,e,s){let n=Q(e);return {initialSeconds:t,totalSeconds:e,parts:n,state:s,isRunning:s===f.RUNNING,isCompleted:e===0&&s===f.STOPPED}}function R(t,e={}){let s=O(t),n=J(e.timeProvider),m=s,i=y(s,s,f.IDLE),u=new Set,c=o=>{try{e.onSnapshot?.(o);}catch{}for(let N of u)try{N(o);}catch{}},r=o=>{i=y(m,i.totalSeconds,o);try{e.onStateChange?.(o,i);}catch{}c(i);},a=o=>{i=y(m,o,d.getCurrentState()),c(i);},b=o=>{try{e.onError?.(o);}catch{}},d=_({onStateChange:o=>{r(o);}}),p=D(s,{onTick:o=>{a(o);},onComplete:()=>{d.complete(),a(0);},onError:o=>{b(o),d.stop();}},{timeProvider:n,tickIntervalMs:e.tickIntervalMs});return {start:()=>{if(!d.canStart())return false;let o=p.start();return o&&(d.start(),a(p.getTotalSeconds())),o},pause:()=>{if(!d.canPause())return false;p.stop();let o=d.pause();return o&&a(p.getTotalSeconds()),o},resume:()=>{if(!d.canResume())return false;let o=p.start();return o&&(d.resume(),a(p.getTotalSeconds())),o},reset:o=>{if(p.stop(),typeof o=="number"){let N=O(o);m=N,p.setInitialValue(N);}else m=s,p.reset();return d.reset(),a(p.getTotalSeconds()),true},stop:()=>{p.stop();let o=d.stop();return o&&(p.setSeconds(0),a(0)),o},setSeconds:o=>{p.setSeconds(o),a(p.getTotalSeconds());},getSnapshot:()=>i,subscribe:o=>{u.add(o);try{o(i);}catch{}return {unsubscribe:()=>{u.delete(o);}}},destroy:()=>{p.destroy(),d.destroy(),u.clear(),i=y(m,0,f.STOPPED);}}}function Z(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function $(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function h(t,e=2){return !Number.isFinite(t)||t<0?"0".repeat(e):Math.floor(t).toString().padStart(e,"0")}function k(t){return Math.floor(t/60)}function tt(t){return k(t)%60}function et(t){return Math.floor(t/3600)%24}function nt(t){return Math.floor(t/86400)%7}function ot(t){return Math.floor(t/604800)%52}function rt(t){return Math.floor(t/31536e3)}function I(){let t=r=>$(Z(r));return {formatTime:r=>{let a=t(r);return {minutes:h(k(a)),seconds:h(a%60)}},formatMinutes:r=>{let a=t(r);return h(tt(a))},formatSeconds:r=>{let a=t(r);return h(a%60)},formatHours:r=>{let a=t(r);return h(et(a))},formatDays:r=>{let a=t(r);return h(nt(a))},formatWeeks:r=>{let a=t(r);return h(ot(a))},formatYears:r=>{let a=t(r);return h(rt(a))}}}var T=I();function at(t){return T.formatTime(t)}function st(t){return T.formatMinutes(t)}function it(t){return T.formatSeconds(t)}function ut(t){return T.formatHours(t)}function ct(t){return T.formatDays(t)}function mt(t){return T.formatWeeks(t)}function ft(t){return T.formatYears(t)}function dt(t,e={}){let{onSnapshot:s,onStateChange:n,onError:m}=e;if(s!==void 0&&typeof s!="function")throw new Error("onSnapshot must be a function");if(n!==void 0&&typeof n!="function")throw new Error("onStateChange must be a function");if(m!==void 0&&typeof m!="function")throw new Error("onError must be a function");let i=I(),u=R(t,{onError:m}),c=u.getSnapshot(),r=c.state,a=Number.NaN,b=l=>{if(m)try{m(l);}catch{}},d=l=>{if(s)try{s(l);}catch(g){b(g instanceof Error?g:new Error(String(g)));}},p=l=>{if(n)try{n(l);}catch(g){b(g instanceof Error?g:new Error(String(g)));}},P=u.subscribe(l=>{c=l,l.state!==r&&(r=l.state,p(l.state)),l.totalSeconds!==a&&(a=l.totalSeconds,d(l));});return {start:()=>{u.start();},pause:()=>{u.pause();},resume:()=>{u.resume();},reset:l=>{u.reset(l);},stop:()=>{u.stop();},getSeconds:()=>i.formatSeconds(c.totalSeconds),getMinutes:()=>i.formatMinutes(c.totalSeconds),getHours:()=>i.formatHours(c.totalSeconds),getDays:()=>i.formatDays(c.totalSeconds),getWeeks:()=>i.formatWeeks(c.totalSeconds),getYears:()=>i.formatYears(c.totalSeconds),getCurrentState:()=>c.state,getSnapshot:()=>c,destroy:()=>{try{P.unsubscribe();}finally{u.destroy();}}}}exports.Countdown=dt;exports.CountdownEngine=R;exports.Formatter=I;exports.TimerState=f;exports.buildSnapshot=y;exports.defaultFormatter=T;exports.formatDays=ct;exports.formatHours=ut;exports.formatMinutes=st;exports.formatSeconds=it;exports.formatTime=at;exports.formatWeeks=mt;exports.formatYears=ft;
1
+ 'use strict';function W(){return {now:()=>performance.now(),isHighResolution:true,type:"performance"}}function X(){return {now:()=>Date.now(),isHighResolution:false,type:"date"}}function y(){let t,o=X();function n(){try{if(typeof performance<"u"&&typeof performance.now=="function"){let e=performance.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0&&e<=Number.MAX_SAFE_INTEGER){t=W();return}}throw new Error("performance.now() not available or invalid")}catch{t=o;}}return n(),{now:()=>{try{let e=t.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0&&e<=Number.MAX_SAFE_INTEGER)return e;throw new Error("Invalid time value returned")}catch{t!==o&&(t=o);try{let e=o.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0)return e}catch{}return 0}},get isHighResolution(){return t.isHighResolution},get type(){return t.type}}}function k(t,o=0){let n=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;return ()=>{let e=t();return typeof e!="number"||!Number.isFinite(e)||e<n||(n=e),n}}y();var z=10,j=100;function B(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?j:Math.max(z,Math.floor(t))}function A(t,o,n={}){if(typeof t!="number"||!Number.isFinite(t))throw new Error("initialSeconds must be a finite number");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");let e=Math.floor(Math.max(0,t)),s=null,a=null,u=0,c=e,i=e,S=B(n.tickIntervalMs),g=y(),f=n.timeProvider??(()=>g.now()),l=()=>setInterval(()=>{try{if(a===null)return;let h=f()-a-u,D=Math.floor(h/1e3),r=Number.isFinite(D)?Math.min(i,Math.max(0,i-D)):i;e=r,r!==c&&(c=r,o.onTick(r)),r===0&&(d(),o.onComplete());}catch(p){d(),o.onError(p instanceof Error?p:new Error(String(p)));}},S),N=()=>{if(s||e<=0)return false;try{if(a!==null&&e<i){let p=(i-e)*1e3;u=f()-a-p;}else a=f(),u=0,c=e;return s=l(),!0}catch(p){return o.onError(p instanceof Error?p:new Error(String(p))),false}},d=()=>{s&&(clearInterval(s),s=null);},b=()=>{d(),e=i,a=null,u=0,c=i;},v=p=>{if(typeof p!="number"||!Number.isFinite(p))return;let h=Math.floor(Math.max(0,Math.min(p,Number.MAX_SAFE_INTEGER)));e=h,a=null,u=0,c=h;};return {start:N,stop:d,reset:b,setSeconds:v,setInitialValue:p=>{if(typeof p!="number"||!Number.isFinite(p))return;let h=Math.floor(Math.max(0,Math.min(p,Number.MAX_SAFE_INTEGER)));i=h,v(h);},getTotalSeconds:()=>e,getInitialValue:()=>i,isRunning:()=>s!==null,destroy:()=>{d(),e=0,a=null,u=0;}}}var m=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"}),I={[m.IDLE]:{start:m.RUNNING},[m.RUNNING]:{pause:m.PAUSED,reset:m.IDLE,stop:m.STOPPED,complete:m.STOPPED},[m.PAUSED]:{resume:m.RUNNING,reset:m.IDLE,stop:m.STOPPED},[m.STOPPED]:{reset:m.IDLE}};function O(t){if(t!==void 0){if(typeof t!="object"||t===null)throw new Error("events must be an object");if(t.onStateChange!==void 0&&typeof t.onStateChange!="function")throw new Error("events.onStateChange must be a function")}let o=m.IDLE;function n(g){let f=I[o]?.[g];if(!f)return false;o=f;try{t?.onStateChange?.(f);}catch{}return true}function e(){return n("start")}function s(){return n("resume")}function a(){return n("pause")}function u(){return n("reset")}function c(){return n("stop")}function i(){return n("complete")}function S(){o===m.IDLE||o===m.STOPPED||n("stop");}return {start:e,resume:s,pause:a,reset:u,stop:c,complete:i,getCurrentState:()=>o,canStart:()=>!!I[o]?.start,canResume:()=>!!I[o]?.resume,canPause:()=>!!I[o]?.pause,isRunning:()=>o===m.RUNNING,destroy:S}}function x(t){let o=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,n=o,e=Math.floor(n/31536e3);n-=e*31536e3;let s=Math.floor(n/604800);n-=s*604800;let a=Math.floor(n/86400);n-=a*86400;let u=Math.floor(n/3600);n-=u*3600;let c=Math.floor(n/60);return n-=c*60,{years:e,weeks:s,days:a,hours:u,minutes:c,seconds:n,totalDays:Math.floor(o/86400),totalHours:Math.floor(o/3600),totalMinutes:Math.floor(o/60)}}function C(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function R(t){if(typeof t!="number"||!Number.isFinite(t)||!Number.isInteger(t))throw new Error("initialSeconds must be a finite, non-negative integer");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");return t}function J(t){let o;if(t)if(typeof t=="function")o=t;else if(typeof t.now=="function"){let n=t;o=()=>n.now();}else throw new Error("timeProvider must implement a now(): number method");else {let n=y();o=()=>n.now();}return k(o)}function P(t,o,n){let e=C(t),s=C(o),a=x(s);return {initialSeconds:e,totalSeconds:s,parts:a,state:n,isRunning:n===m.RUNNING,isCompleted:s===0&&n===m.STOPPED}}function F(t,o={}){let n=R(t),e=J(o.timeProvider),s=n,a=P(n,n,m.IDLE),u=new Set,c=r=>{try{o.onSnapshot?.(r);}catch{}for(let w of u)try{w(r);}catch{}},i=r=>{let w=r===m.STOPPED?0:l.getTotalSeconds();a=P(s,w,r);try{o.onStateChange?.(r,a);}catch{}c(a);},S=r=>{a=P(s,r,f.getCurrentState()),c(a);},g=r=>{try{o.onError?.(r);}catch{}},f=O({onStateChange:r=>{i(r);}}),l=A(n,{onTick:r=>{S(r);},onComplete:()=>{f.complete();},onError:r=>{g(r),f.stop();}},{timeProvider:e,tickIntervalMs:o.tickIntervalMs});return {start:()=>{if(!f.canStart())return false;let r=l.start();return r&&f.start(),r},pause:()=>f.canPause()?(l.stop(),f.pause()):false,resume:()=>{if(!f.canResume())return false;let r=l.start();return r&&f.resume(),r},reset:r=>{if(l.stop(),typeof r=="number"){let _=R(r);s=_,l.setInitialValue(_);}else s=n,l.reset();return f.reset()||S(l.getTotalSeconds()),true},stop:()=>{l.stop();let r=f.stop();return r&&l.setSeconds(0),r},setSeconds:r=>{let w=R(r);l.setSeconds(w),S(l.getTotalSeconds());},getSnapshot:()=>a,subscribe:r=>{u.add(r);try{r(a);}catch{}return {unsubscribe:()=>{u.delete(r);}}},destroy:()=>{l.destroy(),f.destroy(),u.clear(),a=P(s,0,m.STOPPED);}}}function Q(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function T(t,o=2){return t.toString().padStart(o,"0")}function M(){let t=i=>x(C(Q(i)));return {formatTime:i=>{let S=t(i);return {minutes:T(S.totalMinutes),seconds:T(S.seconds)}},formatMinutes:i=>T(t(i).minutes),formatSeconds:i=>T(t(i).seconds),formatHours:i=>T(t(i).hours),formatDays:i=>T(t(i).days),formatWeeks:i=>T(t(i).weeks),formatYears:i=>T(t(i).years)}}var E=M();function Z(t){return E.formatTime(t)}function $(t){return E.formatMinutes(t)}function tt(t){return E.formatSeconds(t)}function et(t){return E.formatHours(t)}function nt(t){return E.formatDays(t)}function ot(t){return E.formatWeeks(t)}function rt(t){return E.formatYears(t)}function it(t,o={}){let{onSnapshot:n,onStateChange:e,onError:s}=o;if(n!==void 0&&typeof n!="function")throw new Error("onSnapshot must be a function");if(e!==void 0&&typeof e!="function")throw new Error("onStateChange must be a function");if(s!==void 0&&typeof s!="function")throw new Error("onError must be a function");let a=M(),u=F(t,{onError:s}),c=u.getSnapshot(),i=c.state,S=Number.NaN,g=d=>{if(s)try{s(d);}catch{}},f=d=>{if(n)try{n(d);}catch(b){g(b instanceof Error?b:new Error(String(b)));}},l=d=>{if(e)try{e(d);}catch(b){g(b instanceof Error?b:new Error(String(b)));}},N=u.subscribe(d=>{c=d,d.state!==i&&(i=d.state,l(d.state)),d.totalSeconds!==S&&(S=d.totalSeconds,f(d));});return {start:()=>{u.start();},pause:()=>{u.pause();},resume:()=>{u.resume();},reset:d=>{u.reset(d);},stop:()=>{u.stop();},getSeconds:()=>a.formatSeconds(c.totalSeconds),getMinutes:()=>a.formatMinutes(c.totalSeconds),getHours:()=>a.formatHours(c.totalSeconds),getDays:()=>a.formatDays(c.totalSeconds),getWeeks:()=>a.formatWeeks(c.totalSeconds),getYears:()=>a.formatYears(c.totalSeconds),getCurrentState:()=>c.state,getSnapshot:()=>c,destroy:()=>{try{N.unsubscribe();}finally{u.destroy();}}}}exports.Countdown=it;exports.CountdownEngine=F;exports.Formatter=M;exports.TimerState=m;exports.buildSnapshot=P;exports.defaultFormatter=E;exports.formatDays=nt;exports.formatHours=et;exports.formatMinutes=$;exports.formatSeconds=tt;exports.formatTime=Z;exports.formatWeeks=ot;exports.formatYears=rt;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CountdownSnapshot, T as TimerState } from './countdown-engine-qnWxt-ed.cjs';
2
- export { a as CountdownEngine, c as CountdownEngineInstance, d as CountdownEngineOptions, e as CountdownParts, b as buildSnapshot } from './countdown-engine-qnWxt-ed.cjs';
1
+ import { C as CountdownSnapshot, T as TimerState } from './countdown-engine-DEKF_8iT.cjs';
2
+ export { a as CountdownEngine, c as CountdownEngineInstance, d as CountdownEngineOptions, e as CountdownParts, b as buildSnapshot } from './countdown-engine-DEKF_8iT.cjs';
3
3
  export { FormatTarget, Formatter, defaultFormatter, formatDays, formatHours, formatMinutes, formatSeconds, formatTime, formatWeeks, formatYears } from './format.cjs';
4
4
 
5
5
  interface CountdownOptions {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CountdownSnapshot, T as TimerState } from './countdown-engine-qnWxt-ed.js';
2
- export { a as CountdownEngine, c as CountdownEngineInstance, d as CountdownEngineOptions, e as CountdownParts, b as buildSnapshot } from './countdown-engine-qnWxt-ed.js';
1
+ import { C as CountdownSnapshot, T as TimerState } from './countdown-engine-DEKF_8iT.js';
2
+ export { a as CountdownEngine, c as CountdownEngineInstance, d as CountdownEngineOptions, e as CountdownParts, b as buildSnapshot } from './countdown-engine-DEKF_8iT.js';
3
3
  export { FormatTarget, Formatter, defaultFormatter, formatDays, formatHours, formatMinutes, formatSeconds, formatTime, formatWeeks, formatYears } from './format.js';
4
4
 
5
5
  interface CountdownOptions {
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- function Y(){return {now:()=>performance.now(),isHighResolution:true,type:"performance"}}function W(){return {now:()=>Date.now(),isHighResolution:false,type:"date"}}function w(){let t,e=W();function s(){try{if(typeof performance<"u"&&typeof performance.now=="function"){let n=performance.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0&&n<=Number.MAX_SAFE_INTEGER){t=Y();return}}throw new Error("performance.now() not available or invalid")}catch{t=e;}}return s(),{now:()=>{try{let n=t.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0&&n<=Number.MAX_SAFE_INTEGER)return n;throw new Error("Invalid time value returned")}catch{t!==e&&(t=e);try{let n=e.now();if(typeof n=="number"&&Number.isFinite(n)&&!isNaN(n)&&n>=0)return n}catch{}return 0}},get isHighResolution(){return t.isHighResolution},get type(){return t.type}}}w();var L=10,V=100;function D(t,e,s={}){if(typeof t!="number"||!Number.isFinite(t))throw new Error("initialSeconds must be a finite number");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");let n=Math.floor(Math.max(0,t)),m=null,i=null,u=0,c=n,r=n,a=Math.max(L,Math.floor(s.tickIntervalMs??V)),b=w(),d=s.timeProvider??(()=>b.now()),p=()=>setInterval(()=>{try{if(i===null)return;let E=d()-i-u,x=Math.floor(E/1e3),o=Math.max(0,r-x);n=o,o!==c&&(c=o,e.onTick(o)),o===0&&(l(),e.onComplete());}catch(S){l(),e.onError(S instanceof Error?S:new Error(String(S)));}},a),P=()=>{if(m||n<=0)return false;try{if(i!==null&&n<r){let S=(r-n)*1e3;u=d()-i-S;}else i=d(),u=0,c=n;return m=p(),!0}catch(S){return e.onError(S instanceof Error?S:new Error(String(S))),false}},l=()=>{m&&(clearInterval(m),m=null);},g=()=>{l(),n=r,i=null,u=0,c=r;},v=S=>{if(typeof S!="number"||!Number.isFinite(S))return;let E=Math.floor(Math.max(0,Math.min(S,Number.MAX_SAFE_INTEGER)));n=E,i=null,u=0,c=E;};return {start:P,stop:l,reset:g,setSeconds:v,setInitialValue:S=>{if(typeof S!="number"||!Number.isFinite(S))return;let E=Math.floor(Math.max(0,Math.min(S,Number.MAX_SAFE_INTEGER)));r=E,v(E);},getTotalSeconds:()=>n,getInitialValue:()=>r,isRunning:()=>m!==null,destroy:()=>{l(),n=0,i=null,u=0;}}}var f=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"}),M={[f.IDLE]:{start:f.RUNNING},[f.RUNNING]:{pause:f.PAUSED,reset:f.IDLE,stop:f.STOPPED,complete:f.STOPPED},[f.PAUSED]:{resume:f.RUNNING,reset:f.IDLE,stop:f.STOPPED},[f.STOPPED]:{reset:f.IDLE}};function _(t){if(t!==void 0){if(typeof t!="object"||t===null)throw new Error("events must be an object");if(t.onStateChange!==void 0&&typeof t.onStateChange!="function")throw new Error("events.onStateChange must be a function")}let e=f.IDLE;function s(b){let d=M[e]?.[b];if(!d)return false;e=d;try{t?.onStateChange?.(d);}catch{}return true}function n(){return s("start")}function m(){return s("resume")}function i(){return s("pause")}function u(){return s("reset")}function c(){return s("stop")}function r(){return s("complete")}function a(){e===f.IDLE||e===f.STOPPED||s("stop");}return {start:n,resume:m,pause:i,reset:u,stop:c,complete:r,getCurrentState:()=>e,canStart:()=>!!M[e]?.start,canResume:()=>!!M[e]?.resume,canPause:()=>!!M[e]?.pause,isRunning:()=>e===f.RUNNING,destroy:a}}function O(t){if(typeof t!="number"||!Number.isFinite(t)||!Number.isInteger(t))throw new Error("initialSeconds must be a finite, non-negative integer");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");return t}function J(t){if(!t){let e=w();return ()=>e.now()}if(typeof t=="function")return t;if(typeof t.now=="function"){let e=t;return ()=>e.now()}throw new Error("timeProvider must implement a now(): number method")}function Q(t){let e=Math.max(0,Math.floor(t)),s=Math.floor(e/31536e3),n=Math.floor(e/604800)%52,m=Math.floor(e/86400)%7,i=Math.floor(e/3600)%24,u=Math.floor(e/60)%60,c=e%60,r=Math.floor(e/86400),a=Math.floor(e/3600),b=Math.floor(e/60);return {years:s,weeks:n,days:m,hours:i,minutes:u,seconds:c,totalDays:r,totalHours:a,totalMinutes:b}}function y(t,e,s){let n=Q(e);return {initialSeconds:t,totalSeconds:e,parts:n,state:s,isRunning:s===f.RUNNING,isCompleted:e===0&&s===f.STOPPED}}function R(t,e={}){let s=O(t),n=J(e.timeProvider),m=s,i=y(s,s,f.IDLE),u=new Set,c=o=>{try{e.onSnapshot?.(o);}catch{}for(let N of u)try{N(o);}catch{}},r=o=>{i=y(m,i.totalSeconds,o);try{e.onStateChange?.(o,i);}catch{}c(i);},a=o=>{i=y(m,o,d.getCurrentState()),c(i);},b=o=>{try{e.onError?.(o);}catch{}},d=_({onStateChange:o=>{r(o);}}),p=D(s,{onTick:o=>{a(o);},onComplete:()=>{d.complete(),a(0);},onError:o=>{b(o),d.stop();}},{timeProvider:n,tickIntervalMs:e.tickIntervalMs});return {start:()=>{if(!d.canStart())return false;let o=p.start();return o&&(d.start(),a(p.getTotalSeconds())),o},pause:()=>{if(!d.canPause())return false;p.stop();let o=d.pause();return o&&a(p.getTotalSeconds()),o},resume:()=>{if(!d.canResume())return false;let o=p.start();return o&&(d.resume(),a(p.getTotalSeconds())),o},reset:o=>{if(p.stop(),typeof o=="number"){let N=O(o);m=N,p.setInitialValue(N);}else m=s,p.reset();return d.reset(),a(p.getTotalSeconds()),true},stop:()=>{p.stop();let o=d.stop();return o&&(p.setSeconds(0),a(0)),o},setSeconds:o=>{p.setSeconds(o),a(p.getTotalSeconds());},getSnapshot:()=>i,subscribe:o=>{u.add(o);try{o(i);}catch{}return {unsubscribe:()=>{u.delete(o);}}},destroy:()=>{p.destroy(),d.destroy(),u.clear(),i=y(m,0,f.STOPPED);}}}function Z(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function $(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function h(t,e=2){return !Number.isFinite(t)||t<0?"0".repeat(e):Math.floor(t).toString().padStart(e,"0")}function k(t){return Math.floor(t/60)}function tt(t){return k(t)%60}function et(t){return Math.floor(t/3600)%24}function nt(t){return Math.floor(t/86400)%7}function ot(t){return Math.floor(t/604800)%52}function rt(t){return Math.floor(t/31536e3)}function I(){let t=r=>$(Z(r));return {formatTime:r=>{let a=t(r);return {minutes:h(k(a)),seconds:h(a%60)}},formatMinutes:r=>{let a=t(r);return h(tt(a))},formatSeconds:r=>{let a=t(r);return h(a%60)},formatHours:r=>{let a=t(r);return h(et(a))},formatDays:r=>{let a=t(r);return h(nt(a))},formatWeeks:r=>{let a=t(r);return h(ot(a))},formatYears:r=>{let a=t(r);return h(rt(a))}}}var T=I();function at(t){return T.formatTime(t)}function st(t){return T.formatMinutes(t)}function it(t){return T.formatSeconds(t)}function ut(t){return T.formatHours(t)}function ct(t){return T.formatDays(t)}function mt(t){return T.formatWeeks(t)}function ft(t){return T.formatYears(t)}function dt(t,e={}){let{onSnapshot:s,onStateChange:n,onError:m}=e;if(s!==void 0&&typeof s!="function")throw new Error("onSnapshot must be a function");if(n!==void 0&&typeof n!="function")throw new Error("onStateChange must be a function");if(m!==void 0&&typeof m!="function")throw new Error("onError must be a function");let i=I(),u=R(t,{onError:m}),c=u.getSnapshot(),r=c.state,a=Number.NaN,b=l=>{if(m)try{m(l);}catch{}},d=l=>{if(s)try{s(l);}catch(g){b(g instanceof Error?g:new Error(String(g)));}},p=l=>{if(n)try{n(l);}catch(g){b(g instanceof Error?g:new Error(String(g)));}},P=u.subscribe(l=>{c=l,l.state!==r&&(r=l.state,p(l.state)),l.totalSeconds!==a&&(a=l.totalSeconds,d(l));});return {start:()=>{u.start();},pause:()=>{u.pause();},resume:()=>{u.resume();},reset:l=>{u.reset(l);},stop:()=>{u.stop();},getSeconds:()=>i.formatSeconds(c.totalSeconds),getMinutes:()=>i.formatMinutes(c.totalSeconds),getHours:()=>i.formatHours(c.totalSeconds),getDays:()=>i.formatDays(c.totalSeconds),getWeeks:()=>i.formatWeeks(c.totalSeconds),getYears:()=>i.formatYears(c.totalSeconds),getCurrentState:()=>c.state,getSnapshot:()=>c,destroy:()=>{try{P.unsubscribe();}finally{u.destroy();}}}}export{dt as Countdown,R as CountdownEngine,I as Formatter,f as TimerState,y as buildSnapshot,T as defaultFormatter,ct as formatDays,ut as formatHours,st as formatMinutes,it as formatSeconds,at as formatTime,mt as formatWeeks,ft as formatYears};
1
+ function W(){return {now:()=>performance.now(),isHighResolution:true,type:"performance"}}function X(){return {now:()=>Date.now(),isHighResolution:false,type:"date"}}function y(){let t,o=X();function n(){try{if(typeof performance<"u"&&typeof performance.now=="function"){let e=performance.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0&&e<=Number.MAX_SAFE_INTEGER){t=W();return}}throw new Error("performance.now() not available or invalid")}catch{t=o;}}return n(),{now:()=>{try{let e=t.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0&&e<=Number.MAX_SAFE_INTEGER)return e;throw new Error("Invalid time value returned")}catch{t!==o&&(t=o);try{let e=o.now();if(typeof e=="number"&&Number.isFinite(e)&&!isNaN(e)&&e>=0)return e}catch{}return 0}},get isHighResolution(){return t.isHighResolution},get type(){return t.type}}}function k(t,o=0){let n=typeof o=="number"&&Number.isFinite(o)&&o>=0?o:0;return ()=>{let e=t();return typeof e!="number"||!Number.isFinite(e)||e<n||(n=e),n}}y();var z=10,j=100;function B(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?j:Math.max(z,Math.floor(t))}function A(t,o,n={}){if(typeof t!="number"||!Number.isFinite(t))throw new Error("initialSeconds must be a finite number");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");let e=Math.floor(Math.max(0,t)),s=null,a=null,u=0,c=e,i=e,S=B(n.tickIntervalMs),g=y(),f=n.timeProvider??(()=>g.now()),l=()=>setInterval(()=>{try{if(a===null)return;let h=f()-a-u,D=Math.floor(h/1e3),r=Number.isFinite(D)?Math.min(i,Math.max(0,i-D)):i;e=r,r!==c&&(c=r,o.onTick(r)),r===0&&(d(),o.onComplete());}catch(p){d(),o.onError(p instanceof Error?p:new Error(String(p)));}},S),N=()=>{if(s||e<=0)return false;try{if(a!==null&&e<i){let p=(i-e)*1e3;u=f()-a-p;}else a=f(),u=0,c=e;return s=l(),!0}catch(p){return o.onError(p instanceof Error?p:new Error(String(p))),false}},d=()=>{s&&(clearInterval(s),s=null);},b=()=>{d(),e=i,a=null,u=0,c=i;},v=p=>{if(typeof p!="number"||!Number.isFinite(p))return;let h=Math.floor(Math.max(0,Math.min(p,Number.MAX_SAFE_INTEGER)));e=h,a=null,u=0,c=h;};return {start:N,stop:d,reset:b,setSeconds:v,setInitialValue:p=>{if(typeof p!="number"||!Number.isFinite(p))return;let h=Math.floor(Math.max(0,Math.min(p,Number.MAX_SAFE_INTEGER)));i=h,v(h);},getTotalSeconds:()=>e,getInitialValue:()=>i,isRunning:()=>s!==null,destroy:()=>{d(),e=0,a=null,u=0;}}}var m=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"}),I={[m.IDLE]:{start:m.RUNNING},[m.RUNNING]:{pause:m.PAUSED,reset:m.IDLE,stop:m.STOPPED,complete:m.STOPPED},[m.PAUSED]:{resume:m.RUNNING,reset:m.IDLE,stop:m.STOPPED},[m.STOPPED]:{reset:m.IDLE}};function O(t){if(t!==void 0){if(typeof t!="object"||t===null)throw new Error("events must be an object");if(t.onStateChange!==void 0&&typeof t.onStateChange!="function")throw new Error("events.onStateChange must be a function")}let o=m.IDLE;function n(g){let f=I[o]?.[g];if(!f)return false;o=f;try{t?.onStateChange?.(f);}catch{}return true}function e(){return n("start")}function s(){return n("resume")}function a(){return n("pause")}function u(){return n("reset")}function c(){return n("stop")}function i(){return n("complete")}function S(){o===m.IDLE||o===m.STOPPED||n("stop");}return {start:e,resume:s,pause:a,reset:u,stop:c,complete:i,getCurrentState:()=>o,canStart:()=>!!I[o]?.start,canResume:()=>!!I[o]?.resume,canPause:()=>!!I[o]?.pause,isRunning:()=>o===m.RUNNING,destroy:S}}function x(t){let o=Number.isFinite(t)?Math.max(0,Math.floor(t)):0,n=o,e=Math.floor(n/31536e3);n-=e*31536e3;let s=Math.floor(n/604800);n-=s*604800;let a=Math.floor(n/86400);n-=a*86400;let u=Math.floor(n/3600);n-=u*3600;let c=Math.floor(n/60);return n-=c*60,{years:e,weeks:s,days:a,hours:u,minutes:c,seconds:n,totalDays:Math.floor(o/86400),totalHours:Math.floor(o/3600),totalMinutes:Math.floor(o/60)}}function C(t){return typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t)}function R(t){if(typeof t!="number"||!Number.isFinite(t)||!Number.isInteger(t))throw new Error("initialSeconds must be a finite, non-negative integer");if(t<0)throw new Error("initialSeconds must be non-negative");if(t>Number.MAX_SAFE_INTEGER)throw new Error("initialSeconds exceeds maximum safe integer");return t}function J(t){let o;if(t)if(typeof t=="function")o=t;else if(typeof t.now=="function"){let n=t;o=()=>n.now();}else throw new Error("timeProvider must implement a now(): number method");else {let n=y();o=()=>n.now();}return k(o)}function P(t,o,n){let e=C(t),s=C(o),a=x(s);return {initialSeconds:e,totalSeconds:s,parts:a,state:n,isRunning:n===m.RUNNING,isCompleted:s===0&&n===m.STOPPED}}function F(t,o={}){let n=R(t),e=J(o.timeProvider),s=n,a=P(n,n,m.IDLE),u=new Set,c=r=>{try{o.onSnapshot?.(r);}catch{}for(let w of u)try{w(r);}catch{}},i=r=>{let w=r===m.STOPPED?0:l.getTotalSeconds();a=P(s,w,r);try{o.onStateChange?.(r,a);}catch{}c(a);},S=r=>{a=P(s,r,f.getCurrentState()),c(a);},g=r=>{try{o.onError?.(r);}catch{}},f=O({onStateChange:r=>{i(r);}}),l=A(n,{onTick:r=>{S(r);},onComplete:()=>{f.complete();},onError:r=>{g(r),f.stop();}},{timeProvider:e,tickIntervalMs:o.tickIntervalMs});return {start:()=>{if(!f.canStart())return false;let r=l.start();return r&&f.start(),r},pause:()=>f.canPause()?(l.stop(),f.pause()):false,resume:()=>{if(!f.canResume())return false;let r=l.start();return r&&f.resume(),r},reset:r=>{if(l.stop(),typeof r=="number"){let _=R(r);s=_,l.setInitialValue(_);}else s=n,l.reset();return f.reset()||S(l.getTotalSeconds()),true},stop:()=>{l.stop();let r=f.stop();return r&&l.setSeconds(0),r},setSeconds:r=>{let w=R(r);l.setSeconds(w),S(l.getTotalSeconds());},getSnapshot:()=>a,subscribe:r=>{u.add(r);try{r(a);}catch{}return {unsubscribe:()=>{u.delete(r);}}},destroy:()=>{l.destroy(),f.destroy(),u.clear(),a=P(s,0,m.STOPPED);}}}function Q(t){return typeof t=="number"?t:t&&typeof t.totalSeconds=="number"?t.totalSeconds:0}function T(t,o=2){return t.toString().padStart(o,"0")}function M(){let t=i=>x(C(Q(i)));return {formatTime:i=>{let S=t(i);return {minutes:T(S.totalMinutes),seconds:T(S.seconds)}},formatMinutes:i=>T(t(i).minutes),formatSeconds:i=>T(t(i).seconds),formatHours:i=>T(t(i).hours),formatDays:i=>T(t(i).days),formatWeeks:i=>T(t(i).weeks),formatYears:i=>T(t(i).years)}}var E=M();function Z(t){return E.formatTime(t)}function $(t){return E.formatMinutes(t)}function tt(t){return E.formatSeconds(t)}function et(t){return E.formatHours(t)}function nt(t){return E.formatDays(t)}function ot(t){return E.formatWeeks(t)}function rt(t){return E.formatYears(t)}function it(t,o={}){let{onSnapshot:n,onStateChange:e,onError:s}=o;if(n!==void 0&&typeof n!="function")throw new Error("onSnapshot must be a function");if(e!==void 0&&typeof e!="function")throw new Error("onStateChange must be a function");if(s!==void 0&&typeof s!="function")throw new Error("onError must be a function");let a=M(),u=F(t,{onError:s}),c=u.getSnapshot(),i=c.state,S=Number.NaN,g=d=>{if(s)try{s(d);}catch{}},f=d=>{if(n)try{n(d);}catch(b){g(b instanceof Error?b:new Error(String(b)));}},l=d=>{if(e)try{e(d);}catch(b){g(b instanceof Error?b:new Error(String(b)));}},N=u.subscribe(d=>{c=d,d.state!==i&&(i=d.state,l(d.state)),d.totalSeconds!==S&&(S=d.totalSeconds,f(d));});return {start:()=>{u.start();},pause:()=>{u.pause();},resume:()=>{u.resume();},reset:d=>{u.reset(d);},stop:()=>{u.stop();},getSeconds:()=>a.formatSeconds(c.totalSeconds),getMinutes:()=>a.formatMinutes(c.totalSeconds),getHours:()=>a.formatHours(c.totalSeconds),getDays:()=>a.formatDays(c.totalSeconds),getWeeks:()=>a.formatWeeks(c.totalSeconds),getYears:()=>a.formatYears(c.totalSeconds),getCurrentState:()=>c.state,getSnapshot:()=>c,destroy:()=>{try{N.unsubscribe();}finally{u.destroy();}}}}export{it as Countdown,F as CountdownEngine,M as Formatter,m as TimerState,P as buildSnapshot,E as defaultFormatter,nt as formatDays,et as formatHours,$ as formatMinutes,tt as formatSeconds,Z as formatTime,ot as formatWeeks,rt as formatYears};
@@ -1 +1 @@
1
- 'use strict';var c=t=>!Number.isFinite(t)||t<0?0:t>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t);function h(t={}){let{startMs:e=0,tickMs:r=1e3,highResolution:a=true}=t,o=c(e),i=c(r);return {now:()=>o,advance:(s=i)=>(o=c(o+c(s)),o),set:s=>(o=c(s),o),reset:()=>(o=c(e),o),getTime:()=>o,isHighResolution:a,type:"fake"}}function T(t){return {now:()=>t.now(),isHighResolution:t.isHighResolution,type:t.type}}var n=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"});({[n.IDLE]:{start:n.RUNNING},[n.RUNNING]:{pause:n.PAUSED,reset:n.IDLE,stop:n.STOPPED,complete:n.STOPPED},[n.PAUSED]:{resume:n.RUNNING,reset:n.IDLE,stop:n.STOPPED},[n.STOPPED]:{reset:n.IDLE}});var m=t=>typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t),l=t=>{let e=m(t),r=Math.floor(e/31536e3),a=Math.floor(e/604800)%52,o=Math.floor(e/86400)%7,i=Math.floor(e/3600)%24,S=Math.floor(e/60)%60,d=e%60,p=Math.floor(e/86400),u=Math.floor(e/3600),s=Math.floor(e/60);return {years:r,weeks:a,days:o,hours:i,minutes:S,seconds:d,totalDays:p,totalHours:u,totalMinutes:s}};function b(t={}){let e=m(t.initialSeconds??t.totalSeconds??0),r=m(t.totalSeconds??t.initialSeconds??0),a=t.state??(r>0?n.IDLE:n.STOPPED),o=l(r);return {initialSeconds:e,totalSeconds:r,parts:o,state:a,isRunning:a===n.RUNNING,isCompleted:r===0&&a===n.STOPPED}}function w(t={}){let{totalSeconds:e=0,step:r=1,count:a=1,initialSeconds:o}=t,i=m(e),S=m(r),d=m(a)||1,p=[];for(let u=0;u<d;u+=1){let s=Math.max(i-S*u,0);p.push(b({initialSeconds:o??i,totalSeconds:s,state:s===0?n.STOPPED:n.RUNNING}));}return p}var f=(t,e)=>e?`${t}: ${e}`:t;function x(t,e,r){if(t.state!==e)throw new Error(f(r??"Unexpected countdown state",`expected ${e} but received ${t.state}`))}function I(t,e){if(!t.isCompleted||t.totalSeconds!==0)throw new Error(f(e??"Countdown should be completed"))}function y(t,e,r=0,a){if(typeof e!="number"||!Number.isFinite(e))throw new Error("Expected remaining seconds must be a finite number");if(Math.abs(t.totalSeconds-Math.floor(e))>r)throw new Error(f(a??"Unexpected remaining seconds",`expected ${e}\xB1${r} but received ${t.totalSeconds}`))}exports.TimerState=n;exports.assertRemainingSeconds=y;exports.assertSnapshotCompleted=I;exports.assertSnapshotState=x;exports.buildSnapshot=b;exports.buildSnapshotSequence=w;exports.createFakeTimeProvider=h;exports.toTimeProvider=T;
1
+ 'use strict';var u=e=>!Number.isFinite(e)||e<0?0:e>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(e);function M(e={}){let{startMs:n=0,tickMs:t=1e3,highResolution:a=true}=e,r=u(n),s=u(t);return {now:()=>r,advance:(i=s)=>(r=u(r+u(i)),r),set:i=>(r=u(i),r),reset:()=>(r=u(n),r),getTime:()=>r,isHighResolution:a,type:"fake"}}function R(e){return {now:()=>e.now(),isHighResolution:e.isHighResolution,type:e.type}}function h(e){let n=Number.isFinite(e)?Math.max(0,Math.floor(e)):0,t=n,a=Math.floor(t/31536e3);t-=a*31536e3;let r=Math.floor(t/604800);t-=r*604800;let s=Math.floor(t/86400);t-=s*86400;let m=Math.floor(t/3600);t-=m*3600;let p=Math.floor(t/60);return t-=p*60,{years:a,weeks:r,days:s,hours:m,minutes:p,seconds:t,totalDays:Math.floor(n/86400),totalHours:Math.floor(n/3600),totalMinutes:Math.floor(n/60)}}function c(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?0:e>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(e)}var o=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"});({[o.IDLE]:{start:o.RUNNING},[o.RUNNING]:{pause:o.PAUSED,reset:o.IDLE,stop:o.STOPPED,complete:o.STOPPED},[o.PAUSED]:{resume:o.RUNNING,reset:o.IDLE,stop:o.STOPPED},[o.STOPPED]:{reset:o.IDLE}});function P(e={}){let n=c(e.initialSeconds??e.totalSeconds??0),t=c(e.totalSeconds??e.initialSeconds??0),a=e.state??(t>0?o.IDLE:o.STOPPED),r=h(t);return {initialSeconds:n,totalSeconds:t,parts:r,state:a,isRunning:a===o.RUNNING,isCompleted:t===0&&a===o.STOPPED}}function A(e={}){let{totalSeconds:n=0,step:t=1,count:a=1,initialSeconds:r}=e,s=c(n),m=c(t),p=c(a)||1,S=[];for(let f=0;f<p;f+=1){let i=Math.max(s-m*f,0);S.push(P({initialSeconds:r??s,totalSeconds:i,state:i===0?o.STOPPED:o.RUNNING}));}return S}var d=(e,n)=>n?`${e}: ${n}`:e;function U(e,n,t){if(e.state!==n)throw new Error(d(t??"Unexpected countdown state",`expected ${n} but received ${e.state}`))}function F(e,n){if(!e.isCompleted||e.totalSeconds!==0)throw new Error(d(n??"Countdown should be completed"))}function v(e,n,t=0,a){if(typeof n!="number"||!Number.isFinite(n))throw new Error("Expected remaining seconds must be a finite number");if(Math.abs(e.totalSeconds-Math.floor(n))>t)throw new Error(d(a??"Unexpected remaining seconds",`expected ${n}\xB1${t} but received ${e.totalSeconds}`))}exports.TimerState=o;exports.assertRemainingSeconds=v;exports.assertSnapshotCompleted=F;exports.assertSnapshotState=U;exports.buildSnapshot=P;exports.buildSnapshotSequence=A;exports.createFakeTimeProvider=M;exports.toTimeProvider=R;
@@ -1,4 +1,4 @@
1
- import { f as TimeProvider, T as TimerState, C as CountdownSnapshot } from './countdown-engine-qnWxt-ed.cjs';
1
+ import { f as TimeProvider, T as TimerState, C as CountdownSnapshot } from './countdown-engine-DEKF_8iT.cjs';
2
2
 
3
3
  interface FakeTimeProvider extends TimeProvider {
4
4
  advance: (ms?: number) => number;
@@ -1,4 +1,4 @@
1
- import { f as TimeProvider, T as TimerState, C as CountdownSnapshot } from './countdown-engine-qnWxt-ed.js';
1
+ import { f as TimeProvider, T as TimerState, C as CountdownSnapshot } from './countdown-engine-DEKF_8iT.js';
2
2
 
3
3
  interface FakeTimeProvider extends TimeProvider {
4
4
  advance: (ms?: number) => number;
@@ -1 +1 @@
1
- var c=t=>!Number.isFinite(t)||t<0?0:t>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t);function h(t={}){let{startMs:e=0,tickMs:r=1e3,highResolution:a=true}=t,o=c(e),i=c(r);return {now:()=>o,advance:(s=i)=>(o=c(o+c(s)),o),set:s=>(o=c(s),o),reset:()=>(o=c(e),o),getTime:()=>o,isHighResolution:a,type:"fake"}}function T(t){return {now:()=>t.now(),isHighResolution:t.isHighResolution,type:t.type}}var n=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"});({[n.IDLE]:{start:n.RUNNING},[n.RUNNING]:{pause:n.PAUSED,reset:n.IDLE,stop:n.STOPPED,complete:n.STOPPED},[n.PAUSED]:{resume:n.RUNNING,reset:n.IDLE,stop:n.STOPPED},[n.STOPPED]:{reset:n.IDLE}});var m=t=>typeof t!="number"||!Number.isFinite(t)||t<=0?0:t>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(t),l=t=>{let e=m(t),r=Math.floor(e/31536e3),a=Math.floor(e/604800)%52,o=Math.floor(e/86400)%7,i=Math.floor(e/3600)%24,S=Math.floor(e/60)%60,d=e%60,p=Math.floor(e/86400),u=Math.floor(e/3600),s=Math.floor(e/60);return {years:r,weeks:a,days:o,hours:i,minutes:S,seconds:d,totalDays:p,totalHours:u,totalMinutes:s}};function b(t={}){let e=m(t.initialSeconds??t.totalSeconds??0),r=m(t.totalSeconds??t.initialSeconds??0),a=t.state??(r>0?n.IDLE:n.STOPPED),o=l(r);return {initialSeconds:e,totalSeconds:r,parts:o,state:a,isRunning:a===n.RUNNING,isCompleted:r===0&&a===n.STOPPED}}function w(t={}){let{totalSeconds:e=0,step:r=1,count:a=1,initialSeconds:o}=t,i=m(e),S=m(r),d=m(a)||1,p=[];for(let u=0;u<d;u+=1){let s=Math.max(i-S*u,0);p.push(b({initialSeconds:o??i,totalSeconds:s,state:s===0?n.STOPPED:n.RUNNING}));}return p}var f=(t,e)=>e?`${t}: ${e}`:t;function x(t,e,r){if(t.state!==e)throw new Error(f(r??"Unexpected countdown state",`expected ${e} but received ${t.state}`))}function I(t,e){if(!t.isCompleted||t.totalSeconds!==0)throw new Error(f(e??"Countdown should be completed"))}function y(t,e,r=0,a){if(typeof e!="number"||!Number.isFinite(e))throw new Error("Expected remaining seconds must be a finite number");if(Math.abs(t.totalSeconds-Math.floor(e))>r)throw new Error(f(a??"Unexpected remaining seconds",`expected ${e}\xB1${r} but received ${t.totalSeconds}`))}export{n as TimerState,y as assertRemainingSeconds,I as assertSnapshotCompleted,x as assertSnapshotState,b as buildSnapshot,w as buildSnapshotSequence,h as createFakeTimeProvider,T as toTimeProvider};
1
+ var u=e=>!Number.isFinite(e)||e<0?0:e>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(e);function M(e={}){let{startMs:n=0,tickMs:t=1e3,highResolution:a=true}=e,r=u(n),s=u(t);return {now:()=>r,advance:(i=s)=>(r=u(r+u(i)),r),set:i=>(r=u(i),r),reset:()=>(r=u(n),r),getTime:()=>r,isHighResolution:a,type:"fake"}}function R(e){return {now:()=>e.now(),isHighResolution:e.isHighResolution,type:e.type}}function h(e){let n=Number.isFinite(e)?Math.max(0,Math.floor(e)):0,t=n,a=Math.floor(t/31536e3);t-=a*31536e3;let r=Math.floor(t/604800);t-=r*604800;let s=Math.floor(t/86400);t-=s*86400;let m=Math.floor(t/3600);t-=m*3600;let p=Math.floor(t/60);return t-=p*60,{years:a,weeks:r,days:s,hours:m,minutes:p,seconds:t,totalDays:Math.floor(n/86400),totalHours:Math.floor(n/3600),totalMinutes:Math.floor(n/60)}}function c(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?0:e>=Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:Math.floor(e)}var o=Object.freeze({IDLE:"IDLE",RUNNING:"RUNNING",PAUSED:"PAUSED",STOPPED:"STOPPED"});({[o.IDLE]:{start:o.RUNNING},[o.RUNNING]:{pause:o.PAUSED,reset:o.IDLE,stop:o.STOPPED,complete:o.STOPPED},[o.PAUSED]:{resume:o.RUNNING,reset:o.IDLE,stop:o.STOPPED},[o.STOPPED]:{reset:o.IDLE}});function P(e={}){let n=c(e.initialSeconds??e.totalSeconds??0),t=c(e.totalSeconds??e.initialSeconds??0),a=e.state??(t>0?o.IDLE:o.STOPPED),r=h(t);return {initialSeconds:n,totalSeconds:t,parts:r,state:a,isRunning:a===o.RUNNING,isCompleted:t===0&&a===o.STOPPED}}function A(e={}){let{totalSeconds:n=0,step:t=1,count:a=1,initialSeconds:r}=e,s=c(n),m=c(t),p=c(a)||1,S=[];for(let f=0;f<p;f+=1){let i=Math.max(s-m*f,0);S.push(P({initialSeconds:r??s,totalSeconds:i,state:i===0?o.STOPPED:o.RUNNING}));}return S}var d=(e,n)=>n?`${e}: ${n}`:e;function U(e,n,t){if(e.state!==n)throw new Error(d(t??"Unexpected countdown state",`expected ${n} but received ${e.state}`))}function F(e,n){if(!e.isCompleted||e.totalSeconds!==0)throw new Error(d(n??"Countdown should be completed"))}function v(e,n,t=0,a){if(typeof n!="number"||!Number.isFinite(n))throw new Error("Expected remaining seconds must be a finite number");if(Math.abs(e.totalSeconds-Math.floor(n))>t)throw new Error(d(a??"Unexpected remaining seconds",`expected ${n}\xB1${t} but received ${e.totalSeconds}`))}export{o as TimerState,v as assertRemainingSeconds,F as assertSnapshotCompleted,U as assertSnapshotState,P as buildSnapshot,A as buildSnapshotSequence,M as createFakeTimeProvider,R as toTimeProvider};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timekeeper-countdown/core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Lightweight countdown engine that powers the Timekeeper packages. Pure TypeScript with no runtime dependencies.",
5
5
  "keywords": [
6
6
  "countdown",
@@ -54,6 +54,7 @@
54
54
  "test": "vitest run",
55
55
  "test:ui": "vitest --ui",
56
56
  "test:coverage": "vitest run --coverage",
57
+ "test:mutation": "stryker run",
57
58
  "typecheck": "tsc --noEmit",
58
59
  "lint": "eslint .",
59
60
  "lint:fix": "eslint . --fix",
@@ -62,7 +63,7 @@
62
63
  "prepublishOnly": "npm run build && npm run test && npm run typecheck"
63
64
  },
64
65
  "engines": {
65
- "node": ">=18"
66
+ "node": ">=22"
66
67
  },
67
68
  "publishConfig": {
68
69
  "registry": "https://registry.npmjs.org",