apply (op) {
    if (op.type === ObjectOperation.NOP) return
    else if (op.type === ObjectOperation.CREATE) {
      // clone here as the operations value must not be changed
      super.create(cloneDeep(op.val))
    } else if (op.type === ObjectOperation.DELETE) {
      super.delete(op.val.id)
    } else if (op.type === ObjectOperation.UPDATE) {
      const diff = op.diff
      super.update(op.path, diff)
    } else if (op.type === ObjectOperation.SET) {
      super.set(op.path, op.val)
    } else {
      throw new Error('Illegal state.')
    }
    this.emit('operation:applied', op, this)
  }
Apply a given operation.

    @param {ObjectOperation} op