Comparing version 1.6.1 to 1.7.0
@@ -50,3 +50,3 @@ import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv'; | ||
type CacheableMemoryOptions = { | ||
ttl?: number; | ||
ttl?: number | string; | ||
useClone?: boolean; | ||
@@ -80,4 +80,4 @@ lruSize?: number; | ||
constructor(options?: CacheableMemoryOptions); | ||
get ttl(): number; | ||
set ttl(value: number); | ||
get ttl(): number | string | undefined; | ||
set ttl(value: number | string | undefined); | ||
get useClone(): boolean; | ||
@@ -93,3 +93,4 @@ set useClone(value: boolean); | ||
get<T>(key: string): any; | ||
set(key: string, value: any, ttl?: number): void; | ||
getRaw(key: string): CacheableItem$1 | undefined; | ||
set(key: string, value: any, ttl?: number | string): void; | ||
has(key: string): boolean; | ||
@@ -110,2 +111,3 @@ take<T>(key: string): any; | ||
private concatStores; | ||
private setTtl; | ||
} | ||
@@ -128,2 +130,5 @@ | ||
declare const shorthandToMilliseconds: (shorthand?: string | number) => number | undefined; | ||
declare const shorthandToTime: (shorthand?: string | number, fromDate?: Date) => number; | ||
declare enum CacheableHooks { | ||
@@ -145,3 +150,3 @@ BEFORE_SET = "BEFORE_SET", | ||
value: unknown; | ||
ttl?: number; | ||
ttl?: number | string; | ||
}; | ||
@@ -153,3 +158,3 @@ type CacheableOptions = { | ||
nonBlocking?: boolean; | ||
ttl?: number; | ||
ttl?: number | string; | ||
}; | ||
@@ -170,4 +175,4 @@ declare class Cacheable extends Hookified { | ||
set nonBlocking(nonBlocking: boolean); | ||
get ttl(): number | undefined; | ||
set ttl(ttl: number | undefined); | ||
get ttl(): number | string | undefined; | ||
set ttl(ttl: number | string | undefined); | ||
setPrimary(primary: Keyv | KeyvStoreAdapter): void; | ||
@@ -190,4 +195,5 @@ setSecondary(secondary: Keyv | KeyvStoreAdapter): void; | ||
private hasManyKeyv; | ||
private setTtl; | ||
} | ||
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory }; | ||
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory, shorthandToMilliseconds, shorthandToTime }; |
@@ -5,2 +5,69 @@ // src/index.ts | ||
// src/shorthand-time.ts | ||
var shorthandToMilliseconds = (shorthand) => { | ||
let milliseconds; | ||
if (shorthand === void 0) { | ||
return void 0; | ||
} | ||
if (typeof shorthand === "number") { | ||
milliseconds = shorthand; | ||
} else if (typeof shorthand === "string") { | ||
shorthand = shorthand.trim(); | ||
if (Number.isNaN(Number(shorthand))) { | ||
const match = /^([\d.]+)\s*(ms|s|m|h|hr|d)$/i.exec(shorthand); | ||
if (!match) { | ||
throw new Error( | ||
`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.` | ||
); | ||
} | ||
const [, value, unit] = match; | ||
const numericValue = Number.parseFloat(value); | ||
const unitLower = unit.toLowerCase(); | ||
switch (unitLower) { | ||
case "ms": { | ||
milliseconds = numericValue; | ||
break; | ||
} | ||
case "s": { | ||
milliseconds = numericValue * 1e3; | ||
break; | ||
} | ||
case "m": { | ||
milliseconds = numericValue * 1e3 * 60; | ||
break; | ||
} | ||
case "h": { | ||
milliseconds = numericValue * 1e3 * 60 * 60; | ||
break; | ||
} | ||
case "hr": { | ||
milliseconds = numericValue * 1e3 * 60 * 60; | ||
break; | ||
} | ||
case "d": { | ||
milliseconds = numericValue * 1e3 * 60 * 60 * 24; | ||
break; | ||
} | ||
/* c8 ignore next 3 */ | ||
default: { | ||
milliseconds = Number(shorthand); | ||
} | ||
} | ||
} else { | ||
milliseconds = Number(shorthand); | ||
} | ||
} else { | ||
throw new TypeError("Time must be a string or a number."); | ||
} | ||
return milliseconds; | ||
}; | ||
var shorthandToTime = (shorthand, fromDate) => { | ||
fromDate ||= /* @__PURE__ */ new Date(); | ||
const milliseconds = shorthandToMilliseconds(shorthand); | ||
if (milliseconds === void 0) { | ||
return fromDate.getTime(); | ||
} | ||
return fromDate.getTime() + milliseconds; | ||
}; | ||
// src/memory-lru.ts | ||
@@ -93,3 +160,3 @@ var ListNode = class { | ||
_lru = new DoublyLinkedList(); | ||
_ttl = 0; | ||
_ttl; | ||
// Turned off by default | ||
@@ -106,3 +173,3 @@ _useClone = true; | ||
if (options?.ttl) { | ||
this._ttl = options.ttl; | ||
this.setTtl(options.ttl); | ||
} | ||
@@ -124,3 +191,3 @@ if (options?.useClone !== void 0) { | ||
set ttl(value) { | ||
this._ttl = value; | ||
this.setTtl(value); | ||
} | ||
@@ -171,7 +238,23 @@ get useClone() { | ||
} | ||
getRaw(key) { | ||
const store = this.getStore(key); | ||
const item = store.get(key); | ||
if (!item) { | ||
return void 0; | ||
} | ||
if (item.expires && item.expires && Date.now() > item.expires) { | ||
store.delete(key); | ||
return void 0; | ||
} | ||
this.lruMoveToFront(key); | ||
return item; | ||
} | ||
set(key, value, ttl) { | ||
const store = this.getStore(key); | ||
let expires; | ||
if (ttl !== void 0 || this._ttl !== 0) { | ||
expires = Date.now() + (ttl ?? this._ttl); | ||
if (ttl !== void 0 || this._ttl !== void 0) { | ||
const finalTtl = shorthandToTime(ttl ?? this._ttl); | ||
if (finalTtl !== void 0) { | ||
expires = finalTtl; | ||
} | ||
} | ||
@@ -343,2 +426,11 @@ if (this._lruSize > 0) { | ||
} | ||
setTtl(ttl) { | ||
if (typeof ttl === "string" || ttl === void 0) { | ||
this._ttl = ttl; | ||
} else if (ttl > 0) { | ||
this._ttl = ttl; | ||
} else { | ||
this._ttl = void 0; | ||
} | ||
} | ||
}; | ||
@@ -364,3 +456,2 @@ | ||
const result = this._cache.get(key); | ||
console.log("result", result); | ||
if (result) { | ||
@@ -614,3 +705,3 @@ return result; | ||
if (options?.ttl) { | ||
this._ttl = options.ttl; | ||
this.setTtl(options.ttl); | ||
} | ||
@@ -643,3 +734,3 @@ } | ||
set ttl(ttl) { | ||
this._ttl = ttl; | ||
this.setTtl(ttl); | ||
} | ||
@@ -660,3 +751,4 @@ setPrimary(primary) { | ||
if (result) { | ||
await this._primary.set(key, result, this._ttl); | ||
const finalTtl = shorthandToMilliseconds(this._ttl); | ||
await this._primary.set(key, result, finalTtl); | ||
} | ||
@@ -694,3 +786,4 @@ } | ||
result[i] = secondaryResult[i]; | ||
await this._primary.set(key, secondaryResult[i], this._ttl); | ||
const finalTtl = shorthandToMilliseconds(this._ttl); | ||
await this._primary.set(key, secondaryResult[i], finalTtl); | ||
} | ||
@@ -717,3 +810,3 @@ } | ||
let result = false; | ||
const finalTtl = ttl ?? this._ttl; | ||
const finalTtl = shorthandToMilliseconds(ttl ?? this._ttl); | ||
try { | ||
@@ -887,3 +980,3 @@ const item = { key, value, ttl: finalTtl }; | ||
for (const item of items) { | ||
const finalTtl = item.ttl ?? this._ttl; | ||
const finalTtl = shorthandToMilliseconds(item.ttl ?? this._ttl); | ||
promises.push(keyv.set(item.key, item.value, finalTtl)); | ||
@@ -901,2 +994,11 @@ } | ||
} | ||
setTtl(ttl) { | ||
if (typeof ttl === "string" || ttl === void 0) { | ||
this._ttl = ttl; | ||
} else if (ttl > 0) { | ||
this._ttl = ttl; | ||
} else { | ||
this._ttl = void 0; | ||
} | ||
} | ||
}; | ||
@@ -909,3 +1011,5 @@ export { | ||
CacheableStats, | ||
KeyvCacheableMemory | ||
KeyvCacheableMemory, | ||
shorthandToMilliseconds, | ||
shorthandToTime | ||
}; |
{ | ||
"name": "cacheable", | ||
"version": "1.6.1", | ||
"version": "1.7.0", | ||
"description": "Simple Caching Engine using Keyv", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -22,2 +22,3 @@ [<img align="center" src="https://cacheable.org/logo.svg" alt="Cacheable" />](https://github.com/jaredwray/cacheable) | ||
* Comprehensive testing and code coverage | ||
* Shorthand for ttl in milliseconds `(1m = 60000) (1h = 3600000) (1d = 86400000)` | ||
* Distributed Caching Sync via Pub/Sub (coming soon) | ||
@@ -27,2 +28,17 @@ * ESM and CommonJS support with TypeScript | ||
## Table of Contents | ||
* [Getting Started](#getting-started) | ||
* [Basic Usage](#basic-usage) | ||
* [Hooks and Events](#hooks-and-events) | ||
* [Storage Tiering and Caching](#storage-tiering-and-caching) | ||
* [Shorthand for Time to Live (ttl)](#shorthand-for-time-to-live-ttl) | ||
* [Non-Blocking Operations](#non-blocking-operations) | ||
* [CacheSync - Distributed Updates](#cachesync---distributed-updates) | ||
* [Cacheable Options](#cacheable-options) | ||
* [Cacheable Statistics (Instance Only)](#cacheable-statistics-instance-only) | ||
* [API](#api) | ||
* [CacheableMemory - In-Memory Cache](#cacheablememory---in-memory-cache) | ||
* [How to Contribute](#how-to-contribute) | ||
* [License and Copyright](#license-and-copyright) | ||
## Getting Started | ||
@@ -104,2 +120,40 @@ | ||
# Shorthand for Time to Live (ttl) | ||
By default `Cacheable` and `CacheableMemory` the `ttl` is in milliseconds but you can use shorthand for the time to live. Here are the following shorthand values: | ||
* `ms`: Milliseconds such as (1ms = 1) | ||
* `s`: Seconds such as (1s = 1000) | ||
* `m`: Minutes such as (1m = 60000) | ||
* `h` or `hr`: Hours such as (1h = 3600000) | ||
* `d`: Days such as (1d = 86400000) | ||
Here is an example of how to use the shorthand for the `ttl`: | ||
```javascript | ||
import { Cacheable } from 'cacheable'; | ||
const cache = new Cacheable({ ttl: '15m' }); //sets the default ttl to 15 minutes (900000 ms) | ||
cache.set('key', 'value', '1h'); //sets the ttl to 1 hour (3600000 ms) and overrides the default | ||
``` | ||
if you want to disable the `ttl` you can set it to `0` or `undefined`: | ||
```javascript | ||
import { Cacheable } from 'cacheable'; | ||
const cache = new Cacheable({ ttl: 0 }); //sets the default ttl to 0 which is disabled | ||
cache.set('key', 'value', 0); //sets the ttl to 0 which is disabled | ||
``` | ||
If you set the ttl to anything below `0` or `undefined` it will disable the ttl for the cache and the value that returns will be `undefined`. With no ttl set the value will be stored `indefinitely`. | ||
```javascript | ||
import { Cacheable } from 'cacheable'; | ||
const cache = new Cacheable({ ttl: 0 }); //sets the default ttl to 0 which is disabled | ||
console.log(cache.ttl); // undefined | ||
cache.ttl = '1h'; // sets the default ttl to 1 hour (3600000 ms) | ||
console.log(cache.ttl); // '1h' | ||
cache.ttl = -1; // sets the default ttl to 0 which is disabled | ||
console.log(cache.ttl); // undefined | ||
``` | ||
## Non-Blocking Operations | ||
@@ -137,2 +191,3 @@ | ||
* `stats`: To enable statistics for this instance. Default is `false`. | ||
* `ttl`: The default time to live for the cache in milliseconds. Default is `undefined` which is disabled. | ||
@@ -188,3 +243,3 @@ ## Cacheable Statistics (Instance Only) | ||
const options = { | ||
ttl: 60 * 60 * 1000, // 1 hour | ||
ttl: '1h', // 1 hour | ||
useClones: true, // use clones for the values (default is true) | ||
@@ -206,3 +261,3 @@ lruSize: 1000, // the size of the LRU cache (default is 0 which is unlimited) | ||
* `ttl`: The time to live for the cache in milliseconds. | ||
* `ttl`: The time to live for the cache in milliseconds. Default is `undefined` which is means indefinitely. | ||
* `useClones`: If the cache should use clones for the values. Default is `true`. | ||
@@ -221,3 +276,3 @@ * `lruSize`: The size of the LRU cache. Default is `0` which is unlimited. | ||
* `keys()`: The keys in the cache. | ||
* `items()`: The items in the cache as `{ key, value, expiration }`. | ||
* `items()`: The items in the cache as `{ key, value, expires? }`. | ||
* `checkExpired()`: Checks for expired keys in the cache. This is used by the `checkInterval` property. | ||
@@ -224,0 +279,0 @@ * `startIntervalCheck()`: Starts the interval check for expired keys if `checkInterval` is above 0 ms. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79533
2203
281