@stackone/transport 1.12.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 CHANGED
@@ -14,11 +14,16 @@ type BasicAuthorizationParams = {
14
14
  type BearerAuthorizationParams = {
15
15
  type: 'bearer';
16
16
  token: string;
17
- includeBearer?: boolean;
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
@@ -374,7 +379,7 @@ interface IHttpClient {
374
379
  maxRedirects?: number;
375
380
  responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
376
381
  cacheTTL?: number;
377
- context?: unknown;
382
+ context?: RequestContext;
378
383
  payload?: P;
379
384
  httpsAgent?: https.Agent;
380
385
  httpAgent?: http.Agent;
@@ -395,7 +400,7 @@ interface IHttpClient {
395
400
  queryParams?: HttpQueryParams;
396
401
  maxRedirects?: number;
397
402
  cacheTTL?: number;
398
- context?: unknown;
403
+ context?: RequestContext;
399
404
  requestConfig?: RequestConfig;
400
405
  }): Promise<HttpResponse<T>>;
401
406
  post<P, T>({
@@ -411,7 +416,7 @@ interface IHttpClient {
411
416
  url: string;
412
417
  maxRedirects?: number;
413
418
  cacheTTL?: number;
414
- context?: unknown;
419
+ context?: RequestContext;
415
420
  payload?: P;
416
421
  requestConfig?: RequestConfig;
417
422
  }): Promise<HttpResponse<T>>;
@@ -876,4 +881,4 @@ type LockEntry = {
876
881
  unlock: Unlock;
877
882
  };
878
883
  //#endregion
879
- export { CUSTOM_ERROR_CONFIG_SCHEMA, ConcurrencyManager, type CustomErrorConfig, type ErrorMappingFn, EventClient, HttpClient, HttpClientManager, HttpErrorMessages, type HttpHeaders, type HttpMethod, HttpMethods, type HttpParameters, type HttpQueryParams, type HttpResponse, HttpResponseError, HttpTransportFactory, type ICacheClient, type IHttpClient, InstanceManager, type Lock, type LockEntry, LockManager, MemoryStore, type MemoryStoreConfig, type PruneCount, type PubSubListener, QueueManager, RateLimitManager, RedisClient, type RedisClientConfig, type RedisClientType, RequestClientFactory, type RequestContext, type RequestParameter, RequestParameterLocations, ScriptManager, SubscriptionManager, type Unlock, buildHttpClientInstance, createAuthorizationHeaders, getTransportInstance, isFailedStatusCode, isInfoStatusCode, isSuccessStatusCode, parseRequestParameters };
884
+ export { CUSTOM_ERROR_CONFIG_SCHEMA, type ConcurrencyConfig, ConcurrencyManager, type CustomErrorConfig, type ErrorMappingFn, EventClient, HttpClient, HttpClientManager, HttpErrorMessages, type HttpHeaders, type HttpMethod, HttpMethods, type HttpParameters, type HttpQueryParams, type HttpResponse, HttpResponseError, HttpTransportFactory, type ICacheClient, type IHttpClient, InstanceManager, type Lock, type LockEntry, LockManager, MemoryStore, type MemoryStoreConfig, type PruneCount, type PubSubListener, QueueManager, type RateLimitConfig, RateLimitManager, RedisClient, type RedisClientConfig, type RedisClientType, RequestClientFactory, type RequestConfig, type RequestContext, type RequestParameter, RequestParameterLocations, ScriptManager, SubscriptionManager, type Unlock, buildHttpClientInstance, createAuthorizationHeaders, getTransportInstance, isFailedStatusCode, isInfoStatusCode, isSuccessStatusCode, parseRequestParameters };
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?: boolean;
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
@@ -374,7 +379,7 @@ interface IHttpClient {
374
379
  maxRedirects?: number;
375
380
  responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
376
381
  cacheTTL?: number;
377
- context?: unknown;
382
+ context?: RequestContext;
378
383
  payload?: P;
379
384
  httpsAgent?: https.Agent;
380
385
  httpAgent?: http.Agent;
@@ -395,7 +400,7 @@ interface IHttpClient {
395
400
  queryParams?: HttpQueryParams;
396
401
  maxRedirects?: number;
397
402
  cacheTTL?: number;
398
- context?: unknown;
403
+ context?: RequestContext;
399
404
  requestConfig?: RequestConfig;
400
405
  }): Promise<HttpResponse<T>>;
401
406
  post<P, T>({
@@ -411,7 +416,7 @@ interface IHttpClient {
411
416
  url: string;
412
417
  maxRedirects?: number;
413
418
  cacheTTL?: number;
414
- context?: unknown;
419
+ context?: RequestContext;
415
420
  payload?: P;
416
421
  requestConfig?: RequestConfig;
417
422
  }): Promise<HttpResponse<T>>;
@@ -876,4 +881,4 @@ type LockEntry = {
876
881
  unlock: Unlock;
877
882
  };
878
883
  //#endregion
879
- export { CUSTOM_ERROR_CONFIG_SCHEMA, ConcurrencyManager, type CustomErrorConfig, type ErrorMappingFn, EventClient, HttpClient, HttpClientManager, HttpErrorMessages, type HttpHeaders, type HttpMethod, HttpMethods, type HttpParameters, type HttpQueryParams, type HttpResponse, HttpResponseError, HttpTransportFactory, type ICacheClient, type IHttpClient, InstanceManager, type Lock, type LockEntry, LockManager, MemoryStore, type MemoryStoreConfig, type PruneCount, type PubSubListener, QueueManager, RateLimitManager, RedisClient, type RedisClientConfig, type RedisClientType, RequestClientFactory, type RequestContext, type RequestParameter, RequestParameterLocations, ScriptManager, SubscriptionManager, type Unlock, buildHttpClientInstance, createAuthorizationHeaders, getTransportInstance, isFailedStatusCode, isInfoStatusCode, isSuccessStatusCode, parseRequestParameters };
884
+ export { CUSTOM_ERROR_CONFIG_SCHEMA, type ConcurrencyConfig, ConcurrencyManager, type CustomErrorConfig, type ErrorMappingFn, EventClient, HttpClient, HttpClientManager, HttpErrorMessages, type HttpHeaders, type HttpMethod, HttpMethods, type HttpParameters, type HttpQueryParams, type HttpResponse, HttpResponseError, HttpTransportFactory, type ICacheClient, type IHttpClient, InstanceManager, type Lock, type LockEntry, LockManager, MemoryStore, type MemoryStoreConfig, type PruneCount, type PubSubListener, QueueManager, type RateLimitConfig, RateLimitManager, RedisClient, type RedisClientConfig, type RedisClientType, RequestClientFactory, type RequestConfig, type RequestContext, type RequestParameter, RequestParameterLocations, ScriptManager, SubscriptionManager, type Unlock, buildHttpClientInstance, createAuthorizationHeaders, getTransportInstance, isFailedStatusCode, isInfoStatusCode, isSuccessStatusCode, parseRequestParameters };
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])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/transport",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",