@jointly/cache-candidate 2.0.0 → 2.1.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/README.md CHANGED
@@ -101,6 +101,9 @@ The options available are:
101
101
  - `executionTime`: The execution time of the current function execution in milliseconds.
102
102
  - `args`: The arguments passed to the current function.
103
103
  - `timeFrameCacheRecords`: The cache records of the last `timeFrame` milliseconds.
104
+ - `customKeyFunction` (_optional_): A function to generate a custom key for every cache record.
105
+ The function receives the arguments passed to the current function and should return a string.
106
+ If not passed, the key will be generated based on an internal algorithm that considers the arguments passed to the function.
104
107
  - `millisecondThreshold` (_optional_): The threshold in milliseconds to be considered for the condition checks. If not passed, this criteria will be ignored.
105
108
  - `requestsThreshold` (_optional_): The number of requests to be considered for the condition checks. Default: `1`.
106
109
  - `expirationMode` (_optional_): The expiration mode to use. Default: `default`.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Z=Object.create;var O=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,ae=Object.prototype.hasOwnProperty;var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),ie=(e,t)=>{for(var n in t)O(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of te(t))!ae.call(e,a)&&a!==n&&O(e,a,{get:()=>t[a],enumerable:!(i=ee(t,a))||i.enumerable});return e};var D=(e,t,n)=>(n=e!=null?Z(ne(e)):{},N(t||!e||!e.__esModule?O(n,"default",{value:e,enumerable:!0}):n,e)),re=e=>N(O({},"__esModule",{value:!0}),e);var R=I((je,W)=>{"use strict";var w=Object.defineProperty,oe=Object.getOwnPropertyDescriptor,ce=Object.getOwnPropertyNames,de=Object.prototype.hasOwnProperty,ue=(e,t)=>{for(var n in t)w(e,n,{get:t[n],enumerable:!0})},se=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ce(t))!de.call(e,a)&&a!==n&&w(e,a,{get:()=>t[a],enumerable:!(i=oe(t,a))||i.enumerable});return e},le=e=>se(w({},"__esModule",{value:!0}),e),U={};ue(U,{Hooks:()=>q});W.exports=le(U);var q=(e=>(e.SETUP="SETUP",e.INIT="INIT",e.EXECUTION_PRE="EXECUTION_PRE",e.EXECUTION_POST="EXECUTION_POST",e.DATACACHE_RECORD_ADD_PRE="DATACACHE_RECORD_ADD_PRE",e.DATACACHE_RECORD_ADD_POST="DATACACHE_RECORD_ADD_POST",e.DATACACHE_RECORD_DELETE_PRE="DATACACHE_RECORD_DELETE_PRE",e.DATACACHE_RECORD_DELETE_POST="DATACACHE_RECORD_DELETE_POST",e.CACHE_HIT="CACHE_HIT",e))(q||{})});var $=I((Ue,Q)=>{"use strict";var k=Object.defineProperty,he=Object.getOwnPropertyDescriptor,Ce=Object.getOwnPropertyNames,fe=Object.prototype.hasOwnProperty,pe=(e,t)=>{for(var n in t)k(e,n,{get:t[n],enumerable:!0})},me=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ce(t))!fe.call(e,a)&&a!==n&&k(e,a,{get:()=>t[a],enumerable:!(i=he(t,a))||i.enumerable});return e},ge=e=>me(k({},"__esModule",{value:!0}),e),J={};pe(J,{Hook:()=>Te,hook:()=>Ae});Q.exports=ge(J);var ye={before:()=>{},after:()=>{}},Ee={before:()=>{},after:()=>{}};function Te(e){return function(t,n,i){let a={},r=i.value,{before:o,after:h}={...ye,...e};return i.value=function(...c){o({context:a,args:c,target:t,propertyKey:n,descriptor:i});let d=r.apply(this,c);return h({context:a,args:c,target:t,propertyKey:n,descriptor:i,result:d}),d},i}}function Ae(e){return function(t){let n={},{before:i,after:a}={...Ee,...e};return function(...r){i({context:n,args:r});let o=t(...r);return a({context:n,args:r,result:o}),o}}}});var _e={};ie(_e,{CacheCandidate:()=>z,CacheCandidateOptionsDefault:()=>A,cacheCandidate:()=>G});module.exports=re(_e);var j=(e=new Map)=>({get:async t=>e.get(JSON.stringify(t)),has:async t=>e.has(JSON.stringify(t)),set:async(t,n)=>e.set(JSON.stringify(t),n),delete:async t=>e.delete(JSON.stringify(t))});var A={ttl:6e5,timeFrame:3e4,requestsThreshold:1,cache:j(),expirationMode:"default",keepAlive:!1,plugins:[],fetchingMode:"default",events:{onCacheHit:e=>e,onCacheSet:e=>e,onCacheDelete:e=>e,onBeforeFunctionExecution:e=>e,onAfterFunctionExecution:e=>e}};var P=Symbol("DataCacheRecordNotFound"),b=Symbol("RunningQueryRecordNotFound");var S=D(R());var V=require("crypto");var L=D(R()),X=D($());async function u(e,t,n){for(let i of t){let a=i.hooks.filter(o=>o.hook===e);if(a.length>1)throw new Error(`Only one hook instance per plugin is allowed. ${i.name} has ${a.length} instances of ${e}}`);if(a.length===0)continue;let r=a[0];if(xe(r))await r.action(n,i.additionalParameters);else throw new Error(`Hook ${e} for plugin ${i.name} is not actionable.`)}}function xe(e){return[e.action!==void 0,typeof e.action=="function"].every(t=>t===!0)}function K(e,t,n,i){return(0,X.hook)({before:()=>{u(e,n.plugins,i)},after:({result:a})=>{u(t,n.plugins,{...i,result:a})}})}function H({options:e}){e.plugins&&e.plugins.forEach(t=>{if(!t.hooks||!Array.isArray(t.hooks)||t.hooks.length===0)throw new Error(`Plugin ${t.name} has no hooks.`);t.hooks.forEach(n=>{if(!L.Hooks[n.hook])throw new Error(`Invalid hook ${n}`)})})}var l=D(R());function Oe(e,t){return Date.now()<e+t.timeFrame}function De({key:e,timeframeCache:t,executionTime:n,executionEnd:i}){t.has(e)?t.get(e).push({executionTime:n,executionEnd:i}):t.set(e,[{executionEnd:i,executionTime:n}])}function Pe({options:e,key:t,timeframeCache:n}){if(n.has(t)){let i=n.get(t),a=i.filter(({executionEnd:r})=>Oe(r,e));i.length!==a.length&&n.set(t,a)}}function Re({key:e,runningQueryCache:t}){return t.has(e)?t.get(e):b}function T(...e){return(0,V.createHash)("sha256").update(e.join("|")).digest("hex")}function g({birthTime:e,options:t}){return Date.now()-e>=t.ttl}async function y({options:e,key:t,HookPayload:n,staleMap:i}){if(await e.cache.has(t)){let{result:a,birthTime:r}=await e.cache.get(t);return g({birthTime:r,options:e})?(await p({options:e,key:t,HookPayload:n,result:a,staleMap:i}),P):a}return P}async function E({options:e,key:t,result:n,HookPayload:i}){return await u(l.Hooks.DATACACHE_RECORD_ADD_PRE,e.plugins,i),e.cache.set(t,{result:n,birthTime:Date.now()},e.ttl).then(async()=>{await u(l.Hooks.DATACACHE_RECORD_ADD_POST,e.plugins,{...i,result:n}),e.events.onCacheSet({key:t})})}async function p({options:e,key:t,HookPayload:n,result:i,staleMap:a}){e.fetchingMode==="stale-while-revalidate"&&a.set(t,i);let r=_(e.expirationMode,"call-delete")?e.cache.delete:()=>Promise.resolve();K(l.Hooks.DATACACHE_RECORD_DELETE_PRE,l.Hooks.DATACACHE_RECORD_DELETE_POST,e,n)(r)(t).then(()=>{e.events.onCacheDelete({key:t})})}function _(e,t){switch(t){case"set-timeout":return e==="default"||e==="timeout-only";case"call-delete":return e==="default"}}async function B({result:e,runningQueryCache:t,key:n,executionStart:i,options:a,timeframeCache:r,timeoutCache:o,args:h,staleMap:c,HookPayload:d}){let C=Date.now(),f=C-i;a.events.onAfterFunctionExecution({key:n,executionTime:f}),De({key:n,timeframeCache:r,executionTime:f,executionEnd:C}),await x({options:a,key:n,timeframeCache:r,executionTime:f,args:h})>=a.requestsThreshold?E({options:a,key:n,result:e,HookPayload:d}).finally(()=>{t.delete(n),_(a.expirationMode,"set-timeout")&&o.set(n,setTimeout(()=>{p({options:a,key:n,HookPayload:d,result:e,staleMap:c}),o.delete(n)},a.ttl).unref())}):t.delete(n)}async function x({options:e,key:t,timeframeCache:n,executionTime:i,args:a}){let r=0,o=n.get(t);return e.candidateFunction?r=await be(e,i,a,o):e.millisecondThreshold?r=ve(i,e,o):r=o.length,r}function ve(e,t,n){let i=0;return e>t.millisecondThreshold&&(i=n.filter(a=>a.executionTime>t.millisecondThreshold).length),i}async function be(e,t,n,i){let a=0;return await e.candidateFunction({timeFrameCacheRecords:i,options:e,args:n})&&(a=e.requestsThreshold),a}function we({timeoutCache:e,key:t}){e.get(t)?.refresh()}function ke(e=10){return Math.random().toString(36).substring(2,e+2)}function F(e){if(e.expirationMode==="eject"&&e.keepAlive===!0)throw new Error(`The cache-candidate currently doesn't support the "eject" expiration mode with the "keepAlive" option.`)}function He(){let e={getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x};return Object.defineProperty(e,"getDataCacheRecord",{value:y,writable:!1}),Object.defineProperty(e,"addDataCacheRecord",{value:E,writable:!1}),Object.defineProperty(e,"deleteDataCacheRecord",{value:p,writable:!1}),Object.defineProperty(e,"isDataCacheRecordExpired",{value:g,writable:!1}),e}async function v({options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,args:r,staleMap:o,originalMethod:h}){let c={options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,fnArgs:r,internals:He()};await u(l.Hooks.INIT,e.plugins,c);let d=await y({options:e,key:t,HookPayload:c,staleMap:o});if(d!==P)return e.keepAlive&&_(e.expirationMode,"set-timeout")&&we({timeoutCache:n,key:t}),await u(l.Hooks.CACHE_HIT,e.plugins,{...c,result:d}),e.events.onCacheHit({key:t}),Promise.resolve(d);let C=Re({key:t,runningQueryCache:i});if(C!==b)return await u(l.Hooks.CACHE_HIT,e.plugins,{...c,result:C}),e.events.onCacheHit({key:t}),C;if(e.fetchingMode==="stale-while-revalidate"&&o.has(t)){let m=o.get(t);return await u(l.Hooks.CACHE_HIT,e.plugins,{...c,result:m}),e.events.onCacheHit({key:t}),o.delete(t),v({options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,args:r,staleMap:o,originalMethod:h}),Promise.resolve(m)}Pe({options:e,key:t,timeframeCache:a}),await u(l.Hooks.EXECUTION_PRE,e.plugins,c),e.events.onBeforeFunctionExecution({key:t});let f=Date.now(),s=h(...r);return await u(l.Hooks.EXECUTION_POST,e.plugins,{...c,result:s}),s instanceof Promise?(i.set(t,s),s.then(m=>B({result:m,runningQueryCache:i,key:t,executionStart:f,options:e,timeframeCache:a,timeoutCache:n,args:r,staleMap:o,HookPayload:c})),s):(B({result:s,runningQueryCache:i,key:t,executionStart:f,options:e,timeframeCache:a,timeoutCache:n,args:r,staleMap:o,HookPayload:c}),s)}function M(e){let t=new Map,n=new Map,i=ke(),a=new Map,r={...A,...e,events:{...A.events,...e.events||{}}};return{timeframeCache:t,runningQueryCache:n,uniqueIdentifier:i,timeoutCache:a,options:r,staleMap:new Map}}function z(e={}){let{timeframeCache:t,runningQueryCache:n,uniqueIdentifier:i,timeoutCache:a,options:r,staleMap:o}=M(e);return H({options:r}),F(r),u(S.Hooks.SETUP,r.plugins,{options:{...r,plugins:void 0},key:"",timeoutCache:a,runningQueryCache:n,timeframeCache:t,fnArgs:[],internals:{getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x}}),function(c,d,C){let f=C.value;C.value=async function(...s){let m=c.constructor.name+JSON.stringify(this),Y=T([d,i,m,JSON.stringify(s)]);return v({options:r,key:Y,timeoutCache:a,runningQueryCache:n,timeframeCache:t,args:s,staleMap:o,originalMethod:f})}}}function G(e,t={}){let{timeframeCache:n,runningQueryCache:i,uniqueIdentifier:a,timeoutCache:r,options:o,staleMap:h}=M(t);return H({options:o}),F(o),u(S.Hooks.SETUP,o.plugins,{options:{...o,plugins:void 0},key:"",timeoutCache:r,runningQueryCache:i,timeframeCache:n,fnArgs:[],internals:{getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x}}),function(...d){return v({options:o,key:T([a,JSON.stringify(d)]),timeoutCache:r,runningQueryCache:i,timeframeCache:n,args:d,staleMap:h,originalMethod:e})}}0&&(module.exports={CacheCandidate,CacheCandidateOptionsDefault,cacheCandidate});
1
+ "use strict";var Z=Object.create;var O=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,ae=Object.prototype.hasOwnProperty;var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),ie=(e,t)=>{for(var n in t)O(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of te(t))!ae.call(e,a)&&a!==n&&O(e,a,{get:()=>t[a],enumerable:!(i=ee(t,a))||i.enumerable});return e};var D=(e,t,n)=>(n=e!=null?Z(ne(e)):{},N(t||!e||!e.__esModule?O(n,"default",{value:e,enumerable:!0}):n,e)),re=e=>N(O({},"__esModule",{value:!0}),e);var R=I((je,W)=>{"use strict";var w=Object.defineProperty,oe=Object.getOwnPropertyDescriptor,ce=Object.getOwnPropertyNames,ue=Object.prototype.hasOwnProperty,de=(e,t)=>{for(var n in t)w(e,n,{get:t[n],enumerable:!0})},se=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of ce(t))!ue.call(e,a)&&a!==n&&w(e,a,{get:()=>t[a],enumerable:!(i=oe(t,a))||i.enumerable});return e},le=e=>se(w({},"__esModule",{value:!0}),e),U={};de(U,{Hooks:()=>q});W.exports=le(U);var q=(e=>(e.SETUP="SETUP",e.INIT="INIT",e.EXECUTION_PRE="EXECUTION_PRE",e.EXECUTION_POST="EXECUTION_POST",e.DATACACHE_RECORD_ADD_PRE="DATACACHE_RECORD_ADD_PRE",e.DATACACHE_RECORD_ADD_POST="DATACACHE_RECORD_ADD_POST",e.DATACACHE_RECORD_DELETE_PRE="DATACACHE_RECORD_DELETE_PRE",e.DATACACHE_RECORD_DELETE_POST="DATACACHE_RECORD_DELETE_POST",e.CACHE_HIT="CACHE_HIT",e))(q||{})});var Q=I((Ue,K)=>{"use strict";var k=Object.defineProperty,he=Object.getOwnPropertyDescriptor,Ce=Object.getOwnPropertyNames,fe=Object.prototype.hasOwnProperty,pe=(e,t)=>{for(var n in t)k(e,n,{get:t[n],enumerable:!0})},me=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ce(t))!fe.call(e,a)&&a!==n&&k(e,a,{get:()=>t[a],enumerable:!(i=he(t,a))||i.enumerable});return e},ge=e=>me(k({},"__esModule",{value:!0}),e),J={};pe(J,{Hook:()=>Te,hook:()=>Ae});K.exports=ge(J);var ye={before:()=>{},after:()=>{}},Ee={before:()=>{},after:()=>{}};function Te(e){return function(t,n,i){let a={},r=i.value,{before:o,after:h}={...ye,...e};return i.value=function(...c){o({context:a,args:c,target:t,propertyKey:n,descriptor:i});let u=r.apply(this,c);return h({context:a,args:c,target:t,propertyKey:n,descriptor:i,result:u}),u},i}}function Ae(e){return function(t){let n={},{before:i,after:a}={...Ee,...e};return function(...r){i({context:n,args:r});let o=t(...r);return a({context:n,args:r,result:o}),o}}}});var _e={};ie(_e,{CacheCandidate:()=>z,CacheCandidateOptionsDefault:()=>A,cacheCandidate:()=>G});module.exports=re(_e);var j=(e=new Map)=>({get:async t=>e.get(JSON.stringify(t)),has:async t=>e.has(JSON.stringify(t)),set:async(t,n)=>e.set(JSON.stringify(t),n),delete:async t=>e.delete(JSON.stringify(t))});var A={ttl:6e5,timeFrame:3e4,requestsThreshold:1,cache:j(),expirationMode:"default",keepAlive:!1,plugins:[],fetchingMode:"default",events:{onCacheHit:e=>e,onCacheSet:e=>e,onCacheDelete:e=>e,onBeforeFunctionExecution:e=>e,onAfterFunctionExecution:e=>e}};var P=Symbol("DataCacheRecordNotFound"),b=Symbol("RunningQueryRecordNotFound");var S=D(R());var V=require("crypto");var $=D(R()),L=D(Q());async function d(e,t,n){for(let i of t){let a=i.hooks.filter(o=>o.hook===e);if(a.length>1)throw new Error(`Only one hook instance per plugin is allowed. ${i.name} has ${a.length} instances of ${e}}`);if(a.length===0)continue;let r=a[0];if(xe(r))await r.action(n,i.additionalParameters);else throw new Error(`Hook ${e} for plugin ${i.name} is not actionable.`)}}function xe(e){return[e.action!==void 0,typeof e.action=="function"].every(t=>t===!0)}function X(e,t,n,i){return(0,L.hook)({before:()=>{d(e,n.plugins,i)},after:({result:a})=>{d(t,n.plugins,{...i,result:a})}})}function H({options:e}){e.plugins&&e.plugins.forEach(t=>{if(!t.hooks||!Array.isArray(t.hooks)||t.hooks.length===0)throw new Error(`Plugin ${t.name} has no hooks.`);t.hooks.forEach(n=>{if(!$.Hooks[n.hook])throw new Error(`Invalid hook ${n}`)})})}var l=D(R());function Oe(e,t){return Date.now()<e+t.timeFrame}function De({key:e,timeframeCache:t,executionTime:n,executionEnd:i}){t.has(e)?t.get(e).push({executionTime:n,executionEnd:i}):t.set(e,[{executionEnd:i,executionTime:n}])}function Pe({options:e,key:t,timeframeCache:n}){if(n.has(t)){let i=n.get(t),a=i.filter(({executionEnd:r})=>Oe(r,e));i.length!==a.length&&n.set(t,a)}}function Re({key:e,runningQueryCache:t}){return t.has(e)?t.get(e):b}function T(...e){return(0,V.createHash)("sha256").update(e.join("|")).digest("hex")}function g({birthTime:e,options:t}){return Date.now()-e>=t.ttl}async function y({options:e,key:t,HookPayload:n,staleMap:i}){if(await e.cache.has(t)){let{result:a,birthTime:r}=await e.cache.get(t);return g({birthTime:r,options:e})?(await p({options:e,key:t,HookPayload:n,result:a,staleMap:i}),P):a}return P}async function E({options:e,key:t,result:n,HookPayload:i}){return await d(l.Hooks.DATACACHE_RECORD_ADD_PRE,e.plugins,i),e.cache.set(t,{result:n,birthTime:Date.now()},e.ttl).then(async()=>{await d(l.Hooks.DATACACHE_RECORD_ADD_POST,e.plugins,{...i,result:n}),e.events.onCacheSet({key:t})})}async function p({options:e,key:t,HookPayload:n,result:i,staleMap:a}){e.fetchingMode==="stale-while-revalidate"&&a.set(t,i);let r=_(e.expirationMode,"call-delete")?e.cache.delete:()=>Promise.resolve();X(l.Hooks.DATACACHE_RECORD_DELETE_PRE,l.Hooks.DATACACHE_RECORD_DELETE_POST,e,n)(r)(t).then(()=>{e.events.onCacheDelete({key:t})})}function _(e,t){switch(t){case"set-timeout":return e==="default"||e==="timeout-only";case"call-delete":return e==="default"}}async function B({result:e,runningQueryCache:t,key:n,executionStart:i,options:a,timeframeCache:r,timeoutCache:o,args:h,staleMap:c,HookPayload:u}){let C=Date.now(),f=C-i;a.events.onAfterFunctionExecution({key:n,executionTime:f}),De({key:n,timeframeCache:r,executionTime:f,executionEnd:C}),await x({options:a,key:n,timeframeCache:r,executionTime:f,args:h})>=a.requestsThreshold?E({options:a,key:n,result:e,HookPayload:u}).finally(()=>{t.delete(n),_(a.expirationMode,"set-timeout")&&o.set(n,setTimeout(()=>{p({options:a,key:n,HookPayload:u,result:e,staleMap:c}),o.delete(n)},a.ttl).unref())}):t.delete(n)}async function x({options:e,key:t,timeframeCache:n,executionTime:i,args:a}){let r=0,o=n.get(t);return e.candidateFunction?r=await be(e,i,a,o):e.millisecondThreshold?r=ve(i,e,o):r=o.length,r}function ve(e,t,n){let i=0;return e>t.millisecondThreshold&&(i=n.filter(a=>a.executionTime>t.millisecondThreshold).length),i}async function be(e,t,n,i){let a=0;return await e.candidateFunction({timeFrameCacheRecords:i,options:e,args:n})&&(a=e.requestsThreshold),a}function we({timeoutCache:e,key:t}){e.get(t)?.refresh()}function ke(e=10){return Math.random().toString(36).substring(2,e+2)}function F(e){if(e.expirationMode==="eject"&&e.keepAlive===!0)throw new Error(`The cache-candidate currently doesn't support the "eject" expiration mode with the "keepAlive" option.`)}function He(){let e={getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x};return Object.defineProperty(e,"getDataCacheRecord",{value:y,writable:!1}),Object.defineProperty(e,"addDataCacheRecord",{value:E,writable:!1}),Object.defineProperty(e,"deleteDataCacheRecord",{value:p,writable:!1}),Object.defineProperty(e,"isDataCacheRecordExpired",{value:g,writable:!1}),e}async function v({options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,args:r,staleMap:o,originalMethod:h}){let c={options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,fnArgs:r,internals:He()};await d(l.Hooks.INIT,e.plugins,c);let u=await y({options:e,key:t,HookPayload:c,staleMap:o});if(u!==P)return e.keepAlive&&_(e.expirationMode,"set-timeout")&&we({timeoutCache:n,key:t}),await d(l.Hooks.CACHE_HIT,e.plugins,{...c,result:u}),e.events.onCacheHit({key:t}),Promise.resolve(u);let C=Re({key:t,runningQueryCache:i});if(C!==b)return await d(l.Hooks.CACHE_HIT,e.plugins,{...c,result:C}),e.events.onCacheHit({key:t}),C;if(e.fetchingMode==="stale-while-revalidate"&&o.has(t)){let m=o.get(t);return await d(l.Hooks.CACHE_HIT,e.plugins,{...c,result:m}),e.events.onCacheHit({key:t}),o.delete(t),v({options:e,key:t,timeoutCache:n,runningQueryCache:i,timeframeCache:a,args:r,staleMap:o,originalMethod:h}),Promise.resolve(m)}Pe({options:e,key:t,timeframeCache:a}),await d(l.Hooks.EXECUTION_PRE,e.plugins,c),e.events.onBeforeFunctionExecution({key:t});let f=Date.now(),s=h(...r);return await d(l.Hooks.EXECUTION_POST,e.plugins,{...c,result:s}),s instanceof Promise?(i.set(t,s),s.then(m=>B({result:m,runningQueryCache:i,key:t,executionStart:f,options:e,timeframeCache:a,timeoutCache:n,args:r,staleMap:o,HookPayload:c})),s):(B({result:s,runningQueryCache:i,key:t,executionStart:f,options:e,timeframeCache:a,timeoutCache:n,args:r,staleMap:o,HookPayload:c}),s)}function M(e){let t=new Map,n=new Map,i=ke(),a=new Map,r={...A,...e,events:{...A.events,...e.events||{}}};return{timeframeCache:t,runningQueryCache:n,uniqueIdentifier:i,timeoutCache:a,options:r,staleMap:new Map}}function z(e={}){let{timeframeCache:t,runningQueryCache:n,uniqueIdentifier:i,timeoutCache:a,options:r,staleMap:o}=M(e);return H({options:r}),F(r),d(S.Hooks.SETUP,r.plugins,{options:{...r,plugins:void 0},key:"",timeoutCache:a,runningQueryCache:n,timeframeCache:t,fnArgs:[],internals:{getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x}}),function(c,u,C){let f=C.value;C.value=async function(...s){let m=c.constructor.name+JSON.stringify(this),Y=T([u,i,m,JSON.stringify(s)]);return v({options:r,key:Y,timeoutCache:a,runningQueryCache:n,timeframeCache:t,args:s,staleMap:o,originalMethod:f})}}}function G(e,t={}){let{timeframeCache:n,runningQueryCache:i,uniqueIdentifier:a,timeoutCache:r,options:o,staleMap:h}=M(t);return H({options:o}),F(o),d(S.Hooks.SETUP,o.plugins,{options:{...o,plugins:void 0},key:"",timeoutCache:r,runningQueryCache:i,timeframeCache:n,fnArgs:[],internals:{getDataCacheKey:T,getDataCacheRecord:y,addDataCacheRecord:E,deleteDataCacheRecord:p,isDataCacheRecordExpired:g,getExceedingAmount:x}}),function(...u){return v({options:o,key:t.customKeyFunction?t.customKeyFunction(u):T([a,JSON.stringify(u)]),timeoutCache:r,runningQueryCache:i,timeframeCache:n,args:u,staleMap:h,originalMethod:e})}}0&&(module.exports={CacheCandidate,CacheCandidateOptionsDefault,cacheCandidate});
package/dist/models.d.ts CHANGED
@@ -16,6 +16,7 @@ export interface CacheCandidateInputOptions {
16
16
  ttl?: number;
17
17
  timeFrame?: number;
18
18
  candidateFunction?: (CandidateFunctionOptions: any) => boolean;
19
+ customKeyFunction?: (args: any) => string;
19
20
  millisecondThreshold?: number;
20
21
  requestsThreshold?: number;
21
22
  expirationMode?: 'default' | 'timeout-only' | 'eject';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jointly/cache-candidate",
3
3
  "private": false,
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -33,24 +33,24 @@
33
33
  },
34
34
  "prepare": "npm run build",
35
35
  "devDependencies": {
36
- "@commitlint/cli": "^17.3.0",
37
- "@commitlint/config-conventional": "^17.3.0",
36
+ "@commitlint/cli": "^19.3.0",
37
+ "@commitlint/config-conventional": "^19.2.2",
38
38
  "@jointly/cache-candidate-plugin-base": "^2.0.0",
39
- "@types/jest": "^29.2.5",
40
- "@types/node": "^18.11.12",
39
+ "@types/jest": "^29.5.12",
40
+ "@types/node": "^20.12.10",
41
41
  "@types/redis": "^4.0.11",
42
- "@typescript-eslint/eslint-plugin": "^5.46.0",
43
- "@typescript-eslint/parser": "^5.46.0",
42
+ "@typescript-eslint/eslint-plugin": "^7.8.0",
43
+ "@typescript-eslint/parser": "^7.8.0",
44
44
  "benchmark": "^2.1.4",
45
- "esbuild": "^0.16.4",
45
+ "esbuild": "^0.21.0",
46
46
  "eslint": "^8.29.0",
47
47
  "generate-changelog": "^1.8.0",
48
- "husky": "^8.0.2",
49
- "jest": "^29.3.1",
50
- "lint-staged": "^13.1.0",
51
- "prettier": "^2.8.1",
52
- "rimraf": "^3.0.2",
53
- "ts-jest": "^29.0.3",
48
+ "husky": "^9.0.11",
49
+ "jest": "^29.7.0",
50
+ "lint-staged": "^15.2.2",
51
+ "prettier": "^3.2.5",
52
+ "rimraf": "^5.0.5",
53
+ "ts-jest": "^29.1.2",
54
54
  "typescript": "^4.9.4"
55
55
  },
56
56
  "lint-staged": {
@@ -66,6 +66,6 @@
66
66
  "license": "MIT",
67
67
  "author": "Jointly <dev@jointly.pro>",
68
68
  "dependencies": {
69
- "hook-fn": "^1.0.3"
69
+ "hook-fn": "^1.0.6"
70
70
  }
71
71
  }