hfs
Version:
HTTP File Server
74 lines (73 loc) • 2.81 kB
JavaScript
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchLoad = watchLoad;
const fs_1 = require("fs");
const promises_1 = __importDefault(require("fs/promises"));
const misc_1 = require("./misc");
const debounceAsync_1 = require("./debounceAsync");
const events_1 = require("./events");
function watchLoad(path, parser, { failedOnFirstAttempt, immediateFirst } = {}) {
let doing = false;
let watcher;
const debounced = (0, debounceAsync_1.debounceAsync)(load, { wait: 500, maxWait: 1000 });
let retry;
let last;
const emitter = new events_1.BetterEventEmitter();
install(true);
const save = (0, debounceAsync_1.debounceAsync)(async (data, { reparse = false } = {}) => {
await promises_1.default.writeFile(path, data, 'utf8');
last = data;
if (reparse)
await parser(data);
emitter.emit('change', last);
});
return { unwatch, save, emitter, getText: () => last, getPath: () => path };
function install(first = false) {
try {
watcher = (0, fs_1.watch)(path, () => {
if (!save.isWorking())
void debounced();
});
debounced().catch(x => x);
if (immediateFirst)
void debounced.flush();
}
catch (e) {
retry = setTimeout(install, 3000); // manual watching until watch is successful
if (first)
failedOnFirstAttempt === null || failedOnFirstAttempt === void 0 ? void 0 : failedOnFirstAttempt();
}
}
function unwatch() {
watcher === null || watcher === void 0 ? void 0 : watcher.close();
clearTimeout(retry);
watcher = undefined;
}
async function load() {
if (doing)
return;
doing = true;
try {
const text = await (0, misc_1.readFileBusy)(path).catch(e => {
if (e.code === 'EPERM')
console.error("missing permissions on file", path); // warn user, who could be clueless about this problem
return '';
});
if (text === last)
return;
last = text;
emitter.emit('change', last);
console.debug('loaded', path);
unwatch();
install(); // reinstall, as the original file could have been renamed. We watch by the name.
await parser(text);
}
finally {
doing = false;
}
}
}
;