Skip to content

Commit e7d6f9a

Browse files
committed
⚡ add local image cache for base64 pipeline
1 parent dde0843 commit e7d6f9a

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ yarn-error.log*
1515

1616
# macOS-specific files
1717
.DS_Store
18+
19+
# user cache
20+
.cache

src/utils/getBase64FromImageUrl.ts

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,69 @@
11
import memoize from 'p-memoize'
2+
import { resolve } from 'node:path'
3+
import { readFile, appendFile, writeFile } from 'node:fs/promises'
24
import { encode } from 'base64-arraybuffer'
35

4-
const getImageId = (s?: string | null) => /(?=[^\/]+$).+(?=\?)/g.exec(s || '')?.[0] || s
6+
const isDev = process.env.NODE_ENV === 'development'
7+
// tab separated
8+
const SEPARATOR = '\t'
9+
const LINE_BREAK = '\n'
10+
const CACHE_PATH = resolve('.', '.cache', 'base64.txt')
11+
const FILE_OPTIONS = { encoding: 'utf-8' } as const
12+
13+
const getImageId = (s?: string | null) => {
14+
const paths = s?.split('?')[0].split('/')
15+
return paths?.[paths?.length - 1].split('_')[0] || s
16+
}
17+
18+
const getCache = async () => {
19+
try {
20+
await appendFile(CACHE_PATH, '', FILE_OPTIONS)
21+
return await readFile(CACHE_PATH, FILE_OPTIONS)
22+
} catch {
23+
try {
24+
await writeFile(CACHE_PATH, '', FILE_OPTIONS)
25+
return await ''
26+
} catch {
27+
return await ''
28+
}
29+
}
30+
}
31+
32+
const getIdValueInCache = async (id: string) => {
33+
const cache = await getCache()
34+
if (!cache) return null
35+
const lines = cache.split(LINE_BREAK)
36+
for (const line of lines) {
37+
const [key, value] = line.split(SEPARATOR)
38+
if (key === id) {
39+
console.log('[getBase64FromImageUrl]: CACHE HIT: ', id)
40+
return value
41+
}
42+
}
43+
return null
44+
}
45+
46+
const saveKeyValueInCache = async (key: string, value: string) => {
47+
console.log('[getBase64FromImageUrl]: CACHE SAVE: ', key)
48+
await appendFile(CACHE_PATH, [key, value].join(SEPARATOR) + LINE_BREAK, FILE_OPTIONS)
49+
}
550

651
type GetBase64FromImageUrl = (url?: string | null) => Promise<string | undefined>
752
const getBase64FromImageUrl: GetBase64FromImageUrl = async url => {
8-
if (!url) return
9-
console.log('[getBase64FromImageUrl]', getImageId(url))
53+
const id = getImageId(url)
54+
if (!url || !id) return
55+
if (isDev) {
56+
const valueInCache = await getIdValueInCache(id)
57+
if (valueInCache) return valueInCache
58+
}
59+
1060
const imageData = await fetch(url)
11-
// @ts-ignore-error
61+
console.log('[getBase64FromImageUrl]: FETCH: ', id)
1262
const buffer = await imageData.arrayBuffer()
1363
const contentType = await imageData.headers.get('content-type')
14-
return `data:image/${contentType};base64,` + encode(buffer)
64+
const value = `data:image/${contentType};base64,` + encode(buffer)
65+
if (isDev) await saveKeyValueInCache(id, value)
66+
return value
1567
}
1668

1769
export default memoize(getBase64FromImageUrl)

0 commit comments

Comments
 (0)