This repository has been archived on 2023-10-27. You can view files and clone it, but cannot push or open issues or pull requests.
node-fetch-cache/classes/caching/file_system_cache.js

76 lines
2.1 KiB
JavaScript
Raw Normal View History

2021-07-06 01:40:53 +00:00
import cacache from 'cacache';
import { Readable } from 'stream';
2021-07-05 18:17:21 +00:00
import { KeyTimeout } from './key_timeout.js';
2021-06-12 23:26:05 +00:00
2021-07-06 01:40:53 +00:00
function getBodyAndMetaKeys(key) {
return [`${key}body`, `${key}meta`];
}
2021-07-05 18:17:21 +00:00
export class FileSystemCache {
2021-06-12 23:26:05 +00:00
constructor(options = {}) {
this.ttl = options.ttl;
this.keyTimeout = new KeyTimeout();
2021-07-06 01:40:53 +00:00
this.cacheDirectory = options.cacheDirectory || '.cache';
2021-06-12 23:26:05 +00:00
}
2021-07-06 01:40:53 +00:00
async get(key) {
const [, metaKey] = getBodyAndMetaKeys(key);
const metaInfo = await cacache.get.info(this.cacheDirectory, metaKey);
if (!metaInfo) {
return undefined;
}
const metaBuffer = await cacache.get.byDigest(this.cacheDirectory, metaInfo.integrity);
const metaData = JSON.parse(metaBuffer);
const { bodyStreamIntegrity, bodyStreamLength } = metaData;
delete metaData.bodyStreamIntegrity;
delete metaData.bodyStreamLength;
const bodyStream = bodyStreamLength > 0
? cacache.get.stream.byDigest(this.cacheDirectory, bodyStreamIntegrity)
: Readable.from(Buffer.alloc(0));
return {
bodyStream,
metaData,
};
2021-06-12 23:26:05 +00:00
}
remove(key) {
2021-07-06 01:40:53 +00:00
const [bodyKey, metaKey] = getBodyAndMetaKeys(key);
2021-06-12 23:26:05 +00:00
this.keyTimeout.clearTimeout(key);
2021-07-06 01:40:53 +00:00
return Promise.all([
cacache.rm.entry(this.cacheDirectory, bodyKey),
cacache.rm.entry(this.cacheDirectory, metaKey),
]);
2021-06-12 23:26:05 +00:00
}
2021-07-06 01:40:53 +00:00
async set(key, bodyStream, metaData, bodyStreamLength) {
const [bodyKey, metaKey] = getBodyAndMetaKeys(key);
const metaCopy = { ...metaData, bodyStreamLength };
this.keyTimeout.clearTimeout(key);
if (bodyStreamLength > 0) {
metaCopy.bodyStreamIntegrity = await new Promise((fulfill, reject) => {
bodyStream.pipe(cacache.put.stream(this.cacheDirectory, bodyKey))
.on('integrity', (i) => fulfill(i))
.on('error', (e) => {
reject(e);
});
});
}
const metaBuffer = Buffer.from(JSON.stringify(metaCopy));
await cacache.put(this.cacheDirectory, metaKey, metaBuffer);
2021-06-12 23:26:05 +00:00
if (typeof this.ttl === 'number') {
this.keyTimeout.updateTimeout(key, this.ttl, () => this.remove(key));
}
}
2021-07-05 18:17:21 +00:00
}