Files
2025-03-28 12:30:19 +11:00

231 lines
5.4 KiB
JavaScript

"use strict";
exports.__esModule = true;
exports.default = exports.WriteStream = exports.ReadStream = exports.ReadAfterDestroyedError = void 0;
var _crypto = _interopRequireDefault(require("crypto"));
var _fs = _interopRequireDefault(require("fs"));
var _os = _interopRequireDefault(require("os"));
var _path = _interopRequireDefault(require("path"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
class ReadAfterDestroyedError extends Error {}
exports.ReadAfterDestroyedError = ReadAfterDestroyedError;
class ReadStream extends _fs.default.ReadStream {
constructor(writeStream, name) {
super("", {});
this.name = name;
this._writeStream = writeStream;
this.error = this._writeStream.error;
this.addListener("error", error => {
this.error = error;
});
this.open();
}
get ended() {
return this._readableState.ended;
}
_read(n) {
if (typeof this.fd !== "number")
return this.once("open", function() {
this._read(n);
});
if (this._writeStream.finished || this._writeStream.closed)
return super._read(n);
const unread = this._writeStream.bytesWritten - this.bytesRead;
if (unread === 0) {
const retry = () => {
this._writeStream.removeListener("finish", retry);
this._writeStream.removeListener("write", retry);
this._read(n);
};
this._writeStream.addListener("finish", retry);
this._writeStream.addListener("write", retry);
return;
}
return super._read(Math.min(n, unread));
}
_destroy(error, callback) {
if (typeof this.fd !== "number") {
this.once("open", this._destroy.bind(this, error, callback));
return;
}
_fs.default.close(this.fd, closeError => {
callback(closeError || error);
this.fd = null;
this.closed = true;
this.emit("close");
});
}
open() {
if (!this._writeStream) return;
if (typeof this._writeStream.fd !== "number") {
this._writeStream.once("open", () => this.open());
return;
}
this.path = this._writeStream.path;
super.open();
}
}
exports.ReadStream = ReadStream;
class WriteStream extends _fs.default.WriteStream {
constructor() {
super("", {
autoClose: false
});
this._readStreams = new Set();
this.error = null;
this._cleanupSync = () => {
process.removeListener("exit", this._cleanupSync);
process.removeListener("SIGINT", this._cleanupSync);
if (typeof this.fd === "number")
try {
_fs.default.closeSync(this.fd);
} catch (error) {}
try {
_fs.default.unlinkSync(this.path);
} catch (error) {}
};
}
get finished() {
return this._writableState.finished;
}
open() {
_crypto.default.randomBytes(16, (error, buffer) => {
if (error) {
this.destroy(error);
return;
}
this.path = _path.default.join(
_os.default.tmpdir(),
`capacitor-${buffer.toString("hex")}.tmp`
);
_fs.default.open(this.path, "wx", this.mode, (error, fd) => {
if (error) {
this.destroy(error);
return;
}
process.addListener("exit", this._cleanupSync);
process.addListener("SIGINT", this._cleanupSync);
this.fd = fd;
this.emit("open", fd);
this.emit("ready");
});
});
}
_write(chunk, encoding, callback) {
super._write(chunk, encoding, error => {
if (!error) this.emit("write");
callback(error);
});
}
_destroy(error, callback) {
if (typeof this.fd !== "number") {
this.once("open", this._destroy.bind(this, error, callback));
return;
}
process.removeListener("exit", this._cleanupSync);
process.removeListener("SIGINT", this._cleanupSync);
const unlink = error => {
_fs.default.unlink(this.path, unlinkError => {
callback(unlinkError || error);
this.fd = null;
this.closed = true;
this.emit("close");
});
};
if (typeof this.fd === "number") {
_fs.default.close(this.fd, closeError => {
unlink(closeError || error);
});
return;
}
unlink(error);
}
destroy(error, callback) {
if (error) this.error = error;
if (this.destroyed) return super.destroy(error, callback);
if (typeof callback === "function")
this.once("close", callback.bind(this, error));
if (this._readStreams.size === 0) {
super.destroy(error, callback);
return;
}
this._destroyPending = true;
if (error)
for (let readStream of this._readStreams) readStream.destroy(error);
}
createReadStream(name) {
if (this.destroyed)
throw new ReadAfterDestroyedError(
"A ReadStream cannot be created from a destroyed WriteStream."
);
const readStream = new ReadStream(this, name);
this._readStreams.add(readStream);
const remove = () => {
this._deleteReadStream(readStream);
readStream.removeListener("end", remove);
readStream.removeListener("close", remove);
};
readStream.addListener("end", remove);
readStream.addListener("close", remove);
return readStream;
}
_deleteReadStream(readStream) {
if (this._readStreams.delete(readStream) && this._destroyPending)
this.destroy();
}
}
exports.WriteStream = WriteStream;
var _default = WriteStream;
exports.default = _default;