@aedart/support
Version:
The Ion support package
191 lines (176 loc) • 5.32 kB
TypeScript
/**
* @aedart/support
*
* BSD-3-Clause, Copyright (c) 2023-present Alin Eugen Deac <aedart@gmail.com>.
*/
import { ConstructorLike } from '@aedart/contracts';
import { MixinFunction } from '@aedart/contracts/support/mixins';
/**
* Mixin Builder
*
* @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/
* @see https://justinfagnani.com/2016/01/07/enhancing-mixins-with-decorator-functions/
*
* @template T = object
*/
declare class Builder<T = object> {
/**
* The target superclass
*
* @template T = object
*
* @type {ConstructorLike<T>}
*
* @protected
*/
protected readonly _superclass: ConstructorLike<T>;
/**
* Create a new Mixin Builder instance
*
* @param {ConstructorLike<T>} [superclass=class {}]
*/
constructor(superclass?: ConstructorLike<T>);
/**
* Apply given mixins to the superclass
*
* @param {...MixinFunction} mixins
*
* @return {ConstructorLike<T>} Subclass of given superclass with given mixins applied
*/
with(...mixins: MixinFunction[]): ConstructorLike<T>;
/**
* Returns the superclass
*
* **Note**: _Method is intended for testing purposes only, or situations when
* no mixins are desired applied!_
*
* @param {...MixinFunction} [mixins] Ignored
*
* @return {ConstructorLike<T>} The superclass
*/
none(...mixins: MixinFunction[]): ConstructorLike<T>;
}
/**
* Decorates given mixin such that it can be used by {@link import('@aedart/support/mixins').isApplicationOf},
* {@link import('@aedart/support/mixins').hasMixin} and other mixin utility methods
*
* @param {MixinFunction} mixin
*
* @returns {MixinFunction}
*/
declare const Bare: (mixin: MixinFunction) => MixinFunction;
/**
* Decorates given mixin such that it caches its applications.
*
* Method ensures that when mixin is applied multiple times to the same
* superclass, the mixin will only create one subclass, memoize it and return
* it for each application.
*
* @see https://justinfagnani.com/2016/01/07/enhancing-mixins-with-decorator-functions/#cachingmixinapplications
*
* @param {MixinFunction} mixin
*
* @returns {MixinFunction}
*/
declare const Cached: (mixin: MixinFunction) => MixinFunction;
/**
* Decorates mixin such that it is only applied if not already on the superclass'
* prototype chain.
*
* @param {MixinFunction} mixin
*
* @returns {MixinFunction}
*/
declare const DeDupe: (mixin: MixinFunction) => MixinFunction;
/**
* Adds {@link Symbol.hasInstance} to mixin, if not already in mixin
*
* @param {MixinFunction} mixin
*
* @returns {MixinFunction}
*/
declare const HasInstance: (mixin: MixinFunction) => MixinFunction;
/**
* Decorates given mixin to add deduplication, application caching, and instance of support
*
* @param {MixinFunction} mixin
*
* @returns {MixinFunction}
*/
declare const Mixin: (mixin: MixinFunction) => MixinFunction;
/**
* Applies mixin to superclass
*
* @param {object} superclass
* @param {MixinFunction} mixin
*
* @returns {object}
*/
declare function apply(superclass: object, mixin: MixinFunction): object;
/**
* Determine if given target has an application of given `mixin` on its prototype
* chain.
*
* @param {object} target
* @param {MixinFunction} mixin
*
* @returns {boolean}
*/
declare function hasMixin(target: object, mixin: MixinFunction): boolean;
/**
* Determine if object is a prototype created by the application of
* `mixin` to a superclass.
*
* @param {object} proto
* @param {MixinFunction} mixin
*
* @returns {boolean}
*/
declare function isApplicationOf(proto: object, mixin: MixinFunction): boolean;
/**
* Mix superclass with one or more abstract subclasses ("Mixins")
*
* **example**:
* ```ts
* const BoxMixin = <T extends AbstractConstructor>(superclass: T) => class extends superclass {
* // ...not shown...
* }
*
* class A extends mix().with(
* BoxMixin
* ) {
* // ...not shown...
* }
* ```
*
* @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/
* @see https://justinfagnani.com/2016/01/07/enhancing-mixins-with-decorator-functions/
*
* @template T = object
*
* @param {ConstructorLike<T>} [superclass=class {}]
*
* @return {Builder<T>} New Mixin Builder instance
*/
declare function mix<T = object>(superclass?: ConstructorLike<T>): Builder<T>;
/**
* Unwrap the given wrapped mixin
*
* @param {MixinFunction} wrapped A wrapped mixin produced by the {@link import('@aedart/support/mixins').wrap} function
*
* @returns {MixinFunction}
*/
declare function unwrap(wrapped: MixinFunction): MixinFunction;
/**
* Setup given mixin to be wrapped by given `wrapper` and allow
* it to be unwrapped at a later point.
*
* @param {MixinFunction} mixin
* @param {MixinFunction} wrapper
*
* @returns {MixinFunction}
*/
declare function wrap(mixin: MixinFunction, wrapper: MixinFunction): MixinFunction;
export { Bare, Builder, Cached, DeDupe, HasInstance, Mixin, apply, hasMixin, isApplicationOf, mix, unwrap, wrap };