-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathadd.js
79 lines (72 loc) · 1.9 KB
/
add.js
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
import * as Server from '@ucanto/server'
import * as Store from '@web3-storage/capabilities/store'
import * as API from '../types.js'
import { allocate } from '../space-allocate.js'
/**
* @param {API.StoreServiceContext} context
* @returns {API.ServiceMethod<API.StoreAdd, API.StoreAddSuccess, API.Failure>}
*/
export function storeAddProvider(context) {
const { storeTable, carStoreBucket, maxUploadSize } = context
return Server.provide(Store.add, async ({ capability, invocation }) => {
const { link, origin, size } = capability.nb
if (size > maxUploadSize) {
return {
error: new Server.Failure(
`Maximum size exceeded: ${maxUploadSize}, split DAG into smaller shards.`
),
}
}
const space = /** @type {import('@ucanto/interface').DIDKey} */ (
Server.DID.parse(capability.with).did()
)
const issuer = invocation.issuer.did()
const [allocated, carIsLinkedToSpace, carExists] = await Promise.all([
allocate(
{
capability: {
with: space,
},
},
context
),
storeTable.exists(space, link),
carStoreBucket.has(link),
])
// If failed to allocate space, fail with allocation error
if (allocated.error) {
return allocated
}
if (!carIsLinkedToSpace) {
await storeTable.insert({
space,
link,
size,
origin,
issuer,
invocation: invocation.cid,
})
}
if (carExists) {
return {
ok: {
status: 'done',
allocated: carIsLinkedToSpace ? 0 : size,
with: space,
link,
},
}
}
const { url, headers } = await carStoreBucket.createUploadUrl(link, size)
return {
ok: {
status: 'upload',
allocated: size,
with: space,
link,
url: url.toString(),
headers,
},
}
})
}