fs-cache-fast/index.mjs

81 lines
2.1 KiB
JavaScript

import fsSyncOriginal from 'fs'
import fsPromisesOriginal from 'fs/promises'
import crypto from 'crypto'
import path from 'path'
import os from 'os'
export default class FSCache {
constructor(options = {}, fsSync, fsPromises) {
this.fsSync = fsSync || fsSyncOriginal
this.fsPromises = fsPromises || fsPromisesOriginal
this.id = crypto.randomBytes(15).toString('base64').replace(/\//g, '-')
this.parse_json = options.parse_json ?? true
this.prefix = options.prefix ? options.prefix + '-' : ''
this.hash_alg = options.hash_alg || 'md5'
this.cache_dir = options.cache_dir || path.join(os.tmpdir(), this.id)
// Verify hash algorithm is supported on this system
crypto.createHash(this.hash_alg)
this.fsSync.mkdirSync(this.cache_dir, { recursive: true })
}
_parseCacheData(data, overwrite = {}) {
return overwrite.parse_json ?? this.parse_json ? JSON.parse(data) : data
}
_parseSetData(data, overwrite = {}) {
return overwrite.parse_json ?? this.parse_json ? JSON.stringify(data) : data
}
hash(name) {
return crypto.hash(this.hash_alg, name)
}
get(name, fallback, opts) {
return this.fsPromises.readFile(
path.join(this.cache_dir, this.hash(name)),
{ encoding: 'utf8' }
)
.then(
data => this._parseCacheData(data, opts),
err => (fallback)
)
}
getSync(name, fallback, opts) {
let data;
try {
data = this.fsSync.readFileSync(
path.join(this.cache_dir, this.hash(name)),
{ encoding: 'utf8' }
)
} catch {
return fallback
}
return this._parseCacheData(data, opts)
}
set(name, data, opts = {}) {
try {
return this.fsPromises.writeFile(
path.join(this.cache_dir, this.hash(name)),
this._parseSetData(data, opts),
{ encoding: opts.encoding || 'utf8' }
)
} catch (err) {
return Promise.reject(err)
}
}
setSync(name, data, opts = {}) {
this.fsSync.writeFileSync(
path.join(this.cache_dir, this.hash(name)),
this._parseSetData(data, opts),
{ encoding: opts.encoding || 'utf8' }
)
}
}