Skip to content

Commit

Permalink
perf: improve isBlobLike (#3070)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uzlopak committed Apr 8, 2024
1 parent 7ae20e6 commit 413fd4d
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 7 deletions.
64 changes: 64 additions & 0 deletions benchmarks/core/is-blob-like.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { bench, group, run } from 'mitata'
import { isBlobLike } from '../../lib/core/util.js'

const buffer = Buffer.alloc(1)

const blob = new Blob(['asd'], {
type: 'application/json'
})

const file = new File(['asd'], 'file.txt', {
type: 'text/plain'
})

const blobLikeStream = {
[Symbol.toStringTag]: 'Blob',
stream: () => {}
}

const fileLikeStream = {
stream: () => {},
[Symbol.toStringTag]: 'File'
}

const blobLikeArrayBuffer = {
[Symbol.toStringTag]: 'Blob',
arrayBuffer: () => {}
}

const fileLikeArrayBuffer = {
[Symbol.toStringTag]: 'File',
arrayBuffer: () => {}
}

group('isBlobLike', () => {
bench('blob', () => {
return isBlobLike(blob)
})
bench('file', () => {
return isBlobLike(file)
})
bench('blobLikeStream', () => {
return isBlobLike(blobLikeStream)
})
bench('fileLikeStream', () => {
return isBlobLike(fileLikeStream)
})
bench('fileLikeArrayBuffer', () => {
return isBlobLike(fileLikeArrayBuffer)
})
bench('blobLikeArrayBuffer', () => {
return isBlobLike(blobLikeArrayBuffer)
})
bench('buffer', () => {
return isBlobLike(buffer)
})
bench('null', () => {
return isBlobLike(null)
})
bench('string', () => {
return isBlobLike('invalid')
})
})

await run()
21 changes: 14 additions & 7 deletions lib/core/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ function isStream (obj) {

// based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License)
function isBlobLike (object) {
return (Blob && object instanceof Blob) || (
object &&
typeof object === 'object' &&
(typeof object.stream === 'function' ||
typeof object.arrayBuffer === 'function') &&
/^(Blob|File)$/.test(object[Symbol.toStringTag])
)
if (object === null) {
return false
} else if (object instanceof Blob) {
return true
} else if (typeof object !== 'object') {
return false
} else {
const sTag = object[Symbol.toStringTag]

return (sTag === 'Blob' || sTag === 'File') && (
('stream' in object && typeof object.stream === 'function') ||
('arrayBuffer' in object && typeof object.arrayBuffer === 'function')
)
}
}

function buildURL (url, queryParams) {
Expand Down
67 changes: 67 additions & 0 deletions test/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use strict'

const { strictEqual } = require('node:assert')
const { test, describe } = require('node:test')
const { isBlobLike } = require('../lib/core/util')
const { Blob, File } = require('node:buffer')

describe('isBlobLike', () => {
test('buffer', () => {
const buffer = Buffer.alloc(1)
strictEqual(isBlobLike(buffer), false)
})

test('blob', { skip: !Blob }, () => {
const blob = new Blob(['asd'], {
type: 'application/json'
})
strictEqual(isBlobLike(blob), true)
})

test('file', { skip: !File }, () => {
const file = new File(['asd'], 'file.txt', {
type: 'text/plain'
})
strictEqual(isBlobLike(file), true)
})

test('blobLikeStream', () => {
const blobLikeStream = {
[Symbol.toStringTag]: 'Blob',
stream: () => { }
}
strictEqual(isBlobLike(blobLikeStream), true)
})

test('fileLikeStream', () => {
const fileLikeStream = {
stream: () => { },
[Symbol.toStringTag]: 'File'
}
strictEqual(isBlobLike(fileLikeStream), true)
})

test('fileLikeArrayBuffer', () => {
const blobLikeArrayBuffer = {
[Symbol.toStringTag]: 'Blob',
arrayBuffer: () => { }
}
strictEqual(isBlobLike(blobLikeArrayBuffer), true)
})

test('blobLikeArrayBuffer', () => {
const fileLikeArrayBuffer = {
[Symbol.toStringTag]: 'File',
arrayBuffer: () => { }
}
strictEqual(isBlobLike(fileLikeArrayBuffer), true)
})

test('string', () => {
strictEqual(isBlobLike('Blob'), false)
})

test('null', () => {
strictEqual(isBlobLike(null), false)
})
})

0 comments on commit 413fd4d

Please sign in to comment.