80 lines
2.1 KiB
JavaScript
80 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' }
|
|
)
|
|
}
|
|
}
|