@stackone/transport 1.13.0 → 1.14.0
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.d.mts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -14,11 +14,16 @@ type BasicAuthorizationParams = {
|
|
|
14
14
|
type BearerAuthorizationParams = {
|
|
15
15
|
type: 'bearer';
|
|
16
16
|
token: string;
|
|
17
|
-
includeBearer
|
|
17
|
+
includeBearer: boolean;
|
|
18
|
+
};
|
|
19
|
+
type OAuth2AuthorizationParams = {
|
|
20
|
+
type: 'oauth2';
|
|
21
|
+
token: string;
|
|
22
|
+
includeBearer: boolean;
|
|
18
23
|
};
|
|
19
24
|
//#endregion
|
|
20
25
|
//#region src/authorization/authorizationHeaders.d.ts
|
|
21
|
-
declare const createAuthorizationHeaders: (authenticationParams: BasicAuthorizationParams | BearerAuthorizationParams) => {
|
|
26
|
+
declare const createAuthorizationHeaders: (authenticationParams: BasicAuthorizationParams | BearerAuthorizationParams | OAuth2AuthorizationParams) => {
|
|
22
27
|
authorization: string;
|
|
23
28
|
};
|
|
24
29
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -14,11 +14,16 @@ type BasicAuthorizationParams = {
|
|
|
14
14
|
type BearerAuthorizationParams = {
|
|
15
15
|
type: 'bearer';
|
|
16
16
|
token: string;
|
|
17
|
-
includeBearer
|
|
17
|
+
includeBearer: boolean;
|
|
18
|
+
};
|
|
19
|
+
type OAuth2AuthorizationParams = {
|
|
20
|
+
type: 'oauth2';
|
|
21
|
+
token: string;
|
|
22
|
+
includeBearer: boolean;
|
|
18
23
|
};
|
|
19
24
|
//#endregion
|
|
20
25
|
//#region src/authorization/authorizationHeaders.d.ts
|
|
21
|
-
declare const createAuthorizationHeaders: (authenticationParams: BasicAuthorizationParams | BearerAuthorizationParams) => {
|
|
26
|
+
declare const createAuthorizationHeaders: (authenticationParams: BasicAuthorizationParams | BearerAuthorizationParams | OAuth2AuthorizationParams) => {
|
|
22
27
|
authorization: string;
|
|
23
28
|
};
|
|
24
29
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(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},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const l=c(require(`@stackone/utils`)),u=c(require(`redis`)),d=c(require(`axios`)),f=c(require(`node:https`)),p=c(require(`crypto`)),m=c(require(`node:timers`)),h=c(require(`jsonpath`)),g=c(require(`qs`)),_=c(require(`@stackone/expressions`)),v=e=>{switch(e.type){case`basic`:return y(e);case`bearer`:return b(e);default:throw Error(`Invalid authentication type`)}},y=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n,i=Buffer.from(`${e}:${t}`).toString(r);return{authorization:`Basic ${i}`}},b=({token:e,includeBearer:t=!0})=>({authorization:`${t?`Bearer `:``}${e}`});var x=class{locks;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);if(r&&i){i.push({lock:n,unlock:t});let e=i.length-2;await i[e].lock}else 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 S=1e3,C=100,ee=60,w=6e4,T=ee,E=w,te=w*10,ne=C,re=10;let D=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var O=class{config;instantiator;dataStore;lockManager;expiryMap;evictionFrequency;staleDataThreshold;truncateThreshold;truncationPercentage;logger;typeGuard;dispose;evictionInterval;lastAccessedAt=Date.now();constructor(e={}){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 x,this.expiryMap=e?.expiryMap??new Map,this.evictionFrequency=e?.evictionFrequency??E,this.staleDataThreshold=e?.staleDataThreshold??te,this.truncateThreshold=e?.truncateThreshold??ne,this.truncationPercentage=e?.truncationPercentage??re,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 setData({key:e,value:t,cacheTTL:n=T}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),(0,l.notMissing)(this.typeGuard)&&!this.typeGuard(t))return!1;let r=n*S,i=Date.now()+r;return await this.lockManager.withLock(e,async()=>{((0,l.notMissing)(this.typeGuard)&&this.typeGuard(t)||(0,l.isMissing)(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,i)}),!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;this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/C;(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);let i=this.dataStore.size;return{dataStoreSize:e,prunedDataStoreSize:i}}startEvictionTask(){if((0,l.notMissing)(this.evictionInterval))return;let e=async()=>{let t;try{let n=this.lastAccessedAt+this.staleDataThreshold,r=Date.now();if(n<r){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}t=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(e,this.evictionFrequency)}catch(t){t instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:t,code:D.MemoryStorePruneError}),this.evictionInterval=setTimeout(e,this.evictionFrequency)}finally{if((0,l.notMissing)(t?.dataStoreSize)&&(0,l.notMissing)(t?.prunedDataStoreSize)){let{dataStoreSize:e,prunedDataStoreSize:n}=t,r=e-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(e,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&(clearTimeout(this.evictionInterval),this.evictionInterval=void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return(0,l.notMissing)(this.evictionInterval)&&(0,l.notMissing)(this.dataStore)&&(0,l.notMissing)(this.expiryMap)&&(0,l.notMissing)(this.lockManager)}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()),i=r.filter(t=>t.includes(e)),a=[],o=t?parseInt(t,10):0;for(let e=o;e<n+o;e++){let t=i[e];if(!t)break;let r=await this.getData(t);if(r&&a.push(r),a.length>=n)break}return{items:a,cursor:a.length<n?void 0:(o+n).toString()}}};const ie=1e3,ae=6e4;let oe=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var se=class{executorMethodStore=null;promiseStore=null;logger;eventClientConfig=null;executorMethodStoreConfig=null;pendingPromiseStoreConfig=null;constructor(e,t,n){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 O(i),this.promiseStore=new O(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/ie;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,l.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,l.isMissing)(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??ae),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:oe.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){(0,l.notMissing)(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):(0,l.notMissing)(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return(0,l.isObject)(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}};let k=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 ce=async(e,t)=>{try{let n=await le.build(e,t);return n??void 0}catch(e){let n=e;t?.error({message:`Error building Cache Manager`,error:n,code:k.RedisClientError,category:`buildRedisClientInstance`});return}};var le=class e{#redisClient;#logger;static async build({getRedisClient:t=u.createClient,host:n,port:r,tls:i,reconnect:a=!0,database:o},s){let c=new e;c.#logger=s;try{c.#redisClient=t({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:n,port:r,tls:i},database:o,disableOfflineQueue:!0});let s=de(e.name,c.#logger);return ue(c.#redisClient,s),await c.#redisClient.connect(),c}catch(t){let n=t;return c.#logger?.error({message:`Error building Cache Manager.`,error:n,code:k.RedisClientError,category:e.name}),null}}#parseData(e){try{return JSON.parse(e)}catch{return e}}async getData(t){if(!this.#isRedisClientAvailable())return null;try{let e=await this.#redisClient.get(t);if(!e)return null;let n=this.#parseData(e);return(0,l.isString)(n)?e:n}catch(t){let n=t;return this.#logger?.error({message:`Error getting data`,error:n,code:k.RedisClientReadError,category:e.name}),null}}async setData({key:t,value:n,cacheTTL:r,groupKey:i}){if(!this.#isRedisClientAvailable())return!1;try{let e=(0,l.isString)(n)?n:JSON.stringify(n);return await this.#redisClient.set(t,e,{EX:r}),(0,l.notMissing)(i)&&await this.#redisClient.sAdd(i,[t]),!0}catch(t){let n=t;return this.#logger?.error({message:`Error setting data`,error:n,code:k.RedisClientWriteError,category:e.name}),!1}}async executeScript({sha1:t,keys:n,args:r}){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.evalSha(t,{keys:n,arguments:r})}catch(t){let n=t;return this.#logger?.error({message:`Error executing script`,error:n,code:k.RedisClientScriptExecuteError,category:e.name}),null}}async loadScript(t){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.scriptLoad(t)}catch(t){let n=t;return this.#logger?.error({message:`Error loading script`,error:n,code:k.RedisClientScriptLoadError,category:e.name}),null}}async#executeCounterCommand(t,n,r){if(!this.#isRedisClientAvailable())return null;if(!Number.isFinite(r)||r<=0)return this.#logger?.error({message:`Invalid cacheTTL parameter`,category:e.name,code:k.RedisClientInvalidTTL}),null;try{let e=[{args:[t,n]},{args:[`expire`,n,r.toString()]}],i=await this.#redisClient.multiExecutor(e),a=i?.[0];return typeof a==`number`?a:null}catch(n){let r=n;return this.#logger?.error({message:`Error executing ${t} operation`,error:r,code:k.RedisClientCommandError,category:e.name}),null}}async increment(e,t){return this.#executeCounterCommand(`incr`,e,t)}async decrement(e,t){return this.#executeCounterCommand(`decr`,e,t)}async subscribe(t,n){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pSubscribe(t,n),!0}catch(n){let r=n;return this.#logger?.error({message:`Error subscribing to ${t}`,error:r,code:k.RedisClientSubscribeError,category:e.name}),!1}}async unsubscribe(t){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pUnsubscribe(t),!0}catch(n){let r=n;return this.#logger?.error({message:`Error unsubscribing from ${t}`,error:r,code:k.RedisClientUnsubscribeError,category:e.name}),!1}}async publish(t,n){if(!this.#isRedisClientAvailable())return null;try{let r=await this.#redisClient.publish(t,n);return r===0&&this.#logger?.debug({message:`No subscribers found for channel ${t}`,category:e.name}),r}catch(n){let r=n;return this.#logger?.error({message:`Error publishing to ${t}`,error:r,code:k.RedisClientPublishError,category:e.name}),null}}getClient(){return this.#isRedisClientAvailable()?this.#redisClient:null}#isRedisClientAvailable(){let t=this.#redisClient.isReady&&this.#redisClient.isOpen;return t||this.#logger?.error({message:`Redis Client is not ready.`,category:e.name,code:k.RedisClientRedisNotReady}),t}async listData({partialKey:t,limit:n,cursor:r}){try{let e=r?parseInt(r,10):0,i=await this.#redisClient.sScan(t,e,{COUNT:n}),a=[];for(let e of i.members){let t=await this.getData(e);(0,l.notMissing)(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(t){let n=t;return this.#logger?.error({message:`Error listing data`,error:n,code:k.RedisClientListError,category:e.name}),{items:null}}}async deleteData(t){try{if(!this.#isRedisClientAvailable())return!1;let n=await this.#redisClient.del(t);return n===0&&this.#logger?.debug({message:`No keys deleted for ${t}`,category:e.name}),n>0}catch(t){let n=t;return this.#logger?.error({message:`Error deleting data`,error:n,code:k.RedisClientDeleteError,category:e.name}),!1}}};const ue=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},de=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:k.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 fe=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});var pe=class{cacheClient=null;scriptMap=new Map;logger;scripts;redisClientConfig;constructor(e){this.scripts=e}async initialize({redisClientConfig:e,logger:t,scriptMap:n},...r){this.redisClientConfig=e,this.logger=t,this.cacheClient=await ce(this.redisClientConfig,this.logger)??null,await this.loadScripts(this.scripts,n),await this.additionalInitialization(...r)}async additionalInitialization(...e){}async loadScripts(e,t){(0,l.notMissing)(t)&&(this.scriptMap=t);for(let[t,n]of Object.entries(e)){let e=await this.cacheClient?.loadScript?.(n);(0,l.notMissing)(e)?this.scriptMap?.set(t,e):this.logger?.error({message:`Error loading script ${t}`,category:this.constructor.name,code:fe.ScriptManagerLoadingError})}}async executeScript(e,t,n){try{await this.isReady()||await this.initialize({redisClientConfig:this.redisClientConfig,logger:this.logger,scriptMap:this.scriptMap});let r=this.scriptMap?.get(e);if((0,l.isMissing)(r))throw Error(`Script for ${e} not found`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(r){throw r instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${r.message}`,category:this.constructor.name,context:{keys:t,args:n},error:r,code:fe.ScriptManagerExecutionError}),r}}async isReady(){return(0,l.notMissing)(this.cacheClient)}},me=class e{options={getCacheClient:ce};subscriptionMap=null;subscriptionClient=null;logger;constructor(e){this.options={...this.options,...e}}async initialize(t=this.options){let{config:n,getCacheClient:r,logger:i}=t;if(this.logger=i,this.subscriptionMap=new O({instantiator:`${t?.instantiator}(${this.constructor.name})`,evictionFrequency:t?.subscriptionTTL,staleDataThreshold:t?.staleSubscriptionsThreshold,truncateThreshold:t?.truncateThreshold,truncationPercentage:t?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),(0,l.notMissing)(n))this.subscriptionClient=await r?.(n,this.logger)??null,this.logger?.info({message:`${e.name} initialized for ${t.instantiator}.`,category:e.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,l.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,l.notMissing)(this.subscriptionClient)&&(0,l.notMissing)(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const he=6e4,ge=15e3,_e=!1,ve=6e4,ye=15e3,be=1e4,xe=1;let Se=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),Ce=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});const we={[Ce.rPush]:`
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(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},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const l=c(require(`@stackone/utils`)),u=c(require(`redis`)),d=c(require(`axios`)),f=c(require(`node:https`)),p=c(require(`crypto`)),m=c(require(`node:timers`)),h=c(require(`jsonpath`)),g=c(require(`qs`)),_=c(require(`@stackone/expressions`)),v=e=>{switch(e.type){case`basic`:return y(e);case`bearer`:return b(e);case`oauth2`:return b(e);default:throw Error(`Invalid authentication type`)}},y=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n,i=Buffer.from(`${e}:${t}`).toString(r);return{authorization:`Basic ${i}`}},b=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var x=class{locks;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);if(r&&i){i.push({lock:n,unlock:t});let e=i.length-2;await i[e].lock}else 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 S=1e3,C=100,ee=60,w=6e4,T=ee,E=w,te=w*10,ne=C,re=10;let D=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var O=class{config;instantiator;dataStore;lockManager;expiryMap;evictionFrequency;staleDataThreshold;truncateThreshold;truncationPercentage;logger;typeGuard;dispose;evictionInterval;lastAccessedAt=Date.now();constructor(e={}){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 x,this.expiryMap=e?.expiryMap??new Map,this.evictionFrequency=e?.evictionFrequency??E,this.staleDataThreshold=e?.staleDataThreshold??te,this.truncateThreshold=e?.truncateThreshold??ne,this.truncationPercentage=e?.truncationPercentage??re,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 setData({key:e,value:t,cacheTTL:n=T}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),(0,l.notMissing)(this.typeGuard)&&!this.typeGuard(t))return!1;let r=n*S,i=Date.now()+r;return await this.lockManager.withLock(e,async()=>{((0,l.notMissing)(this.typeGuard)&&this.typeGuard(t)||(0,l.isMissing)(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,i)}),!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;this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/C;(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);let i=this.dataStore.size;return{dataStoreSize:e,prunedDataStoreSize:i}}startEvictionTask(){if((0,l.notMissing)(this.evictionInterval))return;let e=async()=>{let t;try{let n=this.lastAccessedAt+this.staleDataThreshold,r=Date.now();if(n<r){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}t=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(e,this.evictionFrequency)}catch(t){t instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:t,code:D.MemoryStorePruneError}),this.evictionInterval=setTimeout(e,this.evictionFrequency)}finally{if((0,l.notMissing)(t?.dataStoreSize)&&(0,l.notMissing)(t?.prunedDataStoreSize)){let{dataStoreSize:e,prunedDataStoreSize:n}=t,r=e-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(e,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&(clearTimeout(this.evictionInterval),this.evictionInterval=void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return(0,l.notMissing)(this.evictionInterval)&&(0,l.notMissing)(this.dataStore)&&(0,l.notMissing)(this.expiryMap)&&(0,l.notMissing)(this.lockManager)}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()),i=r.filter(t=>t.includes(e)),a=[],o=t?parseInt(t,10):0;for(let e=o;e<n+o;e++){let t=i[e];if(!t)break;let r=await this.getData(t);if(r&&a.push(r),a.length>=n)break}return{items:a,cursor:a.length<n?void 0:(o+n).toString()}}};const ie=1e3,ae=6e4;let oe=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var se=class{executorMethodStore=null;promiseStore=null;logger;eventClientConfig=null;executorMethodStoreConfig=null;pendingPromiseStoreConfig=null;constructor(e,t,n){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 O(i),this.promiseStore=new O(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/ie;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,l.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,l.isMissing)(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??ae),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:oe.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){(0,l.notMissing)(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):(0,l.notMissing)(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return(0,l.isObject)(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}};let k=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 ce=async(e,t)=>{try{let n=await le.build(e,t);return n??void 0}catch(e){let n=e;t?.error({message:`Error building Cache Manager`,error:n,code:k.RedisClientError,category:`buildRedisClientInstance`});return}};var le=class e{#redisClient;#logger;static async build({getRedisClient:t=u.createClient,host:n,port:r,tls:i,reconnect:a=!0,database:o},s){let c=new e;c.#logger=s;try{c.#redisClient=t({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:n,port:r,tls:i},database:o,disableOfflineQueue:!0});let s=de(e.name,c.#logger);return ue(c.#redisClient,s),await c.#redisClient.connect(),c}catch(t){let n=t;return c.#logger?.error({message:`Error building Cache Manager.`,error:n,code:k.RedisClientError,category:e.name}),null}}#parseData(e){try{return JSON.parse(e)}catch{return e}}async getData(t){if(!this.#isRedisClientAvailable())return null;try{let e=await this.#redisClient.get(t);if(!e)return null;let n=this.#parseData(e);return(0,l.isString)(n)?e:n}catch(t){let n=t;return this.#logger?.error({message:`Error getting data`,error:n,code:k.RedisClientReadError,category:e.name}),null}}async setData({key:t,value:n,cacheTTL:r,groupKey:i}){if(!this.#isRedisClientAvailable())return!1;try{let e=(0,l.isString)(n)?n:JSON.stringify(n);return await this.#redisClient.set(t,e,{EX:r}),(0,l.notMissing)(i)&&await this.#redisClient.sAdd(i,[t]),!0}catch(t){let n=t;return this.#logger?.error({message:`Error setting data`,error:n,code:k.RedisClientWriteError,category:e.name}),!1}}async executeScript({sha1:t,keys:n,args:r}){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.evalSha(t,{keys:n,arguments:r})}catch(t){let n=t;return this.#logger?.error({message:`Error executing script`,error:n,code:k.RedisClientScriptExecuteError,category:e.name}),null}}async loadScript(t){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.scriptLoad(t)}catch(t){let n=t;return this.#logger?.error({message:`Error loading script`,error:n,code:k.RedisClientScriptLoadError,category:e.name}),null}}async#executeCounterCommand(t,n,r){if(!this.#isRedisClientAvailable())return null;if(!Number.isFinite(r)||r<=0)return this.#logger?.error({message:`Invalid cacheTTL parameter`,category:e.name,code:k.RedisClientInvalidTTL}),null;try{let e=[{args:[t,n]},{args:[`expire`,n,r.toString()]}],i=await this.#redisClient.multiExecutor(e),a=i?.[0];return typeof a==`number`?a:null}catch(n){let r=n;return this.#logger?.error({message:`Error executing ${t} operation`,error:r,code:k.RedisClientCommandError,category:e.name}),null}}async increment(e,t){return this.#executeCounterCommand(`incr`,e,t)}async decrement(e,t){return this.#executeCounterCommand(`decr`,e,t)}async subscribe(t,n){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pSubscribe(t,n),!0}catch(n){let r=n;return this.#logger?.error({message:`Error subscribing to ${t}`,error:r,code:k.RedisClientSubscribeError,category:e.name}),!1}}async unsubscribe(t){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pUnsubscribe(t),!0}catch(n){let r=n;return this.#logger?.error({message:`Error unsubscribing from ${t}`,error:r,code:k.RedisClientUnsubscribeError,category:e.name}),!1}}async publish(t,n){if(!this.#isRedisClientAvailable())return null;try{let r=await this.#redisClient.publish(t,n);return r===0&&this.#logger?.debug({message:`No subscribers found for channel ${t}`,category:e.name}),r}catch(n){let r=n;return this.#logger?.error({message:`Error publishing to ${t}`,error:r,code:k.RedisClientPublishError,category:e.name}),null}}getClient(){return this.#isRedisClientAvailable()?this.#redisClient:null}#isRedisClientAvailable(){let t=this.#redisClient.isReady&&this.#redisClient.isOpen;return t||this.#logger?.error({message:`Redis Client is not ready.`,category:e.name,code:k.RedisClientRedisNotReady}),t}async listData({partialKey:t,limit:n,cursor:r}){try{let e=r?parseInt(r,10):0,i=await this.#redisClient.sScan(t,e,{COUNT:n}),a=[];for(let e of i.members){let t=await this.getData(e);(0,l.notMissing)(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(t){let n=t;return this.#logger?.error({message:`Error listing data`,error:n,code:k.RedisClientListError,category:e.name}),{items:null}}}async deleteData(t){try{if(!this.#isRedisClientAvailable())return!1;let n=await this.#redisClient.del(t);return n===0&&this.#logger?.debug({message:`No keys deleted for ${t}`,category:e.name}),n>0}catch(t){let n=t;return this.#logger?.error({message:`Error deleting data`,error:n,code:k.RedisClientDeleteError,category:e.name}),!1}}};const ue=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},de=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:k.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 fe=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});var pe=class{cacheClient=null;scriptMap=new Map;logger;scripts;redisClientConfig;constructor(e){this.scripts=e}async initialize({redisClientConfig:e,logger:t,scriptMap:n},...r){this.redisClientConfig=e,this.logger=t,this.cacheClient=await ce(this.redisClientConfig,this.logger)??null,await this.loadScripts(this.scripts,n),await this.additionalInitialization(...r)}async additionalInitialization(...e){}async loadScripts(e,t){(0,l.notMissing)(t)&&(this.scriptMap=t);for(let[t,n]of Object.entries(e)){let e=await this.cacheClient?.loadScript?.(n);(0,l.notMissing)(e)?this.scriptMap?.set(t,e):this.logger?.error({message:`Error loading script ${t}`,category:this.constructor.name,code:fe.ScriptManagerLoadingError})}}async executeScript(e,t,n){try{await this.isReady()||await this.initialize({redisClientConfig:this.redisClientConfig,logger:this.logger,scriptMap:this.scriptMap});let r=this.scriptMap?.get(e);if((0,l.isMissing)(r))throw Error(`Script for ${e} not found`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(r){throw r instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${r.message}`,category:this.constructor.name,context:{keys:t,args:n},error:r,code:fe.ScriptManagerExecutionError}),r}}async isReady(){return(0,l.notMissing)(this.cacheClient)}},me=class e{options={getCacheClient:ce};subscriptionMap=null;subscriptionClient=null;logger;constructor(e){this.options={...this.options,...e}}async initialize(t=this.options){let{config:n,getCacheClient:r,logger:i}=t;if(this.logger=i,this.subscriptionMap=new O({instantiator:`${t?.instantiator}(${this.constructor.name})`,evictionFrequency:t?.subscriptionTTL,staleDataThreshold:t?.staleSubscriptionsThreshold,truncateThreshold:t?.truncateThreshold,truncationPercentage:t?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),(0,l.notMissing)(n))this.subscriptionClient=await r?.(n,this.logger)??null,this.logger?.info({message:`${e.name} initialized for ${t.instantiator}.`,category:e.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,l.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,l.notMissing)(this.subscriptionClient)&&(0,l.notMissing)(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const he=6e4,ge=15e3,_e=!1,ve=6e4,ye=15e3,be=1e4,xe=1;let Se=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),Ce=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});const we={[Ce.rPush]:`
|
|
2
2
|
local queueLength = redis.call('RPUSH', KEYS[1], ARGV[1])
|
|
3
3
|
|
|
4
4
|
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{delay as e,exponentialBackoffInMS as t,generateRequestId as n,getContentHash as r,isFunction as i,isFutureUnixTimestamp as a,isMissing as o,isNumber as s,isObject as c,isString as l,notMissing as u}from"@stackone/utils";import*as d from"redis";import f,{isAxiosError as p}from"axios";import m from"node:https";import{randomUUID as h}from"crypto";import{clearTimeout as g}from"node:timers";import _ from"jsonpath";import v from"qs";import{safeEvaluate as y}from"@stackone/expressions";var b=Object.create,x=Object.defineProperty,S=Object.getOwnPropertyDescriptor,C=Object.getOwnPropertyNames,ee=Object.getPrototypeOf,te=Object.prototype.hasOwnProperty,w=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),T=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=C(t),a=0,o=i.length,s;a<o;a++)s=i[a],!te.call(e,s)&&s!==n&&x(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=S(t,s))||r.enumerable});return e},E=(e,t,n)=>(n=e==null?{}:b(ee(e)),T(t||!e||!e.__esModule?x(n,`default`,{value:e,enumerable:!0}):n,e));const ne=e=>{switch(e.type){case`basic`:return re(e);case`bearer`:return D(e);default:throw Error(`Invalid authentication type`)}},re=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n,i=Buffer.from(`${e}:${t}`).toString(r);return{authorization:`Basic ${i}`}},D=({token:e,includeBearer:t=!0})=>({authorization:`${t?`Bearer `:``}${e}`});var O=class{locks;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);if(r&&i){i.push({lock:n,unlock:t});let e=i.length-2;await i[e].lock}else 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 ie=1e3,ae=100,oe=60,se=6e4,ce=oe,le=se,ue=se*10,de=ae,fe=10;let pe=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var me=class{config;instantiator;dataStore;lockManager;expiryMap;evictionFrequency;staleDataThreshold;truncateThreshold;truncationPercentage;logger;typeGuard;dispose;evictionInterval;lastAccessedAt=Date.now();constructor(e={}){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 O,this.expiryMap=e?.expiryMap??new Map,this.evictionFrequency=e?.evictionFrequency??le,this.staleDataThreshold=e?.staleDataThreshold??ue,this.truncateThreshold=e?.truncateThreshold??de,this.truncationPercentage=e?.truncationPercentage??fe,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 setData({key:e,value:t,cacheTTL:n=ce}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),u(this.typeGuard)&&!this.typeGuard(t))return!1;let r=n*ie,i=Date.now()+r;return await this.lockManager.withLock(e,async()=>{(u(this.typeGuard)&&this.typeGuard(t)||o(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,i)}),!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;this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/ae;(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);let i=this.dataStore.size;return{dataStoreSize:e,prunedDataStoreSize:i}}startEvictionTask(){if(u(this.evictionInterval))return;let e=async()=>{let t;try{let n=this.lastAccessedAt+this.staleDataThreshold,r=Date.now();if(n<r){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}t=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(e,this.evictionFrequency)}catch(t){t instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:t,code:pe.MemoryStorePruneError}),this.evictionInterval=setTimeout(e,this.evictionFrequency)}finally{if(u(t?.dataStoreSize)&&u(t?.prunedDataStoreSize)){let{dataStoreSize:e,prunedDataStoreSize:n}=t,r=e-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(e,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&(clearTimeout(this.evictionInterval),this.evictionInterval=void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return u(this.evictionInterval)&&u(this.dataStore)&&u(this.expiryMap)&&u(this.lockManager)}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()),i=r.filter(t=>t.includes(e)),a=[],o=t?parseInt(t,10):0;for(let e=o;e<n+o;e++){let t=i[e];if(!t)break;let r=await this.getData(t);if(r&&a.push(r),a.length>=n)break}return{items:a,cursor:a.length<n?void 0:(o+n).toString()}}};const he=1e3,ge=6e4;let _e=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var ve=class{executorMethodStore=null;promiseStore=null;logger;eventClientConfig=null;executorMethodStoreConfig=null;pendingPromiseStoreConfig=null;constructor(e,t,n){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 me(i),this.promiseStore=new me(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/he;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 u(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);o(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??ge),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:_e.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){u(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):u(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return c(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}};let k=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 ye=async(e,t)=>{try{let n=await be.build(e,t);return n??void 0}catch(e){let n=e;t?.error({message:`Error building Cache Manager`,error:n,code:k.RedisClientError,category:`buildRedisClientInstance`});return}};var be=class e{#redisClient;#logger;static async build({getRedisClient:t=d.createClient,host:n,port:r,tls:i,reconnect:a=!0,database:o},s){let c=new e;c.#logger=s;try{c.#redisClient=t({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:n,port:r,tls:i},database:o,disableOfflineQueue:!0});let s=Se(e.name,c.#logger);return xe(c.#redisClient,s),await c.#redisClient.connect(),c}catch(t){let n=t;return c.#logger?.error({message:`Error building Cache Manager.`,error:n,code:k.RedisClientError,category:e.name}),null}}#parseData(e){try{return JSON.parse(e)}catch{return e}}async getData(t){if(!this.#isRedisClientAvailable())return null;try{let e=await this.#redisClient.get(t);if(!e)return null;let n=this.#parseData(e);return l(n)?e:n}catch(t){let n=t;return this.#logger?.error({message:`Error getting data`,error:n,code:k.RedisClientReadError,category:e.name}),null}}async setData({key:t,value:n,cacheTTL:r,groupKey:i}){if(!this.#isRedisClientAvailable())return!1;try{let e=l(n)?n:JSON.stringify(n);return await this.#redisClient.set(t,e,{EX:r}),u(i)&&await this.#redisClient.sAdd(i,[t]),!0}catch(t){let n=t;return this.#logger?.error({message:`Error setting data`,error:n,code:k.RedisClientWriteError,category:e.name}),!1}}async executeScript({sha1:t,keys:n,args:r}){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.evalSha(t,{keys:n,arguments:r})}catch(t){let n=t;return this.#logger?.error({message:`Error executing script`,error:n,code:k.RedisClientScriptExecuteError,category:e.name}),null}}async loadScript(t){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.scriptLoad(t)}catch(t){let n=t;return this.#logger?.error({message:`Error loading script`,error:n,code:k.RedisClientScriptLoadError,category:e.name}),null}}async#executeCounterCommand(t,n,r){if(!this.#isRedisClientAvailable())return null;if(!Number.isFinite(r)||r<=0)return this.#logger?.error({message:`Invalid cacheTTL parameter`,category:e.name,code:k.RedisClientInvalidTTL}),null;try{let e=[{args:[t,n]},{args:[`expire`,n,r.toString()]}],i=await this.#redisClient.multiExecutor(e),a=i?.[0];return typeof a==`number`?a:null}catch(n){let r=n;return this.#logger?.error({message:`Error executing ${t} operation`,error:r,code:k.RedisClientCommandError,category:e.name}),null}}async increment(e,t){return this.#executeCounterCommand(`incr`,e,t)}async decrement(e,t){return this.#executeCounterCommand(`decr`,e,t)}async subscribe(t,n){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pSubscribe(t,n),!0}catch(n){let r=n;return this.#logger?.error({message:`Error subscribing to ${t}`,error:r,code:k.RedisClientSubscribeError,category:e.name}),!1}}async unsubscribe(t){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pUnsubscribe(t),!0}catch(n){let r=n;return this.#logger?.error({message:`Error unsubscribing from ${t}`,error:r,code:k.RedisClientUnsubscribeError,category:e.name}),!1}}async publish(t,n){if(!this.#isRedisClientAvailable())return null;try{let r=await this.#redisClient.publish(t,n);return r===0&&this.#logger?.debug({message:`No subscribers found for channel ${t}`,category:e.name}),r}catch(n){let r=n;return this.#logger?.error({message:`Error publishing to ${t}`,error:r,code:k.RedisClientPublishError,category:e.name}),null}}getClient(){return this.#isRedisClientAvailable()?this.#redisClient:null}#isRedisClientAvailable(){let t=this.#redisClient.isReady&&this.#redisClient.isOpen;return t||this.#logger?.error({message:`Redis Client is not ready.`,category:e.name,code:k.RedisClientRedisNotReady}),t}async listData({partialKey:t,limit:n,cursor:r}){try{let e=r?parseInt(r,10):0,i=await this.#redisClient.sScan(t,e,{COUNT:n}),a=[];for(let e of i.members){let t=await this.getData(e);u(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(t){let n=t;return this.#logger?.error({message:`Error listing data`,error:n,code:k.RedisClientListError,category:e.name}),{items:null}}}async deleteData(t){try{if(!this.#isRedisClientAvailable())return!1;let n=await this.#redisClient.del(t);return n===0&&this.#logger?.debug({message:`No keys deleted for ${t}`,category:e.name}),n>0}catch(t){let n=t;return this.#logger?.error({message:`Error deleting data`,error:n,code:k.RedisClientDeleteError,category:e.name}),!1}}};const xe=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},Se=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:k.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 Ce=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});var we=class{cacheClient=null;scriptMap=new Map;logger;scripts;redisClientConfig;constructor(e){this.scripts=e}async initialize({redisClientConfig:e,logger:t,scriptMap:n},...r){this.redisClientConfig=e,this.logger=t,this.cacheClient=await ye(this.redisClientConfig,this.logger)??null,await this.loadScripts(this.scripts,n),await this.additionalInitialization(...r)}async additionalInitialization(...e){}async loadScripts(e,t){u(t)&&(this.scriptMap=t);for(let[t,n]of Object.entries(e)){let e=await this.cacheClient?.loadScript?.(n);u(e)?this.scriptMap?.set(t,e):this.logger?.error({message:`Error loading script ${t}`,category:this.constructor.name,code:Ce.ScriptManagerLoadingError})}}async executeScript(e,t,n){try{await this.isReady()||await this.initialize({redisClientConfig:this.redisClientConfig,logger:this.logger,scriptMap:this.scriptMap});let r=this.scriptMap?.get(e);if(o(r))throw Error(`Script for ${e} not found`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(r){throw r instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${r.message}`,category:this.constructor.name,context:{keys:t,args:n},error:r,code:Ce.ScriptManagerExecutionError}),r}}async isReady(){return u(this.cacheClient)}},Te=class e{options={getCacheClient:ye};subscriptionMap=null;subscriptionClient=null;logger;constructor(e){this.options={...this.options,...e}}async initialize(t=this.options){let{config:n,getCacheClient:r,logger:i}=t;if(this.logger=i,this.subscriptionMap=new me({instantiator:`${t?.instantiator}(${this.constructor.name})`,evictionFrequency:t?.subscriptionTTL,staleDataThreshold:t?.staleSubscriptionsThreshold,truncateThreshold:t?.truncateThreshold,truncationPercentage:t?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),u(n))this.subscriptionClient=await r?.(n,this.logger)??null,this.logger?.info({message:`${e.name} initialized for ${t.instantiator}.`,category:e.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),i=r(t.toString());return await this.subscriptionMap?.setData({key:e,value:i}),n===i?!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 u(this.subscriptionClient)&&u(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const Ee=6e4,De=15e3,Oe=!1,ke=6e4,Ae=15e3,je=1e4,Me=1;let Ne=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),Pe=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});const Fe={[Pe.rPush]:`
|
|
1
|
+
import{delay as e,exponentialBackoffInMS as t,generateRequestId as n,getContentHash as r,isFunction as i,isFutureUnixTimestamp as a,isMissing as o,isNumber as s,isObject as c,isString as l,notMissing as u}from"@stackone/utils";import*as d from"redis";import f,{isAxiosError as p}from"axios";import m from"node:https";import{randomUUID as h}from"crypto";import{clearTimeout as g}from"node:timers";import _ from"jsonpath";import v from"qs";import{safeEvaluate as y}from"@stackone/expressions";var b=Object.create,x=Object.defineProperty,S=Object.getOwnPropertyDescriptor,C=Object.getOwnPropertyNames,ee=Object.getPrototypeOf,te=Object.prototype.hasOwnProperty,w=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),T=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=C(t),a=0,o=i.length,s;a<o;a++)s=i[a],!te.call(e,s)&&s!==n&&x(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=S(t,s))||r.enumerable});return e},E=(e,t,n)=>(n=e==null?{}:b(ee(e)),T(t||!e||!e.__esModule?x(n,`default`,{value:e,enumerable:!0}):n,e));const ne=e=>{switch(e.type){case`basic`:return re(e);case`bearer`:return D(e);case`oauth2`:return D(e);default:throw Error(`Invalid authentication type`)}},re=({username:e=``,password:t=``,encoding:n=`base64`})=>{let r=n,i=Buffer.from(`${e}:${t}`).toString(r);return{authorization:`Basic ${i}`}},D=({token:e,includeBearer:t})=>({authorization:`${t?`Bearer `:``}${e}`});var O=class{locks;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);if(r&&i){i.push({lock:n,unlock:t});let e=i.length-2;await i[e].lock}else 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 ie=1e3,ae=100,oe=60,se=6e4,ce=oe,le=se,ue=se*10,de=ae,fe=10;let pe=function(e){return e.MemoryStorePruneError=`MemoryStorePruneError`,e}({});var me=class{config;instantiator;dataStore;lockManager;expiryMap;evictionFrequency;staleDataThreshold;truncateThreshold;truncationPercentage;logger;typeGuard;dispose;evictionInterval;lastAccessedAt=Date.now();constructor(e={}){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 O,this.expiryMap=e?.expiryMap??new Map,this.evictionFrequency=e?.evictionFrequency??le,this.staleDataThreshold=e?.staleDataThreshold??ue,this.truncateThreshold=e?.truncateThreshold??de,this.truncationPercentage=e?.truncationPercentage??fe,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 setData({key:e,value:t,cacheTTL:n=ce}){if(this.isReady()||this.initialize(),this.updateLastAccessedAt(),u(this.typeGuard)&&!this.typeGuard(t))return!1;let r=n*ie,i=Date.now()+r;return await this.lockManager.withLock(e,async()=>{(u(this.typeGuard)&&this.typeGuard(t)||o(this.typeGuard)&&this.typeGuardBypass(t))&&this.dataStore.set(e,t),this.expiryMap.set(e,i)}),!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;this.dataStore.forEach(async(e,i)=>{let a=Date.now(),o=this.expiryMap.get(i)??0,s=this.truncateThreshold*this.truncationPercentage/ae;(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);let i=this.dataStore.size;return{dataStoreSize:e,prunedDataStoreSize:i}}startEvictionTask(){if(u(this.evictionInterval))return;let e=async()=>{let t;try{let n=this.lastAccessedAt+this.staleDataThreshold,r=Date.now();if(n<r){this.logger?.warning({message:`Closing the ${this.instantiator}'s MemoryStore instance - received no requests for a while.`,category:`MemoryStore`}),this.close();return}t=await this.pruneExpiredKeys(),this.evictionInterval=setTimeout(e,this.evictionFrequency)}catch(t){t instanceof Error&&this.logger?.error({message:`Error during pruning expired keys:`,category:`MemoryStore`,error:t,code:pe.MemoryStorePruneError}),this.evictionInterval=setTimeout(e,this.evictionFrequency)}finally{if(u(t?.dataStoreSize)&&u(t?.prunedDataStoreSize)){let{dataStoreSize:e,prunedDataStoreSize:n}=t,r=e-n;this.logger?.debug({message:`Pruned ${r} expired keys, ${n} remain, scheduling next prune.`,category:`MemoryStore`,context:{instantiator:this.instantiator}})}}};this.evictionInterval=setTimeout(e,this.evictionFrequency)}stopEvictionTask(){this.evictionInterval&&(clearTimeout(this.evictionInterval),this.evictionInterval=void 0)}updateLastAccessedAt(){this.lastAccessedAt=Date.now()}isReady(){return u(this.evictionInterval)&&u(this.dataStore)&&u(this.expiryMap)&&u(this.lockManager)}close(){this.stopEvictionTask(),this.dataStore.clear(),this.expiryMap.clear(),this.lockManager.close()}async listData({partialKey:e,cursor:t,limit:n}){let r=Array.from(this.dataStore.keys()),i=r.filter(t=>t.includes(e)),a=[],o=t?parseInt(t,10):0;for(let e=o;e<n+o;e++){let t=i[e];if(!t)break;let r=await this.getData(t);if(r&&a.push(r),a.length>=n)break}return{items:a,cursor:a.length<n?void 0:(o+n).toString()}}};const he=1e3,ge=6e4;let _e=function(e){return e.EventClientResolveError=`EventClientResolveError`,e}({});var ve=class{executorMethodStore=null;promiseStore=null;logger;eventClientConfig=null;executorMethodStoreConfig=null;pendingPromiseStoreConfig=null;constructor(e,t,n){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 me(i),this.promiseStore=new me(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/he;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 u(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);o(n)&&(await this.setPendingEvent(e,this.eventClientConfig?.defaultTimeoutMS??ge),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:_e.EventClientResolveError})}}async defaultExecutorMethodDispose(e,t){u(t?.resolve)?t.resolve(this.eventClientConfig?.timeoutResolveValue):u(t?.reject)&&t.reject(Error(`Event key: ${e} was not resolved or the event was disposed`))}defaultExecutorMethodTypeGuard(e){return c(e)&&e.hasOwnProperty(`resolve`)&&e.hasOwnProperty(`reject`)}async defaultPendingPromiseDispose(e,t){t instanceof Promise&&t?.finally(()=>{})}defaultPendingPromiseTypeGuard(e){return e instanceof Promise}};let k=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 ye=async(e,t)=>{try{let n=await be.build(e,t);return n??void 0}catch(e){let n=e;t?.error({message:`Error building Cache Manager`,error:n,code:k.RedisClientError,category:`buildRedisClientInstance`});return}};var be=class e{#redisClient;#logger;static async build({getRedisClient:t=d.createClient,host:n,port:r,tls:i,reconnect:a=!0,database:o},s){let c=new e;c.#logger=s;try{c.#redisClient=t({socket:{reconnectStrategy:a?e=>Math.min(e*20,5e3):!1,host:n,port:r,tls:i},database:o,disableOfflineQueue:!0});let s=Se(e.name,c.#logger);return xe(c.#redisClient,s),await c.#redisClient.connect(),c}catch(t){let n=t;return c.#logger?.error({message:`Error building Cache Manager.`,error:n,code:k.RedisClientError,category:e.name}),null}}#parseData(e){try{return JSON.parse(e)}catch{return e}}async getData(t){if(!this.#isRedisClientAvailable())return null;try{let e=await this.#redisClient.get(t);if(!e)return null;let n=this.#parseData(e);return l(n)?e:n}catch(t){let n=t;return this.#logger?.error({message:`Error getting data`,error:n,code:k.RedisClientReadError,category:e.name}),null}}async setData({key:t,value:n,cacheTTL:r,groupKey:i}){if(!this.#isRedisClientAvailable())return!1;try{let e=l(n)?n:JSON.stringify(n);return await this.#redisClient.set(t,e,{EX:r}),u(i)&&await this.#redisClient.sAdd(i,[t]),!0}catch(t){let n=t;return this.#logger?.error({message:`Error setting data`,error:n,code:k.RedisClientWriteError,category:e.name}),!1}}async executeScript({sha1:t,keys:n,args:r}){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.evalSha(t,{keys:n,arguments:r})}catch(t){let n=t;return this.#logger?.error({message:`Error executing script`,error:n,code:k.RedisClientScriptExecuteError,category:e.name}),null}}async loadScript(t){if(!this.#isRedisClientAvailable())return null;try{return await this.#redisClient.scriptLoad(t)}catch(t){let n=t;return this.#logger?.error({message:`Error loading script`,error:n,code:k.RedisClientScriptLoadError,category:e.name}),null}}async#executeCounterCommand(t,n,r){if(!this.#isRedisClientAvailable())return null;if(!Number.isFinite(r)||r<=0)return this.#logger?.error({message:`Invalid cacheTTL parameter`,category:e.name,code:k.RedisClientInvalidTTL}),null;try{let e=[{args:[t,n]},{args:[`expire`,n,r.toString()]}],i=await this.#redisClient.multiExecutor(e),a=i?.[0];return typeof a==`number`?a:null}catch(n){let r=n;return this.#logger?.error({message:`Error executing ${t} operation`,error:r,code:k.RedisClientCommandError,category:e.name}),null}}async increment(e,t){return this.#executeCounterCommand(`incr`,e,t)}async decrement(e,t){return this.#executeCounterCommand(`decr`,e,t)}async subscribe(t,n){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pSubscribe(t,n),!0}catch(n){let r=n;return this.#logger?.error({message:`Error subscribing to ${t}`,error:r,code:k.RedisClientSubscribeError,category:e.name}),!1}}async unsubscribe(t){if(!this.#isRedisClientAvailable())return!1;try{return await this.#redisClient.pUnsubscribe(t),!0}catch(n){let r=n;return this.#logger?.error({message:`Error unsubscribing from ${t}`,error:r,code:k.RedisClientUnsubscribeError,category:e.name}),!1}}async publish(t,n){if(!this.#isRedisClientAvailable())return null;try{let r=await this.#redisClient.publish(t,n);return r===0&&this.#logger?.debug({message:`No subscribers found for channel ${t}`,category:e.name}),r}catch(n){let r=n;return this.#logger?.error({message:`Error publishing to ${t}`,error:r,code:k.RedisClientPublishError,category:e.name}),null}}getClient(){return this.#isRedisClientAvailable()?this.#redisClient:null}#isRedisClientAvailable(){let t=this.#redisClient.isReady&&this.#redisClient.isOpen;return t||this.#logger?.error({message:`Redis Client is not ready.`,category:e.name,code:k.RedisClientRedisNotReady}),t}async listData({partialKey:t,limit:n,cursor:r}){try{let e=r?parseInt(r,10):0,i=await this.#redisClient.sScan(t,e,{COUNT:n}),a=[];for(let e of i.members){let t=await this.getData(e);u(t)&&a.push(t)}return{items:a,cursor:i.cursor>0?i.cursor.toString():void 0}}catch(t){let n=t;return this.#logger?.error({message:`Error listing data`,error:n,code:k.RedisClientListError,category:e.name}),{items:null}}}async deleteData(t){try{if(!this.#isRedisClientAvailable())return!1;let n=await this.#redisClient.del(t);return n===0&&this.#logger?.debug({message:`No keys deleted for ${t}`,category:e.name}),n>0}catch(t){let n=t;return this.#logger?.error({message:`Error deleting data`,error:n,code:k.RedisClientDeleteError,category:e.name}),!1}}};const xe=(e,t)=>{t.forEach(({eventName:t,listener:n})=>{e.on(t,n)})},Se=(e=`RedisClient`,t)=>[{eventName:`error`,listener:n=>{t?.error({message:`Redis client error ${n.message}`,error:n,code:k.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 Ce=function(e){return e.ScriptManagerExecutionError=`ScriptManagerExecutionError`,e.ScriptManagerLoadingError=`ScriptManagerLoadingError`,e}({});var we=class{cacheClient=null;scriptMap=new Map;logger;scripts;redisClientConfig;constructor(e){this.scripts=e}async initialize({redisClientConfig:e,logger:t,scriptMap:n},...r){this.redisClientConfig=e,this.logger=t,this.cacheClient=await ye(this.redisClientConfig,this.logger)??null,await this.loadScripts(this.scripts,n),await this.additionalInitialization(...r)}async additionalInitialization(...e){}async loadScripts(e,t){u(t)&&(this.scriptMap=t);for(let[t,n]of Object.entries(e)){let e=await this.cacheClient?.loadScript?.(n);u(e)?this.scriptMap?.set(t,e):this.logger?.error({message:`Error loading script ${t}`,category:this.constructor.name,code:Ce.ScriptManagerLoadingError})}}async executeScript(e,t,n){try{await this.isReady()||await this.initialize({redisClientConfig:this.redisClientConfig,logger:this.logger,scriptMap:this.scriptMap});let r=this.scriptMap?.get(e);if(o(r))throw Error(`Script for ${e} not found`);return await this.cacheClient?.executeScript?.({sha1:r,keys:t,args:n})??null}catch(r){throw r instanceof Error&&this.logger?.error({message:`Error executing script ${e}: ${r.message}`,category:this.constructor.name,context:{keys:t,args:n},error:r,code:Ce.ScriptManagerExecutionError}),r}}async isReady(){return u(this.cacheClient)}},Te=class e{options={getCacheClient:ye};subscriptionMap=null;subscriptionClient=null;logger;constructor(e){this.options={...this.options,...e}}async initialize(t=this.options){let{config:n,getCacheClient:r,logger:i}=t;if(this.logger=i,this.subscriptionMap=new me({instantiator:`${t?.instantiator}(${this.constructor.name})`,evictionFrequency:t?.subscriptionTTL,staleDataThreshold:t?.staleSubscriptionsThreshold,truncateThreshold:t?.truncateThreshold,truncationPercentage:t?.truncationPercentage,typeGuard:e=>typeof e==`string`,dispose:async e=>{await this.subscriptionClient?.unsubscribe?.(e)}}),u(n))this.subscriptionClient=await r?.(n,this.logger)??null,this.logger?.info({message:`${e.name} initialized for ${t.instantiator}.`,category:e.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),i=r(t.toString());return await this.subscriptionMap?.setData({key:e,value:i}),n===i?!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 u(this.subscriptionClient)&&u(this.subscriptionMap)}close(){this.subscriptionMap?.close(),this.subscriptionMap=null,this.subscriptionClient=null}};const Ee=6e4,De=15e3,Oe=!1,ke=6e4,Ae=15e3,je=1e4,Me=1;let Ne=function(e){return e.QueueManagerInitializationError=`QueueManagerInitializationError`,e.QueueManagerJoinAndWaitTurnError=`QueueManagerJoinAndWaitTurnError`,e.QueueManagerLengthError=`QueueManagerLengthError`,e.QueueManagerPopError=`QueueManagerPopError`,e}({}),Pe=function(e){return e.rPush=`rPush`,e.lPush=`lPush`,e.lPop=`lPop`,e.llen=`llen`,e}({});const Fe={[Pe.rPush]:`
|
|
2
2
|
local queueLength = redis.call('RPUSH', KEYS[1], ARGV[1])
|
|
3
3
|
|
|
4
4
|
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|