@autonomys/auto-dag-data 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/ipld/builders.d.ts +2 -2
- package/dist/ipld/builders.d.ts.map +1 -1
- package/dist/ipld/chunker.d.ts +9 -7
- package/dist/ipld/chunker.d.ts.map +1 -1
- package/dist/ipld/chunker.js +63 -24
- package/dist/ipld/nodes.d.ts +6 -6
- package/dist/ipld/nodes.d.ts.map +1 -1
- package/dist/ipld/nodes.js +14 -13
- package/dist/metadata/offchain/file.d.ts +3 -3
- package/dist/metadata/offchain/folder.d.ts +2 -2
- package/dist/metadata/offchain/folder.js +2 -2
- package/dist/metadata/onchain/protobuf/OnchainMetadata.d.ts +1 -1
- package/dist/metadata/onchain/protobuf/OnchainMetadata.js +2 -2
- package/dist/utils/metadata.d.ts +3 -0
- package/dist/utils/metadata.d.ts.map +1 -0
- package/dist/utils/metadata.js +1 -0
- package/package.json +2 -1
- package/src/ipld/builders.ts +2 -2
- package/src/ipld/chunker.ts +80 -31
- package/src/ipld/nodes.ts +51 -34
- package/src/metadata/offchain/file.ts +3 -3
- package/src/metadata/offchain/folder.ts +4 -4
- package/src/metadata/onchain/protobuf/OnchainMetadata.proto +7 -6
- package/src/metadata/onchain/protobuf/OnchainMetadata.ts +3 -3
- package/src/utils/metadata.ts +6 -0
- package/tests/chunker.spec.ts +85 -22
- package/tests/nodes.spec.ts +15 -9
package/src/ipld/chunker.ts
CHANGED
|
@@ -3,41 +3,71 @@ import type { AwaitIterable } from 'interface-store'
|
|
|
3
3
|
import { CID } from 'multiformats'
|
|
4
4
|
import { cidOfNode } from '../cid/index.js'
|
|
5
5
|
import { decodeIPLDNodeData, FileUploadOptions, OffchainMetadata } from '../metadata/index.js'
|
|
6
|
+
import { stringifyMetadata } from '../utils/metadata.js'
|
|
6
7
|
import { Builders, fileBuilders, metadataBuilders } from './builders.js'
|
|
7
8
|
import { createFolderInlinkIpldNode, createFolderIpldNode } from './nodes.js'
|
|
8
9
|
import { chunkBuffer, encodeNode, PBNode } from './utils.js'
|
|
9
10
|
|
|
10
11
|
type ChunkerLimits = {
|
|
11
|
-
|
|
12
|
+
maxNodeSize: number
|
|
12
13
|
maxLinkPerNode: number
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
type ChunkerOptions = ChunkerLimits & FileUploadOptions
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
const DEFAULT_NODE_MAX_SIZE = 65535
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
// u8 -> 1 byte (may grow in the future but unlikely further than 255)
|
|
21
|
+
const NODE_TYPE_SIZE = 1
|
|
22
|
+
// u32 -> 4 bytes
|
|
23
|
+
const NODE_LINK_DEPTH_SIZE = 4
|
|
24
|
+
// u64 -> 8 bytes
|
|
25
|
+
const NODE_SIZE_SIZE = 8
|
|
26
|
+
// Limit at 255 string length (Mac Limit)
|
|
27
|
+
const MAX_NAME_SIZE = 255
|
|
28
|
+
const END_OF_STRING_BYTE = 1
|
|
29
|
+
const NODE_NAME_SIZE = MAX_NAME_SIZE + END_OF_STRING_BYTE
|
|
30
|
+
// Upload options may be amplified in the future
|
|
31
|
+
const NODE_UPLOAD_OPTIONS_SIZE = 100
|
|
32
|
+
// Reserve 100 bytes for future use
|
|
33
|
+
const NODE_RESERVED_SIZE = 100
|
|
34
|
+
|
|
35
|
+
export const NODE_METADATA_SIZE =
|
|
36
|
+
NODE_TYPE_SIZE +
|
|
37
|
+
NODE_LINK_DEPTH_SIZE +
|
|
38
|
+
NODE_SIZE_SIZE +
|
|
39
|
+
NODE_NAME_SIZE +
|
|
40
|
+
NODE_RESERVED_SIZE +
|
|
41
|
+
NODE_UPLOAD_OPTIONS_SIZE
|
|
42
|
+
|
|
43
|
+
export const DEFAULT_MAX_CHUNK_SIZE = DEFAULT_NODE_MAX_SIZE - NODE_METADATA_SIZE
|
|
44
|
+
|
|
45
|
+
export const LINK_SIZE_IN_BYTES = 40
|
|
46
|
+
export const DEFAULT_MAX_LINK_PER_NODE = Math.floor(DEFAULT_MAX_CHUNK_SIZE / LINK_SIZE_IN_BYTES)
|
|
21
47
|
|
|
22
48
|
export const processFileToIPLDFormat = (
|
|
23
49
|
blockstore: BaseBlockstore,
|
|
24
50
|
file: AwaitIterable<Buffer>,
|
|
25
|
-
totalSize:
|
|
51
|
+
totalSize: bigint,
|
|
26
52
|
filename?: string,
|
|
27
53
|
{
|
|
28
|
-
|
|
54
|
+
maxNodeSize = DEFAULT_MAX_CHUNK_SIZE,
|
|
29
55
|
maxLinkPerNode = DEFAULT_MAX_LINK_PER_NODE,
|
|
30
56
|
encryption = undefined,
|
|
31
57
|
compression = undefined,
|
|
32
58
|
}: Partial<ChunkerOptions> = {
|
|
33
|
-
|
|
59
|
+
maxNodeSize: DEFAULT_MAX_CHUNK_SIZE,
|
|
34
60
|
maxLinkPerNode: DEFAULT_MAX_LINK_PER_NODE,
|
|
35
61
|
encryption: undefined,
|
|
36
62
|
compression: undefined,
|
|
37
63
|
},
|
|
38
64
|
): Promise<CID> => {
|
|
65
|
+
if (filename && filename.length > MAX_NAME_SIZE) {
|
|
66
|
+
throw new Error(`Filename is too long: ${filename.length} > ${MAX_NAME_SIZE}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
39
69
|
return processBufferToIPLDFormat(blockstore, file, filename, totalSize, fileBuilders, {
|
|
40
|
-
|
|
70
|
+
maxNodeSize,
|
|
41
71
|
maxLinkPerNode,
|
|
42
72
|
encryption,
|
|
43
73
|
compression,
|
|
@@ -47,20 +77,24 @@ export const processFileToIPLDFormat = (
|
|
|
47
77
|
export const processMetadataToIPLDFormat = async (
|
|
48
78
|
blockstore: BaseBlockstore,
|
|
49
79
|
metadata: OffchainMetadata,
|
|
50
|
-
limits: {
|
|
51
|
-
|
|
80
|
+
limits: { maxNodeSize: number; maxLinkPerNode: number } = {
|
|
81
|
+
maxNodeSize: DEFAULT_MAX_CHUNK_SIZE,
|
|
52
82
|
maxLinkPerNode: DEFAULT_MAX_LINK_PER_NODE,
|
|
53
83
|
},
|
|
54
84
|
): Promise<CID> => {
|
|
55
|
-
|
|
56
|
-
|
|
85
|
+
if (metadata.name && metadata.name.length > MAX_NAME_SIZE) {
|
|
86
|
+
throw new Error(`Filename is too long: ${metadata.name.length} > ${MAX_NAME_SIZE}`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const buffer = Buffer.from(stringifyMetadata(metadata))
|
|
90
|
+
|
|
57
91
|
return processBufferToIPLDFormat(
|
|
58
92
|
blockstore,
|
|
59
93
|
(async function* () {
|
|
60
94
|
yield buffer
|
|
61
95
|
})(),
|
|
62
|
-
name,
|
|
63
|
-
buffer.byteLength,
|
|
96
|
+
metadata.name,
|
|
97
|
+
BigInt(buffer.byteLength),
|
|
64
98
|
metadataBuilders,
|
|
65
99
|
limits,
|
|
66
100
|
)
|
|
@@ -70,21 +104,25 @@ const processBufferToIPLDFormat = async (
|
|
|
70
104
|
blockstore: BaseBlockstore,
|
|
71
105
|
buffer: AwaitIterable<Buffer>,
|
|
72
106
|
filename: string | undefined,
|
|
73
|
-
totalSize:
|
|
107
|
+
totalSize: bigint,
|
|
74
108
|
builders: Builders,
|
|
75
109
|
{
|
|
76
|
-
|
|
110
|
+
maxNodeSize: maxNodeSize = DEFAULT_MAX_CHUNK_SIZE,
|
|
77
111
|
maxLinkPerNode = DEFAULT_MAX_LINK_PER_NODE,
|
|
78
112
|
encryption = undefined,
|
|
79
113
|
compression = undefined,
|
|
80
114
|
}: ChunkerOptions = {
|
|
81
|
-
|
|
115
|
+
maxNodeSize: DEFAULT_MAX_CHUNK_SIZE,
|
|
82
116
|
maxLinkPerNode: DEFAULT_MAX_LINK_PER_NODE,
|
|
83
117
|
encryption: undefined,
|
|
84
118
|
compression: undefined,
|
|
85
119
|
},
|
|
86
120
|
): Promise<CID> => {
|
|
87
|
-
|
|
121
|
+
if (filename && filename.length > MAX_NAME_SIZE) {
|
|
122
|
+
throw new Error(`Filename is too long: ${filename.length} > ${MAX_NAME_SIZE}`)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const bufferChunks = chunkBuffer(buffer, { maxChunkSize: maxNodeSize - NODE_METADATA_SIZE })
|
|
88
126
|
|
|
89
127
|
let CIDs: CID[] = []
|
|
90
128
|
for await (const chunk of bufferChunks) {
|
|
@@ -96,7 +134,7 @@ const processBufferToIPLDFormat = async (
|
|
|
96
134
|
|
|
97
135
|
return processBufferToIPLDFormatFromChunks(blockstore, CIDs, filename, totalSize, builders, {
|
|
98
136
|
maxLinkPerNode,
|
|
99
|
-
|
|
137
|
+
maxNodeSize,
|
|
100
138
|
encryption,
|
|
101
139
|
compression,
|
|
102
140
|
})
|
|
@@ -106,20 +144,24 @@ export const processBufferToIPLDFormatFromChunks = async (
|
|
|
106
144
|
blockstore: BaseBlockstore,
|
|
107
145
|
chunks: AwaitIterable<CID>,
|
|
108
146
|
filename: string | undefined,
|
|
109
|
-
totalSize:
|
|
147
|
+
totalSize: bigint,
|
|
110
148
|
builders: Builders,
|
|
111
149
|
{
|
|
112
|
-
|
|
150
|
+
maxNodeSize: maxNodeSize = DEFAULT_MAX_CHUNK_SIZE,
|
|
113
151
|
maxLinkPerNode = DEFAULT_MAX_LINK_PER_NODE,
|
|
114
152
|
encryption = undefined,
|
|
115
153
|
compression = undefined,
|
|
116
154
|
}: Partial<ChunkerOptions> = {
|
|
117
|
-
|
|
155
|
+
maxNodeSize: DEFAULT_MAX_CHUNK_SIZE,
|
|
118
156
|
maxLinkPerNode: DEFAULT_MAX_LINK_PER_NODE,
|
|
119
157
|
encryption: undefined,
|
|
120
158
|
compression: undefined,
|
|
121
159
|
},
|
|
122
160
|
): Promise<CID> => {
|
|
161
|
+
if (filename && filename.length > MAX_NAME_SIZE) {
|
|
162
|
+
throw new Error(`Filename is too long: ${filename.length} > ${MAX_NAME_SIZE}`)
|
|
163
|
+
}
|
|
164
|
+
|
|
123
165
|
let chunkCount = 0
|
|
124
166
|
let CIDs: CID[] = []
|
|
125
167
|
for await (const chunk of chunks) {
|
|
@@ -147,7 +189,7 @@ export const processBufferToIPLDFormatFromChunks = async (
|
|
|
147
189
|
for (let i = 0; i < CIDs.length; i += maxLinkPerNode) {
|
|
148
190
|
const chunk = CIDs.slice(i, i + maxLinkPerNode)
|
|
149
191
|
|
|
150
|
-
const node = builders.inlink(chunk, chunk.length, depth,
|
|
192
|
+
const node = builders.inlink(chunk, chunk.length, depth, maxNodeSize)
|
|
151
193
|
const cid = cidOfNode(node)
|
|
152
194
|
await blockstore.put(cid, encodeNode(node))
|
|
153
195
|
newCIDs.push(cid)
|
|
@@ -155,7 +197,7 @@ export const processBufferToIPLDFormatFromChunks = async (
|
|
|
155
197
|
depth++
|
|
156
198
|
CIDs = newCIDs
|
|
157
199
|
}
|
|
158
|
-
const head = builders.root(CIDs, totalSize, depth, filename,
|
|
200
|
+
const head = builders.root(CIDs, totalSize, depth, filename, maxNodeSize, {
|
|
159
201
|
compression,
|
|
160
202
|
encryption,
|
|
161
203
|
})
|
|
@@ -169,19 +211,23 @@ export const processFolderToIPLDFormat = async (
|
|
|
169
211
|
blockstore: BaseBlockstore,
|
|
170
212
|
children: CID[],
|
|
171
213
|
name: string,
|
|
172
|
-
size:
|
|
214
|
+
size: bigint,
|
|
173
215
|
{
|
|
174
216
|
maxLinkPerNode = DEFAULT_MAX_LINK_PER_NODE,
|
|
175
|
-
|
|
217
|
+
maxNodeSize: maxNodeSize = DEFAULT_MAX_CHUNK_SIZE,
|
|
176
218
|
compression = undefined,
|
|
177
219
|
encryption = undefined,
|
|
178
220
|
}: Partial<ChunkerOptions> = {
|
|
179
221
|
maxLinkPerNode: DEFAULT_MAX_LINK_PER_NODE,
|
|
180
|
-
|
|
222
|
+
maxNodeSize: DEFAULT_MAX_CHUNK_SIZE,
|
|
181
223
|
compression: undefined,
|
|
182
224
|
encryption: undefined,
|
|
183
225
|
},
|
|
184
226
|
): Promise<CID> => {
|
|
227
|
+
if (name.length > MAX_NAME_SIZE) {
|
|
228
|
+
throw new Error(`Filename is too long: ${name.length} > ${MAX_NAME_SIZE}`)
|
|
229
|
+
}
|
|
230
|
+
|
|
185
231
|
let cids = children
|
|
186
232
|
let depth = 0
|
|
187
233
|
while (cids.length > maxLinkPerNode) {
|
|
@@ -197,7 +243,7 @@ export const processFolderToIPLDFormat = async (
|
|
|
197
243
|
depth++
|
|
198
244
|
}
|
|
199
245
|
|
|
200
|
-
const node = createFolderIpldNode(cids, name, depth, size,
|
|
246
|
+
const node = createFolderIpldNode(cids, name, depth, size, maxNodeSize, {
|
|
201
247
|
compression,
|
|
202
248
|
encryption,
|
|
203
249
|
})
|
|
@@ -215,12 +261,15 @@ export const processChunksToIPLDFormat = async (
|
|
|
215
261
|
blockstore: BaseBlockstore,
|
|
216
262
|
chunks: AwaitIterable<Buffer>,
|
|
217
263
|
builders: Builders,
|
|
218
|
-
{
|
|
264
|
+
{ maxNodeSize = DEFAULT_MAX_CHUNK_SIZE }: { maxNodeSize?: number },
|
|
219
265
|
): Promise<Buffer> => {
|
|
220
|
-
const bufferChunks = chunkBuffer(chunks, {
|
|
266
|
+
const bufferChunks = chunkBuffer(chunks, {
|
|
267
|
+
maxChunkSize: maxNodeSize - NODE_METADATA_SIZE,
|
|
268
|
+
ignoreLastChunk: false,
|
|
269
|
+
})
|
|
221
270
|
|
|
222
271
|
for await (const chunk of bufferChunks) {
|
|
223
|
-
if (chunk.byteLength <
|
|
272
|
+
if (chunk.byteLength < maxNodeSize) {
|
|
224
273
|
return chunk
|
|
225
274
|
}
|
|
226
275
|
|
package/src/ipld/nodes.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { CID } from 'multiformats/cid'
|
|
2
2
|
import { FileUploadOptions, OffchainMetadata } from '../metadata/index.js'
|
|
3
3
|
import { encodeIPLDNodeData, MetadataType } from '../metadata/onchain/index.js'
|
|
4
|
+
import { stringifyMetadata } from '../utils/metadata.js'
|
|
4
5
|
import { DEFAULT_MAX_CHUNK_SIZE, ensureNodeMaxSize } from './chunker.js'
|
|
5
6
|
import { createNode, PBNode } from './index.js'
|
|
6
7
|
|
|
7
8
|
/// Creates a file chunk ipld node
|
|
8
|
-
export const createFileChunkIpldNode = (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
export const createFileChunkIpldNode = (
|
|
10
|
+
data: Buffer,
|
|
11
|
+
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
12
|
+
): PBNode =>
|
|
13
|
+
ensureNodeMaxSize(
|
|
14
|
+
createNode(
|
|
15
|
+
encodeIPLDNodeData({
|
|
16
|
+
type: MetadataType.FileChunk,
|
|
17
|
+
size: BigInt(data.length).valueOf(),
|
|
18
|
+
linkDepth: 0,
|
|
19
|
+
data,
|
|
20
|
+
}),
|
|
21
|
+
[],
|
|
22
|
+
),
|
|
23
|
+
maxNodeSize,
|
|
17
24
|
)
|
|
18
25
|
|
|
19
26
|
// Creates a file ipld node
|
|
@@ -21,7 +28,7 @@ export const createFileChunkIpldNode = (data: Buffer): PBNode =>
|
|
|
21
28
|
// @todo: add the file's metadata
|
|
22
29
|
export const createChunkedFileIpldNode = (
|
|
23
30
|
links: CID[],
|
|
24
|
-
size:
|
|
31
|
+
size: bigint,
|
|
25
32
|
linkDepth: number,
|
|
26
33
|
name?: string,
|
|
27
34
|
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
@@ -52,7 +59,7 @@ export const createFileInlinkIpldNode = (
|
|
|
52
59
|
createNode(
|
|
53
60
|
encodeIPLDNodeData({
|
|
54
61
|
type: MetadataType.FileInlink,
|
|
55
|
-
size,
|
|
62
|
+
size: BigInt(size).valueOf(),
|
|
56
63
|
linkDepth,
|
|
57
64
|
}),
|
|
58
65
|
links.map((cid) => ({ Hash: cid })),
|
|
@@ -67,17 +74,21 @@ export const createSingleFileIpldNode = (
|
|
|
67
74
|
data: Buffer,
|
|
68
75
|
name?: string,
|
|
69
76
|
uploadOptions?: FileUploadOptions,
|
|
77
|
+
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
70
78
|
): PBNode =>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
ensureNodeMaxSize(
|
|
80
|
+
createNode(
|
|
81
|
+
encodeIPLDNodeData({
|
|
82
|
+
type: MetadataType.File,
|
|
83
|
+
name,
|
|
84
|
+
size: BigInt(data.length).valueOf(),
|
|
85
|
+
linkDepth: 0,
|
|
86
|
+
data,
|
|
87
|
+
uploadOptions,
|
|
88
|
+
}),
|
|
89
|
+
[],
|
|
90
|
+
),
|
|
91
|
+
maxNodeSize,
|
|
81
92
|
)
|
|
82
93
|
|
|
83
94
|
// Creates a file ipld node
|
|
@@ -93,7 +104,7 @@ export const createMetadataInlinkIpldNode = (
|
|
|
93
104
|
createNode(
|
|
94
105
|
encodeIPLDNodeData({
|
|
95
106
|
type: MetadataType.FileInlink,
|
|
96
|
-
size,
|
|
107
|
+
size: BigInt(size).valueOf(),
|
|
97
108
|
linkDepth,
|
|
98
109
|
}),
|
|
99
110
|
links.map((cid) => ({ Hash: cid })),
|
|
@@ -109,26 +120,32 @@ export const createSingleMetadataIpldNode = (data: Buffer, name?: string): PBNod
|
|
|
109
120
|
encodeIPLDNodeData({
|
|
110
121
|
type: MetadataType.Metadata,
|
|
111
122
|
name,
|
|
112
|
-
size: data.length,
|
|
123
|
+
size: BigInt(data.length).valueOf(),
|
|
113
124
|
linkDepth: 0,
|
|
114
125
|
data,
|
|
115
126
|
}),
|
|
116
127
|
[],
|
|
117
128
|
)
|
|
118
129
|
|
|
119
|
-
export const createMetadataChunkIpldNode = (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
export const createMetadataChunkIpldNode = (
|
|
131
|
+
data: Buffer,
|
|
132
|
+
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
133
|
+
): PBNode =>
|
|
134
|
+
ensureNodeMaxSize(
|
|
135
|
+
createNode(
|
|
136
|
+
encodeIPLDNodeData({
|
|
137
|
+
type: MetadataType.MetadataChunk,
|
|
138
|
+
size: BigInt(data.length).valueOf(),
|
|
139
|
+
linkDepth: 0,
|
|
140
|
+
data,
|
|
141
|
+
}),
|
|
142
|
+
),
|
|
143
|
+
maxNodeSize,
|
|
127
144
|
)
|
|
128
145
|
|
|
129
146
|
export const createChunkedMetadataIpldNode = (
|
|
130
147
|
links: CID[],
|
|
131
|
-
size:
|
|
148
|
+
size: bigint,
|
|
132
149
|
linkDepth: number,
|
|
133
150
|
name?: string,
|
|
134
151
|
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
@@ -153,7 +170,7 @@ export const createFolderIpldNode = (
|
|
|
153
170
|
links: CID[],
|
|
154
171
|
name: string,
|
|
155
172
|
linkDepth: number,
|
|
156
|
-
size:
|
|
173
|
+
size: bigint,
|
|
157
174
|
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
158
175
|
uploadOptions?: FileUploadOptions,
|
|
159
176
|
): PBNode =>
|
|
@@ -192,7 +209,7 @@ export const createMetadataNode = (
|
|
|
192
209
|
metadata: OffchainMetadata,
|
|
193
210
|
maxNodeSize: number = DEFAULT_MAX_CHUNK_SIZE,
|
|
194
211
|
): PBNode => {
|
|
195
|
-
const data = Buffer.from(
|
|
212
|
+
const data = Buffer.from(stringifyMetadata(metadata))
|
|
196
213
|
|
|
197
214
|
return ensureNodeMaxSize(
|
|
198
215
|
createNode(
|
|
@@ -6,21 +6,21 @@ export type OffchainFileMetadata = {
|
|
|
6
6
|
dataCid: string
|
|
7
7
|
name?: string
|
|
8
8
|
mimeType?: string
|
|
9
|
-
totalSize:
|
|
9
|
+
totalSize: bigint
|
|
10
10
|
totalChunks: number
|
|
11
11
|
chunks: ChunkInfo[]
|
|
12
12
|
uploadOptions?: FileUploadOptions
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface ChunkInfo {
|
|
16
|
-
size:
|
|
16
|
+
size: bigint
|
|
17
17
|
cid: string
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export const fileMetadata = (
|
|
21
21
|
headCID: CID,
|
|
22
22
|
chunks: ChunkInfo[],
|
|
23
|
-
totalSize:
|
|
23
|
+
totalSize: bigint,
|
|
24
24
|
name?: string | null,
|
|
25
25
|
mimeType?: string | null,
|
|
26
26
|
uploadOptions: FileUploadOptions = {
|
|
@@ -7,14 +7,14 @@ interface ChildrenMetadata {
|
|
|
7
7
|
type: 'folder' | 'file'
|
|
8
8
|
name?: string
|
|
9
9
|
cid: string
|
|
10
|
-
totalSize:
|
|
10
|
+
totalSize: bigint
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export type OffchainFolderMetadata = {
|
|
14
14
|
type: 'folder'
|
|
15
15
|
dataCid: string
|
|
16
16
|
name?: string
|
|
17
|
-
totalSize:
|
|
17
|
+
totalSize: bigint
|
|
18
18
|
totalFiles: number
|
|
19
19
|
children: ChildrenMetadata[]
|
|
20
20
|
uploadOptions: FileUploadOptions
|
|
@@ -29,7 +29,7 @@ export const childrenMetadataFromNode = (node: PBNode): ChildrenMetadata => {
|
|
|
29
29
|
return {
|
|
30
30
|
type: ipldData.type === MetadataType.File ? 'file' : 'folder',
|
|
31
31
|
cid: cidToString(cidOfNode(node)),
|
|
32
|
-
totalSize: ipldData.size ?? 0,
|
|
32
|
+
totalSize: ipldData.size ?? BigInt(0).valueOf(),
|
|
33
33
|
name: ipldData.name,
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -44,7 +44,7 @@ export const folderMetadata = (
|
|
|
44
44
|
|
|
45
45
|
return {
|
|
46
46
|
dataCid: cid,
|
|
47
|
-
totalSize: children.reduce((acc, child) => acc + child.totalSize, 0),
|
|
47
|
+
totalSize: children.reduce((acc, child) => acc + child.totalSize, BigInt(0).valueOf()),
|
|
48
48
|
totalFiles: children.length,
|
|
49
49
|
children,
|
|
50
50
|
type: 'folder',
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
syntax = "proto3";
|
|
2
2
|
|
|
3
3
|
message IPLDNodeData {
|
|
4
|
-
MetadataType type = 1;
|
|
5
|
-
int32 linkDepth = 2;
|
|
6
|
-
optional
|
|
7
|
-
optional string name = 4;
|
|
8
|
-
optional bytes data = 5;
|
|
9
|
-
optional FileUploadOptions uploadOptions = 6;
|
|
4
|
+
MetadataType type = 1; // maxLength = 1
|
|
5
|
+
int32 linkDepth = 2; // maxLength = 4
|
|
6
|
+
optional int64 size = 3; // maxLength = 8
|
|
7
|
+
optional string name = 4; // maxLength = 256
|
|
8
|
+
optional bytes data = 5; // maxLength = XXX
|
|
9
|
+
optional FileUploadOptions uploadOptions = 6; // maxLength = 100
|
|
10
|
+
/// Reserve 100 bytes for future use
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
// MetadataType defines the possible types of metadata.
|
|
@@ -10,7 +10,7 @@ import type { Uint8ArrayList } from 'uint8arraylist'
|
|
|
10
10
|
export interface IPLDNodeData {
|
|
11
11
|
type: MetadataType
|
|
12
12
|
linkDepth: number
|
|
13
|
-
size?:
|
|
13
|
+
size?: bigint
|
|
14
14
|
name?: string
|
|
15
15
|
data?: Uint8Array
|
|
16
16
|
uploadOptions?: FileUploadOptions
|
|
@@ -38,7 +38,7 @@ export namespace IPLDNodeData {
|
|
|
38
38
|
|
|
39
39
|
if (obj.size != null) {
|
|
40
40
|
w.uint32(24)
|
|
41
|
-
w.
|
|
41
|
+
w.int64(obj.size)
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (obj.name != null) {
|
|
@@ -80,7 +80,7 @@ export namespace IPLDNodeData {
|
|
|
80
80
|
break
|
|
81
81
|
}
|
|
82
82
|
case 3: {
|
|
83
|
-
obj.size = reader.
|
|
83
|
+
obj.size = reader.int64()
|
|
84
84
|
break
|
|
85
85
|
}
|
|
86
86
|
case 4: {
|