text: import isEmpty from './isEmpty'
  import debounce from './debounce'
  
  /**
   * bind func to obj
   */
  function bindFunc(obj, method, observer) {
      const oldFn = obj[method]
      obj[method] = function(target) {
          if (observer) {
              observer.call(this, target, {
                  [method]: true,
              })
          }
          if (oldFn) {
              oldFn.call(this, target)
          }
      }
  }
  
  // default methods
  const methods = ['linked', 'linkChanged', 'unlinked']
  
  // extra props
  const extProps = ['observer']
  
  export default Behavior({
      lifetimes: {
          created() {
              this._debounce = null
          },
          detached() {
              if (this._debounce && this._debounce.cancel) {
                  this._debounce.cancel()
              }
          },
      },
      definitionFilter(defFields) {
          const { relations } = defFields
  
          if (!isEmpty(relations)) {
              for (const key in relations) {
                  const relation = relations[key]
  
                  // bind func
                  methods.forEach((method) => bindFunc(relation, method, relation.observer))
  
                  // delete extProps
                  extProps.forEach((prop) => delete relation[prop])
              }
          }
  
          Object.assign(defFields.methods = (defFields.methods || {}), {
              getRelationsName: function(types = ['parent', 'child', 'ancestor', 'descendant']) {
                  return Object.keys(relations || {}).map((key) => {
                      if (relations[key] && types.includes(relations[key].type)) {
                          return key
                      }
                      return null
                  }).filter((v) => !!v)
              },
              debounce: function(func, wait = 0, immediate = false) {
                  return (this._debounce = this._debounce || debounce(func.bind(this), wait, immediate)).call(this)
              },
          })
      },
  })
  