Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@ipld/dag-pb

ipld344.2kApache-2.0 OR MIT4.1.3TypeScript support: included

JS implementation of DAG-PB

ipfs, ipld, multiformats

readme

@ipld/dag-pb

codecov CI

JS implementation of DAG-PB

Table of contents

Install

$ npm i @ipld/dag-pb

Browser <script> tag

Loading this module through a script tag will make it's exports available as IpldDagPb in the global namespace.

<script src="https://unpkg.com/@ipld/dag-pb/dist/index.min.js"></script>

Overview

An implementation of the DAG-PB spec for JavaScript designed for use with multiformats or via the higher-level Block abstraction in @ipld/block.

Example

import { CID } from 'multiformats/cid'
import { sha256 } from 'multiformats/hashes/sha2'
import * as dagPB from '@ipld/dag-pb'

async function run () {
  const bytes = dagPB.encode({
    Data: new TextEncoder().encode('Some data as a string'),
    Links: []
  })

  // also possible if you `import dagPB, { prepare } from '@ipld/dag-pb'`
  // const bytes = dagPB.encode(prepare('Some data as a string'))
  // const bytes = dagPB.encode(prepare(new TextEncoder().encode('Some data as a string')))

  const hash = await sha256.digest(bytes)
  const cid = CID.create(1, dagPB.code, hash)

  console.log(cid, '=>', Buffer.from(bytes).toString('hex'))

  const decoded = dagPB.decode(bytes)

  console.log(decoded)
  console.log(`decoded "Data": ${new TextDecoder().decode(decoded.Data)}`)
}

run().catch((err) => {
  console.error(err)
  process.exit(1)
})

Usage

@ipld/dag-pb is designed to be used within multiformats but can be used separately. encode(), decode(), validate() and prepare() functions are available if you pass in a multiformats object to the default export function. Each of these can operate independently as required.

prepare()

The DAG-PB encoding is very strict about the Data Model forms that are passed in. The objects must exactly resemble what they would if they were to undergo a round-trip of encode & decode. Therefore, extraneous or mistyped properties are not acceptable and will be rejected. See the DAG-PB spec for full details of the acceptable schema and additional constraints.

Due to this strictness, a prepare() function is made available which simplifies construction and allows for more flexible input forms. Prior to encoding objects, call prepare() to receive a new object that strictly conforms to the schema.

import { CID } from 'multiformats/cid'
import { prepare } from '@ipld/dag-pb'

console.log(prepare({ Data: 'some data' }))
// ->{ Data: Uint8Array(9) [115, 111, 109, 101, 32, 100,  97, 116, 97] }
console.log(prepare({ Links: [CID.parse('bafkqabiaaebagba')] }))
// -> { Links: [ { Hash: CID(bafkqabiaaebagba) } ] }

Some features of prepare():

  • Extraneous properties are omitted
  • String values for Data are converted
  • Strings are converted to { Data: bytes } (as are Uint8Arrays)
  • Multiple ways of finding CIDs in the Links array are attempted, including interpreting the whole link element as a CID, reading a Uint8Array as a CID
  • Ensuring that properties are of the correct type (link Name is a string and Tsize is a number)
  • Links array is always present, even if empty
  • Links array is properly sorted

These utility exports are available to make transition from the older ipld-dag-pb library which used DAGNode and DAGLink objects with constructors. createNode() mirrors the new DAGNode() API while createLink() mirrors new DAGLink() API.

  • createNode(data: Uint8Array, links: PBLink[]|void): PBNode: create a correctly formed PBNode object from a Uint8Array and an optional array of correctly formed PBLink objects. The returned object will be suitable for passing to encode() and using prepare() on it should result in a noop.
  • createLink(name: string, size: number, cid: CID): PBLink: create a correctly formed PBLink object from a name, size and CID. The returned object will be suitable for attaching to a PBNode's Links array, or in an array for the second argument to createNode().
import { CID, bytes } from 'multiformats'
import * as Block from 'multiformats/block'
import { sha256 as hasher } from 'multiformats/hashes/sha2'
import * as codec from '@ipld/dag-pb'

const { createLink, createNode } = codec

async function run () {
  const cid1 = CID.parse('QmWDtUQj38YLW8v3q4A6LwPn4vYKEbuKWpgSm6bjKW6Xfe')
  const cid2 = CID.parse('bafyreifepiu23okq5zuyvyhsoiazv2icw2van3s7ko6d3ixl5jx2yj2yhu')

  const links = [createLink('link1', 100, cid1), createLink('link2', 200, cid2)]
  const value = createNode(Uint8Array.from([0, 1, 2, 3, 4]), links)
  console.log(value)

  const block = await Block.encode({ value, codec, hasher })
  console.log(block.cid)
  console.log(`Encoded: ${bytes.toHex(block.bytes).replace(/(.{80})/g, '$1\n         ')}`)
}

run().catch((err) => console.error(err))

Results in:

    {
      Data: Uint8Array(5) [ 0, 1, 2, 3, 4 ],
      Links: [
        {
          Hash: CID(QmWDtUQj38YLW8v3q4A6LwPn4vYKEbuKWpgSm6bjKW6Xfe),
          Name: 'link1',
          Tsize: 100
        },
        {
          Hash: CID(bafyreifepiu23okq5zuyvyhsoiazv2icw2van3s7ko6d3ixl5jx2yj2yhu),
          Name: 'link2',
          Tsize: 200
        }
      ]
    }
    CID(bafybeihsp53wkzsaif76mjv564cawzqyjwianosamlvf6sht2m25ttyxiy)
    Encoded: 122d0a2212207521fe19c374a97759226dc5c0c8e674e73950e81b211f7dd3b6b30883a08a511205
             6c696e6b31186412300a2401711220a47a29adb950ee698ae0f272019ae902b6aa06ee5f53bc3da2
             ebea6fac27583d12056c696e6b3218c8010a050001020304

API Docs

License

Licensed under either of

Contribute

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

changelog

4.1.3 (2024-10-29)

Dependencies

  • dev: bump aegir from 44.1.4 to 45.0.0 (02613e0)

4.1.2 (2024-06-24)

Dependencies

  • dev: bump aegir from 43.0.3 to 44.0.0 (6510fa3)

4.1.1 (2024-06-01)

Dependencies

  • dev: bump aegir from 42.2.11 to 43.0.1 (1426d0a)

4.1.0 (2024-02-16)

Features

4.0.8 (2024-01-10)

Dependencies

  • dev: bump aegir from 41.3.5 to 42.1.0 (63242a2)

4.0.7 (2023-12-28)

Dependencies

  • bump multiformats from 12.1.3 to 13.0.0 (#92) (c06bed1)

4.0.6 (2023-10-03)

Trivial Changes

  • add or force update .github/workflows/js-test-and-release.yml (0041dec)
  • delete templates [skip ci] (#89) (d171c19)

Dependencies

  • dev: bump aegir from 40.0.13 to 41.0.0 (66b0fc1)

4.0.5 (2023-08-08)

Bug Fixes

  • address new typescript linting error (9e3f768)

Dependencies

  • dev: bump aegir from 39.0.13 to 40.0.8 (3ec2876)

4.0.4 (2023-06-19)

Dependencies

  • bump multiformats from 11.0.2 to 12.0.1 (31dc397)

4.0.3 (2023-05-11)

Bug Fixes

  • update import paths to include extension (#82) (9fe97e3)

Dependencies

  • dev: bump aegir from 38.1.8 to 39.0.5 (#81) (e2de671)

4.0.2 (2023-02-14)

Documentation

4.0.1 (2023-02-13)

Dependencies

  • dev: bump aegir from 37.12.1 to 38.1.2 (#73) (d01086a)

4.0.0 (2023-01-06)

⚠ BREAKING CHANGES

  • improve consistency and fidelity of error conditions & messages

Bug Fixes

  • improve consistency and fidelity of error conditions & messages (bbbff4a)

3.0.2 (2023-01-03)

Dependencies

  • bump multiformats from 10.0.3 to 11.0.0 (0bf1cb2)

3.0.1 (2022-11-26)

Bug Fixes

3.0.0 (2022-10-19)

⚠ BREAKING CHANGES

  • publish as esm-only (#56)

Features

Trivial Changes

  • no-release: bump @types/mocha from 9.1.1 to 10.0.0 (#58) (6475261)
  • no-release: bump actions/setup-node from 3.4.1 to 3.5.0 (#57) (72521b4)
  • no-release: bump actions/setup-node from 3.5.0 to 3.5.1 (#60) (eaa7039)

2.1.18 (2022-08-26)

Trivial Changes

  • deps-dev: bump typescript from 4.7.4 to 4.8.2 (#55) (770bc6d)
  • no-release: bump actions/setup-node from 3.2.0 to 3.3.0 (#51) (422f91e)
  • no-release: bump actions/setup-node from 3.3.0 to 3.4.0 (#53) (3f63ff8)
  • no-release: bump actions/setup-node from 3.4.0 to 3.4.1 (#54) (63c6ed2)

2.1.17 (2022-05-25)

Trivial Changes

  • deps-dev: bump typescript from 4.6.4 to 4.7.2 (#50) (756ba25)
  • no-release: bump actions/checkout from 2.4.0 to 3 (#42) (ceee519)
  • no-release: bump actions/setup-node from 3.0.0 to 3.1.0 (#43) (0c4bcb9)
  • no-release: bump actions/setup-node from 3.1.0 to 3.1.1 (#44) (3c44c80)
  • no-release: bump actions/setup-node from 3.1.1 to 3.2.0 (#49) (0fa8119)
  • no-release: bump mocha from 9.2.2 to 10.0.0 (#47) (26392b8)
  • no-release: bump polendina from 2.0.15 to 3.0.0 (#46) (e38782c)
  • no-release: bump polendina from 3.0.0 to 3.1.0 (#48) (1b16aaf)
  • no-release: bump standard from 16.0.4 to 17.0.0 (#45) (c334cad)

2.1.16 (2022-03-02)

Trivial Changes

  • deps-dev: bump typescript from 4.5.5 to 4.6.2 (#41) (59b3cc4)
  • no-release: bump actions/setup-node from 2.5.0 to 2.5.1 (#38) (80cf03c)
  • no-release: bump actions/setup-node from 2.5.1 to 3.0.0 (#40) (a77b15f)

2.1.15 (2021-12-09)

Trivial Changes

  • use semantic-release, update testing (8735b23)