Files
node-file-system-adapter/src/NodeFileSystemWriteableFileStream.ts
T
sugoidogo 8bc2c7d70c
Release / release (push) Successful in 24s
refactor
2026-02-16 15:57:22 -08:00

44 lines
1.8 KiB
TypeScript

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<void> {
if (this.locked) throw new Error("stream is locked")
this.#position = position
}
async truncate(size: number): Promise<void> {
if (this.locked) throw new Error("stream is locked")
return this.#fileHandle.truncate(size)
}
async write(data: FileSystemWriteChunkType): Promise<void> {
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
}
}