UNPKG

@foxpage/foxpage-manager

Version:

foxpage resource manager

159 lines (158 loc) 4.79 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DiskCache = void 0; const crypto_1 = __importDefault(require("crypto")); const fs_extra_1 = require("fs-extra"); const globby_1 = __importDefault(require("globby")); const lodash_1 = __importDefault(require("lodash")); const local_1 = require("./local"); /** * disk cache * * @export * @class DiskCache * @implements {ResourceCache<T>} * @template T */ class DiskCache { constructor(opt) { this.diskCache = new Map(); this.appId = opt.appId; this.type = opt.type; this.logger = opt.logger; } getCurCount() { return this.diskCache.size; } /** * set disk cache * * @param {string} id * @param {T} resource * @return {*} {Promise<void>} */ async set(id, resource) { var _a; try { const hash = this.computeMD5Hash(JSON.stringify(resource)); const filePath = this.generateFilePath(id, hash); this.diskCache.set(id, { filePath, hash }); await (0, local_1.storeContent)(filePath, lodash_1.default.cloneDeep(resource)); await this.delete(id, false); } catch (e) { const msg = e.message; if (msg.indexOf('EEXIST') === -1) { (_a = this.logger) === null || _a === void 0 ? void 0 : _a.error('store content failed: ' + e); } } } /** * get content from disk * * @param {string} id * @return {*} {(Promise<T | null | undefined>)} */ async get(id) { const cached = this.diskCache.get(id); try { let filePath = ''; if (cached) { filePath = cached.filePath; } else { const rootDir = this.getRootDir(id); const files = await this.getFiles(rootDir); filePath = files[0]; } if (filePath) { const result = await (0, fs_extra_1.readJSON)(filePath); return result || null; } return null; } catch (e) { // this.logger?.info('get content failed: ' + e); return null; } } /** * check if exist the content * * @param {string} id * @return {*} {Promise<boolean>} */ async has(id) { return this.diskCache.has(id) || !!(await this.get(id)); } /** * update delete status for delete action * * @param {string} id * @param {boolean} all true: remove all files of the dir, false: only remove the invalid files * @return {*} {Promise<void>} * @memberof DiskCache */ async delete(id, all = true) { const cached = this.diskCache.get(id); if (cached) { try { const rootDir = this.getRootDir(id); if (all) { await (0, fs_extra_1.remove)(rootDir); this.diskCache.delete(id); } else { const files = await this.getFiles(rootDir); const doRemove = async (list) => { for (const fileName of list) { if (!fileName.includes(cached.hash)) { // only remove the invalid files await (0, fs_extra_1.remove)(fileName); } } }; await doRemove(files); } } catch (_e) { // this.logger?.warn('remove content failed,' + e); } } } getRootDir(id) { const dirs = [this.type, id]; const rootDir = (0, local_1.resolveContentDir)(this.appId, dirs); return rootDir; } generateFilePath(id, hash) { const dirs = [this.type, id, hash]; const filePath = (0, local_1.resolveContentPath)(this.appId, dirs); return filePath; } computeMD5Hash(code, len = 8) { const md5 = crypto_1.default.createHash('md5'); md5.update(code); const hash = md5.digest('hex'); return hash.substring(0, len); } async getFiles(root) { const files = await (0, globby_1.default)('**/*', { absolute: true, onlyFiles: true, cwd: root, }); return files; } /** * destroy the instance * */ destroy() { this.diskCache.clear(); } } exports.DiskCache = DiskCache;