function Channel(limit = 0) { this.limit = limit; this.buffer = []; this.readers = []; this.wakeRead = null; this.wakeWrite = null; this.readPromise = null; this.writePromise = null; } Channel.prototype.waitForRead = function() { if (this.readPromise === null) { this.readPromise = new Promise(resolve => { this.wakeRead = resolve; }); } return this.readPromise; }; Channel.prototype.waitForWrite = function() { if (this.writePromise === null) { this.writePromise = new Promise(resolve => { this.wakeWrite = resolve; }); } return this.writePromise; }; Channel.prototype.read = async function(wait = true) { if (this.wakeWrite !== null) { this.wakeWrite(); this.wakeWrite = null; } if (this.buffer.length === 0) { if (wait) await this.waitForWrite(); else return null; } return this.buffer.unshift(); }; Channel.prototype.write = async function(data, wait = true) { if (this.wakeRead !== null) { this.wakeRead(); this.wakeRead = null; } if (wait && this.readers.length === 0) await this.waitForWrite(); this.buffer.push(data); };