Spaces:
Running
Running
export default class SwitchableStream extends TransformStream { | |
private _controller: TransformStreamDefaultController | null = null; | |
private _currentReader: ReadableStreamDefaultReader | null = null; | |
private _switches = 0; | |
constructor() { | |
let controllerRef: TransformStreamDefaultController | undefined; | |
super({ | |
start(controller) { | |
controllerRef = controller; | |
}, | |
}); | |
if (controllerRef === undefined) { | |
throw new Error('Controller not properly initialized'); | |
} | |
this._controller = controllerRef; | |
} | |
async switchSource(newStream: ReadableStream) { | |
if (this._currentReader) { | |
await this._currentReader.cancel(); | |
} | |
this._currentReader = newStream.getReader(); | |
this._pumpStream(); | |
this._switches++; | |
} | |
private async _pumpStream() { | |
if (!this._currentReader || !this._controller) { | |
throw new Error('Stream is not properly initialized'); | |
} | |
try { | |
while (true) { | |
const { done, value } = await this._currentReader.read(); | |
if (done) { | |
break; | |
} | |
this._controller.enqueue(value); | |
} | |
} catch (error) { | |
console.log(error); | |
this._controller.error(error); | |
} | |
} | |
close() { | |
if (this._currentReader) { | |
this._currentReader.cancel(); | |
} | |
this._controller?.terminate(); | |
} | |
get switches() { | |
return this._switches; | |
} | |
} | |