UNPKG

zustand-debounce

Version:

**Lightweight** and **powerful** extension for [Zustand](https://github.com/pmndrs/zustand) providing debounced JSON state storage.

1 lines 6.13 kB
'use strict';var middleware=require('zustand/middleware');var z=Object.defineProperty;var J=(i,e,t)=>e in i?z(i,e,{enumerable:true,configurable:true,writable:true,value:t}):i[e]=t;var o=(i,e,t)=>J(i,typeof e!="symbol"?e+"":e,t);var f=class{constructor(e,t){o(this,"storageApi",e);o(this,"pluginManager",t);}async getItem(e){let t=await this.storageApi.getItem(e);return this.pluginManager?this.pluginManager.applyAfterGetItem(t):t}async setItem(e,t){if(!this.pluginManager)return this.storageApi.setItem(e,t);let r=this.pluginManager.applyBeforeSetItem(t);return this.storageApi.setItem(e,r)}async removeItem(e){return this.storageApi.removeItem(e)}};var a=class{constructor(e){o(this,"wrappedStorage",e);}async getItem(e){return this.wrappedStorage.getItem(e)}async setItem(e,t){await this.wrappedStorage.setItem(e,t);}async removeItem(e){await this.wrappedStorage.removeItem(e);}async flush(){this.wrappedStorage.flush&&await this.wrappedStorage.flush();}};var v=class extends a{constructor(t,r){super(t);o(this,"eventEmitter");this.eventEmitter=r;}on(t,r){this.eventEmitter.on(t,r);}async setItem(t,r){this.eventEmitter.emit("write",t,r),await this.wrappedStorage.setItem(t,r);}async getItem(t){let r=await this.wrappedStorage.getItem(t);return this.eventEmitter.emit("get",t,r),r}async removeItem(t){await this.wrappedStorage.removeItem(t),this.eventEmitter.emit("remove",t);}};var h=class extends a{constructor(t,r={},n){super(t);o(this,"options",r);o(this,"eventEmitter",n);}async setItem(t,r){let{maxRetries:n=3,retryDelay:m=1e3,backoffMultiplier:u=1}=this.options,g=0;for(;g<n;)try{await this.wrappedStorage.setItem(t,r);return}catch(p){if(g++,g>=n)throw this.eventEmitter&&this.eventEmitter.emit("error",t,p),p;let l=m*u**(g-1);this.eventEmitter&&this.eventEmitter.emit("retry",t,g,p,l),await new Promise(d=>setTimeout(d,l));}}};var S=class extends a{constructor(t,r){super(t);o(this,"options",r);}async setItem(t,r){let n=this.options.serialize(r);await this.wrappedStorage.setItem(t,n);}async getItem(t){let r=await this.wrappedStorage.getItem(t);return r?this.options.deserialize(r):null}};var I=class extends a{constructor(t,r,n){super(t);o(this,"options",r);o(this,"timeoutId");o(this,"pendingValue",null);o(this,"lastExecutionTime",0);o(this,"eventEmitter");this.eventEmitter=n;}async setItem(t,r){let{debounceTime:n=0,throttleTime:m=0,immediately:u=false}=this.options;if(u){await this.wrappedStorage.setItem(t,r),this.eventEmitter.emit("save",t,r);return}let g=Date.now();m&&g-this.lastExecutionTime<m||(this.pendingValue={key:t,value:r},this.timeoutId&&clearTimeout(this.timeoutId),this.timeoutId=setTimeout(()=>{if(this.pendingValue!==null){let{key:p,value:l}=this.pendingValue;this.wrappedStorage.setItem(p,l).then(()=>{this.lastExecutionTime=Date.now(),this.eventEmitter.emit("save",p,l),this.pendingValue=null;});}},n));}async flush(){if(this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0),this.pendingValue!==null){let{key:t,value:r}=this.pendingValue;await this.wrappedStorage.setItem(t,r),this.eventEmitter.emit("save",t,r),this.eventEmitter.emit("flush",t,r),this.pendingValue=null;}await this.wrappedStorage.flush?.();}};var w=class extends a{constructor(t,r){super(t);o(this,"options",r);}async setItem(t,r){let n=Date.now()+this.options.ttl,m=JSON.stringify({value:r,expiresAt:n});await this.wrappedStorage.setItem(t,m);}async getItem(t){let r=await this.wrappedStorage.getItem(t);if(!r)return null;try{let{value:n,expiresAt:m}=JSON.parse(r);return Date.now()>m?(await this.removeItem(t),null):n}catch{return null}}};var y=class{constructor(){o(this,"events",{});}on(e,t){this.events[e]||(this.events[e]=[]),this.events[e].push(t);}emit(e,...t){if(this.events[e])for(let r of this.events[e])r(...t);}};var E=class{constructor(){o(this,"plugins",[]);}register(e){for(let t of e){if(!t.name||typeof t.name!="string")throw new Error("Plugin must have a valid name property");this.plugins.push(t);}}applyBeforeSetItem(e){let t=e;for(let r of this.plugins)if(r.beforeSetItem)try{let n=r.beforeSetItem(t);n!==void 0&&(t=n);}catch(n){console.error(`[zustand-debounce] Plugin "${r.name}" beforeSetItem hook failed:`,n);}return t}applyAfterGetItem(e){let t=e;for(let r of this.plugins)if(r.afterGetItem)try{let n=r.afterGetItem(t);n!==void 0&&(t=n);}catch(n){return console.error(`[zustand-debounce] Plugin "${r.name}" afterGetItem hook failed:`,n),null}return t}getPlugins(){return [...this.plugins]}};function R(){let i={};return {getItem:async e=>i[e]||null,setItem:async(e,t)=>{i[e]=t;},removeItem:async e=>{delete i[e];}}}function k(i){if(typeof i=="object"&&i!==null&&typeof i.getItem=="function")return i;if(i==="localStorage"){if(typeof window<"u"&&window.localStorage)return {getItem:async e=>window.localStorage.getItem(e),setItem:async(e,t)=>window.localStorage.setItem(e,t),removeItem:async e=>window.localStorage.removeItem(e)};throw new Error("localStorage no est\xE1 disponible.")}if(i==="sessionStorage"){if(typeof window<"u"&&window.sessionStorage)return {getItem:async e=>window.sessionStorage.getItem(e),setItem:async(e,t)=>window.sessionStorage.setItem(e,t),removeItem:async e=>window.sessionStorage.removeItem(e)};throw new Error("sessionStorage no est\xE1 disponible.")}if(i==="memoryStorage")return R();throw new Error(`Adaptador de almacenamiento no soportado: ${i}`)}function G(i,e={}){let t=new y,{debounceTime:r,throttleTime:n,immediately:m,maxRetries:u,retryDelay:g,onWrite:p,onSave:l,serialize:d,deserialize:x,ttl:T,plugins:O=[],...M}=e,P;O.length>0&&(P=new E,P.register(O));let s=new f(k(i),P);d&&x&&(s=new S(s,{serialize:d,deserialize:x})),typeof T=="number"&&(s=new w(s,{ttl:T})),(u||g)&&(s=new h(s,{maxRetries:u,retryDelay:g})),(r||n||m!==void 0)&&(s=new I(s,{debounceTime:r,throttleTime:n,immediately:m},t));let b=new v(s,t);p&&b.on("write",p),l&&b.on("save",l),s=b;let V={getItem:async c=>await s.getItem(c),setItem:async(c,D)=>{await s.setItem(c,D);},removeItem:async c=>{await s.removeItem(c);}},A=middleware.createJSONStorage(()=>V,M);if(A===void 0)throw new Error("createJSONStorage returned undefined");return A}exports.createDebouncedJSONStorage=G;