diff --git a/from.js b/from.js index 9eaf8bf..33c4e7b 100644 --- a/from.js +++ b/from.js @@ -65,6 +65,9 @@ class BlobDataItem { this.#start = options.start this.size = options.size this.lastModified = options.lastModified + this.originalSize = options.originalSize === undefined + ? options.size + : options.originalSize } /** @@ -75,16 +78,19 @@ class BlobDataItem { return new BlobDataItem({ path: this.#path, lastModified: this.lastModified, + originalSize: this.originalSize, size: end - start, start: this.#start + start }) } async * stream () { - const { mtimeMs } = await stat(this.#path) - if (mtimeMs > this.lastModified) { + const { mtimeMs, size } = await stat(this.#path) + + if (mtimeMs > this.lastModified || this.originalSize !== size) { throw new DOMException('The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.', 'NotReadableError') } + yield * createReadStream(this.#path, { start: this.#start, end: this.#start + this.size - 1 diff --git a/index.js b/index.js index 2542ac2..8a3809c 100644 --- a/index.js +++ b/index.js @@ -83,8 +83,12 @@ const _Blob = class Blob { part = encoder.encode(`${element}`) } - this.#size += ArrayBuffer.isView(part) ? part.byteLength : part.size - this.#parts.push(part) + const size = ArrayBuffer.isView(part) ? part.byteLength : part.size + // Avoid pushing empty parts into the array to better GC them + if (size) { + this.#size += size + this.#parts.push(part) + } } this.#endings = `${options.endings === undefined ? 'transparent' : options.endings}` diff --git a/package.json b/package.json index cfedf63..cc91aa3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fetch-blob", - "version": "3.1.4", + "version": "3.1.5", "description": "Blob & File implementation in Node.js, originally from node-fetch.", "main": "index.js", "type": "module", diff --git a/test/own-misc-test.js b/test/own-misc-test.js index 999837d..abb6fe2 100644 --- a/test/own-misc-test.js +++ b/test/own-misc-test.js @@ -189,6 +189,12 @@ promise_test(async () => { assert_equals(await (await fileFrom('./LICENSE')).text(), license.toString()) }, 'blob part backed up by filesystem slice correctly') +promise_test(async () => { + fs.writeFileSync('temp', '') + await blobFromSync('./temp').text() + fs.unlinkSync('./temp') +}, 'can read empty files') + test(async () => { const blob = blobFromSync('./LICENSE') await new Promise(resolve => setTimeout(resolve, 2000))