streams
streams copied to clipboard
How to create a transformed WritableStream that waits for close?
Now I have this API:
export function adbSyncPush(
stream: AdbBufferedStream,
writer: WritableStreamDefaultWriter<Uint8Array>,
filename: string,
mode: number = (LinuxFileType.File << 12) | 0o666,
mtime: number = (Date.now() / 1000) | 0,
packetSize: number = ADB_SYNC_MAX_PACKET_SIZE,
): WritableStream<Uint8Array> {
// FIXME: `ChunkStream` can't forward `close` Promise.
const { readable, writable } = new ChunkStream(packetSize);
readable.pipeTo(new WritableStream<Uint8Array>({
async start() {
const pathAndMode = `${filename},${mode.toString()}`;
await adbSyncWriteRequest(writer, AdbSyncRequestId.Send, pathAndMode);
},
async write(chunk) {
await adbSyncWriteRequest(writer, AdbSyncRequestId.Data, chunk);
},
async close() {
await adbSyncWriteRequest(writer, AdbSyncRequestId.Done, mtime);
await adbSyncReadResponse(stream, ResponseTypes);
}
}, {
highWaterMark: 16 * 1024,
size(chunk) { return chunk.byteLength; }
}));
return writable;
}
It returns a WrtiableStream
to let the caller write a file on device, the close
handler tells the device to finish the file and return the final result. Let's call it PushFileStream
.
Because each packet can't exceed packetSize
length, I need to split each incoming chunk
s. I think I can re-use the ChunkStream
(a TransformStream
) that's used somewhere else, so I piped the readable
end to PushFileStream
, and returned the writable end of the ChunkStream
to callers.
It can correctly chunk the incoming data and send them to device, however, the writable
of ChunkStream
won't wait for close
of PushFileStream
. If the caller want to close the stream
and writer
after finishing pushing, they may be closed before close
, causing push to fail.
So how can I wait for PushFileStream
close
, or how can I generally use TransformStream
when creating a WritableStream
?