| 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; | |
| } | |
| } | |