diff --git a/src/NodeFileSystemWriteableFileStream.ts b/src/NodeFileSystemWriteableFileStream.ts index e00f103..7120290 100644 --- a/src/NodeFileSystemWriteableFileStream.ts +++ b/src/NodeFileSystemWriteableFileStream.ts @@ -1,5 +1,4 @@ import * as fs from 'node:fs' -import * as asyncfs from 'node:fs/promises' import * as path from 'node:path' import { Writable } from 'node:stream' import type { @@ -11,35 +10,51 @@ import type { export default class NodeFileSystemWritableFileStream extends WritableStream implements FileSystemWritableFileStream { #seek_position = 0 - #name: string - constructor(name: string, options: FileSystemCreateWritableOptions={}) { + #fd: number + constructor(name: string, options: FileSystemCreateWritableOptions = {}) { name = path.normalize(name) - super(Writable.toWeb(fs.createWriteStream(name))) - this.#name = name - if(!options.keepExistingData) this.truncate(0) + let flags = 'w' + if (!options.keepExistingData) flags = 'r+' + const fd = fs.openSync(name, flags) + super(Writable.toWeb(fs.createWriteStream(name, { "fd": fd }))) + this.#fd = fd } async seek(position: number): Promise { + if (this.locked) throw new Error("stream is locked") this.#seek_position = position } - truncate(size: number): Promise { - return asyncfs.truncate(this.#name, size) + async truncate(size: number): Promise { + if (this.locked) throw new Error("stream is locked") + return fs.ftruncateSync(this.#fd, size) } async write(wdata: FileSystemWriteChunkType): Promise { + if (this.locked) throw new Error("stream is locked") if (wdata instanceof Blob) wdata = await wdata.bytes() if (typeof wdata === 'string') wdata = new TextEncoder().encode(wdata) let wsize: number = null let pseek_position = this.#seek_position if ((wdata as WriteParams).type) { const { type, position, size, data } = (wdata as WriteParams) - if (type === 'truncate') return asyncfs.truncate(this.#name, size) + if (type === 'truncate') return this.truncate(size) if (position) this.#seek_position = position if (type === 'seek') return if (size) wsize = size wdata = data } - const file = await asyncfs.open(this.#name,'r+') - await file.write((wdata as Uint8Array), null, wsize, this.#seek_position) - await file.close() + fs.writeSync(this.#fd, (wdata as Uint8Array), null, wsize, this.#seek_position) this.#seek_position = pseek_position } + async #_close() { + try { + fs.closeSync(this.#fd) + } catch { } + } + async close(): Promise { + await super.close() + await this.#_close() + } + async abort(reason?: any): Promise { + await super.abort(reason) + await this.#_close() + } } \ No newline at end of file