All files / src/libs/LifecycleManager/decorators Lifecycle.ts

0% Statements 0/34
0% Branches 0/13
0% Functions 0/5
0% Lines 0/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142                                                                                                                                                                                                                                                                                           
import { copyStaticProperties } from 'src/classes/decorators/Helper';
import {
    ILifecycleManager_,
    ILifecycleState,
    ILifecycleTime,
} from '../interfaces/ILifecycleManager';
import { ILifecycleObject } from '../interfaces/ILifecycleObject';
import { LifecycleManager } from '../LifecycleManager';
 
const manager: ILifecycleManager_ = LifecycleManager;
 
/**
 * Registers lifecycle methods based on time and state.
 * @param instance The instance whose methods are registered.
 * @param time The lifecycle time.
 * @param state The lifecycle state.
 * @param method The lifecycle method.
 */
function registerLifecycleMethod(
    instance: ILifecycleObject,
    time: ILifecycleTime,
    state: ILifecycleState,
    method: keyof ILifecycleObject,
): void {
    Iif (instance[method]) {
        manager.register(time, state, instance[method]?.bind(instance));
    }
}
 
/**
 * Lifecycle decorator.
 * @param type The type of lifecycle to register: 'Static', 'Instance', or 'All'.
 * @returns The decorated constructor with lifecycle management.
 */
export function Lifecycle<
    TargetType extends {
        new (...args: unknown[]): ILifecycleObject;
    } & ILifecycleObject,
>(type?: 'Static' | 'Instance' | 'All'): (constructor: TargetType) => void {
    /**
     * Lifecycle decorator.
     * @param constructor The constructor to decorate with lifecycle methods.
     * @param args The arguments for the constructor.
     * @returns The decorated constructor with lifecycle management.
     */
    return function lifecycle(
        constructor: TargetType,
        ...args: unknown[]
    ): TargetType {
        const original = constructor;
 
        /**
         * Constructs a new instance and registers lifecycle methods.
         * @param constructor The constructor to decorate with lifecycle methods.
         * @param args The arguments for the constructor.
         * @returns The instance with registered lifecycle methods.
         */
        function construct(
            constructor: TargetType,
            args: unknown[],
        ): ILifecycleObject {
            const instance = new constructor(...args);
 
            Iif (type == null || type === 'Instance' || type === 'All') {
                registerLifecycleMethod(
                    instance,
                    'before',
                    'init',
                    'beforeInit',
                );
                registerLifecycleMethod(instance, 'on', 'init', 'onInit');
                registerLifecycleMethod(instance, 'after', 'init', 'afterInit');
 
                registerLifecycleMethod(
                    instance,
                    'before',
                    'load',
                    'beforeLoad',
                );
                registerLifecycleMethod(instance, 'on', 'load', 'onLoad');
                registerLifecycleMethod(instance, 'after', 'load', 'afterLoad');
 
                registerLifecycleMethod(
                    instance,
                    'before',
                    'unload',
                    'beforeUnload',
                );
                registerLifecycleMethod(instance, 'on', 'unload', 'onUnload');
 
                registerLifecycleMethod(
                    instance,
                    'after',
                    'unload',
                    'afterUnload',
                );
            }
 
            return instance;
        }
 
        /**
         * Registers static lifecycle methods.
         */
        Iif (type == null || type === 'Static' || type === 'All') {
            registerLifecycleMethod(original, 'before', 'init', 'beforeInit');
            registerLifecycleMethod(original, 'on', 'init', 'onInit');
            registerLifecycleMethod(original, 'after', 'init', 'afterInit');
 
            registerLifecycleMethod(original, 'before', 'load', 'beforeLoad');
            registerLifecycleMethod(original, 'on', 'load', 'onLoad');
            registerLifecycleMethod(original, 'after', 'load', 'afterLoad');
 
            registerLifecycleMethod(
                original,
                'before',
                'unload',
                'beforeUnload',
            );
            registerLifecycleMethod(original, 'on', 'unload', 'onUnload');
            registerLifecycleMethod(original, 'after', 'unload', 'afterUnload');
        }
 
        /**
         * The wrapped constructor function.
         * @param args The arguments for the constructor.
         * @returns The instance with registered lifecycle methods.
         */
        const wrappedConstructor = function (
            ...args: unknown[]
        ): ILifecycleObject {
            return construct(original, args);
        };
 
        // Transfer prototype
        wrappedConstructor.prototype = original.prototype;
 
        // Copy static methods and properties
        return copyStaticProperties(wrappedConstructor, original);
    };
}
 
Zur TypeDoc-Dokumentation