fatigue-kit 0.2.0 → 0.2.1

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
@@ -114,7 +114,7 @@ Durations accept `'45s' / '30m' / '12h' / '7d'` or milliseconds. Calendar math u
114
114
 
115
115
  ## Migrating legacy records
116
116
 
117
- Coming from an internal `{ times, date, duration, todayCount }` store?
117
+ Coming from a legacy `{ times, date, duration, todayCount }` store?
118
118
 
119
119
  ```ts
120
120
  import { migrateLegacyRecord } from 'fatigue-kit/legacy'
package/README.zh-CN.md CHANGED
@@ -114,7 +114,7 @@ AppState.addEventListener('change', (state) => {
114
114
 
115
115
  ## 迁移旧数据
116
116
 
117
- 从内部 `{ times, date, duration, todayCount }` 存储迁移?
117
+ 从旧版 `{ times, date, duration, todayCount }` 存储迁移?
118
118
 
119
119
  ```ts
120
120
  import { migrateLegacyRecord } from 'fatigue-kit/legacy'
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
 
3
3
  /** Alipay mini-program storage API (object arguments, values wrapped in `{ data }`). */
4
4
  interface AlipayStorageLike {
@@ -24,4 +24,5 @@ interface AlipayAdapterOptions {
24
24
  /** Alipay mini-program adapter backed by `my.getStorageSync` & friends. */
25
25
  declare function alipayAdapter(options?: AlipayAdapterOptions): SyncStorage;
26
26
 
27
- export { type AlipayAdapterOptions, type AlipayStorageLike, alipayAdapter };
27
+ export { alipayAdapter };
28
+ export type { AlipayAdapterOptions, AlipayStorageLike };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
 
3
3
  /** Alipay mini-program storage API (object arguments, values wrapped in `{ data }`). */
4
4
  interface AlipayStorageLike {
@@ -24,4 +24,5 @@ interface AlipayAdapterOptions {
24
24
  /** Alipay mini-program adapter backed by `my.getStorageSync` & friends. */
25
25
  declare function alipayAdapter(options?: AlipayAdapterOptions): SyncStorage;
26
26
 
27
- export { type AlipayAdapterOptions, type AlipayStorageLike, alipayAdapter };
27
+ export { alipayAdapter };
28
+ export type { AlipayAdapterOptions, AlipayStorageLike };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
 
3
3
  /**
4
4
  * Minimal interface shared by `@react-native-async-storage/async-storage` and
@@ -45,4 +45,5 @@ interface AsyncStorageAdapterOptions {
45
45
  */
46
46
  declare function asyncStorageAdapter(client: AsyncStorageLike, options?: AsyncStorageAdapterOptions): AsyncStorageAdapter;
47
47
 
48
- export { type AsyncStorageAdapter, type AsyncStorageAdapterOptions, type AsyncStorageLike, asyncStorageAdapter };
48
+ export { asyncStorageAdapter };
49
+ export type { AsyncStorageAdapter, AsyncStorageAdapterOptions, AsyncStorageLike };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
 
3
3
  /**
4
4
  * Minimal interface shared by `@react-native-async-storage/async-storage` and
@@ -45,4 +45,5 @@ interface AsyncStorageAdapterOptions {
45
45
  */
46
46
  declare function asyncStorageAdapter(client: AsyncStorageLike, options?: AsyncStorageAdapterOptions): AsyncStorageAdapter;
47
47
 
48
- export { type AsyncStorageAdapter, type AsyncStorageAdapterOptions, type AsyncStorageLike, asyncStorageAdapter };
48
+ export { asyncStorageAdapter };
49
+ export type { AsyncStorageAdapter, AsyncStorageAdapterOptions, AsyncStorageLike };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
  import { W as WebStorageAdapterOptions } from '../web-GiaS0cnX.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
  import { W as WebStorageAdapterOptions } from '../web-GiaS0cnX.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
 
3
3
  interface MemoryAdapter extends SyncStorage {
4
4
  /** Snapshot of the underlying map. Handy for tests and debugging. */
@@ -11,4 +11,5 @@ interface MemoryAdapter extends SyncStorage {
11
11
  */
12
12
  declare function memoryAdapter(initial?: Record<string, string>): MemoryAdapter;
13
13
 
14
- export { type MemoryAdapter, memoryAdapter };
14
+ export { memoryAdapter };
15
+ export type { MemoryAdapter };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
 
3
3
  interface MemoryAdapter extends SyncStorage {
4
4
  /** Snapshot of the underlying map. Handy for tests and debugging. */
@@ -11,4 +11,5 @@ interface MemoryAdapter extends SyncStorage {
11
11
  */
12
12
  declare function memoryAdapter(initial?: Record<string, string>): MemoryAdapter;
13
13
 
14
- export { type MemoryAdapter, memoryAdapter };
14
+ export { memoryAdapter };
15
+ export type { MemoryAdapter };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
 
3
3
  interface FileAdapterOptions {
4
4
  /** Pretty-print the backing JSON file. Default `false`. */
@@ -12,4 +12,5 @@ interface FileAdapterOptions {
12
12
  */
13
13
  declare function fileAdapter(filePath: string, options?: FileAdapterOptions): SyncStorage;
14
14
 
15
- export { type FileAdapterOptions, fileAdapter };
15
+ export { fileAdapter };
16
+ export type { FileAdapterOptions };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
 
3
3
  interface FileAdapterOptions {
4
4
  /** Pretty-print the backing JSON file. Default `false`. */
@@ -12,4 +12,5 @@ interface FileAdapterOptions {
12
12
  */
13
13
  declare function fileAdapter(filePath: string, options?: FileAdapterOptions): SyncStorage;
14
14
 
15
- export { type FileAdapterOptions, fileAdapter };
15
+ export { fileAdapter };
16
+ export type { FileAdapterOptions };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
  import { W as WebStorageAdapterOptions } from '../web-GiaS0cnX.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
  import { W as WebStorageAdapterOptions } from '../web-GiaS0cnX.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.cjs';
1
+ import { SyncStorage } from '../index.cjs';
2
2
 
3
3
  /** WeChat mini-program storage API (positional arguments). */
4
4
  interface WeappStorageLike {
@@ -20,4 +20,5 @@ interface WeappAdapterOptions {
20
20
  */
21
21
  declare function weappAdapter(options?: WeappAdapterOptions): SyncStorage;
22
22
 
23
- export { type WeappAdapterOptions, type WeappStorageLike, weappAdapter };
23
+ export { weappAdapter };
24
+ export type { WeappAdapterOptions, WeappStorageLike };
@@ -1,4 +1,4 @@
1
- import { S as SyncStorage } from '../types-hDxN5bc3.js';
1
+ import { SyncStorage } from '../index.js';
2
2
 
3
3
  /** WeChat mini-program storage API (positional arguments). */
4
4
  interface WeappStorageLike {
@@ -20,4 +20,5 @@ interface WeappAdapterOptions {
20
20
  */
21
21
  declare function weappAdapter(options?: WeappAdapterOptions): SyncStorage;
22
22
 
23
- export { type WeappAdapterOptions, type WeappStorageLike, weappAdapter };
23
+ export { weappAdapter };
24
+ export type { WeappAdapterOptions, WeappStorageLike };
@@ -1,2 +1,2 @@
1
- "use strict";var FatigueKit=(()=>{var b=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var j=(t,n)=>{for(var e in n)b(t,e,{get:n[e],enumerable:!0})},L=(t,n,e,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of H(n))!J.call(t,i)&&i!==e&&b(t,i,{get:()=>n[i],enumerable:!(r=Y(n,i))||r.enumerable});return t};var U=t=>L(b({},"__esModule",{value:!0}),t);var Z={};j(Z,{RECORD_VERSION:()=>R,createFatigue:()=>$,memoryAdapter:()=>p});function p(t){let n=new Map(Object.entries(t!=null?t:{}));return{get:e=>{var r;return(r=n.get(e))!=null?r:null},set:(e,r)=>{n.set(e,r)},remove:e=>{n.delete(e)},keys:()=>[...n.keys()],dump:()=>Object.fromEntries(n)}}function D(t){if(t===void 0)return 0;let n=/^(\d{1,2}):(\d{2})$/.exec(t.trim());if(n===null||n[1]===void 0||n[2]===void 0)throw new TypeError(`[fatigue-kit] invalid cutoff: "${t}". Expected 'HH:mm'.`);let e=Number(n[1]),r=Number(n[2]);if(e>23||r>59)throw new TypeError(`[fatigue-kit] invalid cutoff: "${t}". Hours must be 0-23, minutes 0-59.`);return e*60+r}function E(t){let n=new Date(t);return n.setHours(0,0,0,0),n}function W(t,n){switch(n.every){case"day":return E(t).getTime();case"week":{let e=E(t),r=(e.getDay()-n.weekStartsOn+7)%7;return e.setDate(e.getDate()-r),e.getTime()}case"month":{let e=new Date(t);return new Date(e.getFullYear(),e.getMonth(),1).getTime()}case"year":{let e=new Date(t);return new Date(e.getFullYear(),0,1).getTime()}}}function q(t,n){switch(n.every){case"day":{let e=new Date(t);return e.setDate(e.getDate()-1),e.getTime()}case"week":{let e=new Date(t);return e.setDate(e.getDate()-7),e.getTime()}case"month":{let e=new Date(t);return new Date(e.getFullYear(),e.getMonth()-1,1).getTime()}case"year":{let e=new Date(t);return new Date(e.getFullYear()-1,0,1).getTime()}}}function A(t,n){let e=new Date(t);return new Date(e.getFullYear(),e.getMonth(),e.getDate(),Math.floor(n/60),n%60).getTime()}function y(t,n){let e=W(t,n),r=A(e,n.cutoffMinutes);return r<=t?r:A(q(e,n),n.cutoffMinutes)}var K={day:12*36e5,week:8*864e5,month:8*864e5,year:32*864e5};function T(t,n){let e=K[n.every],r=t;for(let i=0;i<50;i++){r+=e;let o=y(r,n);if(o>t)return o}throw new Error("[fatigue-kit] failed to compute the next calendar period")}var B={s:1e3,m:6e4,h:36e5,d:864e5};function h(t){if(typeof t=="number"){if(!Number.isFinite(t)||t<=0)throw new TypeError(`[fatigue-kit] invalid duration: ${t}`);return t}let n=/^(\d+(?:\.\d+)?)\s*([smhd])$/.exec(t.trim());if(n===null||n[1]===void 0||n[2]===void 0)throw new TypeError(`[fatigue-kit] invalid duration: "${t}". Expected a positive number of ms, or '45s' / '30m' / '12h' / '7d'.`);let e=B[n[2]];if(e===void 0)throw new TypeError(`[fatigue-kit] invalid duration: "${t}"`);let r=Number(n[1])*e;if(!(r>0))throw new TypeError(`[fatigue-kit] invalid duration: "${t}"`);return r}var R=1;function w(){return{v:1,hits:[],lifetime:0}}function x(t){if(!t)return w();let n;try{n=JSON.parse(t)}catch(o){return w()}if(n===null||typeof n!="object")return w();let e=n;if(e.v!==1)return w();let r=Array.isArray(e.hits)?e.hits.filter(o=>typeof o=="number"&&Number.isFinite(o)):[];r.sort((o,s)=>o-s);let i=typeof e.lifetime=="number"&&Number.isFinite(e.lifetime)&&e.lifetime>=0?e.lifetime:r.length;return{v:1,hits:r,lifetime:i}}function k(t){return JSON.stringify(t)}function I(t,n,e){let r=0;for(;r<t.hits.length;){let i=t.hits[r];if(i===void 0||i>=n)break;r++}r>0&&t.hits.splice(0,r),t.hits.length>e&&t.hits.splice(0,t.hits.length-e)}var X="fatigue-kit",z=100;function O(t,n){if(typeof t!="string"||t.length===0)throw new TypeError(`[fatigue-kit] ${n} must be a non-empty string`)}function F(t){if(!Number.isInteger(t)||t<1)throw new TypeError(`[fatigue-kit] rule "max" must be a positive integer, got ${t}`)}function M(t){let n=Array.isArray(t)?t:[t];if(n.length===0)throw new TypeError("[fatigue-kit] at least one rule is required");return n.map(e=>{var r;if(e===null||typeof e!="object")throw new TypeError(`[fatigue-kit] unknown rule: ${JSON.stringify(e)}`);if("window"in e)return F(e.max),{kind:"sliding",rule:e,max:e.max,windowMs:h(e.window)};if("every"in e){if(F(e.max),e.every!=="day"&&e.every!=="week"&&e.every!=="month"&&e.every!=="year")throw new TypeError(`[fatigue-kit] invalid "every": ${JSON.stringify(e.every)}`);return{kind:"calendar",rule:e,max:e.max,spec:{every:e.every,cutoffMinutes:D(e.cutoff),weekStartsOn:(r=e.weekStartsOn)!=null?r:1}}}if("cooldown"in e)return{kind:"cooldown",rule:e,cooldownMs:h(e.cooldown)};if("max"in e)return F(e.max),{kind:"lifetime",rule:e,max:e.max};throw new TypeError(`[fatigue-kit] unknown rule: ${JSON.stringify(e)}`)})}function G(t,n,e){switch(t.kind){case"sliding":{let r=e-t.windowMs,i=0,o=Number.POSITIVE_INFINITY;for(let f of n.hits)f>r&&(i++,f<o&&(o=f));let s=t.max-i;return{remaining:s,nextAvailableAt:s<=0&&o!==Number.POSITIVE_INFINITY?o+t.windowMs:void 0}}case"calendar":{let r=y(e,t.spec),i=0;for(let s of n.hits)s>=r&&i++;let o=t.max-i;return{remaining:o,nextAvailableAt:o<=0?T(e,t.spec):void 0}}case"cooldown":{let r=n.hits.length>0?n.hits[n.hits.length-1]:void 0;if(r===void 0)return{remaining:Number.POSITIVE_INFINITY};let i=r+t.cooldownMs;return{remaining:Number.POSITIVE_INFINITY,nextAvailableAt:i>e?i:void 0}}case"lifetime":return{remaining:t.max-n.lifetime}}}function _(t,n,e){let r=Number.POSITIVE_INFINITY,i,o;for(let f of n){let c=G(f,t,e);Number.isFinite(c.remaining)&&(r=Math.min(r,c.remaining)),c.nextAvailableAt!==void 0&&(i===void 0||c.nextAvailableAt>i)&&(i=c.nextAvailableAt),c.remaining>0&&(c.nextAvailableAt===void 0||c.nextAvailableAt<=e)||o!=null||(o=f.rule)}let s={allowed:o===void 0,remaining:Math.max(0,r)};return i!==void 0&&(s.nextAvailableAt=i),o!==void 0&&(s.deniedBy=o),s}function Q(t,n){let e=n;for(let r of t)r.kind==="sliding"?e=Math.min(e,n-r.windowMs):r.kind==="calendar"?e=Math.min(e,y(n,r.spec)):r.kind==="cooldown"&&(e=Math.min(e,n-r.cooldownMs));return e}function $(t={}){var v,S,N,C;let n=(v=t.storage)!=null?v:p(),e=(S=t.clock)!=null?S:{now:()=>Date.now()},r=(N=t.namespace)!=null?N:X,i=(C=t.maxHits)!=null?C:z;if(O(r,"namespace"),!Number.isInteger(i)||i<1)throw new TypeError(`[fatigue-kit] maxHits must be a positive integer, got ${i}`);let o=a=>(O(a,"key"),`${r}:${a}`),s=a=>x(n.get(o(a)));return{tryConsume:(a,u)=>{let m=M(u),g=e.now(),l=s(a),d=_(l,m,g);return d.allowed&&(Number.isFinite(d.remaining)&&(d.remaining=Math.max(0,d.remaining-1)),l.hits.push(g),l.lifetime+=1,I(l,Q(m,g),i),n.set(o(a),k(l))),d},peek:(a,u)=>{let m=M(u);return _(s(a),m,e.now())},reset:a=>{if(a!==void 0){n.remove(o(a));return}if(typeof n.keys!="function")throw new Error("[fatigue-kit] reset() without a key requires a storage adapter implementing keys()");let u=`${r}:`;for(let m of n.keys())m.startsWith(u)&&n.remove(m)},exportRecord:a=>{let u=n.get(o(a));return u?x(u):null},importRecord:(a,u)=>{var l;let m=((l=u.hits)!=null?l:[]).filter(d=>typeof d=="number"&&Number.isFinite(d)).sort((d,V)=>d-V),g=typeof u.lifetime=="number"&&Number.isFinite(u.lifetime)&&u.lifetime>=0?u.lifetime:m.length;n.set(o(a),k({v:1,hits:m,lifetime:g}))}}}return U(Z);})();
1
+ "use strict";var FatigueKit=(()=>{var b=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var j=(t,n)=>{for(var e in n)b(t,e,{get:n[e],enumerable:!0})},L=(t,n,e,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of H(n))!J.call(t,i)&&i!==e&&b(t,i,{get:()=>n[i],enumerable:!(r=Y(n,i))||r.enumerable});return t};var U=t=>L(b({},"__esModule",{value:!0}),t);var Z={};j(Z,{RECORD_VERSION:()=>R,createFatigue:()=>$,memoryAdapter:()=>p});function p(t){let n=new Map(Object.entries(t!=null?t:{}));return{get:e=>{var r;return(r=n.get(e))!=null?r:null},set:(e,r)=>{n.set(e,r)},remove:e=>{n.delete(e)},keys:()=>[...n.keys()],dump:()=>Object.fromEntries(n)}}function D(t){if(t===void 0)return 0;let n=/^(\d{1,2}):(\d{2})$/.exec(t.trim());if(n===null||n[1]===void 0||n[2]===void 0)throw new TypeError(`[fatigue-kit] invalid cutoff: "${t}". Expected 'HH:mm'.`);let e=Number(n[1]),r=Number(n[2]);if(e>23||r>59)throw new TypeError(`[fatigue-kit] invalid cutoff: "${t}". Hours must be 0-23, minutes 0-59.`);return e*60+r}function E(t){let n=new Date(t);return n.setHours(0,0,0,0),n}function W(t,n){switch(n.every){case"day":return E(t).getTime();case"week":{let e=E(t),r=(e.getDay()-n.weekStartsOn+7)%7;return e.setDate(e.getDate()-r),e.getTime()}case"month":{let e=new Date(t);return new Date(e.getFullYear(),e.getMonth(),1).getTime()}case"year":{let e=new Date(t);return new Date(e.getFullYear(),0,1).getTime()}}}function q(t,n){switch(n.every){case"day":{let e=new Date(t);return e.setDate(e.getDate()-1),e.getTime()}case"week":{let e=new Date(t);return e.setDate(e.getDate()-7),e.getTime()}case"month":{let e=new Date(t);return new Date(e.getFullYear(),e.getMonth()-1,1).getTime()}case"year":{let e=new Date(t);return new Date(e.getFullYear()-1,0,1).getTime()}}}function A(t,n){let e=new Date(t);return new Date(e.getFullYear(),e.getMonth(),e.getDate(),Math.floor(n/60),n%60).getTime()}function w(t,n){let e=W(t,n),r=A(e,n.cutoffMinutes);return r<=t?r:A(q(e,n),n.cutoffMinutes)}var K={day:12*36e5,week:8*864e5,month:8*864e5,year:32*864e5};function T(t,n){let e=K[n.every],r=t;for(let i=0;i<50;i++){r+=e;let o=w(r,n);if(o>t)return o}throw new Error("[fatigue-kit] failed to compute the next calendar period")}var X={s:1e3,m:6e4,h:36e5,d:864e5};function h(t){if(typeof t=="number"){if(!Number.isFinite(t)||t<=0)throw new TypeError(`[fatigue-kit] invalid duration: ${t}`);return t}let n=/^(\d+(?:\.\d+)?)\s*([smhd])$/.exec(t.trim());if(n===null||n[1]===void 0||n[2]===void 0)throw new TypeError(`[fatigue-kit] invalid duration: "${t}". Expected a positive number of ms, or '45s' / '30m' / '12h' / '7d'.`);let e=X[n[2]];if(e===void 0)throw new TypeError(`[fatigue-kit] invalid duration: "${t}"`);let r=Number(n[1])*e;if(!(r>0))throw new TypeError(`[fatigue-kit] invalid duration: "${t}"`);return r}var R=1;function y(){return{v:1,hits:[],lifetime:0}}function x(t){if(!t)return y();let n;try{n=JSON.parse(t)}catch(o){return y()}if(n===null||typeof n!="object")return y();let e=n;if(e.v!==1)return y();let r=Array.isArray(e.hits)?e.hits.filter(o=>typeof o=="number"&&Number.isFinite(o)):[];r.sort((o,s)=>o-s);let i=typeof e.lifetime=="number"&&Number.isFinite(e.lifetime)&&e.lifetime>=0?e.lifetime:r.length;return{v:1,hits:r,lifetime:i}}function k(t){return JSON.stringify(t)}function I(t,n,e){let r=0;for(;r<t.hits.length;){let i=t.hits[r];if(i===void 0||i>=n)break;r++}r>0&&t.hits.splice(0,r),t.hits.length>e&&t.hits.splice(0,t.hits.length-e)}var z="fatigue-kit",B=100;function O(t,n){if(typeof t!="string"||t.length===0)throw new TypeError(`[fatigue-kit] ${n} must be a non-empty string`)}function F(t){if(!Number.isInteger(t)||t<1)throw new TypeError(`[fatigue-kit] rule "max" must be a positive integer, got ${t}`)}function M(t){let n=Array.isArray(t)?t:[t];if(n.length===0)throw new TypeError("[fatigue-kit] at least one rule is required");return n.map(e=>{var r;if(e===null||typeof e!="object")throw new TypeError(`[fatigue-kit] unknown rule: ${JSON.stringify(e)}`);if("window"in e)return F(e.max),{kind:"sliding",rule:e,max:e.max,windowMs:h(e.window)};if("every"in e){if(F(e.max),e.every!=="day"&&e.every!=="week"&&e.every!=="month"&&e.every!=="year")throw new TypeError(`[fatigue-kit] invalid "every": ${JSON.stringify(e.every)}`);return{kind:"calendar",rule:e,max:e.max,spec:{every:e.every,cutoffMinutes:D(e.cutoff),weekStartsOn:(r=e.weekStartsOn)!=null?r:1}}}if("cooldown"in e)return{kind:"cooldown",rule:e,cooldownMs:h(e.cooldown)};if("max"in e)return F(e.max),{kind:"lifetime",rule:e,max:e.max};throw new TypeError(`[fatigue-kit] unknown rule: ${JSON.stringify(e)}`)})}function G(t,n,e){switch(t.kind){case"sliding":{let r=e-t.windowMs,i=0,o=Number.POSITIVE_INFINITY;for(let f of n.hits)f>r&&(i++,f<o&&(o=f));let s=t.max-i;return{remaining:s,nextAvailableAt:s<=0&&o!==Number.POSITIVE_INFINITY?o+t.windowMs:void 0}}case"calendar":{let r=w(e,t.spec),i=0;for(let s of n.hits)s>=r&&i++;let o=t.max-i;return{remaining:o,nextAvailableAt:o<=0?T(e,t.spec):void 0}}case"cooldown":{let r=n.hits.length>0?n.hits[n.hits.length-1]:void 0;if(r===void 0)return{remaining:Number.POSITIVE_INFINITY};let i=r+t.cooldownMs;return{remaining:Number.POSITIVE_INFINITY,nextAvailableAt:i>e?i:void 0}}case"lifetime":return{remaining:t.max-n.lifetime}}}function _(t,n,e){let r=Number.POSITIVE_INFINITY,i,o;for(let f of n){let c=G(f,t,e);Number.isFinite(c.remaining)&&(r=Math.min(r,c.remaining)),c.nextAvailableAt!==void 0&&(i===void 0||c.nextAvailableAt>i)&&(i=c.nextAvailableAt),c.remaining>0&&(c.nextAvailableAt===void 0||c.nextAvailableAt<=e)||o!=null||(o=f.rule)}let s={allowed:o===void 0,remaining:Math.max(0,r)};return i!==void 0&&(s.nextAvailableAt=i),o!==void 0&&(s.deniedBy=o),s}function Q(t,n){let e=n;for(let r of t)r.kind==="sliding"?e=Math.min(e,n-r.windowMs):r.kind==="calendar"?e=Math.min(e,w(n,r.spec)):r.kind==="cooldown"&&(e=Math.min(e,n-r.cooldownMs));return e}function $(t={}){var v,S,N,C;let n=(v=t.storage)!=null?v:p(),e=(S=t.clock)!=null?S:{now:()=>Date.now()},r=(N=t.namespace)!=null?N:z,i=(C=t.maxHits)!=null?C:B;if(O(r,"namespace"),!Number.isInteger(i)||i<1)throw new TypeError(`[fatigue-kit] maxHits must be a positive integer, got ${i}`);let o=a=>(O(a,"key"),`${r}:${a}`),s=a=>x(n.get(o(a)));return{tryConsume:(a,u)=>{let m=M(u),g=e.now(),l=s(a),d=_(l,m,g);return d.allowed&&(Number.isFinite(d.remaining)&&(d.remaining=Math.max(0,d.remaining-1)),l.hits.push(g),l.lifetime+=1,I(l,Q(m,g),i),n.set(o(a),k(l))),d},peek:(a,u)=>{let m=M(u);return _(s(a),m,e.now())},reset:a=>{if(a!==void 0){n.remove(o(a));return}if(typeof n.keys!="function")throw new Error("[fatigue-kit] reset() without a key requires a storage adapter implementing keys()");let u=`${r}:`;for(let m of n.keys())m.startsWith(u)&&n.remove(m)},exportRecord:a=>{let u=n.get(o(a));return u?x(u):null},importRecord:(a,u)=>{var l;let m=((l=u.hits)!=null?l:[]).filter(d=>typeof d=="number"&&Number.isFinite(d)).sort((d,V)=>d-V),g=typeof u.lifetime=="number"&&Number.isFinite(u.lifetime)&&u.lifetime>=0?u.lifetime:m.length;n.set(o(a),k({v:1,hits:m,lifetime:g}))}}}return U(Z);})();
2
2
  //# sourceMappingURL=index.global.js.map
package/dist/legacy.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { e as FatigueRecord } from './types-hDxN5bc3.cjs';
1
+ import { FatigueRecord } from './index.cjs';
2
2
 
3
3
  /** Shape of the records written by the legacy internal FatigueManager. */
4
4
  interface LegacyFatigueRecord {
@@ -37,4 +37,5 @@ interface MigratedLegacyRecord {
37
37
  */
38
38
  declare function migrateLegacyRecord(input: string | LegacyFatigueRecord | null | undefined): MigratedLegacyRecord | null;
39
39
 
40
- export { DAY_MS, type LegacyFatigueRecord, type MigratedLegacyRecord, migrateLegacyRecord };
40
+ export { DAY_MS, migrateLegacyRecord };
41
+ export type { LegacyFatigueRecord, MigratedLegacyRecord };
package/dist/legacy.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { e as FatigueRecord } from './types-hDxN5bc3.js';
1
+ import { FatigueRecord } from './index.js';
2
2
 
3
3
  /** Shape of the records written by the legacy internal FatigueManager. */
4
4
  interface LegacyFatigueRecord {
@@ -37,4 +37,5 @@ interface MigratedLegacyRecord {
37
37
  */
38
38
  declare function migrateLegacyRecord(input: string | LegacyFatigueRecord | null | undefined): MigratedLegacyRecord | null;
39
39
 
40
- export { DAY_MS, type LegacyFatigueRecord, type MigratedLegacyRecord, migrateLegacyRecord };
40
+ export { DAY_MS, migrateLegacyRecord };
41
+ export type { LegacyFatigueRecord, MigratedLegacyRecord };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fatigue-kit",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Zero-dependency frequency capping (疲劳度控制) for popups, toasts and guides — one composable API across Web, mini-programs, React Native and Node.js.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -123,12 +123,12 @@
123
123
  "devDependencies": {
124
124
  "@biomejs/biome": "^2.0.0",
125
125
  "@changesets/changelog-github": "^1.0.1",
126
- "@changesets/cli": "^2.29.0",
127
- "@size-limit/preset-small-lib": "^11.2.0",
126
+ "@changesets/cli": "^3.0.3",
127
+ "@size-limit/preset-small-lib": "^14.2.0",
128
128
  "@types/node": "26.6.5",
129
- "size-limit": "^11.2.0",
130
- "tsup": "^8.5.0",
131
- "typescript": "^5.9.0",
132
- "vitest": "^3.2.0"
129
+ "size-limit": "^14.2.0",
130
+ "tsup": "^9.0.0",
131
+ "typescript": "^6.0.3",
132
+ "vitest": "^5.0.5"
133
133
  }
134
134
  }