@stackone/transport 2.19.0 → 2.19.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/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__commonJSMin=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`redis`);s=__toESM(s);let c=require(`@stackone/expressions`),l=require(`axios`);l=__toESM(l);let u=require(`node:https`);u=__toESM(u);let d=require(`crypto`),f=require(`node:timers`),p=require(`jsonpath-plus`),m=require(`@stackone/redaction`),h=require(`qs`);h=__toESM(h);const createAuthorizationHeaders=e=>{switch(e.type){case`none`:return{};case`basic`:return createBasicAuthorizationHeader(e);case`bearer`:return createBearerAuthorizationHeader(e);case`oauth2`:return createBearerAuthorizationHeader(e);default:throw Error(`Invalid authentication type`)}},createBasicAuthorizationHeader=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n;return{authorization:`Basic ${Buffer.from(`${e}:${t}`).toString(r)}`}},createBearerAuthorizationHeader=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var LockManager=class{constructor(){this.locks=new Map}async withLock(e,t){await this.lock(e);try{return t()}finally{this.unlock(e)}}async lock(e){let t,n=new Promise(e=>t=e),r=this.locks.has(e),i=this.locks.get(e);r&&i?(i.push({lock:n,unlock:t}),await i[i.length-2].lock):this.locks.set(e,[{lock:n,unlock:t}])}unlock(e){let t=this.locks.has(e),n=this.locks.get(e);if(t&&n&&n.length>0){let e=n.shift()?.unlock;e?.()}this.queueLength(e)===0&&this.locks.delete(e)}queueLength(e){return this.locks.get(e)?.length}close(){this.locks.clear()}};const g=1e3,_=100,v=60,y=6e4,b=60,x=y,S=y*10,C=100,w=10;let T=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var MemoryStore=class{constructor(e={}){this.lastAccessedAt=Date.now(),this.config=e,this.initialize(e)}initialize(e=this.config){this.instantiator=e?.instantiator??`Unknown`,this.logger=e?.logger,this.dataStore=e?.dataStore??new Map,this.lockManager=e?.lockManager??new LockManager,this.expiryMap=e?.expiryMap??new Map,this.groupMap=new Map,this.groupExpiryMap=new Map,this.evictionFrequency=e?.evictionFrequency??6e4,this.staleDataThreshold=e?.staleDataThreshold??6e5,this.truncateThreshold=e?.truncateThreshold??100,this.truncationPercentage=e?.truncationPercentage??10,this.typeGuard=e?.typeGuard,this.dispose=e?.dispose,this.startEvictionTask()}async getData(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>this.dataStore.get(e)??null)}async getDataKeysFromGroup(e){this.isReady()||this.initialize(),this.updateLastAccessedAt();let t=this.groupExpiryMap.get(e);return(0,o.notMissing)(t)&&t<=Date.now()?(this.groupMap.delete(e),this.groupExpiryMap.delete(e),[]):Array.from(this.groupMap.get(e)??[])}async setData({key:e,value:t,cacheTTL:n=60,groupKeys:r,groupKeyTTL:i}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),(0,o.notMissing)(this.typeGuard)&&!this.typeGuard(t))return!1;let a=n*g,s=Date.now()+a;if(await this.lockManager.withLock(e,async()=>{((0,o.notMissing)(this.typeGuard)&&this.typeGuard(t)||(0,o.isMissing)(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,s)}),(0,o.notMissing)(r)&&r.length>0){let t=(0,o.notMissing)(i)&&Number.isFinite(i)&&i>0?i*g:void 0;for(let n of r)this.groupMap.has(n)||this.groupMap.set(n,new Set),this.groupMap.get(n)?.add(e),(0,o.notMissing)(t)&&this.groupExpiryMap.set(n,Date.now()+t)}return!0}typeGuardBypass(e){return this.logger?.debug({category:`MemoryStore`,message:`${this.instantiator} MemoryStore setting data without type guard - you should probably configure one`}),!0}async delete(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>{if(this.dispose){let t=this.dataStore.get(e);await this.dispose(e,t)}return this.dataStore.delete(e)})}async pruneExpiredKeys(){let e=this.dataStore.size,t=e>=this.truncateThreshold;if(e<=0)return;let n=[],r=0;return this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/100;(o<=a||t&&r>=0&&r<=s)&&n.push(this.lockManager.withLock(i,async()=>(this.dispose&&await this.dispose(i,e),this.dataStore.delete(i)))),r++}),await Promise.all(n),{dataStoreSize:e,prunedDataStoreSize:this.dataStore.size}}startEvictionTask(){if((0,o.notMissing)(this.evictionInterval))return;let executePrune=async()=>{let e;try{if(this.lastAccessedAt+this.staleDataThreshold<Date.now()){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}e=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}catch(e){e instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:e,code:T.MemoryStorePruneError}),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}finally{if((0,o.notMissing)(e?.dataStoreSize)&&(0,o.notMissing)(e?.prunedDataStoreSize)){let{dataStoreSize:t,prunedDataStoreSize:n}=e,r=t-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&=(clearTimeout(this.evictionInterval),void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return(0,o.notMissing)(this.evictionInterval)&&(0,o.notMissing)(this.dataStore)&&(0,o.notMissing)(this.expiryMap)&&(0,o.notMissing)(this.lockManager)}async setTTL(e,t){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),!this.dataStore.has(e)||!Number.isFinite(t)||t<=0)return!1;let n=t*g;return await this.lockManager.withLock(e,async()=>{this.expiryMap.set(e,Date.now()+n)}),!0}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.groupMap.clear(),this.groupExpiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()).filter(t=>t.includes(e)),i=[],a=t?parseInt(t,10):0;for(let e=a;e<n+a;e++){let t=r[e];if(!t)break;let a=await this.getData(t);if(a&&i.push(a),i.length>=n)break}return{items:i,cursor:i.length<n?void 0:(a+n).toString()}}};const E=1e3,ee=6e4;let D=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var EventClient=class{constructor(e,t,n){this.executorMethodStore=null,this.promiseStore=null,this.eventClientConfig=null,this.executorMethodStoreConfig=null,this.pendingPromiseStoreConfig=null,this.eventClientConfig=e,this.executorMethodStoreConfig=t,this.pendingPromiseStoreConfig=n;let r=e?.instantiator?`${e?.instantiator}(${this.constructor.name})`:this.constructor.name,i={logger:this.logger,dispose:this.defaultExecutorMethodDispose,typeGuard:this.defaultExecutorMethodTypeGuard,...this.executorMethodStoreConfig??{},instantiator:r},a={logger:this.logger,dispose:this.defaultPendingPromiseDispose,typeGuard:this.defaultPendingPromiseTypeGuard,...this.pendingPromiseStoreConfig??{},instantiator:r};this.executorMethodStore=new MemoryStore(i),this.promiseStore=new MemoryStore(a)}async setPendingEvent(e,t){let n={resolve:void 0,reject:void 0},r=new Promise((e,t)=>{n.resolve=e,n.reject=t}),i=t/1e3;await this.executorMethodStore?.setData({key:e,value:n,cacheTTL:i}),await this.promiseStore?.setData({key:e,value:r,cacheTTL:i})}async waitForEvent(e,t){let n=await this.promiseStore?.getData(e);return(0,o.notMissing)(n)?n:(await this.setPendingEvent(e,t),this.getPendingEvent(e))}async getPendingEvent(e){return this.promiseStore?.getData(e)??null}async deleteEvent(e){return(await Promise.all([this.promiseStore?.delete(e),this.executorMethodStore?.delete(e)])).every(Boolean)}async resolveEvent(e,t){try{let n=await this.executorMethodStore?.getData(e);(0,o.isMissing)(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??6e4),n=await this.executorMethodStore?.getData(e)),n?.resolve?.(t)}catch(t){t instanceof Error&&this.logger.error({message:`Error handling event for key ${e}: ${t.message}`,category:this.constructor.name,context:{eventKey:e},error:t,code:D.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){(0,o.notMissing)(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):(0,o.notMissing)(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return(0,o.isObject)(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}},AsyncSingleton=class{constructor(){this.instance=null,this.initPromise=null,this.retryTimeout=null,this.status=`uninitialized`,this.initOptions=null,this.initArgs=[]}getRetryDelay(){return 5e3}getSingleton(e){throw Error(`getSingleton method not implemented`)}async getInstance(e,...t){return this.instance?this.instance:((0,o.isMissing)(this.initPromise)&&(this.initOptions=e??null,this.initArgs=t,this.initPromise=this.init(e??null,...t)),this.initPromise)}getInstanceIfReady(){return this.instance}isReady(){return this.status===`ready`}hasInitFailed(){return this.status===`failed`}async init(e,...t){try{let n=await this.initInstance(e,...t);return this.instance=n,this.status=`ready`,n}catch(e){throw this.status=`failed`,this.initPromise=null,(0,o.isMissing)(this.retryTimeout)&&(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.getInstance(this.initOptions,...this.initArgs).catch(()=>{})},this.getRetryDelay())),e}}reset(){this.instance=null,this.initPromise=null,this.initOptions=null,this.status=`uninitialized`,this.retryTimeout&&clearTimeout(this.retryTimeout),this.retryTimeout=null}};let O=function(e){return e.RedisClientError=`RedisClientError`,e.RedisClientCommandError=`RedisClientCommandError`,e.RedisClientDeleteError=`RedisClientDeleteError`,e.RedisClientInvalidTTL=`RedisClientInvalidTTL`,e.RedisClientListError=`RedisClientListError`,e.RedisClientNotInitialized=`RedisClientNotInitialized`,e.RedisClientPublishError=`RedisClientPublishError`,e.RedisClientReadError=`RedisClientReadError`,e.RedisClientRedisNotReady=`RedisClientRedisNotReady`,e.RedisClientScriptError=`RedisClientScriptError`,e.RedisClientScriptExecuteError=`RedisClientScriptExecuteError`,e.RedisClientScriptLoadError=`RedisClientScriptLoadError`,e.RedisClientSubscribeError=`RedisClientSubscribeError`,e.RedisClientUnsubscribeError=`RedisClientUnsubscribeError`,e.RedisClientWriteError=`RedisClientWriteError`,e}({});const buildRedisClientInstance=async(e,t,n)=>{try{return await te.build(e,t,n)??void 0}catch(e){let r=e;t?.error({message:`Error building Cache Manager`,error:r,code:O.RedisClientError,category:n??`buildRedisClientInstance`});return}};var te=class RedisClient{#e;#t;static async build({getRedisClient:e=s.createClient,host:t,port:n,tls:r,keepAlive:i=3e4,reconnect:a=!0,database:o},c,l){let u=new RedisClient;u.#t=c;try{u.#e=e({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:t,port:n,tls:r,keepAlive:i},database:o,disableOfflineQueue:!0});let s=getDefaultRedisListeners(l??`RedisClient`,u.#t);return addRedisEventHandlers(u.#e,s),await u.#e.connect(),u}catch(e){let t=e;return u.#t?.error({message:`Error building Cache Manager.`,error:t,code:O.RedisClientError,category:l??`RedisClient`}),null}}#n(e){try{return JSON.parse(e)}catch{return e}}async getData(e){if(!this.#i())return null;try{let t=await this.#e.get(e);if(!t)return null;let n=this.#n(t);return(0,o.isString)(n)?t:n}catch(e){let t=e;return this.#t?.error({message:`Error getting data`,error:t,code:O.RedisClientReadError,category:RedisClient.name}),null}}async getDataKeysFromGroup(e){if(!this.#i())return null;try{return await this.#e.sMembers(e)}catch(e){let t=e;return this.#t?.error({message:`Error getting data from group`,error:t,code:O.RedisClientReadError,category:RedisClient.name}),null}}async setData({key:e,value:t,cacheTTL:n,groupKeys:r,groupKeyTTL:i}){if(!this.#i())return!1;try{let a=(0,o.isString)(t)?t:JSON.stringify(t);if(await this.#e.set(e,a,{EX:n}),(0,o.notMissing)(r)&&r.length>0)for(let t of r)await this.#e.sAdd(t,[e]),(0,o.notMissing)(i)&&Number.isFinite(i)&&i>0&&await this.#e.expire(t,i);return!0}catch(e){let t=e;return this.#t?.error({message:`Error setting data`,error:t,code:O.RedisClientWriteError,category:RedisClient.name}),!1}}async setTTL(e,t){if(!this.#i())return!1;if(!Number.isFinite(t)||t<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:O.RedisClientInvalidTTL}),!1;try{let n=await this.#e.expire(e,t);return n||this.#t?.debug({message:`No keys updated for ${e}`,category:RedisClient.name}),n}catch(e){let t=e;return this.#t?.error({message:`Error resetting data TTL`,error:t,code:O.RedisClientWriteError,category:RedisClient.name}),!1}}async executeScript({sha1:e,keys:t,args:n}){if(!this.#i())return null;try{return await this.#e.evalSha(e,{keys:t,arguments:n})}catch(e){let t=e;throw this.#t?.error({message:`Error executing script`,error:t,code:O.RedisClientScriptExecuteError,category:RedisClient.name}),t}}async loadScript(e){if(!this.#i())return null;try{return await this.#e.scriptLoad(e)}catch(e){let t=e;return this.#t?.error({message:`Error loading script`,error:t,code:O.RedisClientScriptLoadError,category:RedisClient.name}),null}}async scriptExists(e){if(!this.#i())return e.map(()=>!1);try{return(await this.#e.scriptExists(e)).map(e=>!!e)}catch(t){let n=t;return this.#t?.error({message:`Error checking script existence`,error:n,code:O.RedisClientScriptError,category:RedisClient.name}),e.map(()=>!1)}}async#r(e,t,n){if(!this.#i())return null;if(!Number.isFinite(n)||n<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:O.RedisClientInvalidTTL}),null;try{let r=[{args:[e,t]},{args:[`expire`,t,n.toString()]}],i=(await this.#e.multiExecutor(r))?.[0];return typeof i==`number`?i:null}catch(t){let n=t;return this.#t?.error({message:`Error executing ${e} operation`,error:n,code:O.RedisClientCommandError,category:RedisClient.name}),null}}async increment(e,t){return this.#r(`incr`,e,t)}async decrement(e,t){return this.#r(`decr`,e,t)}async subscribe(e,t){if(!this.#i())return!1;try{return await this.#e.pSubscribe(e,t),!0}catch(t){let n=t;return this.#t?.error({message:`Error subscribing to ${e}`,error:n,code:O.RedisClientSubscribeError,category:RedisClient.name}),!1}}async unsubscribe(e){if(!this.#i())return!1;try{return await this.#e.pUnsubscribe(e),!0}catch(t){let n=t;return this.#t?.error({message:`Error unsubscribing from ${e}`,error:n,code:O.RedisClientUnsubscribeError,category:RedisClient.name}),!1}}async publish(e,t){if(!this.#i())return null;try{let n=await this.#e.publish(e,t);return n===0&&this.#t?.debug({message:`No subscribers found for channel ${e}`,category:RedisClient.name}),n}catch(t){let n=t;return this.#t?.error({message:`Error publishing to ${e}`,error:n,code:O.RedisClientPublishError,category:RedisClient.name}),null}}getClient(){return this.#i()?this.#e:null}#i(){let e=this.#e.isReady&&this.#e.isOpen;return e||this.#t?.error({message:`Redis Client is not ready.`,category:RedisClient.name,code:O.RedisClientRedisNotReady}),e}async listData({partialKey:e,limit:t,cursor:n}){try{let r=n?parseInt(n,10):0,i=await this.#e.sScan(e,r,{COUNT:t}),a=[];for(let e of i.members){let t=await this.getData(e);(0,o.notMissing)(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(e){let t=e;return this.#t?.error({message:`Error listing data`,error:t,code:O.RedisClientListError,category:RedisClient.name}),{items:null}}}async deleteData(e){try{if(!this.#i())return!1;let t=await this.#e.del(e);return t===0&&this.#t?.debug({message:`No keys deleted for ${e}`,category:RedisClient.name}),t>0}catch(e){let t=e;return this.#t?.error({message:`Error deleting data`,error:t,code:O.RedisClientDeleteError,category:RedisClient.name}),!1}}};const addRedisEventHandlers=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},getDefaultRedisListeners=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:O.RedisClientError,category:e})}},{eventName:`ready`,listener:()=>{t?.info({message:`Redis client ready`,category:e})}},{eventName:`connect`,listener:()=>{t?.info({message:`Redis client connected`,category:e})}},{eventName:`reconnecting`,listener:()=>{t?.info({message:`Redis client reconnecting`,category:e})}},{eventName:`end`,listener:()=>{t?.info({message:`Redis client disconnected`,category:e})}}];let ne=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});const re=1500;var ScriptManager=class extends AsyncSingleton{constructor(...e){super(...e),this.isInitialConnection=!0,this.reloadInProgress=null,this.lastReloadTime=0}async initInstance({redisClientConfig:e=this.redisClientConfig,cacheClient:t=this.cacheClient,scripts:n=this.scripts,scriptMap:r=this.scriptMap,logger:i=this.logger,additionalArgs:a=this.additionalArgs}){let s=t??await buildRedisClientInstance(e,i,this.name);if((0,o.isMissing)(s))throw Error(`Failed to build Redis client`);return this.redisClientConfig=e,this.logger=i,this.cacheClient=s,this.scripts=n,this.scriptMap=r??new Map,this.additionalArgs=a??[],await this.loadScripts(n,r),this.setupReconnectHandler(),await this.additionalInitialization(...a??[]),this}setupReconnectHandler(){let e=this.cacheClient?.getClient?.();(0,o.notMissing)(e)&&(e.on(`ready`,async()=>{this.isInitialConnection?this.isInitialConnection=!1:(this.logger?.info({message:`Redis reconnected - reloading scripts`,category:this.name}),await this.reloadScripts())}),e.on(`end`,()=>{this.logger?.info({message:`Redis connection closed`,category:this.name})}))}async reloadScripts(){if((0,o.notMissing)(this.reloadInProgress))return this.logger?.info({message:`Script reload already in progress, waiting for completion`,category:this.name}),this.reloadInProgress;if(!((0,o.isMissing)(this.scripts)||Object.keys(this.scripts).length===0)){this.reloadInProgress=this.performReload();try{await this.reloadInProgress}finally{this.reloadInProgress=null}}}async performReload(){this.logger?.info({message:`Reloading ${Object.keys(this.scripts).length} scripts after Redis reconnection`,category:this.name}),this.scriptMap.clear(),await this.loadScripts(this.scripts),this.lastReloadTime=Date.now()}async loadScripts(e,t){if((0,o.notMissing)(t))for(let[e,n]of t)this.scriptMap.set(e,n);let n=Object.entries(e),r=n.map(([e])=>this.scriptMap.get(e)).filter(o.notMissing),i=new Map;if(r.length>0&&(0,o.notMissing)(this.cacheClient?.scriptExists)){let e=await this.cacheClient.scriptExists(r);if((0,o.notMissing)(e)){r.forEach((t,n)=>{i.set(t,e[n]??!1)});let t=e.filter(Boolean).length;t>0&&this.logger?.info({message:`${t}/${r.length} scripts already exist in Redis; skipping load for existing scripts`,category:this.name})}}for(let[e,t]of n){let n=this.scriptMap.get(e);if(n&&i.get(n))continue;let r=await this.cacheClient?.loadScript?.(t);(0,o.notMissing)(r)?this.scriptMap?.set(e,r):this.logger?.error({message:`Error loading script ${e}`,category:this.name,code:ne.ScriptManagerLoadingError})}}async executeScript(e,t,n){if(!this.isRedisReady())return this.logger?.warning({message:`Redis not ready, cannot execute script ${e}`,category:this.name,context:{keys:t,args:n}}),null;let r=this.scriptMap?.get(e);if((0,o.isMissing)(r))throw this.logger?.error({message:`Script for ${e} not found in script map`,category:this.name,code:ne.ScriptManagerExecutionError}),Error(`Script for ${e} not found`);try{return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(i){if(i instanceof Error&&i.message.includes(`NOSCRIPT`)){let i=Date.now()-this.lastReloadTime;if(i<re){let t=re-i;this.logger?.info({message:`Script ${e} not found, reload occurred ${i}ms ago. Waiting ${t}ms before reloading`,category:this.name}),await(0,o.delay)(t)}if(this.logger?.info({message:`Script ${e} not found in Redis, reloading scripts`,category:this.name}),await this.reloadScripts(),r=this.scriptMap?.get(e),(0,o.isMissing)(r))throw Error(`Script for ${e} could not be reloaded`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}throw i instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${i.message}`,category:this.name,context:{keys:t,args:n},error:i,code:ne.ScriptManagerExecutionError}),i}}isRedisReady(){let e=this.cacheClient?.getClient?.();if((0,o.notMissing)(this.cacheClient)&&(0,o.isMissing)(e))return this.logger?.warning({message:`Cache client exists but getClient() returned null - cannot verify Redis readiness`,category:this.name}),!1;let t=e?.isReady&&e?.isOpen;return this.isReady()&&(0,o.notMissing)(this.cacheClient)&&(t??!1)}},SubscriptionManager=class{constructor(e){this.options={getCacheClient:buildRedisClientInstance},this.subscriptionMap=null,this.subscriptionClient=null,this.name=`SubscriptionManager`,this.options={...this.options,...e}}async initialize(e=this.options){let{config:t,getCacheClient:n,logger:r}=e;if(this.logger=r,this.subscriptionMap=new MemoryStore({instantiator:`${e?.instantiator}(${this.name})`,evictionFrequency:e?.subscriptionTTL,staleDataThreshold:e?.staleSubscriptionsThreshold,truncateThreshold:e?.truncateThreshold,truncationPercentage:e?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),(0,o.notMissing)(t))this.subscriptionClient=await n?.(t,this.logger,e?.instantiator)??null,this.logger?.info({message:`${this.name} initialized for ${e.instantiator}.`,category:this.name});else throw Error(`SubscriptionManager requires a Redis client configuration.`)}async subscribe(e,t){this.isReady()||await this.initialize(this.options);let n=await this.subscriptionMap?.getData(e),r=(0,o.getContentHash)(t.toString());return await this.subscriptionMap?.setData({key:e,value:r}),n===r?!0:await this.subscriptionClient?.subscribe?.(e,t)??!1}async unsubscribe(e){return this.isReady()||await this.initialize(this.options),this.subscriptionClient?.unsubscribe?.(e)??!1}isReady(){return(0,o.notMissing)(this.subscriptionClient)&&(0,o.notMissing)(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const ie=6e4,ae=15e3,oe=!1,se=6e4,ce=15e3,le=1e4,ue=1;let k=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),A=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});var QueueManager=class extends ScriptManager{constructor(...e){super(...e),this.subscriptionManager=null,this.eventClient=null,this.name=`QueueManager`}async additionalInitialization(){if((0,o.isMissing)(this.redisClientConfig))throw Error(`Redis client configuration is required to initialize QueueManager.`);this.subscriptionManager=new SubscriptionManager({config:this.redisClientConfig,instantiator:this.name,subscriptionTTL:6e4,truncateThreshold:le,truncationPercentage:1}),await this.subscriptionManager?.initialize(),this.eventClient=new EventClient({instantiator:this.name,timeoutResolveValue:!1},{instantiator:this.name,evictionFrequency:ce,truncateThreshold:le,truncationPercentage:1},{instantiator:this.name,evictionFrequency:ce,truncateThreshold:le,truncationPercentage:1}),this.logger?.info({category:this.name,message:`QueueManager initialized.`})}async joinAndWaitTurn(e,t,n,r,i=!0){try{let a=`${e}:${t}`;await this.subscriptionManager?.subscribe(a,async(n,r)=>{if(r.includes(a)&&r.includes(t)){let t=`${e}:${n}`;return this.eventClient?.resolveEvent(t,!0)}});let o=await this.executeScript(n?A.lPush:A.rPush,[e],[t,`60000`])===1;return(!i||!o)&&await this.eventClient?.waitForEvent(a,15e3),await this.eventClient?.deleteEvent(a),await r(e,t)}catch(n){throw n instanceof Error&&this.logger?.error({message:`Error in joinAndWaitTurn`,category:this.name,error:n,code:k.QueueManagerJoinAndWaitTurnError,context:{queueName:e,value:t}}),n}}async pop(e){try{return await this.executeScript(A.lPop,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in pop`,category:this.name,error:t,code:k.QueueManagerPopError,context:{queueName:e}}),t}}async length(e){try{return await this.executeScript(A.llen,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in length`,category:this.name,error:t,code:k.QueueManagerLengthError,context:{queueName:e}}),t}}isReady(){return(0,o.notMissing)(this.subscriptionManager)&&(0,o.notMissing)(this.cacheClient)&&(0,o.notMissing)(this.scriptMap)&&this.scriptMap.size>0}close(){this.subscriptionManager?.close(),this.scriptMap?.clear()}};const de=5,fe=12e4,pe=1e4,me=1,he=60,ge=90,j=`__keyevent@0__:`,_e=`${j}set`,ve=`${j}expire`,M=`${j}expired`,ye=`${j}srem`,be=`config_check_test_key`,xe=[_e,ve,M],Se=1,Ce=2e4,we={mainMaxConcurrency:30};let N=function(e){return e.ConcurrencyManagerInitializationError=`ConcurrencyManagerInitializationError`,e.ConcurrencyManagerRedisEventsEmitError=`ConcurrencyManagerRedisEventsEmitError`,e.ConcurrencyManagerRegistrationFailed=`ConcurrencyManagerRegistrationFailed`,e.ConcurrencyManagerPublishNextItemFailed=`ConcurrencyManagerPublishNextItemFailed`,e.ConcurrencyManagerReleaseRequestFailed=`ConcurrencyManagerReleaseRequestFailed`,e}({}),P=function(e){return e.tryConcurrency=`tryConcurrency`,e.removeFromSet=`removeFromSet`,e.publishNextItem=`publishNextItem`,e}({});const Te={[P.tryConcurrency]:`
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,__name=(e,n)=>t(e,`name`,{value:n,configurable:!0}),n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,__commonJSMin=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),__copyProps=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},__toESM=(n,r,a)=>(a=n==null?{}:e(i(n)),__copyProps(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let o=require(`@stackone/utils`),s=require(`redis`);s=__toESM(s);let c=require(`@stackone/expressions`),l=require(`axios`);l=__toESM(l);let u=require(`node:https`);u=__toESM(u);let d=require(`crypto`),f=require(`node:timers`),p=require(`jsonpath-plus`),m=require(`@stackone/redaction`),h=require(`qs`);h=__toESM(h);const createAuthorizationHeaders=e=>{switch(e.type){case`none`:return{};case`basic`:return createBasicAuthorizationHeader(e);case`bearer`:return createBearerAuthorizationHeader(e);case`oauth2`:return createBearerAuthorizationHeader(e);default:throw Error(`Invalid authentication type`)}},createBasicAuthorizationHeader=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n;return{authorization:`Basic ${Buffer.from(`${e}:${t}`).toString(r)}`}},createBearerAuthorizationHeader=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var LockManager=class{constructor(){this.locks=new Map}async withLock(e,t){await this.lock(e);try{return t()}finally{this.unlock(e)}}async lock(e){let t,n=new Promise(e=>t=e),r=this.locks.has(e),i=this.locks.get(e);r&&i?(i.push({lock:n,unlock:t}),await i[i.length-2].lock):this.locks.set(e,[{lock:n,unlock:t}])}unlock(e){let t=this.locks.has(e),n=this.locks.get(e);if(t&&n&&n.length>0){let e=n.shift()?.unlock;e?.()}this.queueLength(e)===0&&this.locks.delete(e)}queueLength(e){return this.locks.get(e)?.length}close(){this.locks.clear()}};const g=1e3,_=100,v=60,y=6e4,b=60,x=y,S=y*10,C=100,w=10;let T=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var MemoryStore=class{constructor(e={}){this.lastAccessedAt=Date.now(),this.config=e,this.initialize(e)}initialize(e=this.config){this.instantiator=e?.instantiator??`Unknown`,this.logger=e?.logger,this.dataStore=e?.dataStore??new Map,this.lockManager=e?.lockManager??new LockManager,this.expiryMap=e?.expiryMap??new Map,this.groupMap=new Map,this.groupExpiryMap=new Map,this.evictionFrequency=e?.evictionFrequency??6e4,this.staleDataThreshold=e?.staleDataThreshold??6e5,this.truncateThreshold=e?.truncateThreshold??100,this.truncationPercentage=e?.truncationPercentage??10,this.typeGuard=e?.typeGuard,this.dispose=e?.dispose,this.startEvictionTask()}async getData(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>this.dataStore.get(e)??null)}async getDataKeysFromGroup(e){this.isReady()||this.initialize(),this.updateLastAccessedAt();let t=this.groupExpiryMap.get(e);return(0,o.notMissing)(t)&&t<=Date.now()?(this.groupMap.delete(e),this.groupExpiryMap.delete(e),[]):Array.from(this.groupMap.get(e)??[])}async setData({key:e,value:t,cacheTTL:n=60,groupKeys:r,groupKeyTTL:i}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),(0,o.notMissing)(this.typeGuard)&&!this.typeGuard(t))return!1;let a=n*g,s=Date.now()+a;if(await this.lockManager.withLock(e,async()=>{((0,o.notMissing)(this.typeGuard)&&this.typeGuard(t)||(0,o.isMissing)(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,s)}),(0,o.notMissing)(r)&&r.length>0){let t=(0,o.notMissing)(i)&&Number.isFinite(i)&&i>0?i*g:void 0;for(let n of r)this.groupMap.has(n)||this.groupMap.set(n,new Set),this.groupMap.get(n)?.add(e),(0,o.notMissing)(t)&&this.groupExpiryMap.set(n,Date.now()+t)}return!0}typeGuardBypass(e){return this.logger?.debug({category:`MemoryStore`,message:`${this.instantiator} MemoryStore setting data without type guard - you should probably configure one`}),!0}async delete(e,t){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>{if(this.dispose){let t=this.dataStore.get(e);await this.dispose(e,t)}if((0,o.notMissing)(t)&&t.length>0)for(let n of t)this.groupMap.get(n)?.delete(e);return this.dataStore.delete(e)})}async pruneExpiredKeys(){let e=this.dataStore.size,t=e>=this.truncateThreshold;if(e<=0)return;let n=[],r=0;return this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/100;(o<=a||t&&r>=0&&r<=s)&&n.push(this.lockManager.withLock(i,async()=>(this.dispose&&await this.dispose(i,e),this.dataStore.delete(i)))),r++}),await Promise.all(n),{dataStoreSize:e,prunedDataStoreSize:this.dataStore.size}}startEvictionTask(){if((0,o.notMissing)(this.evictionInterval))return;let executePrune=async()=>{let e;try{if(this.lastAccessedAt+this.staleDataThreshold<Date.now()){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}e=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}catch(e){e instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:e,code:T.MemoryStorePruneError}),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}finally{if((0,o.notMissing)(e?.dataStoreSize)&&(0,o.notMissing)(e?.prunedDataStoreSize)){let{dataStoreSize:t,prunedDataStoreSize:n}=e,r=t-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&=(clearTimeout(this.evictionInterval),void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return(0,o.notMissing)(this.evictionInterval)&&(0,o.notMissing)(this.dataStore)&&(0,o.notMissing)(this.expiryMap)&&(0,o.notMissing)(this.lockManager)}async setTTL(e,t){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),!this.dataStore.has(e)||!Number.isFinite(t)||t<=0)return!1;let n=t*g;return await this.lockManager.withLock(e,async()=>{this.expiryMap.set(e,Date.now()+n)}),!0}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.groupMap.clear(),this.groupExpiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()).filter(t=>t.includes(e)),i=[],a=t?parseInt(t,10):0;for(let e=a;e<n+a;e++){let t=r[e];if(!t)break;let a=await this.getData(t);if(a&&i.push(a),i.length>=n)break}return{items:i,cursor:i.length<n?void 0:(a+n).toString()}}};const E=1e3,ee=6e4;let D=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var EventClient=class{constructor(e,t,n){this.executorMethodStore=null,this.promiseStore=null,this.eventClientConfig=null,this.executorMethodStoreConfig=null,this.pendingPromiseStoreConfig=null,this.eventClientConfig=e,this.executorMethodStoreConfig=t,this.pendingPromiseStoreConfig=n;let r=e?.instantiator?`${e?.instantiator}(${this.constructor.name})`:this.constructor.name,i={logger:this.logger,dispose:this.defaultExecutorMethodDispose,typeGuard:this.defaultExecutorMethodTypeGuard,...this.executorMethodStoreConfig??{},instantiator:r},a={logger:this.logger,dispose:this.defaultPendingPromiseDispose,typeGuard:this.defaultPendingPromiseTypeGuard,...this.pendingPromiseStoreConfig??{},instantiator:r};this.executorMethodStore=new MemoryStore(i),this.promiseStore=new MemoryStore(a)}async setPendingEvent(e,t){let n={resolve:void 0,reject:void 0},r=new Promise((e,t)=>{n.resolve=e,n.reject=t}),i=t/1e3;await this.executorMethodStore?.setData({key:e,value:n,cacheTTL:i}),await this.promiseStore?.setData({key:e,value:r,cacheTTL:i})}async waitForEvent(e,t){let n=await this.promiseStore?.getData(e);return(0,o.notMissing)(n)?n:(await this.setPendingEvent(e,t),this.getPendingEvent(e))}async getPendingEvent(e){return this.promiseStore?.getData(e)??null}async deleteEvent(e){return(await Promise.all([this.promiseStore?.delete(e),this.executorMethodStore?.delete(e)])).every(Boolean)}async resolveEvent(e,t){try{let n=await this.executorMethodStore?.getData(e);(0,o.isMissing)(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??6e4),n=await this.executorMethodStore?.getData(e)),n?.resolve?.(t)}catch(t){t instanceof Error&&this.logger.error({message:`Error handling event for key ${e}: ${t.message}`,category:this.constructor.name,context:{eventKey:e},error:t,code:D.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){(0,o.notMissing)(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):(0,o.notMissing)(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return(0,o.isObject)(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}},AsyncSingleton=class{constructor(){this.instance=null,this.initPromise=null,this.retryTimeout=null,this.status=`uninitialized`,this.initOptions=null,this.initArgs=[]}getRetryDelay(){return 5e3}getSingleton(e){throw Error(`getSingleton method not implemented`)}async getInstance(e,...t){return this.instance?this.instance:((0,o.isMissing)(this.initPromise)&&(this.initOptions=e??null,this.initArgs=t,this.initPromise=this.init(e??null,...t)),this.initPromise)}getInstanceIfReady(){return this.instance}isReady(){return this.status===`ready`}hasInitFailed(){return this.status===`failed`}async init(e,...t){try{let n=await this.initInstance(e,...t);return this.instance=n,this.status=`ready`,n}catch(e){throw this.status=`failed`,this.initPromise=null,(0,o.isMissing)(this.retryTimeout)&&(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.getInstance(this.initOptions,...this.initArgs).catch(()=>{})},this.getRetryDelay())),e}}reset(){this.instance=null,this.initPromise=null,this.initOptions=null,this.status=`uninitialized`,this.retryTimeout&&clearTimeout(this.retryTimeout),this.retryTimeout=null}};let O=function(e){return e.RedisClientError=`RedisClientError`,e.RedisClientCommandError=`RedisClientCommandError`,e.RedisClientDeleteError=`RedisClientDeleteError`,e.RedisClientInvalidTTL=`RedisClientInvalidTTL`,e.RedisClientListError=`RedisClientListError`,e.RedisClientNotInitialized=`RedisClientNotInitialized`,e.RedisClientPublishError=`RedisClientPublishError`,e.RedisClientReadError=`RedisClientReadError`,e.RedisClientRedisNotReady=`RedisClientRedisNotReady`,e.RedisClientScriptError=`RedisClientScriptError`,e.RedisClientScriptExecuteError=`RedisClientScriptExecuteError`,e.RedisClientScriptLoadError=`RedisClientScriptLoadError`,e.RedisClientSubscribeError=`RedisClientSubscribeError`,e.RedisClientUnsubscribeError=`RedisClientUnsubscribeError`,e.RedisClientWriteError=`RedisClientWriteError`,e}({});const buildRedisClientInstance=async(e,t,n)=>{try{return await te.build(e,t,n)??void 0}catch(e){let r=e;t?.error({message:`Error building Cache Manager`,error:r,code:O.RedisClientError,category:n??`buildRedisClientInstance`});return}};var te=class RedisClient{#e;#t;static async build({getRedisClient:e=s.createClient,host:t,port:n,tls:r,keepAlive:i=3e4,reconnect:a=!0,database:o},c,l){let u=new RedisClient;u.#t=c;try{u.#e=e({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:t,port:n,tls:r,keepAlive:i},database:o,disableOfflineQueue:!0});let s=getDefaultRedisListeners(l??`RedisClient`,u.#t);return addRedisEventHandlers(u.#e,s),await u.#e.connect(),u}catch(e){let t=e;return u.#t?.error({message:`Error building Cache Manager.`,error:t,code:O.RedisClientError,category:l??`RedisClient`}),null}}#n(e){try{return JSON.parse(e)}catch{return e}}async getData(e){if(!this.#i())return null;try{let t=await this.#e.get(e);if(!t)return null;let n=this.#n(t);return(0,o.isString)(n)?t:n}catch(e){let t=e;return this.#t?.error({message:`Error getting data`,error:t,code:O.RedisClientReadError,category:RedisClient.name}),null}}async getDataKeysFromGroup(e){if(!this.#i())return null;try{return await this.#e.sMembers(e)}catch(e){let t=e;return this.#t?.error({message:`Error getting data from group`,error:t,code:O.RedisClientReadError,category:RedisClient.name}),null}}async setData({key:e,value:t,cacheTTL:n,groupKeys:r,groupKeyTTL:i}){if(!this.#i())return!1;try{let a=(0,o.isString)(t)?t:JSON.stringify(t);if(await this.#e.set(e,a,{EX:n}),(0,o.notMissing)(r)&&r.length>0)for(let t of r)await this.#e.sAdd(t,[e]),(0,o.notMissing)(i)&&Number.isFinite(i)&&i>0&&await this.#e.expire(t,i);return!0}catch(e){let t=e;return this.#t?.error({message:`Error setting data`,error:t,code:O.RedisClientWriteError,category:RedisClient.name}),!1}}async setTTL(e,t){if(!this.#i())return!1;if(!Number.isFinite(t)||t<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:O.RedisClientInvalidTTL}),!1;try{let n=await this.#e.expire(e,t);return n||this.#t?.debug({message:`No keys updated for ${e}`,category:RedisClient.name}),n}catch(e){let t=e;return this.#t?.error({message:`Error resetting data TTL`,error:t,code:O.RedisClientWriteError,category:RedisClient.name}),!1}}async executeScript({sha1:e,keys:t,args:n}){if(!this.#i())return null;try{return await this.#e.evalSha(e,{keys:t,arguments:n})}catch(e){let t=e;throw this.#t?.error({message:`Error executing script`,error:t,code:O.RedisClientScriptExecuteError,category:RedisClient.name}),t}}async loadScript(e){if(!this.#i())return null;try{return await this.#e.scriptLoad(e)}catch(e){let t=e;return this.#t?.error({message:`Error loading script`,error:t,code:O.RedisClientScriptLoadError,category:RedisClient.name}),null}}async scriptExists(e){if(!this.#i())return e.map(()=>!1);try{return(await this.#e.scriptExists(e)).map(e=>!!e)}catch(t){let n=t;return this.#t?.error({message:`Error checking script existence`,error:n,code:O.RedisClientScriptError,category:RedisClient.name}),e.map(()=>!1)}}async#r(e,t,n){if(!this.#i())return null;if(!Number.isFinite(n)||n<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:O.RedisClientInvalidTTL}),null;try{let r=[{args:[e,t]},{args:[`expire`,t,n.toString()]}],i=(await this.#e.multiExecutor(r))?.[0];return typeof i==`number`?i:null}catch(t){let n=t;return this.#t?.error({message:`Error executing ${e} operation`,error:n,code:O.RedisClientCommandError,category:RedisClient.name}),null}}async increment(e,t){return this.#r(`incr`,e,t)}async decrement(e,t){return this.#r(`decr`,e,t)}async subscribe(e,t){if(!this.#i())return!1;try{return await this.#e.pSubscribe(e,t),!0}catch(t){let n=t;return this.#t?.error({message:`Error subscribing to ${e}`,error:n,code:O.RedisClientSubscribeError,category:RedisClient.name}),!1}}async unsubscribe(e){if(!this.#i())return!1;try{return await this.#e.pUnsubscribe(e),!0}catch(t){let n=t;return this.#t?.error({message:`Error unsubscribing from ${e}`,error:n,code:O.RedisClientUnsubscribeError,category:RedisClient.name}),!1}}async publish(e,t){if(!this.#i())return null;try{let n=await this.#e.publish(e,t);return n===0&&this.#t?.debug({message:`No subscribers found for channel ${e}`,category:RedisClient.name}),n}catch(t){let n=t;return this.#t?.error({message:`Error publishing to ${e}`,error:n,code:O.RedisClientPublishError,category:RedisClient.name}),null}}getClient(){return this.#i()?this.#e:null}#i(){let e=this.#e.isReady&&this.#e.isOpen;return e||this.#t?.error({message:`Redis Client is not ready.`,category:RedisClient.name,code:O.RedisClientRedisNotReady}),e}async listData({partialKey:e,limit:t,cursor:n}){try{let r=n?parseInt(n,10):0,i=await this.#e.sScan(e,r,{COUNT:t}),a=[];for(let e of i.members){let t=await this.getData(e);(0,o.notMissing)(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(e){let t=e;return this.#t?.error({message:`Error listing data`,error:t,code:O.RedisClientListError,category:RedisClient.name}),{items:null}}}async deleteData(e,t){try{if(!this.#i())return!1;let n=await this.#e.del(e);return n===0&&this.#t?.debug({message:`No keys deleted for ${e}`,category:RedisClient.name}),(0,o.notMissing)(t)&&t.length>0&&(await Promise.allSettled(t.map(t=>this.#e.sRem(t,e)))).forEach((e,n)=>{e.status===`rejected`&&this.#t?.error({message:`Error removing key from group set ${t[n]}`,error:e.reason,code:O.RedisClientDeleteError,category:RedisClient.name})}),n>0}catch(e){let t=e;return this.#t?.error({message:`Error deleting data`,error:t,code:O.RedisClientDeleteError,category:RedisClient.name}),!1}}};const addRedisEventHandlers=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},getDefaultRedisListeners=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:O.RedisClientError,category:e})}},{eventName:`ready`,listener:()=>{t?.info({message:`Redis client ready`,category:e})}},{eventName:`connect`,listener:()=>{t?.info({message:`Redis client connected`,category:e})}},{eventName:`reconnecting`,listener:()=>{t?.info({message:`Redis client reconnecting`,category:e})}},{eventName:`end`,listener:()=>{t?.info({message:`Redis client disconnected`,category:e})}}];let ne=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});const re=1500;var ScriptManager=class extends AsyncSingleton{constructor(...e){super(...e),this.isInitialConnection=!0,this.reloadInProgress=null,this.lastReloadTime=0}async initInstance({redisClientConfig:e=this.redisClientConfig,cacheClient:t=this.cacheClient,scripts:n=this.scripts,scriptMap:r=this.scriptMap,logger:i=this.logger,additionalArgs:a=this.additionalArgs}){let s=t??await buildRedisClientInstance(e,i,this.name);if((0,o.isMissing)(s))throw Error(`Failed to build Redis client`);return this.redisClientConfig=e,this.logger=i,this.cacheClient=s,this.scripts=n,this.scriptMap=r??new Map,this.additionalArgs=a??[],await this.loadScripts(n,r),this.setupReconnectHandler(),await this.additionalInitialization(...a??[]),this}setupReconnectHandler(){let e=this.cacheClient?.getClient?.();(0,o.notMissing)(e)&&(e.on(`ready`,async()=>{this.isInitialConnection?this.isInitialConnection=!1:(this.logger?.info({message:`Redis reconnected - reloading scripts`,category:this.name}),await this.reloadScripts())}),e.on(`end`,()=>{this.logger?.info({message:`Redis connection closed`,category:this.name})}))}async reloadScripts(){if((0,o.notMissing)(this.reloadInProgress))return this.logger?.info({message:`Script reload already in progress, waiting for completion`,category:this.name}),this.reloadInProgress;if(!((0,o.isMissing)(this.scripts)||Object.keys(this.scripts).length===0)){this.reloadInProgress=this.performReload();try{await this.reloadInProgress}finally{this.reloadInProgress=null}}}async performReload(){this.logger?.info({message:`Reloading ${Object.keys(this.scripts).length} scripts after Redis reconnection`,category:this.name}),this.scriptMap.clear(),await this.loadScripts(this.scripts),this.lastReloadTime=Date.now()}async loadScripts(e,t){if((0,o.notMissing)(t))for(let[e,n]of t)this.scriptMap.set(e,n);let n=Object.entries(e),r=n.map(([e])=>this.scriptMap.get(e)).filter(o.notMissing),i=new Map;if(r.length>0&&(0,o.notMissing)(this.cacheClient?.scriptExists)){let e=await this.cacheClient.scriptExists(r);if((0,o.notMissing)(e)){r.forEach((t,n)=>{i.set(t,e[n]??!1)});let t=e.filter(Boolean).length;t>0&&this.logger?.info({message:`${t}/${r.length} scripts already exist in Redis; skipping load for existing scripts`,category:this.name})}}for(let[e,t]of n){let n=this.scriptMap.get(e);if(n&&i.get(n))continue;let r=await this.cacheClient?.loadScript?.(t);(0,o.notMissing)(r)?this.scriptMap?.set(e,r):this.logger?.error({message:`Error loading script ${e}`,category:this.name,code:ne.ScriptManagerLoadingError})}}async executeScript(e,t,n){if(!this.isRedisReady())return this.logger?.warning({message:`Redis not ready, cannot execute script ${e}`,category:this.name,context:{keys:t,args:n}}),null;let r=this.scriptMap?.get(e);if((0,o.isMissing)(r))throw this.logger?.error({message:`Script for ${e} not found in script map`,category:this.name,code:ne.ScriptManagerExecutionError}),Error(`Script for ${e} not found`);try{return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(i){if(i instanceof Error&&i.message.includes(`NOSCRIPT`)){let i=Date.now()-this.lastReloadTime;if(i<re){let t=re-i;this.logger?.info({message:`Script ${e} not found, reload occurred ${i}ms ago. Waiting ${t}ms before reloading`,category:this.name}),await(0,o.delay)(t)}if(this.logger?.info({message:`Script ${e} not found in Redis, reloading scripts`,category:this.name}),await this.reloadScripts(),r=this.scriptMap?.get(e),(0,o.isMissing)(r))throw Error(`Script for ${e} could not be reloaded`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}throw i instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${i.message}`,category:this.name,context:{keys:t,args:n},error:i,code:ne.ScriptManagerExecutionError}),i}}isRedisReady(){let e=this.cacheClient?.getClient?.();if((0,o.notMissing)(this.cacheClient)&&(0,o.isMissing)(e))return this.logger?.warning({message:`Cache client exists but getClient() returned null - cannot verify Redis readiness`,category:this.name}),!1;let t=e?.isReady&&e?.isOpen;return this.isReady()&&(0,o.notMissing)(this.cacheClient)&&(t??!1)}},SubscriptionManager=class{constructor(e){this.options={getCacheClient:buildRedisClientInstance},this.subscriptionMap=null,this.subscriptionClient=null,this.name=`SubscriptionManager`,this.options={...this.options,...e}}async initialize(e=this.options){let{config:t,getCacheClient:n,logger:r}=e;if(this.logger=r,this.subscriptionMap=new MemoryStore({instantiator:`${e?.instantiator}(${this.name})`,evictionFrequency:e?.subscriptionTTL,staleDataThreshold:e?.staleSubscriptionsThreshold,truncateThreshold:e?.truncateThreshold,truncationPercentage:e?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),(0,o.notMissing)(t))this.subscriptionClient=await n?.(t,this.logger,e?.instantiator)??null,this.logger?.info({message:`${this.name} initialized for ${e.instantiator}.`,category:this.name});else throw Error(`SubscriptionManager requires a Redis client configuration.`)}async subscribe(e,t){this.isReady()||await this.initialize(this.options);let n=await this.subscriptionMap?.getData(e),r=(0,o.getContentHash)(t.toString());return await this.subscriptionMap?.setData({key:e,value:r}),n===r?!0:await this.subscriptionClient?.subscribe?.(e,t)??!1}async unsubscribe(e){return this.isReady()||await this.initialize(this.options),this.subscriptionClient?.unsubscribe?.(e)??!1}isReady(){return(0,o.notMissing)(this.subscriptionClient)&&(0,o.notMissing)(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const ie=6e4,ae=15e3,oe=!1,se=6e4,ce=15e3,le=1e4,ue=1;let k=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),A=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});var QueueManager=class extends ScriptManager{constructor(...e){super(...e),this.subscriptionManager=null,this.eventClient=null,this.name=`QueueManager`}async additionalInitialization(){if((0,o.isMissing)(this.redisClientConfig))throw Error(`Redis client configuration is required to initialize QueueManager.`);this.subscriptionManager=new SubscriptionManager({config:this.redisClientConfig,instantiator:this.name,subscriptionTTL:6e4,truncateThreshold:le,truncationPercentage:1}),await this.subscriptionManager?.initialize(),this.eventClient=new EventClient({instantiator:this.name,timeoutResolveValue:!1},{instantiator:this.name,evictionFrequency:ce,truncateThreshold:le,truncationPercentage:1},{instantiator:this.name,evictionFrequency:ce,truncateThreshold:le,truncationPercentage:1}),this.logger?.info({category:this.name,message:`QueueManager initialized.`})}async joinAndWaitTurn(e,t,n,r,i=!0){try{let a=`${e}:${t}`;await this.subscriptionManager?.subscribe(a,async(n,r)=>{if(r.includes(a)&&r.includes(t)){let t=`${e}:${n}`;return this.eventClient?.resolveEvent(t,!0)}});let o=await this.executeScript(n?A.lPush:A.rPush,[e],[t,`60000`])===1;return(!i||!o)&&await this.eventClient?.waitForEvent(a,15e3),await this.eventClient?.deleteEvent(a),await r(e,t)}catch(n){throw n instanceof Error&&this.logger?.error({message:`Error in joinAndWaitTurn`,category:this.name,error:n,code:k.QueueManagerJoinAndWaitTurnError,context:{queueName:e,value:t}}),n}}async pop(e){try{return await this.executeScript(A.lPop,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in pop`,category:this.name,error:t,code:k.QueueManagerPopError,context:{queueName:e}}),t}}async length(e){try{return await this.executeScript(A.llen,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in length`,category:this.name,error:t,code:k.QueueManagerLengthError,context:{queueName:e}}),t}}isReady(){return(0,o.notMissing)(this.subscriptionManager)&&(0,o.notMissing)(this.cacheClient)&&(0,o.notMissing)(this.scriptMap)&&this.scriptMap.size>0}close(){this.subscriptionManager?.close(),this.scriptMap?.clear()}};const de=5,fe=12e4,pe=1e4,me=1,he=60,ge=90,j=`__keyevent@0__:`,_e=`${j}set`,ve=`${j}expire`,M=`${j}expired`,ye=`${j}srem`,be=`config_check_test_key`,xe=[_e,ve,M],Se=1,Ce=2e4,we={mainMaxConcurrency:30};let N=function(e){return e.ConcurrencyManagerInitializationError=`ConcurrencyManagerInitializationError`,e.ConcurrencyManagerRedisEventsEmitError=`ConcurrencyManagerRedisEventsEmitError`,e.ConcurrencyManagerRegistrationFailed=`ConcurrencyManagerRegistrationFailed`,e.ConcurrencyManagerPublishNextItemFailed=`ConcurrencyManagerPublishNextItemFailed`,e.ConcurrencyManagerReleaseRequestFailed=`ConcurrencyManagerReleaseRequestFailed`,e}({}),P=function(e){return e.tryConcurrency=`tryConcurrency`,e.removeFromSet=`removeFromSet`,e.publishNextItem=`publishNextItem`,e}({});const Te={[P.tryConcurrency]:`
|
|
2
2
|
local requestId = KEYS[1]
|
|
3
3
|
local targetKey = KEYS[2]
|
|
4
4
|
local queueKey = KEYS[3]
|
package/dist/index.d.cts
CHANGED
|
@@ -161,7 +161,7 @@ interface ICacheClient<ClientType = unknown> {
|
|
|
161
161
|
unsubscribe?(pattern: string): Promise<boolean>;
|
|
162
162
|
publish?(channel: string, message: string): Promise<number | null>;
|
|
163
163
|
getClient?(): ClientType | null;
|
|
164
|
-
deleteData?(key: string): Promise<boolean>;
|
|
164
|
+
deleteData?(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
165
165
|
close?(): Promise<void> | void;
|
|
166
166
|
}
|
|
167
167
|
type PubSubListener<ReturnsBuffer extends boolean = false> = <T extends (ReturnsBuffer extends true ? Buffer : string)>(message: T, channel: T) => unknown;
|
|
@@ -237,7 +237,7 @@ declare class RedisClient implements ICacheClient<RedisClientType> {
|
|
|
237
237
|
items: T[] | null;
|
|
238
238
|
cursor?: string;
|
|
239
239
|
}>;
|
|
240
|
-
deleteData(key: string): Promise<boolean>;
|
|
240
|
+
deleteData(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
241
241
|
}
|
|
242
242
|
//#endregion
|
|
243
243
|
//#region src/scriptManager/types.d.ts
|
|
@@ -981,7 +981,7 @@ declare class MemoryStore<T> implements ICacheClient {
|
|
|
981
981
|
groupKeyTTL?: number;
|
|
982
982
|
}): Promise<boolean>;
|
|
983
983
|
private typeGuardBypass;
|
|
984
|
-
delete(key: string): Promise<boolean>;
|
|
984
|
+
delete(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
985
985
|
pruneExpiredKeys(): Promise<PruneCount | undefined>;
|
|
986
986
|
private startEvictionTask;
|
|
987
987
|
private stopEvictionTask;
|
package/dist/index.d.mts
CHANGED
|
@@ -160,7 +160,7 @@ interface ICacheClient<ClientType = unknown> {
|
|
|
160
160
|
unsubscribe?(pattern: string): Promise<boolean>;
|
|
161
161
|
publish?(channel: string, message: string): Promise<number | null>;
|
|
162
162
|
getClient?(): ClientType | null;
|
|
163
|
-
deleteData?(key: string): Promise<boolean>;
|
|
163
|
+
deleteData?(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
164
164
|
close?(): Promise<void> | void;
|
|
165
165
|
}
|
|
166
166
|
type PubSubListener<ReturnsBuffer extends boolean = false> = <T extends (ReturnsBuffer extends true ? Buffer : string)>(message: T, channel: T) => unknown;
|
|
@@ -236,7 +236,7 @@ declare class RedisClient implements ICacheClient<RedisClientType> {
|
|
|
236
236
|
items: T[] | null;
|
|
237
237
|
cursor?: string;
|
|
238
238
|
}>;
|
|
239
|
-
deleteData(key: string): Promise<boolean>;
|
|
239
|
+
deleteData(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
240
240
|
}
|
|
241
241
|
//#endregion
|
|
242
242
|
//#region src/scriptManager/types.d.ts
|
|
@@ -980,7 +980,7 @@ declare class MemoryStore<T> implements ICacheClient {
|
|
|
980
980
|
groupKeyTTL?: number;
|
|
981
981
|
}): Promise<boolean>;
|
|
982
982
|
private typeGuardBypass;
|
|
983
|
-
delete(key: string): Promise<boolean>;
|
|
983
|
+
delete(key: string, groupKeys?: string[]): Promise<boolean>;
|
|
984
984
|
pruneExpiredKeys(): Promise<PruneCount | undefined>;
|
|
985
985
|
private startEvictionTask;
|
|
986
986
|
private stopEvictionTask;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,r as t,t as n}from"./chunk-hhuvQGXm.mjs";import{delay as r,exponentialBackoffInMS as i,generateRequestId as a,getContentHash as o,isFunction as s,isFutureUnixTimestamp as c,isMissing as l,isNumber as u,isObject as d,isString as f,notMissing as p,z as m,zStrictObject as h}from"@stackone/utils";import*as g from"redis";import{evaluate as _,safeEvaluate as v}from"@stackone/expressions";import y,{isAxiosError as b}from"axios";import x from"node:https";import{randomUUID as S}from"crypto";import{clearTimeout as C}from"node:timers";import{JSONPath as w}from"jsonpath-plus";import{redactUrl as T}from"@stackone/redaction";import E from"qs";const createAuthorizationHeaders=e=>{switch(e.type){case`none`:return{};case`basic`:return createBasicAuthorizationHeader(e);case`bearer`:return createBearerAuthorizationHeader(e);case`oauth2`:return createBearerAuthorizationHeader(e);default:throw Error(`Invalid authentication type`)}},createBasicAuthorizationHeader=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n;return{authorization:`Basic ${Buffer.from(`${e}:${t}`).toString(r)}`}},createBearerAuthorizationHeader=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var LockManager=class{constructor(){this.locks=new Map}async withLock(e,t){await this.lock(e);try{return t()}finally{this.unlock(e)}}async lock(e){let t,n=new Promise(e=>t=e),r=this.locks.has(e),i=this.locks.get(e);r&&i?(i.push({lock:n,unlock:t}),await i[i.length-2].lock):this.locks.set(e,[{lock:n,unlock:t}])}unlock(e){let t=this.locks.has(e),n=this.locks.get(e);if(t&&n&&n.length>0){let e=n.shift()?.unlock;e?.()}this.queueLength(e)===0&&this.locks.delete(e)}queueLength(e){return this.locks.get(e)?.length}close(){this.locks.clear()}};const D=1e3;let O=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var MemoryStore=class{constructor(e={}){this.lastAccessedAt=Date.now(),this.config=e,this.initialize(e)}initialize(e=this.config){this.instantiator=e?.instantiator??`Unknown`,this.logger=e?.logger,this.dataStore=e?.dataStore??new Map,this.lockManager=e?.lockManager??new LockManager,this.expiryMap=e?.expiryMap??new Map,this.groupMap=new Map,this.groupExpiryMap=new Map,this.evictionFrequency=e?.evictionFrequency??6e4,this.staleDataThreshold=e?.staleDataThreshold??6e5,this.truncateThreshold=e?.truncateThreshold??100,this.truncationPercentage=e?.truncationPercentage??10,this.typeGuard=e?.typeGuard,this.dispose=e?.dispose,this.startEvictionTask()}async getData(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>this.dataStore.get(e)??null)}async getDataKeysFromGroup(e){this.isReady()||this.initialize(),this.updateLastAccessedAt();let t=this.groupExpiryMap.get(e);return p(t)&&t<=Date.now()?(this.groupMap.delete(e),this.groupExpiryMap.delete(e),[]):Array.from(this.groupMap.get(e)??[])}async setData({key:e,value:t,cacheTTL:n=60,groupKeys:r,groupKeyTTL:i}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),p(this.typeGuard)&&!this.typeGuard(t))return!1;let a=n*D,o=Date.now()+a;if(await this.lockManager.withLock(e,async()=>{(p(this.typeGuard)&&this.typeGuard(t)||l(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,o)}),p(r)&&r.length>0){let t=p(i)&&Number.isFinite(i)&&i>0?i*D:void 0;for(let n of r)this.groupMap.has(n)||this.groupMap.set(n,new Set),this.groupMap.get(n)?.add(e),p(t)&&this.groupExpiryMap.set(n,Date.now()+t)}return!0}typeGuardBypass(e){return this.logger?.debug({category:`MemoryStore`,message:`${this.instantiator} MemoryStore setting data without type guard - you should probably configure one`}),!0}async delete(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>{if(this.dispose){let t=this.dataStore.get(e);await this.dispose(e,t)}return this.dataStore.delete(e)})}async pruneExpiredKeys(){let e=this.dataStore.size,t=e>=this.truncateThreshold;if(e<=0)return;let n=[],r=0;return this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/100;(o<=a||t&&r>=0&&r<=s)&&n.push(this.lockManager.withLock(i,async()=>(this.dispose&&await this.dispose(i,e),this.dataStore.delete(i)))),r++}),await Promise.all(n),{dataStoreSize:e,prunedDataStoreSize:this.dataStore.size}}startEvictionTask(){if(p(this.evictionInterval))return;let executePrune=async()=>{let e;try{if(this.lastAccessedAt+this.staleDataThreshold<Date.now()){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}e=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}catch(e){e instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:e,code:O.MemoryStorePruneError}),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}finally{if(p(e?.dataStoreSize)&&p(e?.prunedDataStoreSize)){let{dataStoreSize:t,prunedDataStoreSize:n}=e,r=t-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&=(clearTimeout(this.evictionInterval),void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return p(this.evictionInterval)&&p(this.dataStore)&&p(this.expiryMap)&&p(this.lockManager)}async setTTL(e,t){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),!this.dataStore.has(e)||!Number.isFinite(t)||t<=0)return!1;let n=t*D;return await this.lockManager.withLock(e,async()=>{this.expiryMap.set(e,Date.now()+n)}),!0}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.groupMap.clear(),this.groupExpiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()).filter(t=>t.includes(e)),i=[],a=t?parseInt(t,10):0;for(let e=a;e<n+a;e++){let t=r[e];if(!t)break;let a=await this.getData(t);if(a&&i.push(a),i.length>=n)break}return{items:i,cursor:i.length<n?void 0:(a+n).toString()}}};let k=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var EventClient=class{constructor(e,t,n){this.executorMethodStore=null,this.promiseStore=null,this.eventClientConfig=null,this.executorMethodStoreConfig=null,this.pendingPromiseStoreConfig=null,this.eventClientConfig=e,this.executorMethodStoreConfig=t,this.pendingPromiseStoreConfig=n;let r=e?.instantiator?`${e?.instantiator}(${this.constructor.name})`:this.constructor.name,i={logger:this.logger,dispose:this.defaultExecutorMethodDispose,typeGuard:this.defaultExecutorMethodTypeGuard,...this.executorMethodStoreConfig??{},instantiator:r},a={logger:this.logger,dispose:this.defaultPendingPromiseDispose,typeGuard:this.defaultPendingPromiseTypeGuard,...this.pendingPromiseStoreConfig??{},instantiator:r};this.executorMethodStore=new MemoryStore(i),this.promiseStore=new MemoryStore(a)}async setPendingEvent(e,t){let n={resolve:void 0,reject:void 0},r=new Promise((e,t)=>{n.resolve=e,n.reject=t}),i=t/1e3;await this.executorMethodStore?.setData({key:e,value:n,cacheTTL:i}),await this.promiseStore?.setData({key:e,value:r,cacheTTL:i})}async waitForEvent(e,t){let n=await this.promiseStore?.getData(e);return p(n)?n:(await this.setPendingEvent(e,t),this.getPendingEvent(e))}async getPendingEvent(e){return this.promiseStore?.getData(e)??null}async deleteEvent(e){return(await Promise.all([this.promiseStore?.delete(e),this.executorMethodStore?.delete(e)])).every(Boolean)}async resolveEvent(e,t){try{let n=await this.executorMethodStore?.getData(e);l(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??6e4),n=await this.executorMethodStore?.getData(e)),n?.resolve?.(t)}catch(t){t instanceof Error&&this.logger.error({message:`Error handling event for key ${e}: ${t.message}`,category:this.constructor.name,context:{eventKey:e},error:t,code:k.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){p(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):p(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return d(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}},AsyncSingleton=class{constructor(){this.instance=null,this.initPromise=null,this.retryTimeout=null,this.status=`uninitialized`,this.initOptions=null,this.initArgs=[]}getRetryDelay(){return 5e3}getSingleton(e){throw Error(`getSingleton method not implemented`)}async getInstance(e,...t){return this.instance?this.instance:(l(this.initPromise)&&(this.initOptions=e??null,this.initArgs=t,this.initPromise=this.init(e??null,...t)),this.initPromise)}getInstanceIfReady(){return this.instance}isReady(){return this.status===`ready`}hasInitFailed(){return this.status===`failed`}async init(e,...t){try{let n=await this.initInstance(e,...t);return this.instance=n,this.status=`ready`,n}catch(e){throw this.status=`failed`,this.initPromise=null,l(this.retryTimeout)&&(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.getInstance(this.initOptions,...this.initArgs).catch(()=>{})},this.getRetryDelay())),e}}reset(){this.instance=null,this.initPromise=null,this.initOptions=null,this.status=`uninitialized`,this.retryTimeout&&clearTimeout(this.retryTimeout),this.retryTimeout=null}};let A=function(e){return e.RedisClientError=`RedisClientError`,e.RedisClientCommandError=`RedisClientCommandError`,e.RedisClientDeleteError=`RedisClientDeleteError`,e.RedisClientInvalidTTL=`RedisClientInvalidTTL`,e.RedisClientListError=`RedisClientListError`,e.RedisClientNotInitialized=`RedisClientNotInitialized`,e.RedisClientPublishError=`RedisClientPublishError`,e.RedisClientReadError=`RedisClientReadError`,e.RedisClientRedisNotReady=`RedisClientRedisNotReady`,e.RedisClientScriptError=`RedisClientScriptError`,e.RedisClientScriptExecuteError=`RedisClientScriptExecuteError`,e.RedisClientScriptLoadError=`RedisClientScriptLoadError`,e.RedisClientSubscribeError=`RedisClientSubscribeError`,e.RedisClientUnsubscribeError=`RedisClientUnsubscribeError`,e.RedisClientWriteError=`RedisClientWriteError`,e}({});const buildRedisClientInstance=async(e,t,n)=>{try{return await ee.build(e,t,n)??void 0}catch(e){let r=e;t?.error({message:`Error building Cache Manager`,error:r,code:A.RedisClientError,category:n??`buildRedisClientInstance`});return}};var ee=class RedisClient{#e;#t;static async build({getRedisClient:e=g.createClient,host:t,port:n,tls:r,keepAlive:i=3e4,reconnect:a=!0,database:o},s,c){let l=new RedisClient;l.#t=s;try{l.#e=e({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:t,port:n,tls:r,keepAlive:i},database:o,disableOfflineQueue:!0});let s=getDefaultRedisListeners(c??`RedisClient`,l.#t);return addRedisEventHandlers(l.#e,s),await l.#e.connect(),l}catch(e){let t=e;return l.#t?.error({message:`Error building Cache Manager.`,error:t,code:A.RedisClientError,category:c??`RedisClient`}),null}}#n(e){try{return JSON.parse(e)}catch{return e}}async getData(e){if(!this.#i())return null;try{let t=await this.#e.get(e);if(!t)return null;let n=this.#n(t);return f(n)?t:n}catch(e){let t=e;return this.#t?.error({message:`Error getting data`,error:t,code:A.RedisClientReadError,category:RedisClient.name}),null}}async getDataKeysFromGroup(e){if(!this.#i())return null;try{return await this.#e.sMembers(e)}catch(e){let t=e;return this.#t?.error({message:`Error getting data from group`,error:t,code:A.RedisClientReadError,category:RedisClient.name}),null}}async setData({key:e,value:t,cacheTTL:n,groupKeys:r,groupKeyTTL:i}){if(!this.#i())return!1;try{let a=f(t)?t:JSON.stringify(t);if(await this.#e.set(e,a,{EX:n}),p(r)&&r.length>0)for(let t of r)await this.#e.sAdd(t,[e]),p(i)&&Number.isFinite(i)&&i>0&&await this.#e.expire(t,i);return!0}catch(e){let t=e;return this.#t?.error({message:`Error setting data`,error:t,code:A.RedisClientWriteError,category:RedisClient.name}),!1}}async setTTL(e,t){if(!this.#i())return!1;if(!Number.isFinite(t)||t<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:A.RedisClientInvalidTTL}),!1;try{let n=await this.#e.expire(e,t);return n||this.#t?.debug({message:`No keys updated for ${e}`,category:RedisClient.name}),n}catch(e){let t=e;return this.#t?.error({message:`Error resetting data TTL`,error:t,code:A.RedisClientWriteError,category:RedisClient.name}),!1}}async executeScript({sha1:e,keys:t,args:n}){if(!this.#i())return null;try{return await this.#e.evalSha(e,{keys:t,arguments:n})}catch(e){let t=e;throw this.#t?.error({message:`Error executing script`,error:t,code:A.RedisClientScriptExecuteError,category:RedisClient.name}),t}}async loadScript(e){if(!this.#i())return null;try{return await this.#e.scriptLoad(e)}catch(e){let t=e;return this.#t?.error({message:`Error loading script`,error:t,code:A.RedisClientScriptLoadError,category:RedisClient.name}),null}}async scriptExists(e){if(!this.#i())return e.map(()=>!1);try{return(await this.#e.scriptExists(e)).map(e=>!!e)}catch(t){let n=t;return this.#t?.error({message:`Error checking script existence`,error:n,code:A.RedisClientScriptError,category:RedisClient.name}),e.map(()=>!1)}}async#r(e,t,n){if(!this.#i())return null;if(!Number.isFinite(n)||n<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:A.RedisClientInvalidTTL}),null;try{let r=[{args:[e,t]},{args:[`expire`,t,n.toString()]}],i=(await this.#e.multiExecutor(r))?.[0];return typeof i==`number`?i:null}catch(t){let n=t;return this.#t?.error({message:`Error executing ${e} operation`,error:n,code:A.RedisClientCommandError,category:RedisClient.name}),null}}async increment(e,t){return this.#r(`incr`,e,t)}async decrement(e,t){return this.#r(`decr`,e,t)}async subscribe(e,t){if(!this.#i())return!1;try{return await this.#e.pSubscribe(e,t),!0}catch(t){let n=t;return this.#t?.error({message:`Error subscribing to ${e}`,error:n,code:A.RedisClientSubscribeError,category:RedisClient.name}),!1}}async unsubscribe(e){if(!this.#i())return!1;try{return await this.#e.pUnsubscribe(e),!0}catch(t){let n=t;return this.#t?.error({message:`Error unsubscribing from ${e}`,error:n,code:A.RedisClientUnsubscribeError,category:RedisClient.name}),!1}}async publish(e,t){if(!this.#i())return null;try{let n=await this.#e.publish(e,t);return n===0&&this.#t?.debug({message:`No subscribers found for channel ${e}`,category:RedisClient.name}),n}catch(t){let n=t;return this.#t?.error({message:`Error publishing to ${e}`,error:n,code:A.RedisClientPublishError,category:RedisClient.name}),null}}getClient(){return this.#i()?this.#e:null}#i(){let e=this.#e.isReady&&this.#e.isOpen;return e||this.#t?.error({message:`Redis Client is not ready.`,category:RedisClient.name,code:A.RedisClientRedisNotReady}),e}async listData({partialKey:e,limit:t,cursor:n}){try{let r=n?parseInt(n,10):0,i=await this.#e.sScan(e,r,{COUNT:t}),a=[];for(let e of i.members){let t=await this.getData(e);p(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(e){let t=e;return this.#t?.error({message:`Error listing data`,error:t,code:A.RedisClientListError,category:RedisClient.name}),{items:null}}}async deleteData(e){try{if(!this.#i())return!1;let t=await this.#e.del(e);return t===0&&this.#t?.debug({message:`No keys deleted for ${e}`,category:RedisClient.name}),t>0}catch(e){let t=e;return this.#t?.error({message:`Error deleting data`,error:t,code:A.RedisClientDeleteError,category:RedisClient.name}),!1}}};const addRedisEventHandlers=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},getDefaultRedisListeners=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:A.RedisClientError,category:e})}},{eventName:`ready`,listener:()=>{t?.info({message:`Redis client ready`,category:e})}},{eventName:`connect`,listener:()=>{t?.info({message:`Redis client connected`,category:e})}},{eventName:`reconnecting`,listener:()=>{t?.info({message:`Redis client reconnecting`,category:e})}},{eventName:`end`,listener:()=>{t?.info({message:`Redis client disconnected`,category:e})}}];let te=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});const ne=1500;var ScriptManager=class extends AsyncSingleton{constructor(...e){super(...e),this.isInitialConnection=!0,this.reloadInProgress=null,this.lastReloadTime=0}async initInstance({redisClientConfig:e=this.redisClientConfig,cacheClient:t=this.cacheClient,scripts:n=this.scripts,scriptMap:r=this.scriptMap,logger:i=this.logger,additionalArgs:a=this.additionalArgs}){let o=t??await buildRedisClientInstance(e,i,this.name);if(l(o))throw Error(`Failed to build Redis client`);return this.redisClientConfig=e,this.logger=i,this.cacheClient=o,this.scripts=n,this.scriptMap=r??new Map,this.additionalArgs=a??[],await this.loadScripts(n,r),this.setupReconnectHandler(),await this.additionalInitialization(...a??[]),this}setupReconnectHandler(){let e=this.cacheClient?.getClient?.();p(e)&&(e.on(`ready`,async()=>{this.isInitialConnection?this.isInitialConnection=!1:(this.logger?.info({message:`Redis reconnected - reloading scripts`,category:this.name}),await this.reloadScripts())}),e.on(`end`,()=>{this.logger?.info({message:`Redis connection closed`,category:this.name})}))}async reloadScripts(){if(p(this.reloadInProgress))return this.logger?.info({message:`Script reload already in progress, waiting for completion`,category:this.name}),this.reloadInProgress;if(!(l(this.scripts)||Object.keys(this.scripts).length===0)){this.reloadInProgress=this.performReload();try{await this.reloadInProgress}finally{this.reloadInProgress=null}}}async performReload(){this.logger?.info({message:`Reloading ${Object.keys(this.scripts).length} scripts after Redis reconnection`,category:this.name}),this.scriptMap.clear(),await this.loadScripts(this.scripts),this.lastReloadTime=Date.now()}async loadScripts(e,t){if(p(t))for(let[e,n]of t)this.scriptMap.set(e,n);let n=Object.entries(e),r=n.map(([e])=>this.scriptMap.get(e)).filter(p),i=new Map;if(r.length>0&&p(this.cacheClient?.scriptExists)){let e=await this.cacheClient.scriptExists(r);if(p(e)){r.forEach((t,n)=>{i.set(t,e[n]??!1)});let t=e.filter(Boolean).length;t>0&&this.logger?.info({message:`${t}/${r.length} scripts already exist in Redis; skipping load for existing scripts`,category:this.name})}}for(let[e,t]of n){let n=this.scriptMap.get(e);if(n&&i.get(n))continue;let r=await this.cacheClient?.loadScript?.(t);p(r)?this.scriptMap?.set(e,r):this.logger?.error({message:`Error loading script ${e}`,category:this.name,code:te.ScriptManagerLoadingError})}}async executeScript(e,t,n){if(!this.isRedisReady())return this.logger?.warning({message:`Redis not ready, cannot execute script ${e}`,category:this.name,context:{keys:t,args:n}}),null;let i=this.scriptMap?.get(e);if(l(i))throw this.logger?.error({message:`Script for ${e} not found in script map`,category:this.name,code:te.ScriptManagerExecutionError}),Error(`Script for ${e} not found`);try{return await this.cacheClient?.executeScript?.({sha1:i,keys:t,args:n})??null}catch(a){if(a instanceof Error&&a.message.includes(`NOSCRIPT`)){let a=Date.now()-this.lastReloadTime;if(a<ne){let t=ne-a;this.logger?.info({message:`Script ${e} not found, reload occurred ${a}ms ago. Waiting ${t}ms before reloading`,category:this.name}),await r(t)}if(this.logger?.info({message:`Script ${e} not found in Redis, reloading scripts`,category:this.name}),await this.reloadScripts(),i=this.scriptMap?.get(e),l(i))throw Error(`Script for ${e} could not be reloaded`);return await this.cacheClient?.executeScript?.({sha1:i,keys:t,args:n})??null}throw a instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${a.message}`,category:this.name,context:{keys:t,args:n},error:a,code:te.ScriptManagerExecutionError}),a}}isRedisReady(){let e=this.cacheClient?.getClient?.();if(p(this.cacheClient)&&l(e))return this.logger?.warning({message:`Cache client exists but getClient() returned null - cannot verify Redis readiness`,category:this.name}),!1;let t=e?.isReady&&e?.isOpen;return this.isReady()&&p(this.cacheClient)&&(t??!1)}},SubscriptionManager=class{constructor(e){this.options={getCacheClient:buildRedisClientInstance},this.subscriptionMap=null,this.subscriptionClient=null,this.name=`SubscriptionManager`,this.options={...this.options,...e}}async initialize(e=this.options){let{config:t,getCacheClient:n,logger:r}=e;if(this.logger=r,this.subscriptionMap=new MemoryStore({instantiator:`${e?.instantiator}(${this.name})`,evictionFrequency:e?.subscriptionTTL,staleDataThreshold:e?.staleSubscriptionsThreshold,truncateThreshold:e?.truncateThreshold,truncationPercentage:e?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),p(t))this.subscriptionClient=await n?.(t,this.logger,e?.instantiator)??null,this.logger?.info({message:`${this.name} initialized for ${e.instantiator}.`,category:this.name});else throw Error(`SubscriptionManager requires a Redis client configuration.`)}async subscribe(e,t){this.isReady()||await this.initialize(this.options);let n=await this.subscriptionMap?.getData(e),r=o(t.toString());return await this.subscriptionMap?.setData({key:e,value:r}),n===r?!0:await this.subscriptionClient?.subscribe?.(e,t)??!1}async unsubscribe(e){return this.isReady()||await this.initialize(this.options),this.subscriptionClient?.unsubscribe?.(e)??!1}isReady(){return p(this.subscriptionClient)&&p(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const re=15e3,ie=1e4;let ae=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),j=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});var QueueManager=class extends ScriptManager{constructor(...e){super(...e),this.subscriptionManager=null,this.eventClient=null,this.name=`QueueManager`}async additionalInitialization(){if(l(this.redisClientConfig))throw Error(`Redis client configuration is required to initialize QueueManager.`);this.subscriptionManager=new SubscriptionManager({config:this.redisClientConfig,instantiator:this.name,subscriptionTTL:6e4,truncateThreshold:ie,truncationPercentage:1}),await this.subscriptionManager?.initialize(),this.eventClient=new EventClient({instantiator:this.name,timeoutResolveValue:!1},{instantiator:this.name,evictionFrequency:re,truncateThreshold:ie,truncationPercentage:1},{instantiator:this.name,evictionFrequency:re,truncateThreshold:ie,truncationPercentage:1}),this.logger?.info({category:this.name,message:`QueueManager initialized.`})}async joinAndWaitTurn(e,t,n,r,i=!0){try{let a=`${e}:${t}`;await this.subscriptionManager?.subscribe(a,async(n,r)=>{if(r.includes(a)&&r.includes(t)){let t=`${e}:${n}`;return this.eventClient?.resolveEvent(t,!0)}});let o=await this.executeScript(n?j.lPush:j.rPush,[e],[t,`60000`])===1;return(!i||!o)&&await this.eventClient?.waitForEvent(a,15e3),await this.eventClient?.deleteEvent(a),await r(e,t)}catch(n){throw n instanceof Error&&this.logger?.error({message:`Error in joinAndWaitTurn`,category:this.name,error:n,code:ae.QueueManagerJoinAndWaitTurnError,context:{queueName:e,value:t}}),n}}async pop(e){try{return await this.executeScript(j.lPop,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in pop`,category:this.name,error:t,code:ae.QueueManagerPopError,context:{queueName:e}}),t}}async length(e){try{return await this.executeScript(j.llen,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in length`,category:this.name,error:t,code:ae.QueueManagerLengthError,context:{queueName:e}}),t}}isReady(){return p(this.subscriptionManager)&&p(this.cacheClient)&&p(this.scriptMap)&&this.scriptMap.size>0}close(){this.subscriptionManager?.close(),this.scriptMap?.clear()}};const M=`__keyevent@0__:`,oe=`${M}set`,se=`${M}expire`,N=`${M}expired`,ce=`${M}srem`,le=[oe,se,N],ue={mainMaxConcurrency:30};let P=function(e){return e.ConcurrencyManagerInitializationError=`ConcurrencyManagerInitializationError`,e.ConcurrencyManagerRedisEventsEmitError=`ConcurrencyManagerRedisEventsEmitError`,e.ConcurrencyManagerRegistrationFailed=`ConcurrencyManagerRegistrationFailed`,e.ConcurrencyManagerPublishNextItemFailed=`ConcurrencyManagerPublishNextItemFailed`,e.ConcurrencyManagerReleaseRequestFailed=`ConcurrencyManagerReleaseRequestFailed`,e}({}),F=function(e){return e.tryConcurrency=`tryConcurrency`,e.removeFromSet=`removeFromSet`,e.publishNextItem=`publishNextItem`,e}({});const de={[F.tryConcurrency]:`
|
|
1
|
+
import{n as e,r as t,t as n}from"./chunk-hhuvQGXm.mjs";import{delay as r,exponentialBackoffInMS as i,generateRequestId as a,getContentHash as o,isFunction as s,isFutureUnixTimestamp as c,isMissing as l,isNumber as u,isObject as d,isString as f,notMissing as p,z as m,zStrictObject as h}from"@stackone/utils";import*as g from"redis";import{evaluate as _,safeEvaluate as v}from"@stackone/expressions";import y,{isAxiosError as b}from"axios";import x from"node:https";import{randomUUID as S}from"crypto";import{clearTimeout as C}from"node:timers";import{JSONPath as w}from"jsonpath-plus";import{redactUrl as T}from"@stackone/redaction";import E from"qs";const createAuthorizationHeaders=e=>{switch(e.type){case`none`:return{};case`basic`:return createBasicAuthorizationHeader(e);case`bearer`:return createBearerAuthorizationHeader(e);case`oauth2`:return createBearerAuthorizationHeader(e);default:throw Error(`Invalid authentication type`)}},createBasicAuthorizationHeader=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n;return{authorization:`Basic ${Buffer.from(`${e}:${t}`).toString(r)}`}},createBearerAuthorizationHeader=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var LockManager=class{constructor(){this.locks=new Map}async withLock(e,t){await this.lock(e);try{return t()}finally{this.unlock(e)}}async lock(e){let t,n=new Promise(e=>t=e),r=this.locks.has(e),i=this.locks.get(e);r&&i?(i.push({lock:n,unlock:t}),await i[i.length-2].lock):this.locks.set(e,[{lock:n,unlock:t}])}unlock(e){let t=this.locks.has(e),n=this.locks.get(e);if(t&&n&&n.length>0){let e=n.shift()?.unlock;e?.()}this.queueLength(e)===0&&this.locks.delete(e)}queueLength(e){return this.locks.get(e)?.length}close(){this.locks.clear()}};const D=1e3;let O=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var MemoryStore=class{constructor(e={}){this.lastAccessedAt=Date.now(),this.config=e,this.initialize(e)}initialize(e=this.config){this.instantiator=e?.instantiator??`Unknown`,this.logger=e?.logger,this.dataStore=e?.dataStore??new Map,this.lockManager=e?.lockManager??new LockManager,this.expiryMap=e?.expiryMap??new Map,this.groupMap=new Map,this.groupExpiryMap=new Map,this.evictionFrequency=e?.evictionFrequency??6e4,this.staleDataThreshold=e?.staleDataThreshold??6e5,this.truncateThreshold=e?.truncateThreshold??100,this.truncationPercentage=e?.truncationPercentage??10,this.typeGuard=e?.typeGuard,this.dispose=e?.dispose,this.startEvictionTask()}async getData(e){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>this.dataStore.get(e)??null)}async getDataKeysFromGroup(e){this.isReady()||this.initialize(),this.updateLastAccessedAt();let t=this.groupExpiryMap.get(e);return p(t)&&t<=Date.now()?(this.groupMap.delete(e),this.groupExpiryMap.delete(e),[]):Array.from(this.groupMap.get(e)??[])}async setData({key:e,value:t,cacheTTL:n=60,groupKeys:r,groupKeyTTL:i}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),p(this.typeGuard)&&!this.typeGuard(t))return!1;let a=n*D,o=Date.now()+a;if(await this.lockManager.withLock(e,async()=>{(p(this.typeGuard)&&this.typeGuard(t)||l(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,o)}),p(r)&&r.length>0){let t=p(i)&&Number.isFinite(i)&&i>0?i*D:void 0;for(let n of r)this.groupMap.has(n)||this.groupMap.set(n,new Set),this.groupMap.get(n)?.add(e),p(t)&&this.groupExpiryMap.set(n,Date.now()+t)}return!0}typeGuardBypass(e){return this.logger?.debug({category:`MemoryStore`,message:`${this.instantiator} MemoryStore setting data without type guard - you should probably configure one`}),!0}async delete(e,t){return this.isReady()||this.initialize(),this.updateLastAccessedAt(),this.lockManager.withLock(e,async()=>{if(this.dispose){let t=this.dataStore.get(e);await this.dispose(e,t)}if(p(t)&&t.length>0)for(let n of t)this.groupMap.get(n)?.delete(e);return this.dataStore.delete(e)})}async pruneExpiredKeys(){let e=this.dataStore.size,t=e>=this.truncateThreshold;if(e<=0)return;let n=[],r=0;return this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/100;(o<=a||t&&r>=0&&r<=s)&&n.push(this.lockManager.withLock(i,async()=>(this.dispose&&await this.dispose(i,e),this.dataStore.delete(i)))),r++}),await Promise.all(n),{dataStoreSize:e,prunedDataStoreSize:this.dataStore.size}}startEvictionTask(){if(p(this.evictionInterval))return;let executePrune=async()=>{let e;try{if(this.lastAccessedAt+this.staleDataThreshold<Date.now()){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}e=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}catch(e){e instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:e,code:O.MemoryStorePruneError}),this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}finally{if(p(e?.dataStoreSize)&&p(e?.prunedDataStoreSize)){let{dataStoreSize:t,prunedDataStoreSize:n}=e,r=t-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(executePrune,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&=(clearTimeout(this.evictionInterval),void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return p(this.evictionInterval)&&p(this.dataStore)&&p(this.expiryMap)&&p(this.lockManager)}async setTTL(e,t){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),!this.dataStore.has(e)||!Number.isFinite(t)||t<=0)return!1;let n=t*D;return await this.lockManager.withLock(e,async()=>{this.expiryMap.set(e,Date.now()+n)}),!0}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.groupMap.clear(),this.groupExpiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()).filter(t=>t.includes(e)),i=[],a=t?parseInt(t,10):0;for(let e=a;e<n+a;e++){let t=r[e];if(!t)break;let a=await this.getData(t);if(a&&i.push(a),i.length>=n)break}return{items:i,cursor:i.length<n?void 0:(a+n).toString()}}};let k=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var EventClient=class{constructor(e,t,n){this.executorMethodStore=null,this.promiseStore=null,this.eventClientConfig=null,this.executorMethodStoreConfig=null,this.pendingPromiseStoreConfig=null,this.eventClientConfig=e,this.executorMethodStoreConfig=t,this.pendingPromiseStoreConfig=n;let r=e?.instantiator?`${e?.instantiator}(${this.constructor.name})`:this.constructor.name,i={logger:this.logger,dispose:this.defaultExecutorMethodDispose,typeGuard:this.defaultExecutorMethodTypeGuard,...this.executorMethodStoreConfig??{},instantiator:r},a={logger:this.logger,dispose:this.defaultPendingPromiseDispose,typeGuard:this.defaultPendingPromiseTypeGuard,...this.pendingPromiseStoreConfig??{},instantiator:r};this.executorMethodStore=new MemoryStore(i),this.promiseStore=new MemoryStore(a)}async setPendingEvent(e,t){let n={resolve:void 0,reject:void 0},r=new Promise((e,t)=>{n.resolve=e,n.reject=t}),i=t/1e3;await this.executorMethodStore?.setData({key:e,value:n,cacheTTL:i}),await this.promiseStore?.setData({key:e,value:r,cacheTTL:i})}async waitForEvent(e,t){let n=await this.promiseStore?.getData(e);return p(n)?n:(await this.setPendingEvent(e,t),this.getPendingEvent(e))}async getPendingEvent(e){return this.promiseStore?.getData(e)??null}async deleteEvent(e){return(await Promise.all([this.promiseStore?.delete(e),this.executorMethodStore?.delete(e)])).every(Boolean)}async resolveEvent(e,t){try{let n=await this.executorMethodStore?.getData(e);l(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??6e4),n=await this.executorMethodStore?.getData(e)),n?.resolve?.(t)}catch(t){t instanceof Error&&this.logger.error({message:`Error handling event for key ${e}: ${t.message}`,category:this.constructor.name,context:{eventKey:e},error:t,code:k.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){p(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):p(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return d(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}},AsyncSingleton=class{constructor(){this.instance=null,this.initPromise=null,this.retryTimeout=null,this.status=`uninitialized`,this.initOptions=null,this.initArgs=[]}getRetryDelay(){return 5e3}getSingleton(e){throw Error(`getSingleton method not implemented`)}async getInstance(e,...t){return this.instance?this.instance:(l(this.initPromise)&&(this.initOptions=e??null,this.initArgs=t,this.initPromise=this.init(e??null,...t)),this.initPromise)}getInstanceIfReady(){return this.instance}isReady(){return this.status===`ready`}hasInitFailed(){return this.status===`failed`}async init(e,...t){try{let n=await this.initInstance(e,...t);return this.instance=n,this.status=`ready`,n}catch(e){throw this.status=`failed`,this.initPromise=null,l(this.retryTimeout)&&(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.getInstance(this.initOptions,...this.initArgs).catch(()=>{})},this.getRetryDelay())),e}}reset(){this.instance=null,this.initPromise=null,this.initOptions=null,this.status=`uninitialized`,this.retryTimeout&&clearTimeout(this.retryTimeout),this.retryTimeout=null}};let A=function(e){return e.RedisClientError=`RedisClientError`,e.RedisClientCommandError=`RedisClientCommandError`,e.RedisClientDeleteError=`RedisClientDeleteError`,e.RedisClientInvalidTTL=`RedisClientInvalidTTL`,e.RedisClientListError=`RedisClientListError`,e.RedisClientNotInitialized=`RedisClientNotInitialized`,e.RedisClientPublishError=`RedisClientPublishError`,e.RedisClientReadError=`RedisClientReadError`,e.RedisClientRedisNotReady=`RedisClientRedisNotReady`,e.RedisClientScriptError=`RedisClientScriptError`,e.RedisClientScriptExecuteError=`RedisClientScriptExecuteError`,e.RedisClientScriptLoadError=`RedisClientScriptLoadError`,e.RedisClientSubscribeError=`RedisClientSubscribeError`,e.RedisClientUnsubscribeError=`RedisClientUnsubscribeError`,e.RedisClientWriteError=`RedisClientWriteError`,e}({});const buildRedisClientInstance=async(e,t,n)=>{try{return await ee.build(e,t,n)??void 0}catch(e){let r=e;t?.error({message:`Error building Cache Manager`,error:r,code:A.RedisClientError,category:n??`buildRedisClientInstance`});return}};var ee=class RedisClient{#e;#t;static async build({getRedisClient:e=g.createClient,host:t,port:n,tls:r,keepAlive:i=3e4,reconnect:a=!0,database:o},s,c){let l=new RedisClient;l.#t=s;try{l.#e=e({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:t,port:n,tls:r,keepAlive:i},database:o,disableOfflineQueue:!0});let s=getDefaultRedisListeners(c??`RedisClient`,l.#t);return addRedisEventHandlers(l.#e,s),await l.#e.connect(),l}catch(e){let t=e;return l.#t?.error({message:`Error building Cache Manager.`,error:t,code:A.RedisClientError,category:c??`RedisClient`}),null}}#n(e){try{return JSON.parse(e)}catch{return e}}async getData(e){if(!this.#i())return null;try{let t=await this.#e.get(e);if(!t)return null;let n=this.#n(t);return f(n)?t:n}catch(e){let t=e;return this.#t?.error({message:`Error getting data`,error:t,code:A.RedisClientReadError,category:RedisClient.name}),null}}async getDataKeysFromGroup(e){if(!this.#i())return null;try{return await this.#e.sMembers(e)}catch(e){let t=e;return this.#t?.error({message:`Error getting data from group`,error:t,code:A.RedisClientReadError,category:RedisClient.name}),null}}async setData({key:e,value:t,cacheTTL:n,groupKeys:r,groupKeyTTL:i}){if(!this.#i())return!1;try{let a=f(t)?t:JSON.stringify(t);if(await this.#e.set(e,a,{EX:n}),p(r)&&r.length>0)for(let t of r)await this.#e.sAdd(t,[e]),p(i)&&Number.isFinite(i)&&i>0&&await this.#e.expire(t,i);return!0}catch(e){let t=e;return this.#t?.error({message:`Error setting data`,error:t,code:A.RedisClientWriteError,category:RedisClient.name}),!1}}async setTTL(e,t){if(!this.#i())return!1;if(!Number.isFinite(t)||t<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:A.RedisClientInvalidTTL}),!1;try{let n=await this.#e.expire(e,t);return n||this.#t?.debug({message:`No keys updated for ${e}`,category:RedisClient.name}),n}catch(e){let t=e;return this.#t?.error({message:`Error resetting data TTL`,error:t,code:A.RedisClientWriteError,category:RedisClient.name}),!1}}async executeScript({sha1:e,keys:t,args:n}){if(!this.#i())return null;try{return await this.#e.evalSha(e,{keys:t,arguments:n})}catch(e){let t=e;throw this.#t?.error({message:`Error executing script`,error:t,code:A.RedisClientScriptExecuteError,category:RedisClient.name}),t}}async loadScript(e){if(!this.#i())return null;try{return await this.#e.scriptLoad(e)}catch(e){let t=e;return this.#t?.error({message:`Error loading script`,error:t,code:A.RedisClientScriptLoadError,category:RedisClient.name}),null}}async scriptExists(e){if(!this.#i())return e.map(()=>!1);try{return(await this.#e.scriptExists(e)).map(e=>!!e)}catch(t){let n=t;return this.#t?.error({message:`Error checking script existence`,error:n,code:A.RedisClientScriptError,category:RedisClient.name}),e.map(()=>!1)}}async#r(e,t,n){if(!this.#i())return null;if(!Number.isFinite(n)||n<=0)return this.#t?.error({message:`Invalid cacheTTL parameter`,category:RedisClient.name,code:A.RedisClientInvalidTTL}),null;try{let r=[{args:[e,t]},{args:[`expire`,t,n.toString()]}],i=(await this.#e.multiExecutor(r))?.[0];return typeof i==`number`?i:null}catch(t){let n=t;return this.#t?.error({message:`Error executing ${e} operation`,error:n,code:A.RedisClientCommandError,category:RedisClient.name}),null}}async increment(e,t){return this.#r(`incr`,e,t)}async decrement(e,t){return this.#r(`decr`,e,t)}async subscribe(e,t){if(!this.#i())return!1;try{return await this.#e.pSubscribe(e,t),!0}catch(t){let n=t;return this.#t?.error({message:`Error subscribing to ${e}`,error:n,code:A.RedisClientSubscribeError,category:RedisClient.name}),!1}}async unsubscribe(e){if(!this.#i())return!1;try{return await this.#e.pUnsubscribe(e),!0}catch(t){let n=t;return this.#t?.error({message:`Error unsubscribing from ${e}`,error:n,code:A.RedisClientUnsubscribeError,category:RedisClient.name}),!1}}async publish(e,t){if(!this.#i())return null;try{let n=await this.#e.publish(e,t);return n===0&&this.#t?.debug({message:`No subscribers found for channel ${e}`,category:RedisClient.name}),n}catch(t){let n=t;return this.#t?.error({message:`Error publishing to ${e}`,error:n,code:A.RedisClientPublishError,category:RedisClient.name}),null}}getClient(){return this.#i()?this.#e:null}#i(){let e=this.#e.isReady&&this.#e.isOpen;return e||this.#t?.error({message:`Redis Client is not ready.`,category:RedisClient.name,code:A.RedisClientRedisNotReady}),e}async listData({partialKey:e,limit:t,cursor:n}){try{let r=n?parseInt(n,10):0,i=await this.#e.sScan(e,r,{COUNT:t}),a=[];for(let e of i.members){let t=await this.getData(e);p(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(e){let t=e;return this.#t?.error({message:`Error listing data`,error:t,code:A.RedisClientListError,category:RedisClient.name}),{items:null}}}async deleteData(e,t){try{if(!this.#i())return!1;let n=await this.#e.del(e);return n===0&&this.#t?.debug({message:`No keys deleted for ${e}`,category:RedisClient.name}),p(t)&&t.length>0&&(await Promise.allSettled(t.map(t=>this.#e.sRem(t,e)))).forEach((e,n)=>{e.status===`rejected`&&this.#t?.error({message:`Error removing key from group set ${t[n]}`,error:e.reason,code:A.RedisClientDeleteError,category:RedisClient.name})}),n>0}catch(e){let t=e;return this.#t?.error({message:`Error deleting data`,error:t,code:A.RedisClientDeleteError,category:RedisClient.name}),!1}}};const addRedisEventHandlers=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},getDefaultRedisListeners=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:A.RedisClientError,category:e})}},{eventName:`ready`,listener:()=>{t?.info({message:`Redis client ready`,category:e})}},{eventName:`connect`,listener:()=>{t?.info({message:`Redis client connected`,category:e})}},{eventName:`reconnecting`,listener:()=>{t?.info({message:`Redis client reconnecting`,category:e})}},{eventName:`end`,listener:()=>{t?.info({message:`Redis client disconnected`,category:e})}}];let te=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});const ne=1500;var ScriptManager=class extends AsyncSingleton{constructor(...e){super(...e),this.isInitialConnection=!0,this.reloadInProgress=null,this.lastReloadTime=0}async initInstance({redisClientConfig:e=this.redisClientConfig,cacheClient:t=this.cacheClient,scripts:n=this.scripts,scriptMap:r=this.scriptMap,logger:i=this.logger,additionalArgs:a=this.additionalArgs}){let o=t??await buildRedisClientInstance(e,i,this.name);if(l(o))throw Error(`Failed to build Redis client`);return this.redisClientConfig=e,this.logger=i,this.cacheClient=o,this.scripts=n,this.scriptMap=r??new Map,this.additionalArgs=a??[],await this.loadScripts(n,r),this.setupReconnectHandler(),await this.additionalInitialization(...a??[]),this}setupReconnectHandler(){let e=this.cacheClient?.getClient?.();p(e)&&(e.on(`ready`,async()=>{this.isInitialConnection?this.isInitialConnection=!1:(this.logger?.info({message:`Redis reconnected - reloading scripts`,category:this.name}),await this.reloadScripts())}),e.on(`end`,()=>{this.logger?.info({message:`Redis connection closed`,category:this.name})}))}async reloadScripts(){if(p(this.reloadInProgress))return this.logger?.info({message:`Script reload already in progress, waiting for completion`,category:this.name}),this.reloadInProgress;if(!(l(this.scripts)||Object.keys(this.scripts).length===0)){this.reloadInProgress=this.performReload();try{await this.reloadInProgress}finally{this.reloadInProgress=null}}}async performReload(){this.logger?.info({message:`Reloading ${Object.keys(this.scripts).length} scripts after Redis reconnection`,category:this.name}),this.scriptMap.clear(),await this.loadScripts(this.scripts),this.lastReloadTime=Date.now()}async loadScripts(e,t){if(p(t))for(let[e,n]of t)this.scriptMap.set(e,n);let n=Object.entries(e),r=n.map(([e])=>this.scriptMap.get(e)).filter(p),i=new Map;if(r.length>0&&p(this.cacheClient?.scriptExists)){let e=await this.cacheClient.scriptExists(r);if(p(e)){r.forEach((t,n)=>{i.set(t,e[n]??!1)});let t=e.filter(Boolean).length;t>0&&this.logger?.info({message:`${t}/${r.length} scripts already exist in Redis; skipping load for existing scripts`,category:this.name})}}for(let[e,t]of n){let n=this.scriptMap.get(e);if(n&&i.get(n))continue;let r=await this.cacheClient?.loadScript?.(t);p(r)?this.scriptMap?.set(e,r):this.logger?.error({message:`Error loading script ${e}`,category:this.name,code:te.ScriptManagerLoadingError})}}async executeScript(e,t,n){if(!this.isRedisReady())return this.logger?.warning({message:`Redis not ready, cannot execute script ${e}`,category:this.name,context:{keys:t,args:n}}),null;let i=this.scriptMap?.get(e);if(l(i))throw this.logger?.error({message:`Script for ${e} not found in script map`,category:this.name,code:te.ScriptManagerExecutionError}),Error(`Script for ${e} not found`);try{return await this.cacheClient?.executeScript?.({sha1:i,keys:t,args:n})??null}catch(a){if(a instanceof Error&&a.message.includes(`NOSCRIPT`)){let a=Date.now()-this.lastReloadTime;if(a<ne){let t=ne-a;this.logger?.info({message:`Script ${e} not found, reload occurred ${a}ms ago. Waiting ${t}ms before reloading`,category:this.name}),await r(t)}if(this.logger?.info({message:`Script ${e} not found in Redis, reloading scripts`,category:this.name}),await this.reloadScripts(),i=this.scriptMap?.get(e),l(i))throw Error(`Script for ${e} could not be reloaded`);return await this.cacheClient?.executeScript?.({sha1:i,keys:t,args:n})??null}throw a instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${a.message}`,category:this.name,context:{keys:t,args:n},error:a,code:te.ScriptManagerExecutionError}),a}}isRedisReady(){let e=this.cacheClient?.getClient?.();if(p(this.cacheClient)&&l(e))return this.logger?.warning({message:`Cache client exists but getClient() returned null - cannot verify Redis readiness`,category:this.name}),!1;let t=e?.isReady&&e?.isOpen;return this.isReady()&&p(this.cacheClient)&&(t??!1)}},SubscriptionManager=class{constructor(e){this.options={getCacheClient:buildRedisClientInstance},this.subscriptionMap=null,this.subscriptionClient=null,this.name=`SubscriptionManager`,this.options={...this.options,...e}}async initialize(e=this.options){let{config:t,getCacheClient:n,logger:r}=e;if(this.logger=r,this.subscriptionMap=new MemoryStore({instantiator:`${e?.instantiator}(${this.name})`,evictionFrequency:e?.subscriptionTTL,staleDataThreshold:e?.staleSubscriptionsThreshold,truncateThreshold:e?.truncateThreshold,truncationPercentage:e?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),p(t))this.subscriptionClient=await n?.(t,this.logger,e?.instantiator)??null,this.logger?.info({message:`${this.name} initialized for ${e.instantiator}.`,category:this.name});else throw Error(`SubscriptionManager requires a Redis client configuration.`)}async subscribe(e,t){this.isReady()||await this.initialize(this.options);let n=await this.subscriptionMap?.getData(e),r=o(t.toString());return await this.subscriptionMap?.setData({key:e,value:r}),n===r?!0:await this.subscriptionClient?.subscribe?.(e,t)??!1}async unsubscribe(e){return this.isReady()||await this.initialize(this.options),this.subscriptionClient?.unsubscribe?.(e)??!1}isReady(){return p(this.subscriptionClient)&&p(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const re=15e3,ie=1e4;let ae=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),j=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});var QueueManager=class extends ScriptManager{constructor(...e){super(...e),this.subscriptionManager=null,this.eventClient=null,this.name=`QueueManager`}async additionalInitialization(){if(l(this.redisClientConfig))throw Error(`Redis client configuration is required to initialize QueueManager.`);this.subscriptionManager=new SubscriptionManager({config:this.redisClientConfig,instantiator:this.name,subscriptionTTL:6e4,truncateThreshold:ie,truncationPercentage:1}),await this.subscriptionManager?.initialize(),this.eventClient=new EventClient({instantiator:this.name,timeoutResolveValue:!1},{instantiator:this.name,evictionFrequency:re,truncateThreshold:ie,truncationPercentage:1},{instantiator:this.name,evictionFrequency:re,truncateThreshold:ie,truncationPercentage:1}),this.logger?.info({category:this.name,message:`QueueManager initialized.`})}async joinAndWaitTurn(e,t,n,r,i=!0){try{let a=`${e}:${t}`;await this.subscriptionManager?.subscribe(a,async(n,r)=>{if(r.includes(a)&&r.includes(t)){let t=`${e}:${n}`;return this.eventClient?.resolveEvent(t,!0)}});let o=await this.executeScript(n?j.lPush:j.rPush,[e],[t,`60000`])===1;return(!i||!o)&&await this.eventClient?.waitForEvent(a,15e3),await this.eventClient?.deleteEvent(a),await r(e,t)}catch(n){throw n instanceof Error&&this.logger?.error({message:`Error in joinAndWaitTurn`,category:this.name,error:n,code:ae.QueueManagerJoinAndWaitTurnError,context:{queueName:e,value:t}}),n}}async pop(e){try{return await this.executeScript(j.lPop,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in pop`,category:this.name,error:t,code:ae.QueueManagerPopError,context:{queueName:e}}),t}}async length(e){try{return await this.executeScript(j.llen,[e],[])}catch(t){throw t instanceof Error&&this.logger?.error({message:`Error in length`,category:this.name,error:t,code:ae.QueueManagerLengthError,context:{queueName:e}}),t}}isReady(){return p(this.subscriptionManager)&&p(this.cacheClient)&&p(this.scriptMap)&&this.scriptMap.size>0}close(){this.subscriptionManager?.close(),this.scriptMap?.clear()}};const M=`__keyevent@0__:`,oe=`${M}set`,se=`${M}expire`,N=`${M}expired`,ce=`${M}srem`,le=[oe,se,N],ue={mainMaxConcurrency:30};let P=function(e){return e.ConcurrencyManagerInitializationError=`ConcurrencyManagerInitializationError`,e.ConcurrencyManagerRedisEventsEmitError=`ConcurrencyManagerRedisEventsEmitError`,e.ConcurrencyManagerRegistrationFailed=`ConcurrencyManagerRegistrationFailed`,e.ConcurrencyManagerPublishNextItemFailed=`ConcurrencyManagerPublishNextItemFailed`,e.ConcurrencyManagerReleaseRequestFailed=`ConcurrencyManagerReleaseRequestFailed`,e}({}),F=function(e){return e.tryConcurrency=`tryConcurrency`,e.removeFromSet=`removeFromSet`,e.publishNextItem=`publishNextItem`,e}({});const de={[F.tryConcurrency]:`
|
|
2
2
|
local requestId = KEYS[1]
|
|
3
3
|
local targetKey = KEYS[2]
|
|
4
4
|
local queueKey = KEYS[3]
|