All files / lib/resources main.ts

100% Statements 290/290
100% Branches 34/34
100% Functions 18/18
100% Lines 290/290

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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 2901x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 579x 1x 1x 578x 578x 578x 578x 578x 578x 578x 578x 578x 14x 14x 14x 14x 14x 14x 12169x 1x 1x 12168x 12168x 12168x 14x 14x 14x 14x 14x 14x 10047x 10047x 1x 1x 10046x 10046x 10046x 14x 14x 14x 14x 14x 14x 200x 200x 1x 1x 199x 199x 199x 14x 14x 14x 14x 14x 14x 1865x 1865x 1x 1x 1864x 1864x 1864x 14x 14x 14x 14x 14x 14x 55x 55x 1x 1x 54x 54x 54x 14x 14x 14x 14x 14x 14x 14x 14x 5835x 5835x 5835x 5835x 5835x 5835x 1x 5835x 5835x 5623x 5835x 5835x 209x 5835x 5835x 1x 5835x 5835x 1x 5835x 5835x 5835x 14x 14x 14x 14x 14x 14x 14x 14x 5022x 5022x 2640x 2640x 5022x 5022x 983x 983x 5022x 5022x 30x 30x 5022x 5022x 5022x 14x 14x 14x 14x 14x 14x 14x 14x 554x 554x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x
import PackageData from '../../../package.json' assert { type: 'json' }; // eslint-disable-line
import {RESOURCES_ERR} from "../../app/error/error-codes.js";
import {iCPSError} from "../../app/error/error.js";
import {iCPSAppOptions} from "../../app/factory.js";
import {EventManager, ListenerFunction} from "./event-manager.js";
import {iCPSEvent, iCPSEventLog} from "./events-types.js";
import {NetworkManager} from "./network-manager.js";
import {ResourceManager} from "./resource-manager.js";
import {Validator} from "./validator.js";
 
/**
 * This namespace handles the static access to the singleton functions of the ResourceManager, NetworkManager, Validator and EventManager
 */
export namespace Resources {
    /**
     * The singleton instances of the shared resources
     */
    export let _instances: Resources.Types.Instances;
 
    /**
     * Static package info
     */
    export const PackageInfo: Resources.Types.PackageInfo = {
        name: PackageData.name,
        version: PackageData.version,
        description: PackageData.description,
    };
 
    /**
     * Prepares the global singleton instances. This includes the ResourceManager, NetworkManager, Validator and EventManager.
     * This function should only be called once.
     * @param appOptions - The parsed app options
     * @returns The singleton instances
     * @throws If the function is called with an already initiated singleton
     */
    export function setup(appOptions: iCPSAppOptions): Resources.Types.Instances {
        if (_instances) {
            throw new iCPSError(RESOURCES_ERR.ALREADY_INITIATED);
        }
 
        _instances = {} as Resources.Types.Instances; // Creating one-by one, so they are available as soon as possible
        _instances.event = new EventManager();
        _instances.validator = new Validator();
        _instances.manager = new ResourceManager(appOptions);
        _instances.network = new NetworkManager(appOptions);
 
        return _instances;
    }
 
    /**
     * @returns The singleton instances of the shared resources
     * @throws If the function is called before the singleton is initiated
     */
    export function instances(): Resources.Types.Instances {
        if (!_instances) {
            throw new iCPSError(RESOURCES_ERR.NOT_INITIATED);
        }
 
        return _instances;
    }
 
    /**
     * @returns The singleton instances of the shared event manager
     * @throws If the function is called before the singleton is initiated
     */
    export function event(): EventManager {
        const {event} = instances();
        if (!event) {
            throw new iCPSError(RESOURCES_ERR.EVENT_NOT_INITIATED);
        }
 
        return event;
    }
 
    /**
     * @returns The singleton instances of the shared network manager
     * @throws If the function is called before the singleton is initiated
     */
    export function network(): NetworkManager {
        const {network} = instances();
        if (!network) {
            throw new iCPSError(RESOURCES_ERR.NETWORK_NOT_INITIATED);
        }
 
        return network;
    }
 
    /**
     * @returns The singleton instances of the shared resource manager
     * @throws If the function is called before the singleton is initiated
     */
    export function manager(): ResourceManager {
        const {manager} = instances();
        if (!manager) {
            throw new iCPSError(RESOURCES_ERR.RESOURCE_NOT_INITIATED);
        }
 
        return manager;
    }
 
    /**
     * @returns The singleton instances of the shared validator
     * @throws If the function is called before the singleton is initiated
     */
    export function validator(): Validator {
        const {validator} = instances();
        if (!validator) {
            throw new iCPSError(RESOURCES_ERR.VALIDATOR_NOT_INITIATED);
        }
 
        return validator;
    }
 
    /**
     * Returns a logger interface, that allows emitting log events to the event bus by providing a source object
     * Used to log messages associated to the source object
     * @param source - The source of the log message - either an object or a string
     * @returns The logger interface
     */
    export function logger(source: any | string): Resources.Types.Logger {
        const format = function (...args: unknown[]): string {
            return args.map(arg => String(arg)).join(` `);
        };
 
        return {
            log(...args: any[]) {
                Resources.event().emit(iCPSEventLog.INFO, source, format(args));
            },
            debug(...args: any[]) {
                Resources.event().emit(iCPSEventLog.DEBUG, source, format(args));
            },
            info(...args: any[]) {
                Resources.event().emit(iCPSEventLog.INFO, source, format(args));
            },
            warn(...args: any[]) {
                Resources.event().emit(iCPSEventLog.WARN, source, format(args));
            },
            error(...args: any[]) {
                Resources.event().emit(iCPSEventLog.ERROR, source, format(args));
            },
        };
    }
 
    /**
     * Returns an event interface, that allows listening to events emitted on the event bus, while binding the listener to the registry
     * Used to manage listeners for the listener object
     * @param listenerObject - The source of the registration request, used to track the listeners and enable cleanup
     * @returns The events interface
     */
    export function events(listenerObject: any): Resources.Types.Events {
        return {
            on(event: iCPSEvent, listener: ListenerFunction) {
                Resources.event().on(listenerObject, event, listener);
                return Resources.events(listenerObject); // Returning for chaining
            },
            once(event: iCPSEvent, listener: ListenerFunction) {
                Resources.event().once(listenerObject, event, listener);
                return Resources.events(listenerObject); // Returning for chaining
            },
            removeListeners(event?: iCPSEvent) {
                Resources.event().removeListenersFromRegistry(listenerObject, event);
                return Resources.events(listenerObject); // Returning for chaining
            },
        };
    }
 
    /**
     * Emits an event on the central event bus
     * @param event - The event to emit
     * @param args - Optional arguments to pass to the event
     * @returns True if the event had listeners
     */
    export function emit(event: iCPSEvent, ...args: any[]): boolean {
        return Resources.event().emit(event, ...args);
    }
 
    /**
     * Typing namespace
     */
    export namespace Types {
        /**
         * Type holding all the singleton instances
         */
        export type Instances = {
            /**
             * The resource manager instance
             */
            manager: ResourceManager,
            /**
             * The network manager instance
             */
            network: NetworkManager,
            /**
             * The validator instance
             */
            validator: Validator,
            /**
             * The event manager instance
             */
            event: EventManager,
        }
 
        /**
         * Package Metadata
         */
        export type PackageInfo = {
            /**
             * The name of this package
             */
            name: string,
            /**
             * The version of this package
             */
            version: string,
            /**
             * A short description of this package
             */
            description: string,
        }
        /**
        * Interface to logger event bus, with a source bound to it
        */
        export type Logger = {
           /**
            * Logs a message to the event bus
            * @param args - The arguments to log
            */
           log: (...args: any[]) => void,
           /**
            * Logs a debug message to the event bus
            * @param args - The arguments to log
            */
           debug: (...args: any[]) => void,
           /**
            * Logs an info message to the event bus
            * @param args - The arguments to log
            */
           info: (...args: any[]) => void,
           /**
            * Logs a warn message to the event bus
            * @param args - The arguments to log
            */
           warn: (...args: any[]) => void,
           /**
            * Logs an error message to the event bus
            * @param args - The arguments to log
            */
           error: (...args: any[]) => void,
       }
 
       /**
        * Interface to listener functions of the event bus, with a listener bound to it
        */
       export type Events = {
           /**
            * Registers an event listener to the event bus
            * @param event - The event to listen to
            * @param listener - The listener function to call upon the event
            * @returns This instance for chaining
            */
           on: (event: iCPSEvent, listener: ListenerFunction) => Resources.Types.Events,
           /**
            * Registers an one-time event listener to the event bus
            * @param event - The event to listen to
            * @param listener - The listener function to call upon the event
            * @returns This instance for chaining
            */
           once: (event: iCPSEvent, listener: ListenerFunction) => Resources.Types.Events,
           /**
            * Removes all listeners from the source from the event bus
            * @param event - Optional event to remove listeners for - otherwise all will be removed
            */
           removeListeners: (event?: iCPSEvent) => Resources.Types.Events,
       }
 
       /**
        * Possible regions for this tool to operate in
        */
       export enum Region {
        /**
         * Will use icloud.com
         */
        WORLD = `world`,
        /**
         * Will use icloud.com.cn
         */
        CHINA = `china`,
       }
   }
}