-
Notifications
You must be signed in to change notification settings - Fork 5
IPLD Format API cleanups #51
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,15 +15,15 @@ | |
- [Definitions](#definitions) | ||
- [API](#api) | ||
- [IPLD format utils](#ipld-format-utils) | ||
- [`util.serialize(dagNode, callback)`](#utilserializedagnode-callback) | ||
- [`util.deserialize(binaryBlob, callback)`](#utildeserializebinaryblob-callback) | ||
- [`util.cid(binaryBlob[, options], callback)`](#utilcidbinaryblob-options-callback) | ||
- [`util.serialize(IpldNode)`](#utilserializeipldnode) | ||
- [`util.deserialize(binaryBlob)`](#utildeserializebinaryblob) | ||
- [`util.cid(binaryBlob[, options])`](#utilcidbinaryblob-options) | ||
- [Local resolver methods](#local-resolver-methods) | ||
- [`resolver.resolve(binaryBlob, path, callback)`](#resolverresolvebinaryblob-path-callback) | ||
- [`resolver.tree(binaryBlob, callback)`](#resolvertreebinaryblob-callback) | ||
- [`resolver.resolve(binaryBlob, path)`](#resolverresolvebinaryblob-path) | ||
- [`resolver.tree(binaryBlob)`](#resolvertreebinaryblob) | ||
- [Properties](#properties) | ||
- [`defaultHashAlg`](#defaulthashalg) | ||
- [`multicodec`](#multicodec) | ||
- [`codec`](#codec) | ||
- [Maintainers](#maintainers) | ||
- [Contribute](#contribute) | ||
- [License](#license) | ||
|
@@ -52,87 +52,103 @@ Include this badge in your readme if you make a new module that implements inter | |
|
||
## Definitions | ||
|
||
- **dagNode**: The implementation specific representation of a deserialized block. | ||
- **IPLD Node**: A JavaScript object where all values conform to the [IPLD Data Model](https://github.com/ipld/specs/blob/master/IPLD-Data-Model-v1.md). | ||
|
||
## API | ||
|
||
A valid (read: that follows this interface) IPLD format implementation the following API. | ||
|
||
IPLD Format APIs are restricted to a single IPLD Node, they never access any linked IPLD Nodes. | ||
|
||
### IPLD format utils | ||
|
||
#### `util.serialize(dagNode, callback)` | ||
#### `util.serialize(IpldNode)` | ||
|
||
> Serialize an IPLD Node into a binary blob. | ||
|
||
`IpldNode` is a previously deserialized binary blob. | ||
|
||
Returns an `Buffer` with the serialized version of the given IPLD Node. | ||
|
||
> serializes a dagNode of an IPLD format into its binary format | ||
#### `util.deserialize(binaryBlob)` | ||
|
||
`callback` must have the signature `function (err, binaryBlob)`, where `err` is an Error is the function fails and `binaryBlob` is a Buffer containing the serialized version. | ||
> Deserialize a binary blob into an IPLD Node. | ||
|
||
#### `util.deserialize(binaryBlob, callback)` | ||
The result is a JavaScript object. Its fields are the public API that can be resolved through. It’s up to the format to add convenient methods for manipulating the data. | ||
|
||
> deserializes a binary blob into the instance | ||
All enumerable properties (the ones that are returned by a `Object.keys()` call) of the deserialized object are considered for resolving IPLD Paths. They must only return values whose type is one of the [IPLD Data Model](https://github.com/ipld/specs/blob/master/IPLD-Data-Model-v1.md). | ||
|
||
`callback` must have the signature `function (err, dagNode)`, where `err` is an Error if the function fails and `dagNode` is the dagNode that got deserialized in the process. | ||
The result must be able to be serialized with a `serialize()` call. Deserializing and serializing a `binaryBlob` (`await serialize(await deserialize(binaryBlob))`) needs to result in data that is byte-identical to the input `binaryBlob`. | ||
|
||
#### `util.cid(binaryBlob[, options], callback)` | ||
#### `util.cid(binaryBlob[, options])` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can options made non optional ? That would simplify implemeter side of things as of consumption it’s always indirect anyway (as far as I can tell) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would expect that normally you would just call it without any options as you would want to use the default values for the CID version and the hash algorithm. |
||
|
||
> get the CID of a binary blob | ||
> Calculate the CID of the binary blob. | ||
|
||
Options include: | ||
- version - the CID version to be used (defaults to 1) | ||
- hashAlg - the hash algorithm to be used (default to the one set by the format) | ||
Possible `options` are: | ||
- `cidVersion` (`number`, default: 1): the CID version to be used | ||
- `hashAlg` (`Multicodec`, default: the one the format specifies): the hash algorithm to be used | ||
|
||
`callback` must have the signature `function (err, cid)`, where `err` is an Error if the function fails and `cid` is a CID instance of the binary blob. | ||
This can be used to verify that some data actually has a certain CID. | ||
|
||
Returns a Promise containing the calculated CID of the given binary blob. | ||
|
||
### Local resolver methods | ||
|
||
#### `resolver.resolve(binaryBlob, path, callback)` | ||
#### `resolver.resolve(binaryBlob, path)` | ||
|
||
> resolves a path in block, returns the value and or a link and the partial missing path. This way the IPLD Resolver can fetch the link and continue to resolve. | ||
> Resolves a path within the blob, returns the value and the partial missing path. This way the `js-ipld` can continue to resolve in case the value is a link. | ||
|
||
`callback` must have the signature `function (err, result)`, where `err` is an Error if the function fails and `result` is an object with the following keys: | ||
Returns a `ResolverResult`, which is an Object with the following keys: | ||
|
||
- value: <> - The value resolved or an IPLD link if it was unable to resolve it through. | ||
- remainderPath: <> - The remaining path that was not resolved under block scope. | ||
- `value` (`IPLD Data`): the value resolved, whose type is one of the [IPLD Data model](https://github.com/ipld/specs/blob/master/IPLD-Data-Model-v1.md) | ||
- remainderPath (`string`): the remaining path that was not resolved under block scope | ||
rvagg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If `path` is the root `/`, the result is a nested object that contains all paths that `tree()` returns. The values are the same as accessing them directly with the full path. Example: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn’t it still be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I’m misunderstanding if path is |
||
|
||
`tree()` returns: | ||
`tree()` returns in iterator with those values: | ||
|
||
```JSON | ||
["author/name", "author/email"] | ||
``` | ||
|
||
`resolve(binaryblob, "/", callback)` would then have as a result: | ||
`await resolve(binaryblob, "/")` would then have as a result: | ||
|
||
```JSON | ||
{ | ||
"author": { | ||
"name": "vmx", | ||
"email": "[email protected]" | ||
} | ||
"value": { | ||
"author": { | ||
"name": "vmx", | ||
"email": "[email protected]" | ||
} | ||
}, | ||
"remainderPath": "" | ||
} | ||
``` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Example is no longer up to date here |
||
If `resolve()` is called with the root path (`/`), then the `value` of the `ResolverResult` will equal the return value of a `deserialize()` call. | ||
|
||
Numbers within a path are interpreted as an array. | ||
|
||
#### `resolver.tree(binaryBlob, callback)` | ||
#### `resolver.tree(binaryBlob)` | ||
|
||
> returns all the paths available in this block. | ||
> Returns all the paths available in this blob | ||
|
||
`callback` must have the signature `function (err, result)`, where `err` is an Error if the function fails and `result` is a list of path such as `["/foo", "/bar", "/author/name", ...]`. | ||
Returns an Iterable where each item is a path that can be resolved, e.g. `["/foo", "/bar", "/author/name", ...]`. | ||
|
||
### Properties | ||
|
||
#### `defaultHashAlg` | ||
|
||
> Default hash algorithm of the format | ||
> Default hash algorithm of the format. | ||
|
||
Most formats have one specific hash algorithm, e.g. Bitcoin’s is `dbl-sha2-256`. CBOR can be used with any hash algorithm, though the default in the IPFS world is `sha256`. `defaultHashAlg` is used in the `util.cid()` call if no hash algorithm is given. The value of `defaultHashAlg` is of type `Multicodec` should be one code defined in the [Multihash Table](https://github.com/multiformats/multihash#table-for-multihash). | ||
|
||
Most formats have one specific hash algorithm, e.g. Bitcoin’s is `dbl-sha2-256`. CBOR can be used with any hash algorithm, though the default in the IPFS world is `sha256`. `defaultHashAlg` is used in the `util.cid()` call if no hash algorithm was given. The value of `defaultHashAlg` must be one defined in the [Multihash Table](https://github.com/multiformats/multihash#table-for-multihash-v100-rc-semver). | ||
#### `codec` | ||
|
||
#### `multicodec` | ||
> Identifier for the format implementation. | ||
|
||
> Identifier for the format implementation | ||
The `codec` property of type `Multicodec` is used to register a format implementation in IPLD. It should be one of the codes specified in the [Multicodec Table](https://github.com/multiformats/multicodec#multicodec-table). | ||
|
||
The `multicodec` property is used to register a format implementation in IPLD. It needs to be one specified in the [Multicodec Table](https://github.com/multiformats/multicodec#multicodec-table). | ||
|
||
## Maintainers | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant to say “returns promise for JS object representing a node...”
I also assume that wrapping into promise isn’t required, however it’s worth communicating