/**
 * @aedart/contracts
 * 
 * BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>.
 */

import { AbstractConstructor } from '@aedart/contracts';

/**
 * A function that returns an abstract subclass ("Mix-in") of its argument
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/extends#mix-ins
 * @see https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
 *
 * @example:
 * ```ts
 * const BoxMixin = <T extends AbstractConstructor>(superclass: T) => class extends superclass {
 *      // ...not shown...
 * }
 * ```
 */
type MixinFunction<SuperClass extends AbstractConstructor = AbstractConstructor, AbstractSubclass extends AbstractConstructor = AbstractConstructor> = (superclass: SuperClass) => AbstractSubclass & SuperClass;

/**
 * Support Mixins identifier
 *
 * @type {Symbol}
 */
declare const SUPPORT_MIXINS: unique symbol;
/**
 * Symbol used by "apply mixin" and "is application of" functions
 *
 * @type {symbol}
 */
declare const APPLIED_MIXIN: unique symbol;
/**
 * Symbol used by the mixin wrap and unwrap functions
 *
 * @type {symbol}
 */
declare const WRAPPED_MIXIN: unique symbol;
/**
 * Symbol used for by a "cache" mixin to ensure a mixin is only applied once
 *
 * @type {symbol}
 */
declare const CACHED_APPLICATIONS: unique symbol;

export { APPLIED_MIXIN, CACHED_APPLICATIONS, type MixinFunction, SUPPORT_MIXINS, WRAPPED_MIXIN };
