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