157 lines
8.0 KiB
JavaScript
157 lines
8.0 KiB
JavaScript
"use strict";
|
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
};
|
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
};
|
|
var _Task_instances, _Task_opts, _Task_startedAt, _Task_parsing, _Task_settledAt, _Task_d, _Task_stdout, _Task_stderr, _Task_onSettle, _Task_resolve;
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Task = void 0;
|
|
const Async_1 = require("./Async");
|
|
const Deferred_1 = require("./Deferred");
|
|
let _taskId = 1;
|
|
/**
|
|
* Tasks embody individual jobs given to the underlying child processes. Each
|
|
* instance has a promise that will be resolved or rejected based on the
|
|
* result of the task.
|
|
*/
|
|
class Task {
|
|
/**
|
|
* @param {string} command is the value written to stdin to perform the given
|
|
* task.
|
|
* @param {Parser<T>} parser is used to parse resulting data from the
|
|
* underlying process to a typed object.
|
|
*/
|
|
constructor(command, parser) {
|
|
_Task_instances.add(this);
|
|
this.command = command;
|
|
this.parser = parser;
|
|
this.taskId = _taskId++;
|
|
_Task_opts.set(this, void 0);
|
|
_Task_startedAt.set(this, void 0);
|
|
_Task_parsing.set(this, false);
|
|
_Task_settledAt.set(this, void 0);
|
|
_Task_d.set(this, new Deferred_1.Deferred());
|
|
_Task_stdout.set(this, "");
|
|
_Task_stderr.set(this, ""
|
|
/**
|
|
* @param {string} command is the value written to stdin to perform the given
|
|
* task.
|
|
* @param {Parser<T>} parser is used to parse resulting data from the
|
|
* underlying process to a typed object.
|
|
*/
|
|
);
|
|
// We can't use .finally here, because that creates a promise chain that, if
|
|
// rejected, results in an uncaught rejection.
|
|
__classPrivateFieldGet(this, _Task_d, "f").promise.then(() => __classPrivateFieldGet(this, _Task_instances, "m", _Task_onSettle).call(this), () => __classPrivateFieldGet(this, _Task_instances, "m", _Task_onSettle).call(this));
|
|
}
|
|
/**
|
|
* @return the resolution or rejection of this task.
|
|
*/
|
|
get promise() {
|
|
return __classPrivateFieldGet(this, _Task_d, "f").promise;
|
|
}
|
|
get pending() {
|
|
return __classPrivateFieldGet(this, _Task_d, "f").pending;
|
|
}
|
|
get state() {
|
|
return __classPrivateFieldGet(this, _Task_d, "f").pending
|
|
? "pending"
|
|
: __classPrivateFieldGet(this, _Task_d, "f").rejected
|
|
? "rejected"
|
|
: "resolved";
|
|
}
|
|
onStart(opts) {
|
|
__classPrivateFieldSet(this, _Task_opts, opts, "f");
|
|
__classPrivateFieldSet(this, _Task_startedAt, Date.now(), "f");
|
|
}
|
|
get runtimeMs() {
|
|
var _a;
|
|
return __classPrivateFieldGet(this, _Task_startedAt, "f") == null
|
|
? undefined
|
|
: ((_a = __classPrivateFieldGet(this, _Task_settledAt, "f")) !== null && _a !== void 0 ? _a : Date.now()) - __classPrivateFieldGet(this, _Task_startedAt, "f");
|
|
}
|
|
toString() {
|
|
return (this.constructor.name +
|
|
"(" +
|
|
this.command.replace(/\s+/gm, " ").slice(0, 80).trim() +
|
|
")#" +
|
|
this.taskId);
|
|
}
|
|
onStdout(buf) {
|
|
var _a, _b;
|
|
__classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f") + buf.toString(), "f");
|
|
const passRE = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.passRE;
|
|
if (passRE != null && passRE.exec(__classPrivateFieldGet(this, _Task_stdout, "f")) != null) {
|
|
// remove the pass token from stdout:
|
|
__classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f").replace(passRE, ""), "f");
|
|
__classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, true);
|
|
}
|
|
else {
|
|
const failRE = (_b = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _b === void 0 ? void 0 : _b.failRE;
|
|
if (failRE != null && failRE.exec(__classPrivateFieldGet(this, _Task_stdout, "f")) != null) {
|
|
// remove the fail token from stdout:
|
|
__classPrivateFieldSet(this, _Task_stdout, __classPrivateFieldGet(this, _Task_stdout, "f").replace(failRE, ""), "f");
|
|
__classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, false);
|
|
}
|
|
}
|
|
}
|
|
onStderr(buf) {
|
|
var _a;
|
|
__classPrivateFieldSet(this, _Task_stderr, __classPrivateFieldGet(this, _Task_stderr, "f") + buf.toString(), "f");
|
|
const failRE = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.failRE;
|
|
if (failRE != null && failRE.exec(__classPrivateFieldGet(this, _Task_stderr, "f")) != null) {
|
|
// remove the fail token from stderr:
|
|
__classPrivateFieldSet(this, _Task_stderr, __classPrivateFieldGet(this, _Task_stderr, "f").replace(failRE, ""), "f");
|
|
__classPrivateFieldGet(this, _Task_instances, "m", _Task_resolve).call(this, false);
|
|
}
|
|
}
|
|
/**
|
|
* @return true if the wrapped promise was rejected
|
|
*/
|
|
reject(error) {
|
|
return __classPrivateFieldGet(this, _Task_d, "f").reject(error);
|
|
}
|
|
}
|
|
exports.Task = Task;
|
|
_Task_opts = new WeakMap(), _Task_startedAt = new WeakMap(), _Task_parsing = new WeakMap(), _Task_settledAt = new WeakMap(), _Task_d = new WeakMap(), _Task_stdout = new WeakMap(), _Task_stderr = new WeakMap(), _Task_instances = new WeakSet(), _Task_onSettle = function _Task_onSettle() {
|
|
var _a;
|
|
__classPrivateFieldSet(this, _Task_settledAt, (_a = __classPrivateFieldGet(this, _Task_settledAt, "f")) !== null && _a !== void 0 ? _a : Date.now(), "f");
|
|
}, _Task_resolve = async function _Task_resolve(passed) {
|
|
var _a, _b, _c;
|
|
// fail always wins.
|
|
passed = !__classPrivateFieldGet(this, _Task_d, "f").rejected && passed;
|
|
// wait for stderr and stdout to flush:
|
|
const flushMs = (_b = (_a = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _a === void 0 ? void 0 : _a.streamFlushMillis) !== null && _b !== void 0 ? _b : 0;
|
|
if (flushMs > 0) {
|
|
await (0, Async_1.delay)(flushMs);
|
|
}
|
|
// we're expecting this method may be called concurrently (if there are both
|
|
// pass and fail tokens found in stderr and stdout), but we only want to run
|
|
// this once, so
|
|
if (!this.pending || __classPrivateFieldGet(this, _Task_parsing, "f"))
|
|
return;
|
|
// this.#opts
|
|
// ?.logger()
|
|
// .trace("Task.#resolve()", { command: this.command, state: this.state })
|
|
// Prevent concurrent parsing:
|
|
__classPrivateFieldSet(this, _Task_parsing, true, "f");
|
|
try {
|
|
const parseResult = await this.parser(__classPrivateFieldGet(this, _Task_stdout, "f"), __classPrivateFieldGet(this, _Task_stderr, "f"), passed);
|
|
if (__classPrivateFieldGet(this, _Task_d, "f").resolve(parseResult)) {
|
|
}
|
|
else {
|
|
(_c = __classPrivateFieldGet(this, _Task_opts, "f")) === null || _c === void 0 ? void 0 : _c.observer.emit("internalError", new Error(this.toString() + " ._resolved() more than once"));
|
|
}
|
|
}
|
|
catch (error) {
|
|
this.reject(error);
|
|
}
|
|
};
|
|
//# sourceMappingURL=Task.js.map
|