From fd782219eff8016a00e87f0c8e44af3a3ba74be6 Mon Sep 17 00:00:00 2001 From: Max Isom Date: Sun, 19 Sep 2021 22:04:34 -0400 Subject: Move to ESM, use ytsr, implement caching Closes #315 --- src/services/cache.ts | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/services/cache.ts (limited to 'src/services/cache.ts') diff --git a/src/services/cache.ts b/src/services/cache.ts new file mode 100644 index 0000000..d76eab9 --- /dev/null +++ b/src/services/cache.ts @@ -0,0 +1,52 @@ +import {injectable} from 'inversify'; +import {Cache} from '../models/index.js'; +import debug from '../utils/debug.js'; + +type Seconds = number; + +type Options = { + expiresIn: Seconds; + key?: string; +}; + +const futureTimeToDate = (time: Seconds) => new Date(new Date().getTime() + (time * 1000)); + +@injectable() +export default class CacheProvider { + async wrap(func: (...options: any) => Promise, ...options: T): Promise { + if (options.length === 0) { + throw new Error('Missing cache options'); + } + + const functionArgs = options.slice(0, options.length - 1); + + const { + key = JSON.stringify(functionArgs), + expiresIn + } = options[options.length - 1] as Options; + + const cachedResult = await Cache.findByPk(key); + + if (cachedResult) { + if (new Date() < cachedResult.expiresAt) { + debug(`Cache hit: ${key}`); + return JSON.parse(cachedResult.value); + } + + await cachedResult.destroy(); + } + + debug(`Cache miss: ${key}`); + + const result = await func(...options as any[]); + + // Save result + await Cache.upsert({ + key, + value: JSON.stringify(result), + expiresAt: futureTimeToDate(expiresIn) + }); + + return result; + } +} -- cgit v1.2.3