import { Writable } from 'node:stream' import type { FileSystemWritableFileStream, FileSystemWriteChunkType, WriteParams } from '@sugoidogo/importable-types-web' import type { FileHandle } from 'node:fs/promises' function isWriteParams(data: FileSystemWriteChunkType): data is WriteParams { return ["write", "seek", "truncate"].includes((data as WriteParams).type) } export default class NodeFileSystemWritableFileStream extends WritableStream implements FileSystemWritableFileStream { #position = 0 #fileHandle: FileHandle constructor(fileHandle: FileHandle) { const writeStream = fileHandle.createWriteStream({ "encoding": "binary" }) const writeableStream = Writable.toWeb(writeStream) super(writeableStream) this.#fileHandle = fileHandle } async seek(position: number): Promise { if (this.locked) throw new Error("stream is locked") this.#position = position } async truncate(size: number): Promise { if (this.locked) throw new Error("stream is locked") return this.#fileHandle.truncate(size) } async write(data: FileSystemWriteChunkType): Promise { if (this.locked) throw new Error("stream is locked") let offset: number, length: number, position=this.#position if (isWriteParams(data)) { if (data.type === "seek") return this.seek(data.position) if (data.type === "truncate") return this.truncate(data.size) if (typeof data.position === "number") position = data.position length = data.size data = data.data } if (typeof data === 'string') data = new TextEncoder().encode(data) const { bytesWritten } = await this.#fileHandle.write(data as any, offset, length, position) this.#position=position+bytesWritten } }