-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Quirks of ipfs.add
API #3137
Description
I'm working on #3029 and having a really hard time making changes to ipfs.add
without changing it's current behavior. In the process I'm discovering some quirks that I wanted to point out & hopefully find a way to address:
So it takes arbitrary input and normalizes it. However rules for single vs multiple files are of particular interest here.
js-ipfs/packages/ipfs-core-utils/src/files/normalise-input.js
Lines 30 to 38 in 8cb8c73
* AsyncIterable<Bytes> [single file] | |
* AsyncIterable<Bloby> [multiple files] | |
* AsyncIterable<String> [multiple files] | |
* AsyncIterable<{ path, content: Bytes }> [multiple files] | |
* AsyncIterable<{ path, content: Bloby }> [multiple files] | |
* AsyncIterable<{ path, content: String }> [multiple files] | |
* AsyncIterable<{ path, content: Iterable<Number> }> [multiple files] | |
* AsyncIterable<{ path, content: Iterable<Bytes> }> [multiple files] | |
* AsyncIterable<{ path, content: AsyncIterable<Bytes> }> [multiple files] |
So all AsyncIterator
s represent input with multiple files, except if it is iterator of ArrayBufferView|ArrayBuffer
. This leads to some interesting questions:
-
Is this supposed to produce single file with
hi\nbye
content or two files ?ipfs.add(asyncIterable([Buffer.from('hi\n'), 'bye')])
According to docs
AsyncIterable<Bytes>
is interpreted as single file, howeverAsyncIterable<string>
is interpreted as multiple files. However implementation only checks first the rest are just yielded from content, so I'm guessing it would produce single file. -
And how about if we switch those around ?
ipfs.add(asyncIterable(['hi\n', Buffer.from('bye'))])
According to the documentation
AsyncIterable<string>
is interpreted as multiple, files however since only first chunk is checked I'm guessing this one would produce two files. -
Even more interesting would be if we did this:
ipfs.add(asyncIterable([Buffer.from('hi\n'), {content: 'bye' })])
Which would produce error, although one might expect two files.
Maybe this is not as confusing as I find it to be, but I really wish there was more way to differentiate multiple file add from single file add so implementation would not need to probe async input to decide.
I think things would be so much simpler for both user and implementation if ipfs.add
just always worked with multiples, that would mean that user would have to wrap Bytes|Blob|string|FileObject|AsyncIterable<Bytes>
into array [content]
but it would make API much cleaner also AsyncIterable<*>
as result would make more sense as it's many to many.
Alternatively there could be ipfs.add
and ipfs.addAll
APIs to deal with single files and multiple files respectively. That would also reduce complexity when adding a single file const cid = (await ipfs.add(buffer).next()).value.cid