OverviewFilesCommitsIssuesDocsReleasesPeers

codetree / test / fixtures / workspace / widget-store / lib / widget-store.js

90 lines · javascript ref:
import { Room } from 'widget-rooms'
import { storeSchema, validateName } from './schema.js'

/**
 * A store of widgets, backed by a room.
 *
 * Stands in for hyper-orgs: a facade class that delegates lifecycle to an inner
 * room and exposes a CRUD surface over it.
 */
export class WidgetStore {
  /**
   * Create a store.
   * @param {object} corestore - the corestore to build on
   * @param {object} options - room options
   */
  constructor (corestore, options) {
    this._corestore = corestore
    this._options = options || {}
    this._room = new Room(corestore, this._options)
    this._opened = false
  }

  get key () { return this._room.key }
  get keyHex () { return this._room.key.toString('hex') }
  get writable () { return this._room.writable }
  get view () { return this._room.view }
  get base () { return this._room.base }
  get room () { return this._room }

  async ready () {
    await this._room.ready()
    this._opened = true
  }

  async close () {
    await this._room.close()
    this._opened = false
  }

  async create (name, type, data) {
    validateName(name)
    if (!storeSchema[type]) throw new Error(`Unknown type: ${type}`)
    return this._room.put(name, { type, data })
  }

  async get (name) {
    return this._room.get(name)
  }

  async update (name, data) {
    const existing = await this.get(name)
    if (!existing) throw new Error(`No such widget: ${name}`)
    return this._room.put(name, { ...existing, data })
  }

  async delete (name) {
    return this._room.del(name)
  }

  async list () {
    return this._room.list()
  }

  async checkAccess (peer, level) {
    const member = await this._room.member(peer)
    if (!member) return false
    return member.level >= level
  }

  async addMember (peer, level) {
    return this._room.put('member/' + peer, { level })
  }

  async addResource (name, resource) {
    return this._room.put('resource/' + name, resource)
  }

  async createGrant (peer, scope) {
    return this._room.put('grant/' + peer, { scope })
  }

  async createInvite (level) {
    return this._room.invite(level)
  }

  async addWriter (key) {
    return this._room.addWriter(key)
  }
}