Skip to content

Instantly share code, notes, and snippets.

@deviationist
Last active April 12, 2023 20:13
Show Gist options
  • Save deviationist/92ae71a112a8f2acac87efb77f24b0bd to your computer and use it in GitHub Desktop.
Save deviationist/92ae71a112a8f2acac87efb77f24b0bd to your computer and use it in GitHub Desktop.
A simple file-based cache driver for Node with expiration-support. No external packages needed.
import fs from 'fs';
export default class DiskCache {
static basePath = './.cache';
static prettyPrintJson = false;
#filePath;
#cacheName;
#data = {};
constructor(cacheName) {
this.#cacheName = cacheName ?? 'default-cache';
return this.#readFile();
}
get(key) {
const data = this.#data?.[key];
if (data) {
if (this.#isExpired(data)) {
this.delete(key);
} else {
return data.value;
}
}
}
put(key, value, ttl) {
const expiration = (ttl && Number.isInteger(ttl)) ? this.#unixTimestamp() + ttl : false;
this.#data[key] = { value, expiration };
return this.#writeFile();
}
delete(key) {
try {
delete this.#data[key];
return this.#writeFile();
} catch(e) {
return false;
}
}
getData() {
return this.#data;
}
#getFilePath() {
if (!this.#filePath) {
this.#filePath = `${DiskCache.basePath}/${this.#cacheName}.json`;
}
return this.#filePath;
}
#ensureFileExists() {
const filePath = this.#getFilePath();
if (!fs.existsSync(filePath)) {
fs.closeSync(fs.openSync(filePath, 'w'));
}
}
#writeFile() {
try {
this.#ensureFileExists();
const filePath = this.#getFilePath();
fs.writeFileSync(filePath, JSON.stringify(this.#data, null, DiskCache.prettyPrintJson ? 4 : 0), 'utf8');
return true;
} catch(e) {
return false;
}
}
#readFile() {
try {
this.#ensureFileExists();
const filePath = this.#getFilePath();
this.data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
return true;
} catch(e) {
return false;
}
}
#unixTimestamp() {
return Math.floor(Date.now() / 1000);
}
#isExpired(data) {
return Number.isInteger(data?.expiration) && data?.expiration <= this.#unixTimestamp();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment