const mixin = (behaviour, sharedBehaviour = {}) => {
  const instanceKeys = Reflect.ownKeys(behaviour);
  const sharedKeys = Reflect.ownKeys(sharedBehaviour);
  const typeTag = Symbol("isa");
  function _mixin(clazz) {
    for (let key of instanceKeys) {
      const existing = Object.getOwnPropertyDescriptor(
        clazz.prototype,
        key
      );
      if (!existing || existing.configurable) {
        Object.defineProperty(clazz.prototype, key, {
          value: behaviour[key],
          writable: true
        });
      } else {
      }
    }
    Object.defineProperty(clazz.prototype, typeTag, { value: true });
    return clazz;
  }
  for (let key of sharedKeys) {
    Object.defineProperty(_mixin, key, {
      value: sharedBehaviour[key],
      enumerable: sharedBehaviour.propertyIsEnumerable(key)
    });
  }
  Object.defineProperty(_mixin, Symbol.hasInstance, {
    value: (x) => !!x[typeTag]
  });
  return _mixin;
};
export {
  mixin
};
