diff --git a/cdn/radash.esm.js b/cdn/radash.esm.js index 4d85731c..83098d97 100644 --- a/cdn/radash.esm.js +++ b/cdn/radash.esm.js @@ -441,6 +441,20 @@ const tryit = (func) => { } }; }; +const guard = (func, shouldGuard) => { + const _guard = (err) => { + if (shouldGuard && !shouldGuard(err)) + throw err; + return void 0; + }; + const isPromise = (result) => result instanceof Promise; + try { + const result = func(); + return isPromise(result) ? result.catch(_guard) : result; + } catch (err) { + return _guard(err); + } +}; const chain = (...funcs) => (...args) => { return funcs.slice(1).reduce((acc, fn) => fn(acc), funcs[0](...args)); @@ -874,4 +888,4 @@ const trim = (str, charsToTrim = " ") => { return str.replace(regex, ""); }; -export { alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject }; +export { alphabetical, assign, boil, callable, camel, capitalize, chain, clone, cluster, compose, construct, counting, crush, dash, debounce, defer, diff, draw, first, flat, fork, get, group, guard, intersects, invert, isArray, isDate, isEmpty, isEqual, isFloat, isFunction, isInt, isNumber, isObject, isPrimitive, isString, isSymbol, iterate, keys, last, list, listify, lowerize, map, mapEntries, mapKeys, mapValues, max, memo, merge, min, objectify, omit, parallel, partial, partob, pascal, pick, proxied, random, range, reduce, replace, replaceOrAppend, retry, select, series, set, shake, shift, shuffle, sift, sleep, snake, sort, sum, template, throttle, title, toFloat, toInt, toggle, trim, tryit as try, tryit, uid, unique, upperize, zip, zipToObject }; diff --git a/cdn/radash.js b/cdn/radash.js index 648d75a7..39dfede9 100644 --- a/cdn/radash.js +++ b/cdn/radash.js @@ -444,6 +444,20 @@ var radash = (function (exports) { } }; }; + const guard = (func, shouldGuard) => { + const _guard = (err) => { + if (shouldGuard && !shouldGuard(err)) + throw err; + return void 0; + }; + const isPromise = (result) => result instanceof Promise; + try { + const result = func(); + return isPromise(result) ? result.catch(_guard) : result; + } catch (err) { + return _guard(err); + } + }; const chain = (...funcs) => (...args) => { return funcs.slice(1).reduce((acc, fn) => fn(acc), funcs[0](...args)); @@ -900,6 +914,7 @@ var radash = (function (exports) { exports.fork = fork; exports.get = get; exports.group = group; + exports.guard = guard; exports.intersects = intersects; exports.invert = invert; exports.isArray = isArray; diff --git a/cdn/radash.min.js b/cdn/radash.min.js index 0ba39055..be375a6a 100644 --- a/cdn/radash.min.js +++ b/cdn/radash.min.js @@ -1 +1 @@ -var radash=function(u){"use strict";const _=t=>!!t&&t.constructor===Symbol,b=t=>!!t&&t.constructor===Array,k=t=>!!t&&t.constructor===Object,z=t=>t==null||typeof t!="object"&&typeof t!="function",p=t=>!!(t&&t.constructor&&t.call&&t.apply),U=t=>typeof t=="string"||t instanceof String,K=t=>h(t)&&t%1===0,J=t=>h(t)&&t%1!==0,h=t=>{try{return Number(t)===t}catch{return!1}},P=t=>Object.prototype.toString.call(t)==="[object Date]",W=t=>{if(t===!0||t===!1||t==null)return!0;if(h(t))return t===0;if(P(t))return isNaN(t.getTime());if(p(t)||_(t))return!1;const e=t.length;if(h(e))return e===0;const n=t.size;return h(n)?n===0:Object.keys(t).length===0},S=(t,e)=>{if(Object.is(t,e))return!0;if(t instanceof Date&&e instanceof Date)return t.getTime()===e.getTime();if(t instanceof RegExp&&e instanceof RegExp)return t.toString()===e.toString();if(typeof t!="object"||t===null||typeof e!="object"||e===null)return!1;const n=Reflect.ownKeys(t),r=Reflect.ownKeys(e);if(n.length!==r.length)return!1;for(let s=0;st.reduce((n,r)=>{const s=e(r);return n[s]||(n[s]=[]),n[s].push(r),n},{});function Y(...t){return!t||!t.length?[]:new Array(Math.max(...t.map(({length:e})=>e))).fill([]).map((e,n)=>t.map(r=>r[n]))}function G(t,e){if(!t||!t.length)return{};const n=p(e)?e:b(e)?(r,s)=>e[s]:(r,s)=>e;return t.reduce((r,s,c)=>(r[s]=n(s,c),r),{})}const O=(t,e)=>!t||(t.length??0)===0?null:t.reduce(e),H=(t,e)=>(t||[]).reduce((n,r)=>n+(e?e(r):r),0),Q=(t,e=void 0)=>t?.length>0?t[0]:e,V=(t,e=void 0)=>t?.length>0?t[t.length-1]:e,j=(t,e,n=!1)=>{if(!t)return[];const r=(c,i)=>e(c)-e(i),s=(c,i)=>e(i)-e(c);return t.slice().sort(n===!0?s:r)},v=(t,e,n="asc")=>{if(!t)return[];const r=(c,i)=>`${e(c)}`.localeCompare(e(i)),s=(c,i)=>`${e(i)}`.localeCompare(e(c));return t.slice().sort(n==="desc"?s:r)},x=(t,e)=>t?t.reduce((n,r)=>{const s=e(r);return n[s]=(n[s]??0)+1,n},{}):{},tt=(t,e,n)=>{if(!t)return[];if(!e)return[...t];for(let r=0;rr)=>t.reduce((r,s)=>(r[e(s)]=n(s),r),{}),et=(t,e,n)=>t?t.reduce((r,s,c)=>(n(s,c)&&r.push(e(s,c)),r),[]):[],nt=(t,e)=>{const n=e||(r=>r);return O(t,(r,s)=>n(r)>n(s)?r:s)},rt=(t,e)=>{const n=e||(r=>r);return O(t,(r,s)=>n(r){const n=Math.ceil(t.length/e);return new Array(n).fill(null).map((r,s)=>t.slice(s*e,s*e+e))},ut=(t,e)=>{const n=t.reduce((r,s)=>{const c=e?e(s):s;return r[c]||(r[c]=s),r},{});return Object.values(n)};function*A(t,e,n=s=>s,r=1){const s=p(n)?n:()=>n,c=e?t:0,i=e??t;for(let o=c;o<=i&&(yield s(o),!(o+r>i));o+=r);}const C=(t,e,n,r)=>Array.from(A(t,e,n,r)),ct=t=>t.reduce((e,n)=>(e.push(...n),e),[]),it=(t,e,n)=>{if(!t||!e)return!1;const r=n??(c=>c),s=e.reduce((c,i)=>(c[r(i)]=!0,c),{});return t.some(c=>s[r(c)])},B=(t,e)=>t?t.reduce((n,r)=>{const[s,c]=n;return e(r)?[[...s,r],c]:[s,[...c,r]]},[[],[]]):[[],[]],ot=(t,e,n)=>!e&&!t?[]:e?t?n?t.reduce((r,s)=>{const c=e.find(i=>n(s)===n(i));return c?r.push(c):r.push(s),r},[]):t:[]:t,ft=(t,e,n)=>{if(!t&&!e)return[];if(!e)return[...t];if(!t)return[e];for(let r=0;r{if(!t&&!e)return[];if(!t)return[e];if(!e)return[...t];const s=n?(o,a)=>n(o,a)===n(e,a):o=>o===e;return t.find(s)?t.filter((o,a)=>!s(o,a)):(r?.strategy??"append")==="append"?[...t,e]:[e,...t]},at=t=>t?.filter(e=>!!e)??[],L=(t,e,n)=>{let r=n;for(let s=1;s<=t;s++)r=e(r,s);return r},dt=(t,e,n=r=>r)=>{if(!t?.length&&!e?.length)return[];if(t?.length===void 0)return[...e];if(!e?.length)return[...t];const r=e.reduce((s,c)=>(s[n(c)]=!0,s),{});return t.filter(s=>!r[n(s)])};function gt(t,e){if(t.length===0)return t;const n=e%t.length;return n===0?t:[...t.slice(-n,t.length),...t.slice(0,-n)]}const ht=async(t,e,n)=>{const r=n!==void 0;if(!r&&t?.length<1)throw new Error("Cannot reduce empty array with no init value");const s=r?t:t.slice(1);let c=r?n:t[0];for(const i of s)c=await e(c,i);return c},mt=async(t,e)=>{if(!t)return[];let n=[],r=0;for(const s of t){const c=await e(s,r++);n.push(c)}return n},wt=async t=>{const e=[],n=(c,i)=>e.push({fn:c,rethrow:i?.rethrow??!1}),[r,s]=await m(t)(n);for(const{fn:c,rethrow:i}of e){const[o]=await m(c)(r);if(o&&i)throw o}if(r)throw r;return s};class yt extends Error{constructor(e=[]){super();const n=e.find(r=>r.name)?.name??"";this.name=`AggregateError(${n}...)`,this.message=`AggregateError with ${e.length} errors`,this.stack=e.find(r=>r.stack)?.stack??this.stack,this.errors=e}}const pt=async(t,e,n)=>{const r=e.map((d,y)=>({index:y,item:d})),s=async d=>{const y=[];for(;;){const f=r.pop();if(!f)return d(y);const[l,g]=await m(n)(f.item);y.push({error:l,result:g,index:f.index})}},c=C(1,t).map(()=>new Promise(s)),i=await Promise.all(c),[o,a]=B(j(i.flat(),d=>d.index),d=>!!d.error);if(o.length>0)throw new yt(o.map(d=>d.error));return a.map(d=>d.result)},bt=async(t,e)=>{const n=t?.times??3,r=t?.delay,s=t?.backoff??null;for(const c of A(1,n)){const[i,o]=await m(e)(a=>{throw{_exited:a}});if(!i)return o;if(i._exited)throw i._exited;if(c===n)throw i;r&&await E(r),s&&await E(s(c))}},E=t=>new Promise(e=>setTimeout(e,t)),m=t=>async(...e)=>{try{return[void 0,await t(...e)]}catch(n){return[n,void 0]}},kt=(...t)=>(...e)=>t.slice(1).reduce((n,r)=>r(n),t[0](...e)),Ot=(...t)=>t.reverse().reduce((e,n)=>n(e)),At=(t,...e)=>(...n)=>t(...e,...n),Ct=(t,e)=>n=>t({...e,...n}),Et=t=>new Proxy({},{get:(e,n)=>t(n)}),$t=(t,e,n,r)=>function(...c){const i=n?n(...c):JSON.stringify({args:c}),o=t[i];if(o!==void 0&&(!o.exp||o.exp>new Date().getTime()))return o.value;const a=e(...c);return t[i]={exp:r?new Date().getTime()+r:null,value:a},a},Nt=(t,e={})=>$t({},t,e.key??null,e.ttl??null),_t=({delay:t},e)=>{let n,r=!0;const s=(...c)=>{r?(clearTimeout(n),n=setTimeout(()=>{r&&e(...c)},t)):e(...c)};return s.cancel=()=>{r=!1},s.flush=(...c)=>e(...c),s},zt=({interval:t},e)=>{let n=!0;return(...s)=>{n&&(e(...s),n=!1,setTimeout(()=>{n=!0},t))}},Pt=(t,e)=>{const n=()=>{};return new Proxy(Object.assign(n,t),{get:(r,s)=>r[s],set:(r,s,c)=>(r[s]=c,!0),apply:(r,s,c)=>e(Object.assign({},r))(...c)})},St=(t,e)=>{const n=e===void 0?0:e;if(t==null)return n;const r=parseFloat(t);return isNaN(r)?n:r},M=(t,e)=>{const n=e===void 0?0:e;if(t==null)return n;const r=parseInt(t);return isNaN(r)?n:r},jt=(t,e=n=>n===void 0)=>t?Object.keys(t).reduce((r,s)=>(e(t[s])||(r[s]=t[s]),r),{}):{},$=(t,e)=>Object.keys(t).reduce((r,s)=>(r[e(s,t[s])]=t[s],r),{}),Tt=(t,e)=>Object.keys(t).reduce((r,s)=>(r[s]=e(t[s],s),r),{}),Bt=(t,e)=>t?Object.entries(t).reduce((n,[r,s])=>{const[c,i]=e(r,s);return n[c]=i,n},{}):{},Lt=t=>t?Object.keys(t).reduce((n,r)=>(n[t[r]]=r,n),{}):{},Mt=t=>$(t,e=>e.toLowerCase()),Dt=t=>$(t,e=>e.toUpperCase()),D=t=>{if(z(t))return t;if(typeof t=="function")return t.bind({});const e=new t.constructor;return Object.getOwnPropertyNames(t).forEach(n=>{e[n]=t[n]}),e},Ft=(t,e)=>{if(!t)return[];const n=Object.entries(t);return n.length===0?[]:n.reduce((r,s)=>(r.push(e(s[0],s[1])),r),[])},Rt=(t,e)=>t?e.reduce((n,r)=>(t.hasOwnProperty(r)&&(n[r]=t[r]),n),{}):{},Zt=(t,e)=>t?!e||e.length===0?t:e.reduce((n,r)=>(delete n[r],n),{...t}):{},F=(t,e,n=null)=>{const r=e.split(/[\.\[\]]/g);let s=t;for(const c of r){if(s===null||s===void 0)return n;c.trim()!==""&&(s=s[c])}return s===void 0?n:s},R=(t,e,n)=>{if(!t)return{};if(!e||!n)return t;const r=e.split(/[\.\[\]]/g).filter(i=>!!i.trim()),s=i=>{if(r.length>1){const o=r.shift(),a=M(r[0],null)!==null;i[o]=i[o]===void 0?a?[]:{}:i[o],s(i[o])}else i[r[0]]=n},c=D(t);return s(c),c},Z=(t,e)=>!t&&!e?{}:t?e?Object.entries(t).reduce((n,[r,s])=>({...n,[r]:(()=>k(s)?Z(s,e[r]):e[r])()}),{}):t:e,I=t=>{if(!t)return[];const e=(n,r)=>k(n)?Object.entries(n).flatMap(([s,c])=>e(c,[...r,s])):b(n)?n.flatMap((s,c)=>e(s,[...r,`${c}`])):[r.join(".")];return e(t,[])},It=t=>t?T(I(t),e=>e,e=>F(t,e)):{},qt=t=>t?Object.keys(t).reduce((e,n)=>R(e,n,t[n]),{}):{},N=(t,e)=>Math.floor(Math.random()*(e-t+1)+t),Ut=t=>{const e=t.length;if(e===0)return null;const n=N(0,e-1);return t[n]},Kt=t=>t.map(e=>({rand:Math.random(),value:e})).sort((e,n)=>e.rand-n.rand).map(e=>e.value),Jt=(t,e="")=>{const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+e;return L(t,r=>r+n.charAt(N(0,n.length-1)),"")},Wt=(t,e=n=>`${n}`)=>{const{indexesByKey:n,itemsByIndex:r}=t.reduce((f,l,g)=>({indexesByKey:{...f.indexesByKey,[e(l)]:g},itemsByIndex:{...f.itemsByIndex,[g]:l}}),{indexesByKey:{},itemsByIndex:{}}),s=(f,l)=>n[e(f)]n[e(f)]>n[e(l)]?f:l,i=()=>r[0],o=()=>r[t.length-1],a=(f,l)=>r[n[e(f)]+1]??l??i(),d=(f,l)=>r[n[e(f)]-1]??l??o();return{min:s,max:c,first:i,last:o,next:a,previous:d,spin:(f,l)=>{if(l===0)return f;const g=Math.abs(l),xt=g>t.length?g%t.length:g;return C(0,xt-1).reduce(q=>l>0?a(q):d(q),f)}}},w=t=>{if(!t||t.length===0)return"";const e=t.toLowerCase();return e.substring(0,1).toUpperCase()+e.substring(1,e.length)},Xt=t=>{const e=t?.replace(/([A-Z])+/g,w)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return e.length===0?"":e.length===1?e[0]:e.reduce((n,r)=>`${n}${r.charAt(0).toUpperCase()}${r.slice(1)}`)},Yt=t=>{const e=t?.replace(/([A-Z])+/g,w).split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return e.length===0?"":e.length===1?e[0]:e.reduce((n,r)=>`${n}_${r.toLowerCase()}`)},Gt=t=>{const e=t?.replace(/([A-Z])+/g,w)?.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.toLowerCase())??[];return e.length===0?"":e.length===1?e[0]:e.reduce((n,r)=>`${n}-${r.toLowerCase()}`)},Ht=t=>{const e=t?.split(/[\.\-\s_]/).map(n=>n.toLowerCase())??[];return e.length===0?"":e.map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("")},Qt=t=>t?t.split(/(?=[A-Z])|[\.\-\s_]/).map(e=>e.trim()).filter(e=>!!e).map(e=>w(e.toLowerCase())).join(" "):"",Vt=(t,e,n=/\{\{(.+?)\}\}/g)=>Array.from(t.matchAll(n)).reduce((r,s)=>r.replace(s[0],e[s[1]]),t),vt=(t,e=" ")=>{if(!t)return"";const n=new RegExp(`^[${e}]+|[${e}]+$`,"g");return t.replace(n,"")};return u.alphabetical=v,u.assign=Z,u.boil=O,u.callable=Pt,u.camel=Xt,u.capitalize=w,u.chain=kt,u.clone=D,u.cluster=st,u.compose=Ot,u.construct=qt,u.counting=x,u.crush=It,u.dash=Gt,u.debounce=_t,u.defer=wt,u.diff=dt,u.draw=Ut,u.first=Q,u.flat=ct,u.fork=B,u.get=F,u.group=X,u.intersects=it,u.invert=Lt,u.isArray=b,u.isDate=P,u.isEmpty=W,u.isEqual=S,u.isFloat=J,u.isFunction=p,u.isInt=K,u.isNumber=h,u.isObject=k,u.isPrimitive=z,u.isString=U,u.isSymbol=_,u.iterate=L,u.keys=I,u.last=V,u.list=C,u.listify=Ft,u.lowerize=Mt,u.map=mt,u.mapEntries=Bt,u.mapKeys=$,u.mapValues=Tt,u.max=nt,u.memo=Nt,u.merge=ot,u.min=rt,u.objectify=T,u.omit=Zt,u.parallel=pt,u.partial=At,u.partob=Ct,u.pascal=Ht,u.pick=Rt,u.proxied=Et,u.random=N,u.range=A,u.reduce=ht,u.replace=tt,u.replaceOrAppend=ft,u.retry=bt,u.select=et,u.series=Wt,u.set=R,u.shake=jt,u.shift=gt,u.shuffle=Kt,u.sift=at,u.sleep=E,u.snake=Yt,u.sort=j,u.sum=H,u.template=Vt,u.throttle=zt,u.title=Qt,u.toFloat=St,u.toInt=M,u.toggle=lt,u.trim=vt,u.try=m,u.tryit=m,u.uid=Jt,u.unique=ut,u.upperize=Dt,u.zip=Y,u.zipToObject=G,u}({}); +var radash=function(u){"use strict";const N=t=>!!t&&t.constructor===Symbol,b=t=>!!t&&t.constructor===Array,k=t=>!!t&&t.constructor===Object,P=t=>t==null||typeof t!="object"&&typeof t!="function",p=t=>!!(t&&t.constructor&&t.call&&t.apply),U=t=>typeof t=="string"||t instanceof String,K=t=>h(t)&&t%1===0,J=t=>h(t)&&t%1!==0,h=t=>{try{return Number(t)===t}catch{return!1}},z=t=>Object.prototype.toString.call(t)==="[object Date]",W=t=>{if(t===!0||t===!1||t==null)return!0;if(h(t))return t===0;if(z(t))return isNaN(t.getTime());if(p(t)||N(t))return!1;const n=t.length;if(h(n))return n===0;const e=t.size;return h(e)?e===0:Object.keys(t).length===0},S=(t,n)=>{if(Object.is(t,n))return!0;if(t instanceof Date&&n instanceof Date)return t.getTime()===n.getTime();if(t instanceof RegExp&&n instanceof RegExp)return t.toString()===n.toString();if(typeof t!="object"||t===null||typeof n!="object"||n===null)return!1;const e=Reflect.ownKeys(t),r=Reflect.ownKeys(n);if(e.length!==r.length)return!1;for(let s=0;st.reduce((e,r)=>{const s=n(r);return e[s]||(e[s]=[]),e[s].push(r),e},{});function Y(...t){return!t||!t.length?[]:new Array(Math.max(...t.map(({length:n})=>n))).fill([]).map((n,e)=>t.map(r=>r[e]))}function H(t,n){if(!t||!t.length)return{};const e=p(n)?n:b(n)?(r,s)=>n[s]:(r,s)=>n;return t.reduce((r,s,c)=>(r[s]=e(s,c),r),{})}const O=(t,n)=>!t||(t.length??0)===0?null:t.reduce(n),Q=(t,n)=>(t||[]).reduce((e,r)=>e+(n?n(r):r),0),V=(t,n=void 0)=>t?.length>0?t[0]:n,G=(t,n=void 0)=>t?.length>0?t[t.length-1]:n,j=(t,n,e=!1)=>{if(!t)return[];const r=(c,i)=>n(c)-n(i),s=(c,i)=>n(i)-n(c);return t.slice().sort(e===!0?s:r)},v=(t,n,e="asc")=>{if(!t)return[];const r=(c,i)=>`${n(c)}`.localeCompare(n(i)),s=(c,i)=>`${n(i)}`.localeCompare(n(c));return t.slice().sort(e==="desc"?s:r)},x=(t,n)=>t?t.reduce((e,r)=>{const s=n(r);return e[s]=(e[s]??0)+1,e},{}):{},tt=(t,n,e)=>{if(!t)return[];if(!n)return[...t];for(let r=0;rr)=>t.reduce((r,s)=>(r[n(s)]=e(s),r),{}),nt=(t,n,e)=>t?t.reduce((r,s,c)=>(e(s,c)&&r.push(n(s,c)),r),[]):[],et=(t,n)=>{const e=n||(r=>r);return O(t,(r,s)=>e(r)>e(s)?r:s)},rt=(t,n)=>{const e=n||(r=>r);return O(t,(r,s)=>e(r){const e=Math.ceil(t.length/n);return new Array(e).fill(null).map((r,s)=>t.slice(s*n,s*n+n))},ut=(t,n)=>{const e=t.reduce((r,s)=>{const c=n?n(s):s;return r[c]||(r[c]=s),r},{});return Object.values(e)};function*A(t,n,e=s=>s,r=1){const s=p(e)?e:()=>e,c=n?t:0,i=n??t;for(let o=c;o<=i&&(yield s(o),!(o+r>i));o+=r);}const C=(t,n,e,r)=>Array.from(A(t,n,e,r)),ct=t=>t.reduce((n,e)=>(n.push(...e),n),[]),it=(t,n,e)=>{if(!t||!n)return!1;const r=e??(c=>c),s=n.reduce((c,i)=>(c[r(i)]=!0,c),{});return t.some(c=>s[r(c)])},B=(t,n)=>t?t.reduce((e,r)=>{const[s,c]=e;return n(r)?[[...s,r],c]:[s,[...c,r]]},[[],[]]):[[],[]],ot=(t,n,e)=>!n&&!t?[]:n?t?e?t.reduce((r,s)=>{const c=n.find(i=>e(s)===e(i));return c?r.push(c):r.push(s),r},[]):t:[]:t,ft=(t,n,e)=>{if(!t&&!n)return[];if(!n)return[...t];if(!t)return[n];for(let r=0;r{if(!t&&!n)return[];if(!t)return[n];if(!n)return[...t];const s=e?(o,a)=>e(o,a)===e(n,a):o=>o===n;return t.find(s)?t.filter((o,a)=>!s(o,a)):(r?.strategy??"append")==="append"?[...t,n]:[n,...t]},at=t=>t?.filter(n=>!!n)??[],L=(t,n,e)=>{let r=e;for(let s=1;s<=t;s++)r=n(r,s);return r},dt=(t,n,e=r=>r)=>{if(!t?.length&&!n?.length)return[];if(t?.length===void 0)return[...n];if(!n?.length)return[...t];const r=n.reduce((s,c)=>(s[e(c)]=!0,s),{});return t.filter(s=>!r[e(s)])};function gt(t,n){if(t.length===0)return t;const e=n%t.length;return e===0?t:[...t.slice(-e,t.length),...t.slice(0,-e)]}const ht=async(t,n,e)=>{const r=e!==void 0;if(!r&&t?.length<1)throw new Error("Cannot reduce empty array with no init value");const s=r?t:t.slice(1);let c=r?e:t[0];for(const i of s)c=await n(c,i);return c},mt=async(t,n)=>{if(!t)return[];let e=[],r=0;for(const s of t){const c=await n(s,r++);e.push(c)}return e},wt=async t=>{const n=[],e=(c,i)=>n.push({fn:c,rethrow:i?.rethrow??!1}),[r,s]=await m(t)(e);for(const{fn:c,rethrow:i}of n){const[o]=await m(c)(r);if(o&&i)throw o}if(r)throw r;return s};class yt extends Error{constructor(n=[]){super();const e=n.find(r=>r.name)?.name??"";this.name=`AggregateError(${e}...)`,this.message=`AggregateError with ${n.length} errors`,this.stack=n.find(r=>r.stack)?.stack??this.stack,this.errors=n}}const pt=async(t,n,e)=>{const r=n.map((d,y)=>({index:y,item:d})),s=async d=>{const y=[];for(;;){const f=r.pop();if(!f)return d(y);const[l,g]=await m(e)(f.item);y.push({error:l,result:g,index:f.index})}},c=C(1,t).map(()=>new Promise(s)),i=await Promise.all(c),[o,a]=B(j(i.flat(),d=>d.index),d=>!!d.error);if(o.length>0)throw new yt(o.map(d=>d.error));return a.map(d=>d.result)},bt=async(t,n)=>{const e=t?.times??3,r=t?.delay,s=t?.backoff??null;for(const c of A(1,e)){const[i,o]=await m(n)(a=>{throw{_exited:a}});if(!i)return o;if(i._exited)throw i._exited;if(c===e)throw i;r&&await E(r),s&&await E(s(c))}},E=t=>new Promise(n=>setTimeout(n,t)),m=t=>async(...n)=>{try{return[void 0,await t(...n)]}catch(e){return[e,void 0]}},kt=(t,n)=>{const e=s=>{if(n&&!n(s))throw s},r=s=>s instanceof Promise;try{const s=t();return r(s)?s.catch(e):s}catch(s){return e(s)}},Ot=(...t)=>(...n)=>t.slice(1).reduce((e,r)=>r(e),t[0](...n)),At=(...t)=>t.reverse().reduce((n,e)=>e(n)),Ct=(t,...n)=>(...e)=>t(...n,...e),Et=(t,n)=>e=>t({...n,...e}),_t=t=>new Proxy({},{get:(n,e)=>t(e)}),$t=(t,n,e,r)=>function(...c){const i=e?e(...c):JSON.stringify({args:c}),o=t[i];if(o!==void 0&&(!o.exp||o.exp>new Date().getTime()))return o.value;const a=n(...c);return t[i]={exp:r?new Date().getTime()+r:null,value:a},a},Nt=(t,n={})=>$t({},t,n.key??null,n.ttl??null),Pt=({delay:t},n)=>{let e,r=!0;const s=(...c)=>{r?(clearTimeout(e),e=setTimeout(()=>{r&&n(...c)},t)):n(...c)};return s.cancel=()=>{r=!1},s.flush=(...c)=>n(...c),s},zt=({interval:t},n)=>{let e=!0;return(...s)=>{e&&(n(...s),e=!1,setTimeout(()=>{e=!0},t))}},St=(t,n)=>{const e=()=>{};return new Proxy(Object.assign(e,t),{get:(r,s)=>r[s],set:(r,s,c)=>(r[s]=c,!0),apply:(r,s,c)=>n(Object.assign({},r))(...c)})},jt=(t,n)=>{const e=n===void 0?0:n;if(t==null)return e;const r=parseFloat(t);return isNaN(r)?e:r},M=(t,n)=>{const e=n===void 0?0:n;if(t==null)return e;const r=parseInt(t);return isNaN(r)?e:r},Tt=(t,n=e=>e===void 0)=>t?Object.keys(t).reduce((r,s)=>(n(t[s])||(r[s]=t[s]),r),{}):{},_=(t,n)=>Object.keys(t).reduce((r,s)=>(r[n(s,t[s])]=t[s],r),{}),Bt=(t,n)=>Object.keys(t).reduce((r,s)=>(r[s]=n(t[s],s),r),{}),Lt=(t,n)=>t?Object.entries(t).reduce((e,[r,s])=>{const[c,i]=n(r,s);return e[c]=i,e},{}):{},Mt=t=>t?Object.keys(t).reduce((e,r)=>(e[t[r]]=r,e),{}):{},Dt=t=>_(t,n=>n.toLowerCase()),Ft=t=>_(t,n=>n.toUpperCase()),D=t=>{if(P(t))return t;if(typeof t=="function")return t.bind({});const n=new t.constructor;return Object.getOwnPropertyNames(t).forEach(e=>{n[e]=t[e]}),n},Rt=(t,n)=>{if(!t)return[];const e=Object.entries(t);return e.length===0?[]:e.reduce((r,s)=>(r.push(n(s[0],s[1])),r),[])},Zt=(t,n)=>t?n.reduce((e,r)=>(t.hasOwnProperty(r)&&(e[r]=t[r]),e),{}):{},It=(t,n)=>t?!n||n.length===0?t:n.reduce((e,r)=>(delete e[r],e),{...t}):{},F=(t,n,e=null)=>{const r=n.split(/[\.\[\]]/g);let s=t;for(const c of r){if(s===null||s===void 0)return e;c.trim()!==""&&(s=s[c])}return s===void 0?e:s},R=(t,n,e)=>{if(!t)return{};if(!n||!e)return t;const r=n.split(/[\.\[\]]/g).filter(i=>!!i.trim()),s=i=>{if(r.length>1){const o=r.shift(),a=M(r[0],null)!==null;i[o]=i[o]===void 0?a?[]:{}:i[o],s(i[o])}else i[r[0]]=e},c=D(t);return s(c),c},Z=(t,n)=>!t&&!n?{}:t?n?Object.entries(t).reduce((e,[r,s])=>({...e,[r]:(()=>k(s)?Z(s,n[r]):n[r])()}),{}):t:n,I=t=>{if(!t)return[];const n=(e,r)=>k(e)?Object.entries(e).flatMap(([s,c])=>n(c,[...r,s])):b(e)?e.flatMap((s,c)=>n(s,[...r,`${c}`])):[r.join(".")];return n(t,[])},qt=t=>t?T(I(t),n=>n,n=>F(t,n)):{},Ut=t=>t?Object.keys(t).reduce((n,e)=>R(n,e,t[e]),{}):{},$=(t,n)=>Math.floor(Math.random()*(n-t+1)+t),Kt=t=>{const n=t.length;if(n===0)return null;const e=$(0,n-1);return t[e]},Jt=t=>t.map(n=>({rand:Math.random(),value:n})).sort((n,e)=>n.rand-e.rand).map(n=>n.value),Wt=(t,n="")=>{const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+n;return L(t,r=>r+e.charAt($(0,e.length-1)),"")},Xt=(t,n=e=>`${e}`)=>{const{indexesByKey:e,itemsByIndex:r}=t.reduce((f,l,g)=>({indexesByKey:{...f.indexesByKey,[n(l)]:g},itemsByIndex:{...f.itemsByIndex,[g]:l}}),{indexesByKey:{},itemsByIndex:{}}),s=(f,l)=>e[n(f)]e[n(f)]>e[n(l)]?f:l,i=()=>r[0],o=()=>r[t.length-1],a=(f,l)=>r[e[n(f)]+1]??l??i(),d=(f,l)=>r[e[n(f)]-1]??l??o();return{min:s,max:c,first:i,last:o,next:a,previous:d,spin:(f,l)=>{if(l===0)return f;const g=Math.abs(l),tn=g>t.length?g%t.length:g;return C(0,tn-1).reduce(q=>l>0?a(q):d(q),f)}}},w=t=>{if(!t||t.length===0)return"";const n=t.toLowerCase();return n.substring(0,1).toUpperCase()+n.substring(1,n.length)},Yt=t=>{const n=t?.replace(/([A-Z])+/g,w)?.split(/(?=[A-Z])|[\.\-\s_]/).map(e=>e.toLowerCase())??[];return n.length===0?"":n.length===1?n[0]:n.reduce((e,r)=>`${e}${r.charAt(0).toUpperCase()}${r.slice(1)}`)},Ht=t=>{const n=t?.replace(/([A-Z])+/g,w).split(/(?=[A-Z])|[\.\-\s_]/).map(e=>e.toLowerCase())??[];return n.length===0?"":n.length===1?n[0]:n.reduce((e,r)=>`${e}_${r.toLowerCase()}`)},Qt=t=>{const n=t?.replace(/([A-Z])+/g,w)?.split(/(?=[A-Z])|[\.\-\s_]/).map(e=>e.toLowerCase())??[];return n.length===0?"":n.length===1?n[0]:n.reduce((e,r)=>`${e}-${r.toLowerCase()}`)},Vt=t=>{const n=t?.split(/[\.\-\s_]/).map(e=>e.toLowerCase())??[];return n.length===0?"":n.map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join("")},Gt=t=>t?t.split(/(?=[A-Z])|[\.\-\s_]/).map(n=>n.trim()).filter(n=>!!n).map(n=>w(n.toLowerCase())).join(" "):"",vt=(t,n,e=/\{\{(.+?)\}\}/g)=>Array.from(t.matchAll(e)).reduce((r,s)=>r.replace(s[0],n[s[1]]),t),xt=(t,n=" ")=>{if(!t)return"";const e=new RegExp(`^[${n}]+|[${n}]+$`,"g");return t.replace(e,"")};return u.alphabetical=v,u.assign=Z,u.boil=O,u.callable=St,u.camel=Yt,u.capitalize=w,u.chain=Ot,u.clone=D,u.cluster=st,u.compose=At,u.construct=Ut,u.counting=x,u.crush=qt,u.dash=Qt,u.debounce=Pt,u.defer=wt,u.diff=dt,u.draw=Kt,u.first=V,u.flat=ct,u.fork=B,u.get=F,u.group=X,u.guard=kt,u.intersects=it,u.invert=Mt,u.isArray=b,u.isDate=z,u.isEmpty=W,u.isEqual=S,u.isFloat=J,u.isFunction=p,u.isInt=K,u.isNumber=h,u.isObject=k,u.isPrimitive=P,u.isString=U,u.isSymbol=N,u.iterate=L,u.keys=I,u.last=G,u.list=C,u.listify=Rt,u.lowerize=Dt,u.map=mt,u.mapEntries=Lt,u.mapKeys=_,u.mapValues=Bt,u.max=et,u.memo=Nt,u.merge=ot,u.min=rt,u.objectify=T,u.omit=It,u.parallel=pt,u.partial=Ct,u.partob=Et,u.pascal=Vt,u.pick=Zt,u.proxied=_t,u.random=$,u.range=A,u.reduce=ht,u.replace=tt,u.replaceOrAppend=ft,u.retry=bt,u.select=nt,u.series=Xt,u.set=R,u.shake=Tt,u.shift=gt,u.shuffle=Jt,u.sift=at,u.sleep=E,u.snake=Ht,u.sort=j,u.sum=Q,u.template=vt,u.throttle=zt,u.title=Gt,u.toFloat=jt,u.toInt=M,u.toggle=lt,u.trim=xt,u.try=m,u.tryit=m,u.uid=Wt,u.unique=ut,u.upperize=Ft,u.zip=Y,u.zipToObject=H,u}({}); diff --git a/docs/async/guard.mdx b/docs/async/guard.mdx new file mode 100644 index 00000000..0d4179ef --- /dev/null +++ b/docs/async/guard.mdx @@ -0,0 +1,20 @@ +--- +title: guard +group: 'Async' +description: Have a function return undefined if it errors out +--- + +## Basic usage + +This lets you set a default value if an async function errors out. + +```ts +const users = (await guard(fetchUsers)) ?? [] +``` + +You can choose to guard only specific errors too + +```ts +const isInvalidUserError = (err: any) => err.code === 'INVALID_ID' +const user = (await guard(fetchUser, isInvalidUserError)) ?? DEFAULT_USER +``` diff --git a/package.json b/package.json index 14922641..bb51e48f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "radash", - "version": "10.7.1", + "version": "10.8.1", "description": "Functional utility library - modern, simple, typed, powerful", "main": "dist/cjs/index.cjs", "module": "dist/esm/index.mjs", diff --git a/src/async.ts b/src/async.ts index 70be8ee8..479e138f 100644 --- a/src/async.ts +++ b/src/async.ts @@ -207,3 +207,29 @@ export const tryit = any>( } } } + +/** + * A helper to try an async function that returns undefined + * if it fails. + * + * e.g. const result = await guard(fetchUsers)() ?? []; + */ +export const guard = any>( + func: TFunction, + shouldGuard?: (err: any) => boolean +): ReturnType extends Promise + ? Promise> | undefined> + : ReturnType | undefined => { + const _guard = (err: any) => { + if (shouldGuard && !shouldGuard(err)) throw err + return undefined as any + } + const isPromise = (result: any): result is ReturnType => + result instanceof Promise + try { + const result = func() + return isPromise(result) ? result.catch(_guard) : result + } catch (err) { + return _guard(err) + } +} diff --git a/src/index.ts b/src/index.ts index 63acf05c..35d035fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,6 +31,7 @@ export { } from './array' export { defer, + guard, map, parallel, reduce, diff --git a/src/tests/async.test.ts b/src/tests/async.test.ts index 830bb16f..ffdd986c 100644 --- a/src/tests/async.test.ts +++ b/src/tests/async.test.ts @@ -430,4 +430,59 @@ describe('async module', () => { assert.isAtLeast(diff, backoffs) }) }) + + describe('_.guard', () => { + it('returns result of given async function', async () => { + const result = await _.guard(async () => { + return 'hello' + }) + assert.equal(result, 'hello') + }) + it('returns result of given sync function', async () => { + const result = _.guard(() => { + return 'hello' + }) + assert.equal(result, 'hello') + }) + it('returns error if given async function throws', async () => { + const result = + (await _.guard(async () => { + throw new Error('error') + })) ?? 'good-bye' + assert.equal(result, 'good-bye') + }) + it('returns error if given sync function throws', async () => { + const alwaysThrow = () => { + if (1 > 0) throw new Error('error') + return undefined + } + const result = _.guard(alwaysThrow) ?? 'good-bye' + assert.equal(result, 'good-bye') + }) + it('throws error if shouldGuard returns false', async () => { + const makeFetchUser = (id: number) => { + return async () => { + if (id === 1) return 'user1' + if (id === 2) throw new Error('user not found') + throw new Error('unknown error') + } + } + const isUserNotFoundErr = (err: any) => err.message === 'user not found' + const fetchUser = async (id: number) => + (await _.guard(makeFetchUser(id), isUserNotFoundErr)) ?? 'default-user' + + const user1 = await fetchUser(1) + assert.equal(user1, 'user1') + + const user2 = await fetchUser(2) + assert.equal(user2, 'default-user') + + try { + await fetchUser(3) + assert.fail() + } catch (err: any) { + assert.equal(err.message, 'unknown error') + } + }) + }) })