forked from berty/berty
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.ts
53 lines (49 loc) · 1.32 KB
/
utils.ts
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
import { Buffer } from 'buffer'
import { EOF } from '@berty-tech/grpc-bridge'
import { WelshProtocolServiceClient } from '@berty-tech/grpc-bridge/welsh-clients.gen'
let cache: { cid: string; prom: Promise<string> }[] = []
export const base64ToURLBase64 = (str: string) =>
str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '')
const fetchSource = async (
protocolClient: WelshProtocolServiceClient,
cid: string,
): Promise<string> => {
const stream = await protocolClient.attachmentRetrieve({
attachmentCid: Buffer.from(cid, 'base64'),
})
const data = await new Promise<Buffer>((resolve, reject) => {
let buf = Buffer.from('')
stream.onMessage((msg, err) => {
if (err === EOF) {
resolve(buf)
return
}
if (err) {
reject(err)
return
}
if (msg?.block) {
buf = Buffer.concat([buf, msg.block])
}
})
stream.start()
})
return data.toString('base64')
}
export const getSource = async (
protocolClient: WelshProtocolServiceClient,
cid: string,
): Promise<string> => {
if (!cache.find((item) => item.cid === cid)) {
if (cache.length >= 20) {
// evict
cache = cache.slice(1)
}
cache.push({ cid, prom: fetchSource(protocolClient, cid) })
}
const cached = cache.find((item) => item.cid === cid)
if (!cached) {
throw new Error('unexpected cache miss')
}
return cached.prom
}