Spaces:
Build error
Build error
File size: 2,648 Bytes
c211499 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
import { Options } from './types'
function getContentFromDataUrl(dataURL: string) {
return dataURL.split(/,/)[1]
}
export function isDataUrl(url: string) {
return url.search(/^(data:)/) !== -1
}
export function makeDataUrl(content: string, mimeType: string) {
return `data:${mimeType};base64,${content}`
}
export async function fetchAsDataURL<T>(
url: string,
init: RequestInit | undefined,
process: (data: { result: string; res: Response }) => T,
): Promise<T> {
const res = await fetch(url, init)
if (res.status === 404) {
throw new Error(`Resource "${res.url}" not found`)
}
const blob = await res.blob()
return new Promise<T>((resolve, reject) => {
const reader = new FileReader()
reader.onerror = reject
reader.onloadend = () => {
try {
resolve(process({ res, result: reader.result as string }))
} catch (error) {
reject(error)
}
}
reader.readAsDataURL(blob)
})
}
const cache: { [url: string]: string } = {}
function getCacheKey(
url: string,
contentType: string | undefined,
includeQueryParams: boolean | undefined,
) {
let key = url.replace(/\?.*/, '')
if (includeQueryParams) {
key = url
}
// font resource
if (/ttf|otf|eot|woff2?/i.test(key)) {
key = key.replace(/.*\//, '')
}
return contentType ? `[${contentType}]${key}` : key
}
export async function resourceToDataURL(
resourceUrl: string,
contentType: string | undefined,
options: Options,
) {
const cacheKey = getCacheKey(
resourceUrl,
contentType,
options.includeQueryParams,
)
if (cache[cacheKey] != null) {
return cache[cacheKey]
}
// ref: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
if (options.cacheBust) {
// eslint-disable-next-line no-param-reassign
resourceUrl += (/\?/.test(resourceUrl) ? '&' : '?') + new Date().getTime()
}
let dataURL: string
try {
const content = await fetchAsDataURL(
resourceUrl,
options.fetchRequestInit,
({ res, result }) => {
if (!contentType) {
// eslint-disable-next-line no-param-reassign
contentType = res.headers.get('Content-Type') || ''
}
return getContentFromDataUrl(result)
},
)
dataURL = makeDataUrl(content, contentType!)
} catch (error) {
dataURL = options.imagePlaceholder || ''
let msg = `Failed to fetch resource: ${resourceUrl}`
if (error) {
msg = typeof error === 'string' ? error : error.message
}
if (msg) {
console.warn(msg)
}
}
cache[cacheKey] = dataURL
return dataURL
}
|