Skip to content

Commit

Permalink
Better types for TTL
Browse files Browse the repository at this point in the history
  • Loading branch information
ilovepixelart committed Jan 19, 2025
1 parent cdb5fee commit 85454ca
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 17 deletions.
12 changes: 9 additions & 3 deletions src/cache/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ms from 'ms'
import MemoryCacheEngine from './engine/MemoryCacheEngine'
import RedisCacheEngine from './engine/RedisCacheEngine'

import type { StringValue } from 'ms'
import type ICacheEngine from '../interfaces/ICacheEngine'
import type ICacheOptions from '../interfaces/ICacheOptions'
import type IData from '../interfaces/IData'
Expand All @@ -22,7 +23,11 @@ class CacheEngine {
throw new Error(`Engine options are required for ${cacheOptions.engine} engine`)
}

this.#defaultTTL = ms(cacheOptions.defaultTTL ?? '1 minute')
if (!cacheOptions.defaultTTL) {
cacheOptions.defaultTTL = '1 minute'
}

this.#defaultTTL = typeof cacheOptions.defaultTTL === 'string' ? ms(cacheOptions.defaultTTL) : cacheOptions.defaultTTL

if (cacheOptions.engine === 'redis' && cacheOptions.engineOptions) {
this.#engine = new RedisCacheEngine(cacheOptions.engineOptions)
Expand All @@ -44,8 +49,9 @@ class CacheEngine {
return cacheEntry
}

async set(key: string, value: IData, ttl: string | null): Promise<void> {
const actualTTL = ttl ? ms(ttl) : this.#defaultTTL
async set(key: string, value: IData, ttl: number | StringValue | null): Promise<void> {
const givenTTL = typeof ttl === 'string' ? ms(ttl) : ttl
const actualTTL = givenTTL ?? this.#defaultTTL
await this.#engine.set(key, value, actualTTL)
if (this.#debug) {
console.log(`[ts-cache-mongoose] SET '${key}' - ttl: ${actualTTL.toFixed(0)} ms`)
Expand Down
9 changes: 7 additions & 2 deletions src/cache/engine/MemoryCacheEngine.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import ms from 'ms'

import type { StringValue } from 'ms'
import type ICacheEngine from '../../interfaces/ICacheEngine'
import type IData from '../../interfaces/IData'

Expand All @@ -17,10 +20,12 @@ class MemoryCacheEngine implements ICacheEngine {
return item.value
}

set(key: string, value: IData, ttl = Number.POSITIVE_INFINITY): void {
set(key: string, value: IData, ttl?: number | StringValue): void {
const givenTTL = typeof ttl === 'string' ? ms(ttl) : ttl
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY
this.#cache.set(key, {
value,
expiresAt: Date.now() + ttl,
expiresAt: Date.now() + actualTTL,
})
}

Expand Down
8 changes: 6 additions & 2 deletions src/cache/engine/RedisCacheEngine.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { EJSON } from 'bson'
import IORedis from 'ioredis'
import ms from 'ms'

import { convertToObject } from '../../version'

import type { Redis, RedisOptions } from 'ioredis'
import type { StringValue } from 'ms'
import type ICacheEngine from '../../interfaces/ICacheEngine'
import type IData from '../../interfaces/IData'

Expand All @@ -30,10 +32,12 @@ class RedisCacheEngine implements ICacheEngine {
}
}

async set(key: string, value: IData, ttl = Number.POSITIVE_INFINITY): Promise<void> {
async set(key: string, value: IData, ttl?: number | StringValue): Promise<void> {
try {
const givenTTL = typeof ttl === 'string' ? ms(ttl) : ttl
const actualTTL = givenTTL ?? Number.POSITIVE_INFINITY
const serializedValue = EJSON.stringify(convertToObject(value))
await this.#client.setex(key, Math.ceil(ttl / 1000), serializedValue)
await this.#client.setex(key, Math.ceil(actualTTL / 1000), serializedValue)
} catch (err) {
console.error(err)
}
Expand Down
3 changes: 2 additions & 1 deletion src/extend/aggregate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getKey } from '../key'

import type { Mongoose } from 'mongoose'
import type { StringValue } from 'ms'
import type Cache from '../cache/Cache'

export default function extendQuery(mongoose: Mongoose, cache: Cache): void {
Expand All @@ -18,7 +19,7 @@ export default function extendQuery(mongoose: Mongoose, cache: Cache): void {
return this._ttl
}

mongoose.Aggregate.prototype.cache = function (ttl?: string, customKey?: string) {
mongoose.Aggregate.prototype.cache = function (ttl?: number | StringValue, customKey?: string) {
this._ttl = ttl ?? null
this._key = customKey ?? null
return this
Expand Down
3 changes: 2 additions & 1 deletion src/extend/query.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getKey } from '../key'

import type { Mongoose } from 'mongoose'
import type { StringValue } from 'ms'
import type Cache from '../cache/Cache'

export default function extendQuery(mongoose: Mongoose, cache: Cache): void {
Expand Down Expand Up @@ -32,7 +33,7 @@ export default function extendQuery(mongoose: Mongoose, cache: Cache): void {
return this._ttl
}

mongoose.Query.prototype.cache = function (ttl?: string, customKey?: string) {
mongoose.Query.prototype.cache = function (ttl?: number | StringValue, customKey?: string) {
this._ttl = ttl ?? null
this._key = customKey ?? null
return this
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/ICacheEngine.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { StringValue } from 'ms'
import type IData from './IData'

interface ICacheEngine {
get: (key: string) => Promise<IData> | IData
set: (key: string, value: IData, ttl?: number) => Promise<void> | void
set: (key: string, value: IData, ttl?: number | StringValue) => Promise<void> | void
del: (key: string) => Promise<void> | void
clear: () => Promise<void> | void
close: () => Promise<void> | void
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/ICacheOptions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { RedisOptions } from 'ioredis'
import type { StringValue } from 'ms'

interface ICacheOptions {
engine: 'memory' | 'redis'
engineOptions?: RedisOptions
defaultTTL?: string
defaultTTL?: number | StringValue
debug?: boolean
}

Expand Down
13 changes: 7 additions & 6 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import extendAggregate from './extend/aggregate'
import extendQuery from './extend/query'

import type { Mongoose } from 'mongoose'
import type { StringValue } from 'ms'
import type ICacheOptions from './interfaces/ICacheOptions'

declare module 'mongoose' {
interface Query<ResultType, DocType, THelpers, RawDocType> {
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: string, customKey?: string) => this
cache: (this: Query<ResultType, DocType, THelpers, RawDocType>, ttl?: number | StringValue, customKey?: string) => this
_key: string | null
getCacheKey: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string
_ttl: string | null
getCacheTTL: (this: Query<ResultType, DocType, THelpers, RawDocType>) => string | null
_ttl: number | StringValue | null
getCacheTTL: (this: Query<ResultType, DocType, THelpers, RawDocType>) => number | StringValue | null
op?: string
_path?: unknown
_fields?: unknown
Expand All @@ -20,11 +21,11 @@ declare module 'mongoose' {
}

interface Aggregate<ResultType> {
cache: (this: Aggregate<ResultType>, ttl?: string, customKey?: string) => this
cache: (this: Aggregate<ResultType>, ttl?: number | StringValue, customKey?: string) => this
_key: string | null
getCacheKey: (this: Aggregate<ResultType>) => string
_ttl: string | null
getCacheTTL: (this: Aggregate<ResultType>) => string | null
_ttl: number | StringValue | null
getCacheTTL: (this: Aggregate<ResultType>) => number | StringValue | null
}
}

Expand Down

0 comments on commit 85454ca

Please sign in to comment.