@knighttower/utility
Version:
UtilityJs is a utility library that provides a collection of utility functions for various tasks. The library is designed to be easy to use and covers the most common use cases.
1 lines • 7.68 kB
JavaScript
(()=>{"use strict";var t={d:(e,s)=>{for(var r in s){t.o(s,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:s[r]})}},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{doAsync:()=>d,doPoll:()=>a,doTimeout:()=>h,promisePool:()=>u,promiseQueue:()=>l});class s{constructor(){this.listeners={}}on(t,e){this.registerListener(t,e)}once(t,e){this.registerListener(t,e,1)}exactly(t,e,s){this.registerListener(t,e,s)}off(t){delete this.listeners[t]}detach(t,e){const s=(this.listeners[t]||[]).filter(function(t){return t.callback!==e});return t in this.listeners&&(this.listeners[t]=s,!0)}emit(t,...e){let s=[],r=null;const i=this.extractContextFromArgs(e),n=i[0];if(e=i[1],this.hasListener(t)){s=this.listeners[t]}else if(t.includes("*")){r=this.patternSearch(t,Object.keys(this.listeners)),r.length>0&&r.forEach(t=>{s=s.concat(this.listeners[t])})}else{for(const e in this.listeners){e.includes("*")&&(r=this.patternSearch(e,[t]),r&&(s=s.concat(this.listeners[e])))}}s.forEach((r,i)=>{let o=r.callback;n&&(o=o.bind(n)),void 0!==r.triggerCapacity&&(r.triggerCapacity--,s[i].triggerCapacity=r.triggerCapacity),this.checkToRemoveListener(r)&&this.listeners[t].splice(i,1),o(...e)})}patternSearch(t,e){let s=[];const r=new RegExp(this.setWildCardString(t),"g");return s=e.filter(t=>r.test(t)),0===s.length?null:s}setWildCardString(t){let e=t.replace(/([.+?^${}()|\[\]\/\\])/g,"\\$&");return e=e.replace(/\*/g,"(.*?)"),`^${e}`}extractContextFromArgs(t){let e=null;for(let s=0;s<t.length;s++){const r=t[s];if(r&&"object"==typeof r&&r.hasOwnProperty("__context")){e=r.__context,t.splice(s,1);break}}return[e,t]}registerListener(t,e,s){this.hasListener(t)||(this.listeners[t]=[]),this.listeners[t].push({callback:e,triggerCapacity:s})}checkToRemoveListener(t){return void 0!==t.triggerCapacity&&t.triggerCapacity<=0}hasListener(t){return t in this.listeners}}const r=t=>Array.isArray(t)?t:[t],i=(t=20)=>{const e=()=>Math.random().toString(36).substring(2,15);t=t||40;for(var s="",r=0;r<t/3+1;r++){s+=e()}return s.substring(0,t)};function n(){return"id__"+i(8)+"__"+(new Date).getTime()}function o(t,e){if(null===t){return e?null===e||"null"===e:"null"}let s;switch(typeof t){case"number":case"string":case"boolean":case"undefined":case"bigint":case"symbol":case"function":s=typeof t;break;case"object":s=Array.isArray(t)?"array":"object";break;default:s="unknown"}if(e){if(e.includes("|")){for(let t of e.split("|")){if(s===t){return t}}return!1}return e===s}return s}const l=()=>{const t={completed:0,rejected:0,pending:0,total:0,errors:"",promises:[]};return new class extends s{constructor(){super(),this.queue=[],this.inProgress=!1,this._timer=null,this._stats={...t}}add(t){if(!(t instanceof Promise||!!Array.isArray(t)&&t.length>0&&t.every(t=>t instanceof Promise))){if(!o(t,"function")){return console.error("---\x3e Invalid promise added to the Queue:",t.toString()),this.emit("fail",t.toString())}t=new Promise(async e=>e(await t()))}r(t).forEach(t=>{this._stats.total++,this._stats.pending++,this.queue.push({promiseFunction:t,response:null,status:"pending",error:null})}),this.inProgress||this._next(),this._setTimer()}clear(){return this._timer&&clearInterval(this._timer),this._timer=null,this.queue=[],this.inProgress=!1,this._stats={...t},this}_setTimer(){this._timer&&clearInterval(this._timer),this._timer=setInterval(()=>{"done"===this.status()&&(clearInterval(this._timer),this._timer=null,this.emit("completed",this._stats),this.emit("done",this._stats))},10)}_next(){if(0===this.queue.length){return void(this.inProgress=!1)}this.inProgress=!0;const{promiseFunction:t}=this.queue[0];t.then(t=>{this.queue[0].status="fulfilled",this.queue[0].response=t,this._stats.completed++}).catch(t=>{this._stats.errors+=t+"\n",this.queue[0].status="rejected",this._stats.rejected++}).finally(()=>{this._stats.promises.push(this.queue[0]),this._stats.pending--,this.queue.shift(),this._next()})}stats(){return this._stats}status(){return 0===this.queue.length?"done":"in-progress"}}},a=(t,e={})=>{const s=t=>null!=t&&("object"==typeof t||"function"==typeof t)&&"function"==typeof t.then;if("function"!=typeof t&&!s(t)){throw new Error("doPoll: The first argument must be a function or Promise.")}const{msg:r,interval:i=200,timeout:n=1e3,timeoutMsg:l=r??null,signal:a}=e,u=Number.isFinite(i)&&i>0?i:200,c=Number.isFinite(n)&&n>0?n:1e3,h=s(t);let d,p,f,m,g=!1,_=!1,y=!1;const b=()=>{g=!0,d&&clearTimeout(d),p&&clearInterval(p),a&&a.removeEventListener?.("abort",w)},v=t=>{y||(y=!0,b(),f(t))},P=t=>{y||(y=!0,b(),m(t))},j=t=>"__TIMEOUT__"===t&&o(l,"string")?(console.info(l),P(l)):P(t),S=t=>{(o(t,"boolean")||t)&&v(t)},w=()=>j(a?.reason??"aborted");return{promise:new Promise((e,r)=>{f=e,m=r;const i=()=>{if(!(g||_||y)){try{const e=h?t:t(v,j);s(e)?(_=!0,e.then(t=>{_=!1,S(t)}).catch(t=>{_=!1,g||j(t)})):S(e)}catch(t){g||j(t)}}};h||(p=setInterval(i,u)),i(),d=setTimeout(()=>{g||j("__TIMEOUT__")},c),a?.aborted?w():a&&a.addEventListener?.("abort",w,{once:!0})}),stop:j}},u=()=>{let t="not-started";const e={},i=[];let o={completed:0,rejected:0,pending:0,total:0,errors:""};return new class extends s{constructor(){super();const t=this;this._currentPoll=null,setTimeout(()=>{t._poll()},100)}_poll(){const t=this;return this._currentPoll&&this._currentPoll.stop(),this._currentPoll=a(()=>{if(t.isDone()){return!0}},{timeoutMsg:""}),this._currentPoll}clear(){t="not-started",o={completed:0,rejected:0,pending:0,total:0,errors:""},i.length=0,Object.keys(e).forEach(t=>{e[t].rejecter("Promise pool cleared."),delete e[t]}),this._currentPoll=this._poll()}add(s){const l=this;if(!s){return void l._updateStatus()}t="in-progress";r(s).forEach(t=>{if(!(t instanceof Promise)){if("function"!=typeof t){return console.info("---\x3e Invalid promise added to the pool."),void i.push(t.toString())}t=d(()=>t())}o.total++;const s=n();e[s]={status:"in-progress",response:null,error:null,resolver:null,rejecter:null},new Promise((r,n)=>{e[s].resolver=t=>{"rejected"!==e[s].status&&(e[s].status="completed",e[s].response=t,l._updateStatus(),r(t))},e[s].rejecter=t=>{e[s].status="rejected",e[s].error=t,i.push(t),l._updateStatus(),n()},t.then(t=>{e[s]?.resolver(t)}).catch(t=>{e[s]?.rejecter(t)})}).catch(t=>{e[s]?.rejecter(t)})})}status(){return this._updateStatus(),t}isDone(){return this._updateStatus(),"done"===t}isEmpty(){return 0===o.total}results(){return this._updateStatus(),o}stats(){return this.results()}_updateStatus(){if("done"===t){return}const s=Object.values(e);o={completed:s.filter(t=>"completed"===t.status).length,rejected:s.filter(t=>"rejected"===t.status).length,pending:s.filter(t=>"in-progress"===t.status).length,total:s.length,errors:i.join("\n"),promises:e},this.emit("stats",o);const r=s.every(t=>"completed"===t.status||"rejected"===t.status);t=r||0===o.total?"done":"in-progress","done"===t&&(this.emit("done",o),o.total>0&&(this.emit("completed",o),this.emit("rejected",i,o)))}}},c={};function h(t,e,s,...r){let i,n;if("string"==typeof t&&"number"==typeof e){i=t,n=e}else if("number"==typeof t&&"function"==typeof e){n=t,s=e}else{if(e||"string"!=typeof t){throw new Error("Invalid parameters")}i=t}const o=i?"_doTimeout_"+i:null;function l(){o&&o in c&&delete c[o]}if(o&&o in c&&(clearTimeout(c[o]),delete c[o]),"function"==typeof s&&"number"==typeof n){return function t(){c[o]=setTimeout(()=>{!0===s(...r)?t():l()},n)}(),!0}i&&void 0===n&&l()}function d(t,...e){return new Promise((s,r)=>{try{Promise.resolve(t(...e)).then(t=>s(t)).catch(t=>r(t))}catch(t){r(t)}})}window.promises=e})();