aboutsummaryrefslogtreecommitdiff
path: root/packages/server/src/cache/index.ts
blob: 9bb4abd3278eec0a5276a65599e119735370769d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
 * Utilities for managing server-side cache
 *
 * @module cache
 */

import { caching, Cache } from "cache-manager";
import { cacheAllSources, CacheSource } from "./sources";
import { CacheConfig } from "../types";

export *as sources from "./sources";

export class ServerCache {
	private _cache: Cache;

	public ready = false;

	/**
	 * @param [config] - Cache configuration from the settings
	 */
	constructor(config?: Omit<CacheConfig, "enabled">) {
		this._cache = caching({
			store: "memory",
			max: config?.max || 5000000,
			ttl: config?.ttl || 120,
			refreshThreshold: config?.refreshThreshold || 80
		});
	}

	/**
	 * Returns the cache value specified in the source & caches it if need be
	 *
	 * @template T - The constructor of a cache source
	 * @param Source - Information about where to get the value from
	 * @param args - Source arguments
	 * @returns A value from the cache
	 */
	// eslint-disable-next-line @typescript-eslint/no-explicit-any
	public async receive<T extends new(...args: any[]) => CacheSource>(Source: T, ...args: ConstructorParameters<T>): Promise<unknown> {
		const source = new Source(...args);

		const result = await this._cache.wrap(source.key(), () => source.func()) as T;

		return source.post
			? source.post(result) as T
			: result;
	}

	/**
	 * Initialize the cache.
	 * This will cache all of the available sources.
	 *
	 * @param git_dir - A git directory
	 */
	public async init(git_dir: string): Promise<void> {
		if(this.ready === true) {
			throw(new Error("Cache has already been initialized!"));
		}

		await cacheAllSources(this, git_dir);

		this.ready = true;
	}
}