UNPKG

express-service-bootstrap

Version:

This is a convenience package for starting a express API with security, health checks, process exits etc.

154 lines 8.17 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DisposableSingletonContainer = void 0; const bootstrap_constructor_1 = require("./bootstrap-constructor"); /** * DisposableSingletonContainer is a class that is used to create instances of classes and manage their lifecycle via singleton methods. */ class DisposableSingletonContainer { /** * Creates an instance of DisposableSingletonContainer. * @param singletonContainer The singleton container map(defaults to an empty map) * @param disposeSequenceMap The dispose sequence map(defaults to an empty map, to be filled if singletonContainer is not empty) * @param disposeSequence The dispose sequence number(defaults to 0, to be incremented appropriately if singletonContainer is not empty) * @param bootstrap The bootstrap constructor. */ constructor(singletonContainer = new Map(), disposeSequenceMap = new Map(), disposeSequence = 0, bootstrap = new bootstrap_constructor_1.BootstrapConstructor()) { this.singletonContainer = singletonContainer; this.disposeSequenceMap = disposeSequenceMap; this.disposeSequence = disposeSequence; this.bootstrap = bootstrap; } /** * Creates a new instance of a class with a constructor or returns an existing one based on name. * @param {string} name The name of the instance, has to be unique across all instances. * @param typeConstructor The class constructor * @param constructorArguments The arguments to pass to the constructor(optional) * @param {number} disposeSequence The dispose sequence number(optional) * @returns The instance of the class */ createInstance(name, typeConstructor, constructorArguments, disposeSequence) { if (!this.singletonContainer.has(name)) { const newInstance = this.bootstrap.createInstance(typeConstructor, constructorArguments); this.registerInstance(name, newInstance, disposeSequence, true); } return this.singletonContainer.get(name); } /** * Creates a new instance of a class without a constructor asynchronously or returns an existing one based on name. * @param {string} name The name of the instance, has to be unique across all instances. * @param typeConstructorFunction The class constructor ASYNC function. * @param constructorFunctionArguments The arguments to pass to the constructor(optional) * @param {number} disposeSequence The dispose sequence number(optional) * @returns The instance of the class */ createAsyncInstanceWithoutConstructor(name, typeConstructorFunction, constructorFunctionArguments, disposeSequence) { return __awaiter(this, void 0, void 0, function* () { if (!this.singletonContainer.has(name)) { const newInstance = yield this.bootstrap.createAsyncInstanceWithoutConstructor(typeConstructorFunction, constructorFunctionArguments); this.registerInstance(name, newInstance, disposeSequence, true); } return this.singletonContainer.get(name); }); } /** * Creates a new instance of a class without a constructor or returns an existing one based on name. * @param {string} name The name of the instance, has to be unique across all instances. * @param typeConstructorFunction The class constructor * @param constructorFunctionArguments The arguments to pass to the constructor(optional) * @param {number} disposeSequence The dispose sequence number(optional) * @returns The instance of the class * @template InstanceType The type of the instance * @returns {InstanceType} The instance of the class */ createInstanceWithoutConstructor(name, typeConstructorFunction, constructorFunctionArguments, disposeSequence) { if (!this.singletonContainer.has(name)) { const newInstance = this.bootstrap.createInstanceWithoutConstructor(typeConstructorFunction, constructorFunctionArguments); this.registerInstance(name, newInstance, disposeSequence, true); } return this.singletonContainer.get(name); } /** * Fetches an existing instance based on name. * @param {string} name The name of the instance * @returns The instance of the class or undefined if it does not exist * @template InstanceType The type of the instance * @returns {InstanceType | undefined} The instance of the class or undefined if it does not exist */ fetchInstance(name) { return this.singletonContainer.get(name); } /** * Registers an existing instance based on name. * @param {string} name The name of the instance * @param {InstanceType} instance The instance of the class * @param {number} disposeSequence The dispose sequence number(optional) * @template InstanceType The type of the instance * @returns {void} void */ registerInstance(name, instance, disposeSequence, overrideExistingInstance = true) { //throw new Error('Not implemented'); if (overrideExistingInstance === false && this.singletonContainer.has(name)) { return false; } this.disposeSequence++; disposeSequence = disposeSequence || this.disposeSequence; const existingMembers = this.disposeSequenceMap.get(disposeSequence) || new Set(); existingMembers.add(name); this.disposeSequenceMap.set(disposeSequence, existingMembers); this.singletonContainer.set(name, instance); return true; } /** * Disposes an existing instance based on name. * @param {string} name The name of the instance * @returns {Promise<void>} void */ disposeInstance(name) { return __awaiter(this, void 0, void 0, function* () { if (this.singletonContainer.has(name)) { if (this.singletonContainer.get(name)[Symbol.dispose] != null) { this.singletonContainer.get(name)[Symbol.dispose](); } if (this.singletonContainer.get(name)[Symbol.asyncDispose] != null) { yield this.singletonContainer.get(name)[Symbol.asyncDispose](); } this.singletonContainer.delete(name); this.disposeSequenceMap.forEach((setOfNames, sequence) => { if (setOfNames.has(name)) { setOfNames.delete(name); if (setOfNames.size === 0) { this.disposeSequenceMap.delete(sequence); } } }); } }); } /** * Disposes all existing instances based on the dispose sequence. * @returns {Promise<void>} void */ disposeAll() { return __awaiter(this, void 0, void 0, function* () { //Sort descending order of dispose sequence const sortedDisposeSequence = Array.from(this.disposeSequenceMap.keys()).sort((a, b) => b - a); for (const sequence of sortedDisposeSequence) { for (const instanceName of (this.disposeSequenceMap.get(sequence) || new Set())) { yield this.disposeInstance(instanceName); } } }); } } exports.DisposableSingletonContainer = DisposableSingletonContainer; //# sourceMappingURL=disposable-singleton-container.js.map