All files store.js

97.78% Statements 44/45
94.74% Branches 18/19
100% Functions 11/11
97.73% Lines 43/44
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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 1331x 1x 1x   1x   40x 40x                 51x 51x 51x 51x                           10x 25x 25x 20x   5x     5x                 40x 40x 40x     40x                                   55x 1x     54x   35x       35x   19x           12x 12x 4x 4x 4x   8x         54x 54x 47x   47x 44x     3x       54x 54x   3x   51x                   1x      
const Readable = require('./readStream.js')
const IPLDResolver = require('ipld-resolver')
const Block = require('ipfs-block')
 
module.exports = class Resolver extends IPLDResolver {
  constructor (bs, Vertex) {
    super(bs)
    this.Vertex = Vertex
  }
 
  /**
   * Stores a vertex in the db, returning its merkle link
   * @param {Vertex}
   * @return {Promise}
   */
  async set (vertex) {
    let buffer = await vertex.serialize()
    let cid = await vertex.constructor.cid(buffer)
    return new Promise((resolve, reject) => {
      this.bs.put({
        cid: cid,
        block: new Block(buffer)
      }, resolve.bind(resolve, cid))
    })
  }
 
  /**
   * Fetches a Vertex from the db
   * @param {Vertex} rootVertex the vertex to start fetching from
   * @param {Array} path the path to fetch
   * @return {Promise}
   */
  async getPath (vertex, path) {
    for (let name of path) {
      let edge = vertex.edges.get(name)
      if (edge) {
        vertex = await this.get(edge)
      } else {
        throw new Error('no vertex was found')
      }
    }
    return vertex
  }
 
  /**
   * resolves a [CID](https://github.com/ipfs/js-cid) to a Vertex
   * @param {CID} [cid](https://github.com/ipfs/js-cid)
   * @return {Promise}
   */
  get (cid) {
    return new Promise((resolve, reject) => {
      super.get(cid, (err, [value, edges]) => {
        Iif (err) {
          reject(err)
        } else {
          resolve(new this.Vertex({
            value: value,
            edges: edges,
            store: this
          }))
        }
      })
    })
  }
 
  /**
   * flush a cache trie to the db returning a promise that resolves to a merkle
   * link in the form of a [cid](https://github.com/ipfs/js-cid)
   * @param {Cache}
   * @return {Promise}
   */
  async batch (cache) {
    let promise
    if (cache.op === 'del' && cache.isLeaf) {
      return false
    }
 
    if (!cache.vertex) {
      // this vertex has never existed before!
      cache.vertex = new this.Vertex({
        store: this,
        cache: cache
      })
      promise = Promise.all([...cache.edges].map(([, vertex]) => this.batch(vertex)))
    } else {
      promise = Promise.all([...cache.edges].map(async ([name, nextedCache]) => {
        // if the edge of the vertex is merkle link and the also has the same path
        // but doesn't have a new vertex then resolve the that edge
        //     a <-- we are here in the trie
        //     |
        //     b <-- we are going here next, do we already know about this vertex?
        const cid = cache.vertex.edges.get(name)
        if (cid && nextedCache.op !== 'del' && !nextedCache.vertex) {
          const foundVertex = await this.get(cid)
          nextedCache.vertex = foundVertex
          return this.batch(nextedCache)
        } else {
          return this.batch(nextedCache)
        }
      }))
    }
 
    const cids = await promise
    for (const [edge] of cache.edges) {
      const cid = cids.shift()
      // if there is a hash update the current vertex edge
      if (cid) {
        cache.vertex.edges.set(edge, cid)
      } else {
        // or delete it if it doesn't exist anymore
        cache.vertex.edges.delete(edge)
      }
    }
 
    cache.clear()
    if (cache.vertex.isEmpty) {
      // dont save empty trie nodes
      return false
    } else {
      return this.set(cache.vertex)
    }
  }
 
  /**
   * Creates a read stream returning all the Vertices in a trie given a root merkle link
   * @param {CID} [cid](https://github.com/ipfs/js-cid)
   * @return {ReadStream}
   */
  createReadStream (cid) {
    return new Readable({}, cid, this)
  }
}