From 0f5c6ab384d01c8f53eeb0a92cf5e27a6fefab9f Mon Sep 17 00:00:00 2001 From: LynnSha1ng Date: Wed, 20 Mar 2024 00:24:20 +0800 Subject: [PATCH] feat(curry): add `leading` option for function `debounce` test(curry): add test for `leading` option doc(curry): add description and example of `leading` option --- cdn/radash.esm.js | 6 +++++- cdn/radash.js | 6 +++++- cdn/radash.min.js | 2 +- docs/curry/debounce.mdx | 30 +++++++++++++++++++++++++++--- package.json | 2 +- src/curry.ts | 19 ++++++++++++++++++- src/tests/curry.test.ts | 8 ++++++++ 7 files changed, 65 insertions(+), 8 deletions(-) diff --git a/cdn/radash.esm.js b/cdn/radash.esm.js index a0a63559..b538aa85 100644 --- a/cdn/radash.esm.js +++ b/cdn/radash.esm.js @@ -533,7 +533,7 @@ const memoize = (cache, func, keyFunc, ttl) => { const memo = (func, options = {}) => { return memoize({}, func, options.key ?? null, options.ttl ?? null); }; -const debounce = ({ delay }, func) => { +const debounce = ({ delay, leading = false }, func) => { let timer = void 0; let active = true; const debounced = (...args) => { @@ -543,6 +543,10 @@ const debounce = ({ delay }, func) => { active && func(...args); timer = void 0; }, delay); + if (leading) { + func(...args); + leading = false; + } } else { func(...args); } diff --git a/cdn/radash.js b/cdn/radash.js index ca7ebea6..89d3ce4b 100644 --- a/cdn/radash.js +++ b/cdn/radash.js @@ -536,7 +536,7 @@ var radash = (function (exports) { const memo = (func, options = {}) => { return memoize({}, func, options.key ?? null, options.ttl ?? null); }; - const debounce = ({ delay }, func) => { + const debounce = ({ delay, leading = false }, func) => { let timer = void 0; let active = true; const debounced = (...args) => { @@ -546,6 +546,10 @@ var radash = (function (exports) { active && func(...args); timer = void 0; }, delay); + if (leading) { + func(...args); + leading = false; + } } else { func(...args); } diff --git a/cdn/radash.min.js b/cdn/radash.min.js index f9363f50..cc916b16 100644 --- a/cdn/radash.min.js +++ b/cdn/radash.min.js @@ -1 +1 @@ -var radash=function(i){"use strict";const E=e=>!!e&&e.constructor===Symbol,w=Array.isArray,k=e=>!!e&&e.constructor===Object,N=e=>e==null||typeof e!="object"&&typeof e!="function",y=e=>!!(e&&e.constructor&&e.call&&e.apply),K=e=>typeof e=="string"||e instanceof String,W=e=>h(e)&&e%1===0,J=e=>h(e)&&e%1!==0,h=e=>{try{return Number(e)===e}catch{return!1}},T=e=>Object.prototype.toString.call(e)==="[object Date]",S=e=>!(!e||!e.then||!y(e.then)),X=e=>{if(e===!0||e===!1||e==null)return!0;if(h(e))return e===0;if(T(e))return isNaN(e.getTime());if(y(e)||E(e))return!1;const t=e.length;if(h(t))return t===0;const n=e.size;return h(n)?n===0:Object.keys(e).length===0},j=(e,t)=>{if(Object.is(e,t))return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.toString()===t.toString();if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;const n=Reflect.ownKeys(e),r=Reflect.ownKeys(t);if(n.length!==r.length)return!1;for(let s=0;se.reduce((n,r)=>{const s=t(r);return n[s]||(n[s]=[]),n[s].push(r),n},{});function H(...e){return!e||!e.length?[]:new Array(Math.max(...e.map(({length:t})=>t))).fill([]).map((t,n)=>e.map(r=>r[n]))}function Q(e,t){if(!e||!e.length)return{};const n=y(t)?t:w(t)?(r,s)=>t[s]:(r,s)=>t;return e.reduce((r,s,u)=>(r[s]=n(s,u),r),{})}const O=(e,t)=>!e||(e.length??0)===0?null:e.reduce(t);function V(e,t){return(e||[]).reduce((n,r)=>n+(t?t(r):r),0)}const G=(e,t=void 0)=>e?.length>0?e[0]:t,x=(e,t=void 0)=>e?.length>0?e[e.length-1]:t,z=(e,t,n=!1)=>{if(!e)return[];const r=(u,c)=>t(u)-t(c),s=(u,c)=>t(c)-t(u);return e.slice().sort(n===!0?s:r)},ee=(e,t,n="asc")=>{if(!e)return[];const r=(u,c)=>`${t(u)}`.localeCompare(t(c)),s=(u,c)=>`${t(c)}`.localeCompare(t(u));return e.slice().sort(n==="desc"?s:r)},te=(e,t)=>e?e.reduce((n,r)=>{const s=t(r);return n[s]=(n[s]??0)+1,n},{}):{},ne=(e,t,n)=>{if(!e)return[];if(t===void 0)return[...e];for(let r=0;rr)=>e.reduce((r,s)=>(r[t(s)]=n(s),r),{}),re=(e,t,n)=>e?e.reduce((r,s,u)=>(n(s,u)&&r.push(t(s,u)),r),[]):[];function se(e,t){const n=t??(r=>r);return O(e,(r,s)=>n(r)>n(s)?r:s)}function ie(e,t){const n=t??(r=>r);return O(e,(r,s)=>n(r){const n=Math.ceil(e.length/t);return new Array(n).fill(null).map((r,s)=>e.slice(s*t,s*t+t))},ce=(e,t)=>{const n=e.reduce((r,s)=>{const u=t?t(s):s;return r[u]||(r[u]=s),r},{});return Object.values(n)};function*A(e,t,n=s=>s,r=1){const s=y(n)?n:()=>n,u=t?e:0,c=t??e;for(let o=u;o<=c&&(yield s(o),!(o+r>c));o+=r);}const C=(e,t,n,r)=>Array.from(A(e,t,n,r)),oe=e=>e.reduce((t,n)=>(t.push(...n),t),[]),fe=(e,t,n)=>{if(!e||!t)return!1;const r=n??(u=>u),s=t.reduce((u,c)=>(u[r(c)]=!0,u),{});return e.some(u=>s[r(u)])},R=(e,t)=>e?e.reduce((n,r)=>{const[s,u]=n;return t(r)?[[...s,r],u]:[s,[...u,r]]},[[],[]]):[[],[]],le=(e,t,n)=>!t&&!e?[]:t?e?n?e.reduce((r,s)=>{const u=t.find(c=>n(s)===n(c));return u?r.push(u):r.push(s),r},[]):e:[]:e,ae=(e,t,n)=>{if(!e&&!t)return[];if(!t)return[...e];if(!e)return[t];for(let r=0;r{if(!e&&!t)return[];if(!e)return[t];if(!t)return[...e];const s=n?(o,a)=>n(o,a)===n(t,a):o=>o===t;return e.find(s)?e.filter((o,a)=>!s(o,a)):(r?.strategy??"append")==="append"?[...e,t]:[t,...e]},ge=e=>e?.filter(t=>!!t)??[],B=(e,t,n)=>{let r=n;for(let s=1;s<=e;s++)r=t(r,s);return r},he=(e,t,n=r=>r)=>{if(!e?.length&&!t?.length)return[];if(e?.length===void 0)return[...t];if(!t?.length)return[...e];const r=t.reduce((s,u)=>(s[n(u)]=!0,s),{});return e.filter(s=>!r[n(s)])};function me(e,t){if(e.length===0)return e;const n=t%e.length;return n===0?e:[...e.slice(-n,e.length),...e.slice(0,-n)]}const we=async(e,t,n)=>{const r=n!==void 0;if(!r&&e?.length<1)throw new Error("Cannot reduce empty array with no init value");const s=r?e:e.slice(1);let u=r?n:e[0];for(const[c,o]of s.entries())u=await t(u,o,c);return u},ye=async(e,t)=>{if(!e)return[];let n=[],r=0;for(const s of e){const u=await t(s,r++);n.push(u)}return n},pe=async e=>{const t=[],n=(u,c)=>t.push({fn:u,rethrow:c?.rethrow??!1}),[r,s]=await m(e)(n);for(const{fn:u,rethrow:c}of t){const[o]=await m(u)(r);if(o&&c)throw o}if(r)throw r;return s};class L extends Error{constructor(t=[]){super();const n=t.find(r=>r.name)?.name??"";this.name=`AggregateError(${n}...)`,this.message=`AggregateError with ${t.length} errors`,this.stack=t.find(r=>r.stack)?.stack??this.stack,this.errors=t}}const be=async(e,t,n)=>{const r=t.map((d,b)=>({index:b,item:d})),s=async d=>{const b=[];for(;;){const f=r.pop();if(!f)return d(b);const[l,g]=await m(n)(f.item);b.push({error:l,result:g,index:f.index})}},u=C(1,e).map(()=>new Promise(s)),c=await Promise.all(u),[o,a]=R(z(c.flat(),d=>d.index),d=>!!d.error);if(o.length>0)throw new L(o.map(d=>d.error));return a.map(d=>d.result)};async function ke(e){const t=w(e)?e.map(s=>[null,s]):Object.entries(e),n=await Promise.all(t.map(([s,u])=>u.then(c=>({result:c,exc:null,key:s})).catch(c=>({result:null,exc:c,key:s})))),r=n.filter(s=>s.exc);if(r.length>0)throw new L(r.map(s=>s.exc));return w(e)?n.map(s=>s.result):n.reduce((s,u)=>({...s,[u.key]:u.result}),{})}const Oe=async(e,t)=>{const n=e?.times??3,r=e?.delay,s=e?.backoff??null;for(const u of A(1,n)){const[c,o]=await m(t)(a=>{throw{_exited:a}});if(!c)return o;if(c._exited)throw c._exited;if(u===n)throw c;r&&await $(r),s&&await $(s(u))}},$=e=>new Promise(t=>setTimeout(t,e)),m=e=>(...t)=>{try{const n=e(...t);return S(n)?n.then(r=>[void 0,r]).catch(r=>[r,void 0]):[void 0,n]}catch(n){return[n,void 0]}},Ae=(e,t)=>{const n=s=>{if(t&&!t(s))throw s},r=s=>s instanceof Promise;try{const s=e();return r(s)?s.catch(n):s}catch(s){return n(s)}};function Ce(...e){return(...t)=>e.slice(1).reduce((n,r)=>r(n),e[0](...t))}function $e(...e){return e.reverse().reduce((t,n)=>n(t))}const Pe=(e,...t)=>(...n)=>e(...t,...n),_e=(e,t)=>n=>e({...t,...n}),Ee=e=>new Proxy({},{get:(t,n)=>e(n)}),Ne=(e,t,n,r)=>function(...u){const c=n?n(...u):JSON.stringify({args:u}),o=e[c];if(o!==void 0&&(!o.exp||o.exp>new Date().getTime()))return o.value;const a=t(...u);return e[c]={exp:r?new Date().getTime()+r:null,value:a},a},Te=(e,t={})=>Ne({},e,t.key??null,t.ttl??null),Se=({delay:e},t)=>{let n,r=!0;const s=(...u)=>{r?(clearTimeout(n),n=setTimeout(()=>{r&&t(...u),n=void 0},e)):t(...u)};return s.isPending=()=>n!==void 0,s.cancel=()=>{r=!1},s.flush=(...u)=>t(...u),s},je=({interval:e},t)=>{let n=!0,r;const s=(...u)=>{n&&(t(...u),n=!1,r=setTimeout(()=>{n=!0,r=void 0},e))};return s.isThrottled=()=>r!==void 0,s},ze=(e,t)=>{const n=()=>{};return new Proxy(Object.assign(n,e),{get:(r,s)=>r[s],set:(r,s,u)=>(r[s]=u,!0),apply:(r,s,u)=>t(Object.assign({},r))(...u)})};function Me(e,t,n){return typeof e=="number"&&typeof t=="number"&&(typeof n>"u"||typeof n=="number")?(typeof n>"u"&&(n=t,t=0),e>=Math.min(t,n)&&e{const n=t===void 0?0:t;if(e==null)return n;const r=parseFloat(e);return isNaN(r)?n:r},Z=(e,t)=>{const n=t===void 0?0:t;if(e==null)return n;const r=parseInt(e);return isNaN(r)?n:r},Be=(e,t=n=>n===void 0)=>e?Object.keys(e).reduce((r,s)=>(t(e[s])||(r[s]=e[s]),r),{}):{},P=(e,t)=>Object.keys(e).reduce((r,s)=>(r[t(s,e[s])]=e[s],r),{}),Le=(e,t)=>Object.keys(e).reduce((r,s)=>(r[s]=t(e[s],s),r),{}),Ze=(e,t)=>e?Object.entries(e).reduce((n,[r,s])=>{const[u,c]=t(r,s);return n[u]=c,n},{}):{},De=e=>e?Object.keys(e).reduce((n,r)=>(n[e[r]]=r,n),{}):{},Fe=e=>P(e,t=>t.toLowerCase()),qe=e=>P(e,t=>t.toUpperCase()),D=e=>{if(N(e))return e;if(typeof e=="function")return e.bind({});const t=new e.constructor;return Object.getOwnPropertyNames(e).forEach(n=>{t[n]=e[n]}),t},Ie=(e,t)=>{if(!e)return[];const n=Object.entries(e);return n.length===0?[]:n.reduce((r,s)=>(r.push(t(s[0],s[1])),r),[])},ve=(e,t)=>e?t.reduce((n,r)=>(Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]),n),{}):{},Ue=(e,t)=>e?!t||t.length===0?e:t.reduce((n,r)=>(delete n[r],n),{...e}):{},F=(e,t,n)=>{const r=t.split(/[\.\[\]]/g);let s=e;for(const u of r){if(s===null||s===void 0)return n;const c=u.replace(/['"]/g,"");c.trim()!==""&&(s=s[c])}return s===void 0?n:s},q=(e,t,n)=>{if(!e)return{};if(!t||n===void 0)return e;const r=t.split(/[\.\[\]]/g).filter(c=>!!c.trim()),s=c=>{if(r.length>1){const o=r.shift(),a=Z(r[0],null)!==null;c[o]=c[o]===void 0?a?[]:{}:c[o],s(c[o])}else c[r[0]]=n},u=D(e);return s(u),u},I=(e,t)=>!e||!t?e??t??{}:Object.entries({...e,...t}).reduce((n,[r,s])=>({...n,[r]:(()=>k(e[r])?I(e[r],s):s)()}),{}),v=e=>{if(!e)return[];const t=(n,r)=>k(n)?Object.entries(n).flatMap(([s,u])=>t(u,[...r,s])):w(n)?n.flatMap((s,u)=>t(s,[...r,`${u}`])):[r.join(".")];return t(e,[])},Ke=e=>e?M(v(e),t=>t,t=>F(e,t)):{},We=e=>e?Object.keys(e).reduce((t,n)=>q(t,n,e[n]),{}):{},_=(e,t)=>Math.floor(Math.random()*(t-e+1)+e),Je=e=>{const t=e.length;if(t===0)return null;const n=_(0,t-1);return e[n]},Xe=e=>e.map(t=>({rand:Math.random(),value:t})).sort((t,n)=>t.rand-n.rand).map(t=>t.value),Ye=(e,t="")=>{const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+t;return B(e,r=>r+n.charAt(_(0,n.length-1)),"")},He=(e,t=n=>`${n}`)=>{const{indexesByKey:n,itemsByIndex:r}=e.reduce((f,l,g)=>({indexesByKey:{...f.indexesByKey,[t(l)]:g},itemsByIndex:{...f.itemsByIndex,[g]:l}}),{indexesByKey:{},itemsByIndex:{}}),s=(f,l)=>n[t(f)]n[t(f)]>n[t(l)]?f:l,c=()=>r[0],o=()=>r[e.length-1],a=(f,l)=>r[n[t(f)]+1]??l??c(),d=(f,l)=>r[n[t(f)]-1]??l??o();return{min:s,max:u,first:c,last:o,next:a,previous:d,spin:(f,l)=>{if(l===0)return f;const g=Math.abs(l),rt=g>e.length?g%e.length:g;return C(0,rt-1).reduce(U=>l>0?a(U):d(U),f)}}},p=e=>{if(!e||e.length===0)return"";const t=e.toLowerCase();return t.substring(0,1).toUpperCase()+t.substring(1,t.length)},Qe=e=>{const t=e?.replace(/([A-Z])+/g,p)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.length===1?t[0]:t.reduce((n,r)=>`${n}${r.charAt(0).toUpperCase()}${r.slice(1)}`)},Ve=(e,t)=>{const n=e?.replace(/([A-Z])+/g,p).split(/(?=[A-Z])|[\.\-\s_]/).map(s=>s.toLowerCase())??[];if(n.length===0)return"";if(n.length===1)return n[0];const r=n.reduce((s,u)=>`${s}_${u.toLowerCase()}`);return t?.splitOnNumber===!1?r:r.replace(/([A-Za-z]{1}[0-9]{1})/,s=>`${s[0]}_${s[1]}`)},Ge=e=>{const t=e?.replace(/([A-Z])+/g,p)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.length===1?t[0]:t.reduce((n,r)=>`${n}-${r.toLowerCase()}`)},xe=e=>{const t=e?.split(/[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")},et=e=>e?e.split(/(?=[A-Z])|[\.\-\s_]/).map(t=>t.trim()).filter(t=>!!t).map(t=>p(t.toLowerCase())).join(" "):"",tt=(e,t,n=/\{\{(.+?)\}\}/g)=>Array.from(e.matchAll(n)).reduce((r,s)=>r.replace(s[0],t[s[1]]),e),nt=(e,t=" ")=>{if(!e)return"";const n=t.replace(/[\W]{1}/g,"\\$&"),r=new RegExp(`^[${n}]+|[${n}]+$`,"g");return e.replace(r,"")};return i.all=ke,i.alphabetical=ee,i.assign=I,i.boil=O,i.callable=ze,i.camel=Qe,i.capitalize=p,i.chain=Ce,i.clone=D,i.cluster=ue,i.compose=$e,i.construct=We,i.counting=te,i.crush=Ke,i.dash=Ge,i.debounce=Se,i.defer=pe,i.diff=he,i.draw=Je,i.first=G,i.flat=oe,i.fork=R,i.get=F,i.group=Y,i.guard=Ae,i.inRange=Me,i.intersects=fe,i.invert=De,i.isArray=w,i.isDate=T,i.isEmpty=X,i.isEqual=j,i.isFloat=J,i.isFunction=y,i.isInt=W,i.isNumber=h,i.isObject=k,i.isPrimitive=N,i.isPromise=S,i.isString=K,i.isSymbol=E,i.iterate=B,i.keys=v,i.last=x,i.list=C,i.listify=Ie,i.lowerize=Fe,i.map=ye,i.mapEntries=Ze,i.mapKeys=P,i.mapValues=Le,i.max=se,i.memo=Te,i.merge=le,i.min=ie,i.objectify=M,i.omit=Ue,i.parallel=be,i.partial=Pe,i.partob=_e,i.pascal=xe,i.pick=ve,i.proxied=Ee,i.random=_,i.range=A,i.reduce=we,i.replace=ne,i.replaceOrAppend=ae,i.retry=Oe,i.select=re,i.series=He,i.set=q,i.shake=Be,i.shift=me,i.shuffle=Xe,i.sift=ge,i.sleep=$,i.snake=Ve,i.sort=z,i.sum=V,i.template=tt,i.throttle=je,i.title=et,i.toFloat=Re,i.toInt=Z,i.toggle=de,i.trim=nt,i.try=m,i.tryit=m,i.uid=Ye,i.unique=ce,i.upperize=qe,i.zip=H,i.zipToObject=Q,i}({}); +var radash=function(i){"use strict";const E=e=>!!e&&e.constructor===Symbol,w=Array.isArray,k=e=>!!e&&e.constructor===Object,N=e=>e==null||typeof e!="object"&&typeof e!="function",y=e=>!!(e&&e.constructor&&e.call&&e.apply),K=e=>typeof e=="string"||e instanceof String,W=e=>h(e)&&e%1===0,J=e=>h(e)&&e%1!==0,h=e=>{try{return Number(e)===e}catch{return!1}},T=e=>Object.prototype.toString.call(e)==="[object Date]",S=e=>!(!e||!e.then||!y(e.then)),X=e=>{if(e===!0||e===!1||e==null)return!0;if(h(e))return e===0;if(T(e))return isNaN(e.getTime());if(y(e)||E(e))return!1;const t=e.length;if(h(t))return t===0;const n=e.size;return h(n)?n===0:Object.keys(e).length===0},j=(e,t)=>{if(Object.is(e,t))return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(e instanceof RegExp&&t instanceof RegExp)return e.toString()===t.toString();if(typeof e!="object"||e===null||typeof t!="object"||t===null)return!1;const n=Reflect.ownKeys(e),r=Reflect.ownKeys(t);if(n.length!==r.length)return!1;for(let s=0;se.reduce((n,r)=>{const s=t(r);return n[s]||(n[s]=[]),n[s].push(r),n},{});function H(...e){return!e||!e.length?[]:new Array(Math.max(...e.map(({length:t})=>t))).fill([]).map((t,n)=>e.map(r=>r[n]))}function Q(e,t){if(!e||!e.length)return{};const n=y(t)?t:w(t)?(r,s)=>t[s]:(r,s)=>t;return e.reduce((r,s,u)=>(r[s]=n(s,u),r),{})}const O=(e,t)=>!e||(e.length??0)===0?null:e.reduce(t);function V(e,t){return(e||[]).reduce((n,r)=>n+(t?t(r):r),0)}const G=(e,t=void 0)=>e?.length>0?e[0]:t,x=(e,t=void 0)=>e?.length>0?e[e.length-1]:t,z=(e,t,n=!1)=>{if(!e)return[];const r=(u,c)=>t(u)-t(c),s=(u,c)=>t(c)-t(u);return e.slice().sort(n===!0?s:r)},ee=(e,t,n="asc")=>{if(!e)return[];const r=(u,c)=>`${t(u)}`.localeCompare(t(c)),s=(u,c)=>`${t(c)}`.localeCompare(t(u));return e.slice().sort(n==="desc"?s:r)},te=(e,t)=>e?e.reduce((n,r)=>{const s=t(r);return n[s]=(n[s]??0)+1,n},{}):{},ne=(e,t,n)=>{if(!e)return[];if(t===void 0)return[...e];for(let r=0;rr)=>e.reduce((r,s)=>(r[t(s)]=n(s),r),{}),re=(e,t,n)=>e?e.reduce((r,s,u)=>(n(s,u)&&r.push(t(s,u)),r),[]):[];function se(e,t){const n=t??(r=>r);return O(e,(r,s)=>n(r)>n(s)?r:s)}function ie(e,t){const n=t??(r=>r);return O(e,(r,s)=>n(r){const n=Math.ceil(e.length/t);return new Array(n).fill(null).map((r,s)=>e.slice(s*t,s*t+t))},ce=(e,t)=>{const n=e.reduce((r,s)=>{const u=t?t(s):s;return r[u]||(r[u]=s),r},{});return Object.values(n)};function*A(e,t,n=s=>s,r=1){const s=y(n)?n:()=>n,u=t?e:0,c=t??e;for(let o=u;o<=c&&(yield s(o),!(o+r>c));o+=r);}const C=(e,t,n,r)=>Array.from(A(e,t,n,r)),oe=e=>e.reduce((t,n)=>(t.push(...n),t),[]),fe=(e,t,n)=>{if(!e||!t)return!1;const r=n??(u=>u),s=t.reduce((u,c)=>(u[r(c)]=!0,u),{});return e.some(u=>s[r(u)])},R=(e,t)=>e?e.reduce((n,r)=>{const[s,u]=n;return t(r)?[[...s,r],u]:[s,[...u,r]]},[[],[]]):[[],[]],le=(e,t,n)=>!t&&!e?[]:t?e?n?e.reduce((r,s)=>{const u=t.find(c=>n(s)===n(c));return u?r.push(u):r.push(s),r},[]):e:[]:e,ae=(e,t,n)=>{if(!e&&!t)return[];if(!t)return[...e];if(!e)return[t];for(let r=0;r{if(!e&&!t)return[];if(!e)return[t];if(!t)return[...e];const s=n?(o,a)=>n(o,a)===n(t,a):o=>o===t;return e.find(s)?e.filter((o,a)=>!s(o,a)):(r?.strategy??"append")==="append"?[...e,t]:[t,...e]},ge=e=>e?.filter(t=>!!t)??[],B=(e,t,n)=>{let r=n;for(let s=1;s<=e;s++)r=t(r,s);return r},he=(e,t,n=r=>r)=>{if(!e?.length&&!t?.length)return[];if(e?.length===void 0)return[...t];if(!t?.length)return[...e];const r=t.reduce((s,u)=>(s[n(u)]=!0,s),{});return e.filter(s=>!r[n(s)])};function me(e,t){if(e.length===0)return e;const n=t%e.length;return n===0?e:[...e.slice(-n,e.length),...e.slice(0,-n)]}const we=async(e,t,n)=>{const r=n!==void 0;if(!r&&e?.length<1)throw new Error("Cannot reduce empty array with no init value");const s=r?e:e.slice(1);let u=r?n:e[0];for(const[c,o]of s.entries())u=await t(u,o,c);return u},ye=async(e,t)=>{if(!e)return[];let n=[],r=0;for(const s of e){const u=await t(s,r++);n.push(u)}return n},pe=async e=>{const t=[],n=(u,c)=>t.push({fn:u,rethrow:c?.rethrow??!1}),[r,s]=await m(e)(n);for(const{fn:u,rethrow:c}of t){const[o]=await m(u)(r);if(o&&c)throw o}if(r)throw r;return s};class L extends Error{constructor(t=[]){super();const n=t.find(r=>r.name)?.name??"";this.name=`AggregateError(${n}...)`,this.message=`AggregateError with ${t.length} errors`,this.stack=t.find(r=>r.stack)?.stack??this.stack,this.errors=t}}const be=async(e,t,n)=>{const r=t.map((d,b)=>({index:b,item:d})),s=async d=>{const b=[];for(;;){const f=r.pop();if(!f)return d(b);const[l,g]=await m(n)(f.item);b.push({error:l,result:g,index:f.index})}},u=C(1,e).map(()=>new Promise(s)),c=await Promise.all(u),[o,a]=R(z(c.flat(),d=>d.index),d=>!!d.error);if(o.length>0)throw new L(o.map(d=>d.error));return a.map(d=>d.result)};async function ke(e){const t=w(e)?e.map(s=>[null,s]):Object.entries(e),n=await Promise.all(t.map(([s,u])=>u.then(c=>({result:c,exc:null,key:s})).catch(c=>({result:null,exc:c,key:s})))),r=n.filter(s=>s.exc);if(r.length>0)throw new L(r.map(s=>s.exc));return w(e)?n.map(s=>s.result):n.reduce((s,u)=>({...s,[u.key]:u.result}),{})}const Oe=async(e,t)=>{const n=e?.times??3,r=e?.delay,s=e?.backoff??null;for(const u of A(1,n)){const[c,o]=await m(t)(a=>{throw{_exited:a}});if(!c)return o;if(c._exited)throw c._exited;if(u===n)throw c;r&&await $(r),s&&await $(s(u))}},$=e=>new Promise(t=>setTimeout(t,e)),m=e=>(...t)=>{try{const n=e(...t);return S(n)?n.then(r=>[void 0,r]).catch(r=>[r,void 0]):[void 0,n]}catch(n){return[n,void 0]}},Ae=(e,t)=>{const n=s=>{if(t&&!t(s))throw s},r=s=>s instanceof Promise;try{const s=e();return r(s)?s.catch(n):s}catch(s){return n(s)}};function Ce(...e){return(...t)=>e.slice(1).reduce((n,r)=>r(n),e[0](...t))}function $e(...e){return e.reverse().reduce((t,n)=>n(t))}const Pe=(e,...t)=>(...n)=>e(...t,...n),_e=(e,t)=>n=>e({...t,...n}),Ee=e=>new Proxy({},{get:(t,n)=>e(n)}),Ne=(e,t,n,r)=>function(...u){const c=n?n(...u):JSON.stringify({args:u}),o=e[c];if(o!==void 0&&(!o.exp||o.exp>new Date().getTime()))return o.value;const a=t(...u);return e[c]={exp:r?new Date().getTime()+r:null,value:a},a},Te=(e,t={})=>Ne({},e,t.key??null,t.ttl??null),Se=({delay:e,leading:t=!1},n)=>{let r,s=!0;const u=(...c)=>{s?(clearTimeout(r),r=setTimeout(()=>{s&&n(...c),r=void 0},e),t&&(n(...c),t=!1)):n(...c)};return u.isPending=()=>r!==void 0,u.cancel=()=>{s=!1},u.flush=(...c)=>n(...c),u},je=({interval:e},t)=>{let n=!0,r;const s=(...u)=>{n&&(t(...u),n=!1,r=setTimeout(()=>{n=!0,r=void 0},e))};return s.isThrottled=()=>r!==void 0,s},ze=(e,t)=>{const n=()=>{};return new Proxy(Object.assign(n,e),{get:(r,s)=>r[s],set:(r,s,u)=>(r[s]=u,!0),apply:(r,s,u)=>t(Object.assign({},r))(...u)})};function Me(e,t,n){return typeof e=="number"&&typeof t=="number"&&(typeof n>"u"||typeof n=="number")?(typeof n>"u"&&(n=t,t=0),e>=Math.min(t,n)&&e{const n=t===void 0?0:t;if(e==null)return n;const r=parseFloat(e);return isNaN(r)?n:r},Z=(e,t)=>{const n=t===void 0?0:t;if(e==null)return n;const r=parseInt(e);return isNaN(r)?n:r},Be=(e,t=n=>n===void 0)=>e?Object.keys(e).reduce((r,s)=>(t(e[s])||(r[s]=e[s]),r),{}):{},P=(e,t)=>Object.keys(e).reduce((r,s)=>(r[t(s,e[s])]=e[s],r),{}),Le=(e,t)=>Object.keys(e).reduce((r,s)=>(r[s]=t(e[s],s),r),{}),Ze=(e,t)=>e?Object.entries(e).reduce((n,[r,s])=>{const[u,c]=t(r,s);return n[u]=c,n},{}):{},De=e=>e?Object.keys(e).reduce((n,r)=>(n[e[r]]=r,n),{}):{},Fe=e=>P(e,t=>t.toLowerCase()),qe=e=>P(e,t=>t.toUpperCase()),D=e=>{if(N(e))return e;if(typeof e=="function")return e.bind({});const t=new e.constructor;return Object.getOwnPropertyNames(e).forEach(n=>{t[n]=e[n]}),t},Ie=(e,t)=>{if(!e)return[];const n=Object.entries(e);return n.length===0?[]:n.reduce((r,s)=>(r.push(t(s[0],s[1])),r),[])},ve=(e,t)=>e?t.reduce((n,r)=>(Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]),n),{}):{},Ue=(e,t)=>e?!t||t.length===0?e:t.reduce((n,r)=>(delete n[r],n),{...e}):{},F=(e,t,n)=>{const r=t.split(/[\.\[\]]/g);let s=e;for(const u of r){if(s===null||s===void 0)return n;const c=u.replace(/['"]/g,"");c.trim()!==""&&(s=s[c])}return s===void 0?n:s},q=(e,t,n)=>{if(!e)return{};if(!t||n===void 0)return e;const r=t.split(/[\.\[\]]/g).filter(c=>!!c.trim()),s=c=>{if(r.length>1){const o=r.shift(),a=Z(r[0],null)!==null;c[o]=c[o]===void 0?a?[]:{}:c[o],s(c[o])}else c[r[0]]=n},u=D(e);return s(u),u},I=(e,t)=>!e||!t?e??t??{}:Object.entries({...e,...t}).reduce((n,[r,s])=>({...n,[r]:(()=>k(e[r])?I(e[r],s):s)()}),{}),v=e=>{if(!e)return[];const t=(n,r)=>k(n)?Object.entries(n).flatMap(([s,u])=>t(u,[...r,s])):w(n)?n.flatMap((s,u)=>t(s,[...r,`${u}`])):[r.join(".")];return t(e,[])},Ke=e=>e?M(v(e),t=>t,t=>F(e,t)):{},We=e=>e?Object.keys(e).reduce((t,n)=>q(t,n,e[n]),{}):{},_=(e,t)=>Math.floor(Math.random()*(t-e+1)+e),Je=e=>{const t=e.length;if(t===0)return null;const n=_(0,t-1);return e[n]},Xe=e=>e.map(t=>({rand:Math.random(),value:t})).sort((t,n)=>t.rand-n.rand).map(t=>t.value),Ye=(e,t="")=>{const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+t;return B(e,r=>r+n.charAt(_(0,n.length-1)),"")},He=(e,t=n=>`${n}`)=>{const{indexesByKey:n,itemsByIndex:r}=e.reduce((f,l,g)=>({indexesByKey:{...f.indexesByKey,[t(l)]:g},itemsByIndex:{...f.itemsByIndex,[g]:l}}),{indexesByKey:{},itemsByIndex:{}}),s=(f,l)=>n[t(f)]n[t(f)]>n[t(l)]?f:l,c=()=>r[0],o=()=>r[e.length-1],a=(f,l)=>r[n[t(f)]+1]??l??c(),d=(f,l)=>r[n[t(f)]-1]??l??o();return{min:s,max:u,first:c,last:o,next:a,previous:d,spin:(f,l)=>{if(l===0)return f;const g=Math.abs(l),rt=g>e.length?g%e.length:g;return C(0,rt-1).reduce(U=>l>0?a(U):d(U),f)}}},p=e=>{if(!e||e.length===0)return"";const t=e.toLowerCase();return t.substring(0,1).toUpperCase()+t.substring(1,t.length)},Qe=e=>{const t=e?.replace(/([A-Z])+/g,p)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.length===1?t[0]:t.reduce((n,r)=>`${n}${r.charAt(0).toUpperCase()}${r.slice(1)}`)},Ve=(e,t)=>{const n=e?.replace(/([A-Z])+/g,p).split(/(?=[A-Z])|[\.\-\s_]/).map(s=>s.toLowerCase())??[];if(n.length===0)return"";if(n.length===1)return n[0];const r=n.reduce((s,u)=>`${s}_${u.toLowerCase()}`);return t?.splitOnNumber===!1?r:r.replace(/([A-Za-z]{1}[0-9]{1})/,s=>`${s[0]}_${s[1]}`)},Ge=e=>{const t=e?.replace(/([A-Z])+/g,p)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.length===1?t[0]:t.reduce((n,r)=>`${n}-${r.toLowerCase()}`)},xe=e=>{const t=e?.split(/[\.\-\s_]/).map(n=>n.toLowerCase())??[];return t.length===0?"":t.map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")},et=e=>e?e.split(/(?=[A-Z])|[\.\-\s_]/).map(t=>t.trim()).filter(t=>!!t).map(t=>p(t.toLowerCase())).join(" "):"",tt=(e,t,n=/\{\{(.+?)\}\}/g)=>Array.from(e.matchAll(n)).reduce((r,s)=>r.replace(s[0],t[s[1]]),e),nt=(e,t=" ")=>{if(!e)return"";const n=t.replace(/[\W]{1}/g,"\\$&"),r=new RegExp(`^[${n}]+|[${n}]+$`,"g");return e.replace(r,"")};return i.all=ke,i.alphabetical=ee,i.assign=I,i.boil=O,i.callable=ze,i.camel=Qe,i.capitalize=p,i.chain=Ce,i.clone=D,i.cluster=ue,i.compose=$e,i.construct=We,i.counting=te,i.crush=Ke,i.dash=Ge,i.debounce=Se,i.defer=pe,i.diff=he,i.draw=Je,i.first=G,i.flat=oe,i.fork=R,i.get=F,i.group=Y,i.guard=Ae,i.inRange=Me,i.intersects=fe,i.invert=De,i.isArray=w,i.isDate=T,i.isEmpty=X,i.isEqual=j,i.isFloat=J,i.isFunction=y,i.isInt=W,i.isNumber=h,i.isObject=k,i.isPrimitive=N,i.isPromise=S,i.isString=K,i.isSymbol=E,i.iterate=B,i.keys=v,i.last=x,i.list=C,i.listify=Ie,i.lowerize=Fe,i.map=ye,i.mapEntries=Ze,i.mapKeys=P,i.mapValues=Le,i.max=se,i.memo=Te,i.merge=le,i.min=ie,i.objectify=M,i.omit=Ue,i.parallel=be,i.partial=Pe,i.partob=_e,i.pascal=xe,i.pick=ve,i.proxied=Ee,i.random=_,i.range=A,i.reduce=we,i.replace=ne,i.replaceOrAppend=ae,i.retry=Oe,i.select=re,i.series=He,i.set=q,i.shake=Be,i.shift=me,i.shuffle=Xe,i.sift=ge,i.sleep=$,i.snake=Ve,i.sort=z,i.sum=V,i.template=tt,i.throttle=je,i.title=et,i.toFloat=Re,i.toInt=Z,i.toggle=de,i.trim=nt,i.try=m,i.tryit=m,i.uid=Ye,i.unique=ce,i.upperize=qe,i.zip=H,i.zipToObject=Q,i}({}); diff --git a/docs/curry/debounce.mdx b/docs/curry/debounce.mdx index da28386a..7b2ec3bf 100644 --- a/docs/curry/debounce.mdx +++ b/docs/curry/debounce.mdx @@ -6,15 +6,17 @@ description: Create a debounced callback function ## Basic usage -Debounce accepts an options object with a `delay` and a source function to call +Debounce accepts an options object with `delay`, `leading`, and a source function to call when invoked. When the returned function is invoked it will only call the source function after the `delay` milliseconds of time has passed. Calls that don't result -in invoking the source reset the delay, pushing off the next invocation. +in invoking the source reset the delay, pushing off the next invocation. The `leading` +option decides whether the source function is called on the first invocation of the debounce +function or not. ```ts import { debounce } from 'radash' -const makeSearchRequest = (event) => { +const makeSearchRequest = event => { api.movies.search(event.target.value) } @@ -33,6 +35,28 @@ debounce Invocations: x x x x - - - - - - - - x x x x x x x x x x - - - - - - - Source Invocations: - - - - - - - - - - x - - - - - - - - - - - - - - - - - x - - - - - ``` +## Leading + +The `leading` option, `false` by default, will call the source function immediately +the first time the debounce function is invoked when set to `true`. + +```ts +// hide the header when scroll down and show it when scroll up. + +const header = document.getElementById('page-header') +let lastY = 0 + +window.addEventListener( + 'scroll', + debounce({ delay: 100, leading: true }, () => { + header.style.transform = `translateY(${ + window.scrollY - lastY > 0 ? '-100%' : '0' + })` + lastY = window.scrollY + }) +) +``` + ### Cancel The function returned by `debounce` has a `cancel` method that when called will permanently stop the source function from being debounced. diff --git a/package.json b/package.json index 0f7a54c7..8e991847 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radash", - "version": "12.1.0", + "version": "12.1.1", "description": "Functional utility library - modern, simple, typed, powerful", "main": "dist/cjs/index.cjs", "module": "dist/esm/index.mjs", diff --git a/src/curry.ts b/src/curry.ts index 2725ea53..3e30354b 100644 --- a/src/curry.ts +++ b/src/curry.ts @@ -494,6 +494,19 @@ export type DebounceFunction = { flush(...args: TArgs): void } +export type DebounceConfig = { + /** + * The time in milliseconds to wait before calling the + * source function + */ + delay: number; + /** + * whether the source function will be called on the first + * invocation of the debounce function. `false` by default + */ + leading?: boolean; +} + export type ThrottledFunction = { (...args: TArgs): void /** @@ -512,7 +525,7 @@ export type ThrottledFunction = { * method to invoke them immediately */ export const debounce = ( - { delay }: { delay: number }, + { delay, leading = false }: DebounceConfig, func: (...args: TArgs) => any ) => { let timer: NodeJS.Timeout | undefined = undefined @@ -525,6 +538,10 @@ export const debounce = ( active && func(...args) timer = undefined }, delay) + if (leading) { + func(...args) + leading = false + } } else { func(...args) } diff --git a/src/tests/curry.test.ts b/src/tests/curry.test.ts index a5bbdd75..a5b62fd7 100644 --- a/src/tests/curry.test.ts +++ b/src/tests/curry.test.ts @@ -330,6 +330,14 @@ describe('curry module', () => { expect(mockFunc).toHaveBeenCalledTimes(1) }) + test('executes the function immediately on the first invocation of the debounce function when set `leading` to true', async () => { + func = _.debounce({ delay: 600, leading: true }, mockFunc) + runFunc3Times() + expect(mockFunc).toHaveBeenCalledTimes(1) + await _.sleep(610) + expect(mockFunc).toHaveBeenCalledTimes(2) + }) + test('does not debounce after cancel is called', () => { runFunc3Times() expect(mockFunc).toHaveBeenCalledTimes(0)