UNPKG

@file-cache/core

Version:

A cache for file metadata or file content.

102 lines (100 loc) 2.88 kB
'use strict'; const fs = require('node:fs/promises'); const md5 = require('./md5.cjs'); const _interopDefault = e => e && e.__esModule ? e : { default: e }; const fs__default = /*#__PURE__*/_interopDefault(fs); const readFileCache = async cacheFilePath => { try { const json = JSON.parse(await fs__default.default.readFile(cacheFilePath, "utf-8")); return new Map(Object.entries(json)); } catch { return new Map(); } }; const createFileCache = async (cacheFilePath, mode) => { // When mode is changed, create another cache const cacheFileFullPath = cacheFilePath + "-" + mode; // file <-> Map let fileCacheMap = await readFileCache(cacheFileFullPath); // Processing Map const entryMap = new Map(fileCacheMap); const getAndUpdateCacheContent = async filePath => { try { const hash = md5.md5(await fs__default.default.readFile(filePath)); const normalizedFilePath = filePath.toString(); const cacheValue = fileCacheMap.get(normalizedFilePath); if (cacheValue && cacheValue.hash === hash) { return { changed: false }; } entryMap.set(normalizedFilePath, { hash }); return { changed: true }; } catch (error) { return { changed: false, error }; } }; const getAndUpdateCacheMetadata = async filePath => { const normalizedFilePath = filePath.toString(); const cacheValue = fileCacheMap.get(normalizedFilePath); try { const stat = await fs__default.default.stat(filePath); const metadata = { mtime: stat.mtime.getTime(), size: stat.size }; if (cacheValue && cacheValue.mtime === metadata.mtime && cacheValue.size === stat.size) { return { changed: false }; } entryMap.set(normalizedFilePath, metadata); return { changed: true }; } catch (error) { return { changed: false, error }; } }; return { async getFileDescriptor(filePath) { if (mode === "content") { return getAndUpdateCacheContent(filePath); } else if (mode === "metadata") { return getAndUpdateCacheMetadata(filePath); } throw new Error("Invalid mode" + mode); }, delete(filePath) { return entryMap.delete(filePath); }, clear() { entryMap.clear(); }, async reconcile() { try { await fs__default.default.writeFile(cacheFileFullPath, JSON.stringify(Object.fromEntries(entryMap)), "utf-8"); // reflect the changes in the cacheMap fileCacheMap = new Map(entryMap); return true; } catch (error) { console.error("reconcile is failed", error); return false; } } }; }; exports.createFileCache = createFileCache; //# sourceMappingURL=createFileCache.cjs.map