UNPKG

hfs

Version:
57 lines (56 loc) 2.97 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.storeFileAttr = storeFileAttr; exports.loadFileAttr = loadFileAttr; exports.purgeFileAttr = purgeFileAttr; const kvstorage_1 = require("@rejetto/kvstorage"); const fs_1 = require("fs"); const util_1 = require("util"); const promises_1 = require("fs/promises"); const cross_1 = require("./cross"); const first_1 = require("./first"); const promises_2 = require("node:fs/promises"); const const_1 = require("./const"); const fsx = (0, cross_1.try_)(() => { const lib = require('fs-x-attributes'); return { set: (0, util_1.promisify)(lib.set), get: (0, util_1.promisify)(lib.get) }; }, () => console.warn('fs-x-attributes not available')); const fileAttrDb = new kvstorage_1.KvStorage({ defaultPutDelay: 1000, maxPutDelay: 5000 }); (0, first_1.onProcessExit)(() => fileAttrDb.flush()); const FN = 'file-attr.kv'; if ((0, fs_1.existsSync)(FN)) fileAttrDb.open(FN); const FILE_ATTR_PREFIX = 'user.hfs.'; // user. prefix to be linux compatible /* @param v must be JSON-able or undefined */ async function storeFileAttr(path, k, v) { var _a, _b; const s = await (0, promises_2.stat)(path).catch(() => null); // since we don't have fsx.remove, we simulate it with an empty string if (await (fsx === null || fsx === void 0 ? void 0 : fsx.set(path, FILE_ATTR_PREFIX + k, v === undefined ? '' : JSON.stringify(v)).then(() => 1, () => 0))) { if (s && const_1.IS_WINDOWS) (0, promises_2.utimes)(path, s.atime, s.mtime); // restore timestamps, necessary only on Windows return true; } // fallback to our kv-storage if (!fileAttrDb.isOpen()) if (!s && !v) return; // file was probably deleted, and we were asked to remove a possible attribute, but there's no fileAttrDb, so we are done, don't create the db file for nothing else await fileAttrDb.open(FN); // pipe should be a safe separator return (_b = await ((_a = fileAttrDb.put(`${path}|${k}`, v)) === null || _a === void 0 ? void 0 : _a.catch((e) => { console.error("couldn't store metadata on", path, String(e.message || e)); return false; }))) !== null && _b !== void 0 ? _b : true; // if put is undefined, the value was already there } async function loadFileAttr(path, k) { var _a; return (_a = await (fsx === null || fsx === void 0 ? void 0 : fsx.get(path, FILE_ATTR_PREFIX + k).then((x) => x === '' ? undefined : (0, cross_1.tryJson)(String(x)), () => fileAttrDb.isOpen() ? fileAttrDb.get(`${path}|${k}`) : null))) !== null && _a !== void 0 ? _a : undefined; // normalize, as we get null instead of undefined on windows } async function purgeFileAttr() { let n = 0; await Promise.all(Array.from(fileAttrDb.keys()).map(k => (0, promises_1.access)(k).catch(() => n++ && void fileAttrDb.del(k)))); if (n) await fileAttrDb.rewrite(); console.log(`removed ${n} entrie(s)`); }