- Consolidated duplicate UndoManagers to single instance - Fixed connection promise to only resolve on 'connected' status - Fixed WebSocketProvider import (WebsocketProvider) - Added proper doc.destroy() cleanup - Renamed isPresenceInitialized property to avoid conflict Co-Authored-By: Paperclip <noreply@paperclip.ing>
141 lines
4.0 KiB
JavaScript
141 lines
4.0 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true,
|
|
});
|
|
exports.default = void 0;
|
|
var _lodash = _interopRequireDefault(require("lodash.throttle"));
|
|
var _readline = _interopRequireDefault(require("readline"));
|
|
var _tty = _interopRequireDefault(require("tty"));
|
|
var _util = _interopRequireDefault(require("util"));
|
|
function _interopRequireDefault(e) {
|
|
return e && e.__esModule ? e : { default: e };
|
|
}
|
|
const { promisify } = _util.default;
|
|
const moveCursor = promisify(_readline.default.moveCursor);
|
|
const clearScreenDown = promisify(_readline.default.clearScreenDown);
|
|
const streamWrite = promisify((stream, chunk, callback) => {
|
|
return stream.write(chunk, callback);
|
|
});
|
|
function chunkString(str, size) {
|
|
const ANSI_COLOR = "\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?m";
|
|
const SKIP_ANSI = `(?:${ANSI_COLOR})*`;
|
|
return str.match(new RegExp(`(?:${SKIP_ANSI}.){1,${size}}`, "g")) || [];
|
|
}
|
|
function getTTYStream(stream) {
|
|
if (
|
|
stream instanceof _tty.default.WriteStream &&
|
|
stream.isTTY &&
|
|
stream.columns >= 1
|
|
) {
|
|
return stream;
|
|
}
|
|
return null;
|
|
}
|
|
class Terminal {
|
|
#logLines;
|
|
#nextStatusStr;
|
|
#statusStr;
|
|
#stream;
|
|
#ttyStream;
|
|
#updatePromise;
|
|
#isUpdating;
|
|
#isPendingUpdate;
|
|
#shouldFlush;
|
|
#writeStatusThrottled;
|
|
constructor(stream, opts = {}) {
|
|
this.#logLines = [];
|
|
this.#nextStatusStr = "";
|
|
this.#statusStr = "";
|
|
this.#stream = stream;
|
|
this.#ttyStream = (opts.ttyPrint ?? true) ? getTTYStream(stream) : null;
|
|
this.#updatePromise = null;
|
|
this.#isUpdating = false;
|
|
this.#isPendingUpdate = false;
|
|
this.#shouldFlush = false;
|
|
this.#writeStatusThrottled = (0, _lodash.default)(
|
|
(status) => this.#stream.write(status),
|
|
3500,
|
|
);
|
|
}
|
|
#scheduleUpdate() {
|
|
if (this.#isUpdating) {
|
|
this.#isPendingUpdate = true;
|
|
return;
|
|
}
|
|
this.#isUpdating = true;
|
|
this.#updatePromise = this.#update().then(async () => {
|
|
while (this.#isPendingUpdate) {
|
|
if (!this.#shouldFlush) {
|
|
await new Promise((resolve) => setTimeout(resolve, 33));
|
|
}
|
|
this.#isPendingUpdate = false;
|
|
await this.#update();
|
|
}
|
|
this.#isUpdating = false;
|
|
this.#shouldFlush = false;
|
|
});
|
|
}
|
|
async waitForUpdates() {
|
|
await (this.#updatePromise || Promise.resolve());
|
|
}
|
|
async flush() {
|
|
if (this.#isUpdating) {
|
|
this.#shouldFlush = true;
|
|
}
|
|
await this.waitForUpdates();
|
|
this.#writeStatusThrottled.flush();
|
|
}
|
|
async #update() {
|
|
const ttyStream = this.#ttyStream;
|
|
const nextStatusStr = this.#nextStatusStr;
|
|
const statusStr = this.#statusStr;
|
|
const logLines = this.#logLines;
|
|
this.#statusStr = nextStatusStr;
|
|
this.#logLines = [];
|
|
if (statusStr === nextStatusStr && logLines.length === 0) {
|
|
return;
|
|
}
|
|
if (ttyStream && statusStr.length > 0) {
|
|
const statusLinesCount = statusStr.split("\n").length - 1;
|
|
await moveCursor(ttyStream, -ttyStream.columns, -statusLinesCount - 1);
|
|
await clearScreenDown(ttyStream);
|
|
}
|
|
if (logLines.length > 0) {
|
|
await streamWrite(this.#stream, logLines.join("\n") + "\n");
|
|
}
|
|
if (ttyStream) {
|
|
if (nextStatusStr.length > 0) {
|
|
await streamWrite(this.#stream, nextStatusStr + "\n");
|
|
}
|
|
} else {
|
|
this.#writeStatusThrottled(
|
|
nextStatusStr.length > 0 ? nextStatusStr + "\n" : "",
|
|
);
|
|
}
|
|
}
|
|
status(format, ...args) {
|
|
const nextStatusStr = this.#nextStatusStr;
|
|
const statusStr = _util.default.format(format, ...args);
|
|
this.#nextStatusStr = this.#ttyStream
|
|
? chunkString(statusStr, this.#ttyStream.columns).join("\n")
|
|
: statusStr;
|
|
this.#scheduleUpdate();
|
|
return nextStatusStr;
|
|
}
|
|
log(format, ...args) {
|
|
const line = _util.default.format(format, ...args);
|
|
if (this.#ttyStream) {
|
|
this.#logLines.push(line);
|
|
} else {
|
|
void streamWrite(this.#stream, line + "\n");
|
|
}
|
|
this.#scheduleUpdate();
|
|
}
|
|
persistStatus() {
|
|
this.log(this.#nextStatusStr);
|
|
this.#nextStatusStr = "";
|
|
}
|
|
}
|
|
exports.default = Terminal;
|