UNPKG

mastercache

Version:

Multi-tier cache module for Node.js. Redis, Upstash, CloudfareKV, File, in-memory and others drivers

234 lines (231 loc) 6.67 kB
// ../../node_modules/.pnpm/hexoid@2.0.0/node_modules/hexoid/dist/index.mjs for (r = 256, n = []; r--; ) n[r] = (r + 256).toString(16).substring(1); var r; var n; function hexoid(r) { r = r || 16; var t = "", o = 0; return function() { if (!t || 256 === o) { for (t = "", o = (1 + r) / 2 | 0; o--; ) t += n[256 * Math.random() | 0]; t = t.substring(o = 0, r - 2); } return t + n[o++]; }; } // ../../node_modules/.pnpm/@lukeed+ms@2.0.2/node_modules/@lukeed/ms/dist/index.mjs var RGX = /^(-?(?:\d+)?\.?\d+) *(m(?:illiseconds?|s(?:ecs?)?))?(s(?:ec(?:onds?|s)?)?)?(m(?:in(?:utes?|s)?)?)?(h(?:ours?|rs?)?)?(d(?:ays?)?)?(w(?:eeks?|ks?)?)?(y(?:ears?|rs?)?)?$/; var SEC = 1e3; var MIN = SEC * 60; var HOUR = MIN * 60; var DAY = HOUR * 24; var YEAR = DAY * 365.25; function parse(val) { var num, arr = val.toLowerCase().match(RGX); if (arr != null && (num = parseFloat(arr[1]))) { if (arr[3] != null) return num * SEC; if (arr[4] != null) return num * MIN; if (arr[5] != null) return num * HOUR; if (arr[6] != null) return num * DAY; if (arr[7] != null) return num * DAY * 7; if (arr[8] != null) return num * YEAR; return num; } } // src/helpers.ts function resolveTtl(ttl, defaultTtl = 3e4) { if (typeof ttl === "number") return ttl; if (ttl === null) { return void 0; } if (ttl === void 0) { if (typeof defaultTtl === "number") return defaultTtl; if (typeof defaultTtl === "string") return parse(defaultTtl); return void 0; } return parse(ttl); } // src/cache/cache-entry/cache-entry-options.ts var toId = hexoid(12); var CacheEntryOptions = class _CacheEntryOptions { /** * The options that were passed to the constructor */ #options; /** * Unique identifier that will be used when logging * debug information. */ id; /** * Logical TTL is when the value is considered expired * but still can be in the cache ( Grace period ) */ logicalTtl; /** * Physical TTL is the time when value will be automatically * removed from the cache. This is the Grace period * duration */ physicalTtl; /** * Early expiration TTL is when the value should be * refreshed in the background. */ earlyExpireTtl; /** * Timeouts for the cache operations */ timeouts; /** * Resolved grace period options */ gracePeriod; /** * Max time to wait for the lock to be acquired */ lockTimeout; constructor(options = {}, defaults = {}) { this.id = toId(); const timeouts = { ...defaults.timeouts, ...options.timeouts }; this.#options = { ...defaults, ...options, gracePeriod: { ...defaults.gracePeriod, ...options.gracePeriod }, timeouts: Object.keys(timeouts).length ? timeouts : void 0 }; this.logicalTtl = this.#resolveLogicalTtl(); this.physicalTtl = this.#resolvePhysicalTtl(); this.earlyExpireTtl = this.#resolveEarlyExpireTtl(); this.timeouts = this.#resolveTimeouts(); this.gracePeriod = this.#resolveGracePeriod(); this.lockTimeout = resolveTtl(this.#options.lockTimeout, null); } /** * Resolve the grace period options */ #resolveGracePeriod() { if (!this.#options.gracePeriod || !this.#options.gracePeriod.enabled) { return { enabled: false }; } return { enabled: true, duration: resolveTtl(this.#options.gracePeriod.duration), fallbackDuration: resolveTtl(this.#options.gracePeriod.fallbackDuration) }; } /** * Resolve the timeouts to a duration in milliseconds */ #resolveTimeouts() { const timeouts = this.#options.timeouts; if (!timeouts) return void 0; return { soft: resolveTtl(timeouts.soft, null), hard: resolveTtl(timeouts.hard, null) }; } /** * Early expiration is received as a percentage of the * logical TTL. We need to convert it to a duration * in milliseconds. */ #resolveEarlyExpireTtl() { const percentage = this.#options.earlyExpiration; if (!percentage || percentage <= 0 || percentage >= 1) { return void 0; } if (!this.logicalTtl) return void 0; return this.logicalTtl * percentage; } /** * Returns a new instance of `CacheItemOptions` with the same * options as the current instance, but with any provided * options overriding the current * * For performance reasons, if no options are provided, the * current instance is returned */ cloneWith(options) { return options ? new _CacheEntryOptions(options, this.#options) : this; } /** * Resolve the logical TTL to a duration in milliseconds */ #resolveLogicalTtl() { return resolveTtl(this.#options.ttl); } /** * Resolve the physical TTL to a duration in milliseconds * * If grace period is not enabled then the physical TTL * is the same as the logical TTL */ #resolvePhysicalTtl() { return this.isGracePeriodEnabled ? resolveTtl(this.#options.gracePeriod.duration) : this.logicalTtl; } get isGracePeriodEnabled() { return this.#options.gracePeriod?.enabled; } get suppressL2Errors() { return this.#options.suppressL2Errors; } /** * Set a new logical TTL */ setLogicalTtl(ttl) { this.#options.ttl = ttl; this.logicalTtl = this.#resolveLogicalTtl(); this.physicalTtl = this.#resolvePhysicalTtl(); this.earlyExpireTtl = this.#resolveEarlyExpireTtl(); return this; } /** * Compute the logical TTL timestamp from now */ logicalTtlFromNow() { if (!this.logicalTtl) return void 0; return Date.now() + this.logicalTtl; } /** * Compute the physical TTL timestamp from now */ physicalTtlFromNow() { if (!this.physicalTtl) return void 0; return Date.now() + this.physicalTtl; } /** * Compute the early expiration TTL timestamp from now */ earlyExpireTtlFromNow() { if (!this.earlyExpireTtl) return void 0; return Date.now() + this.earlyExpireTtl; } /** * Compute the lock timeout we should use for the * factory */ factoryTimeout(hasFallbackValue) { if (!this.timeouts) return void 0; if (hasFallbackValue && this.isGracePeriodEnabled && this.timeouts.soft) { return this.timeouts.soft; } return this.timeouts.hard; } /** * Compute the maximum time we should wait for the * lock to be acquired */ getApplicableLockTimeout(hasFallbackValue) { if (this.lockTimeout) { return this.lockTimeout; } if (hasFallbackValue && this.isGracePeriodEnabled && this.timeouts?.soft) { return this.timeouts.soft; } } }; export { CacheEntryOptions }; //# sourceMappingURL=cache-entry-options.js.map