rawx
Version:
process daemon with utilities
289 lines • 12.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
/***
* license.kind
* Original: https://github.com/lilzeta
* Flux this tag if/whenever you feel like
*/
// module.exports = Watch;
// externals
const { watchFile, unwatchFile, Stats } = require("fs");
// modulez require
const Ops = require("../ops/ops");
const Files_Tree = require("./files_tree/files_tree");
const Complex_File_Tree = require("./files_tree/files_complex");
// pause before monitoring the file_tree
const DEFAULT_INITIAL_WATCH_DELAY = 3500;
// Server_Facade behaves as would exposed inner _Server
class Watch_Facade {
constructor(args) {
return watch_creator(args);
}
}
// Now we expose _Watch through Watch_Facade as if we created it w/vanilla
const Watch = Watch_Facade;
const watch_creator = (args) => {
// set in constructor
let o;
// const Watch: Watch_Class = class _Watch <= return into w/a closure
class _Watch {
constructor(args) {
Object.defineProperty(this, "debug", {
enumerable: true,
configurable: true,
writable: true,
value: 2
});
// for both _file_tree/_complex
// trigger: (path: str, target?: number) => void;
// fallback or default if no specifily aligned trigger
Object.defineProperty(this, "trigger_index", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
// if using trigger_indices - length should match watch.paths
Object.defineProperty(this, "trigger_indices", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "simple_trigger_indices", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "trigger_path_count", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "path_hasher", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "poll", {
enumerable: true,
configurable: true,
writable: true,
value: 5000
});
// Either: _file_tree for single tree, _complex for fully explicated forest
Object.defineProperty(this, "files_tree", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "_complex", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
// Must be done immediately from an injector/instatiator/partner/server ...
Object.defineProperty(this, "set_trigger", {
enumerable: true,
configurable: true,
writable: true,
value: (fn) => (this.trigger = fn)
});
Object.defineProperty(this, "trigger", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "watch_hit", {
enumerable: true,
configurable: true,
writable: true,
value: (path, trigger_index) => (curr, prev) => {
o.errata(8, "L:201", `watch_hit, path: ${path}`);
// only when a file is changed ... not possible for dir watch - fs.watch
o.errata(9, "L:203", `watch_hit, trigger_index: ${trigger_index}`);
curr.mtime !== prev.mtime && this.trigger(path, trigger_index);
}
});
Object.defineProperty(this, "watches_clear", {
enumerable: true,
configurable: true,
writable: true,
value: () => __awaiter(this, void 0, void 0, function* () {
if (this._complex) {
this._complex.trees().forEach((file_tree) => {
this.unwatch_tree(file_tree);
});
this._complex = undefined;
this.files_tree = undefined;
}
else {
if (this.files_tree)
this.unwatch_tree(this.files_tree);
this.files_tree = undefined;
}
})
});
let { paths, name } = args, opts = __rest(args, ["paths", "name"]);
let label;
if (name === null || name === void 0 ? void 0 : name.length)
label = `${name}|Watcher`;
else
label = "";
if (args.debug !== undefined) {
this.debug = args.debug;
}
// An Env Configured Ops rebased for `Watch`
o = new Ops({ colors: opts.colors, debug: this.debug, label });
// If used stand-alone only create if opts.files ... Fatal, configuration must be valid
if (!(paths === null || paths === void 0 ? void 0 : paths.length) && !args.complex)
throw new Error("No need for a special proc if no path(s) to watch.");
if (o.defi(args.trigger_index))
this.trigger_index = args.trigger_index;
const { complex, match, trigger_index } = opts;
if (o.defi(args.complex)) {
// Doesn't use watch.paths right now
this._complex = new Complex_File_Tree({
// what are we gonna do about this?
complex: complex.complex,
match,
max_depth: 7,
});
this.trigger_indices = this.map_complex_triggers({
complex: complex.complex,
default_trigger: trigger_index,
});
}
else {
this.simple_trigger_indices = args.trigger_indices;
this.files_tree = new Files_Tree({
root_paths: paths,
match,
});
}
// this.trigger = trigger; // trigger = an async fn
if (o.defi(opts.poll)) {
if (typeof opts.poll === "number") {
this.poll = Math.max(opts.poll, 1000);
}
else {
throw new Error("Validation of Watch.poll arg failed, number only");
}
}
let watch_delay = opts.delay;
if (!o.defi(watch_delay)) {
watch_delay = DEFAULT_INITIAL_WATCH_DELAY;
}
// from syncronous to asyncronous
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
if (!this.trigger) {
throw new Error("Instantiation of Watch is incomplete, trigger must be set");
}
yield this.watch_start().catch(); // TODO other solution to engage promises?
const watch_log = `watch constructor completed & watch has started. f:[${this.trigger_path_count}]`;
o.accent(6, "L:140", watch_log);
}), watch_delay);
}
watch_start() {
return __awaiter(this, void 0, void 0, function* () {
// TODO validate set_trigger has set trigger!
if (this._complex) {
yield this._complex.setup_complex_tree();
this._complex.trees().forEach((file_tree, i) => {
this.watch_tree(file_tree, i);
});
if (this.debug > 7) {
this._complex.trees().forEach((file_tree) => {
o.accent(8, "L:157", file_tree.trunks());
});
}
}
else {
// if !watches cleared already
if (this.files_tree !== undefined) {
yield this.files_tree.setup_tree();
this.watch_tree(this.files_tree);
}
}
});
}
// TODO validation, if n=0 trigger_indices[0] array length must match trunks[0] length...
watch_tree(files_tree, n = 0) {
files_tree.trunks().forEach((path_arr, i) => {
this.trigger_path_count += path_arr.length;
let trigger_index;
// Complex
if (this.trigger_indices) {
// TODO something more stable
o.accent(1, "L:176", `this.trigger_indices`);
o.accent(1, "L:177", this.trigger_indices);
trigger_index = this.trigger_indices[n][i];
}
// not Complex
else if (this.simple_trigger_indices) {
// TODO validate?
trigger_index = this.simple_trigger_indices[i];
}
else {
// The single trigger case
trigger_index = this.trigger_index; // undefined is ok?
}
path_arr.forEach((path) => {
watchFile(path, { interval: this.poll }, this.watch_hit(path, trigger_index));
});
});
}
// Some ambiguities and validation to work out yet
map_complex_triggers({ complex: complex_arr, default_trigger, }) {
return complex_arr.reduce((propogate, complex, i) => {
propogate.push([]); // as in propogate[i] = []
let sub_map;
if (complex.trigger_indices)
// TODO why is the ? needed ...linting errata
sub_map = (n) => { var _a, _b; return (_b = (_a = complex.trigger_indices) === null || _a === void 0 ? void 0 : _a[n]) !== null && _b !== void 0 ? _b : default_trigger; };
else
sub_map = (_) => { var _a; return (_a = complex.trigger_index) !== null && _a !== void 0 ? _a : default_trigger; };
complex.paths.forEach((_root_path, n) => {
propogate[i].push(sub_map(n));
});
return propogate;
}, Array());
}
unwatch_tree(file_tree) {
file_tree.trunks().forEach((path_arr) => {
path_arr.forEach((path) => {
unwatchFile(path);
});
});
}
}
return new _Watch(args);
};
module.exports = Watch;
//# sourceMappingURL=watch.js.map