UNPKG

ipfs-core

Version:

JavaScript implementation of the IPFS specification

99 lines (82 loc) 2.86 kB
import { Key } from 'interface-datastore/key' import { Libp2pRecord } from '@libp2p/record' import errcode from 'err-code' import { logger } from '@libp2p/logger' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' const log = logger('ipfs:ipns:offline-datastore') /** * @typedef {import('@libp2p/interfaces').AbortOptions} AbortOptions */ // Offline datastore aims to mimic the same encoding as routing when storing records // to the local datastore export class OfflineDatastore { /** * @param {import('interface-datastore').Datastore} datastore */ constructor (datastore) { this._datastore = datastore /** @type {any[]} */ this.stores = [] } /** * Put a value to the local datastore indexed by the received key properly encoded. * * @param {Uint8Array} key - identifier of the value. * @param {Uint8Array} value - value to be stored. * @param {AbortOptions} [options] */ async put (key, value, options) { // eslint-disable-line require-await if (!(key instanceof Uint8Array)) { throw errcode(new Error('Offline datastore key must be a Uint8Array'), 'ERR_INVALID_KEY') } if (!(value instanceof Uint8Array)) { throw errcode(new Error('Offline datastore value must be a Uint8Array'), 'ERR_INVALID_VALUE') } let routingKey try { routingKey = this._routingKey(key) } catch (/** @type {any} */ err) { log.error(err) throw errcode(new Error('Not possible to generate the routing key'), 'ERR_GENERATING_ROUTING_KEY') } // Marshal to libp2p record as the DHT does const record = new Libp2pRecord(key, value, new Date()) await this._datastore.put(routingKey, record.serialize(), options) } /** * Get a value from the local datastore indexed by the received key properly encoded. * * @param {Uint8Array} key - identifier of the value to be obtained. * @param {AbortOptions} [options] */ async get (key, options) { if (!(key instanceof Uint8Array)) { throw errcode(new Error('Offline datastore key must be a Uint8Array'), 'ERR_INVALID_KEY') } let routingKey try { routingKey = this._routingKey(key) } catch (/** @type {any} */ err) { log.error(err) throw errcode(new Error('Not possible to generate the routing key'), 'ERR_GENERATING_ROUTING_KEY') } const res = await this._datastore.get(routingKey, options) // Unmarshal libp2p record as the DHT does let record try { record = Libp2pRecord.deserialize(res) } catch (/** @type {any} */ err) { log.error(err) throw err } return record.value } /** * encode key properly - base32(/ipns/{cid}) * * @param {Uint8Array} key */ _routingKey (key) { return new Key('/dht/record/' + uint8ArrayToString(key, 'base32'), false) } }