UNPKG

@mikrokit/di

Version:

A lightweight TypeScript dependency injection container that uses only strip-tipes compliant methodologies and does not rely on reflect-metadata

279 lines (274 loc) 9.07 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { Container: () => Container, Module: () => Module, ProvideScope: () => ProvideScope, attachProviderToken: () => attachProviderToken, createContainer: () => createContainer, createGroupProviderToken: () => createGroupProviderToken, createModule: () => createModule, createProviderToken: () => createProviderToken, defineProvider: () => defineProvider, defineProviderFactory: () => defineProviderFactory, defineStaticProvider: () => defineStaticProvider, defineStaticProviderFactory: () => defineStaticProviderFactory }); module.exports = __toCommonJS(index_exports); // src/utils.ts var mergeDefaults = (defaults, overrides) => { if (!overrides) { return defaults; } return { ...defaults, ...overrides }; }; // src/module.ts var _Module = class _Module { constructor(moduleName, providers) { this.moduleName = moduleName; this.providers = providers ?? /* @__PURE__ */ new Map(); } provide(token, factory, options) { const normalizedOptions = mergeDefaults( _Module.DEFAULT_PROVIDE_OPTIONS, options ); const normalizedToken = "token" in token ? token.token : token; const normalizedFactory = typeof token === "function" && !factory ? token : factory; if (normalizedToken._.group) { this.provideGroupToken( normalizedToken, normalizedFactory ); } else { this.provideSingleToken( normalizedToken, normalizedFactory, normalizedOptions ); } return this; } import(module2) { for (const token of module2.providers.keys()) { const ownProvider = this.providers.get(token); const importedModuleProvider = module2.providers.get(token); if (!ownProvider) { this.providers.set(token, importedModuleProvider); continue; } if (ownProvider.group && importedModuleProvider.group) { ownProvider.factories.push(...importedModuleProvider.factories); continue; } if (ownProvider.group && !importedModuleProvider.group) { throw new Error( `Trying to re-provide group-type provider ${token.toString()} that was already provided as single-type provider` ); } throw new Error( "Trying to re-provide single-type provider for " + token.toString() ); } return this; } provideGroupToken(token, factory) { const existingProviderDefinition = this.providers.get(token); if (existingProviderDefinition && existingProviderDefinition.group !== token._.group) { throw new Error( `Trying to re-provide group-type provider ${token.toString} that was already provided as single-type provider` ); } if (existingProviderDefinition) { existingProviderDefinition.factories.push(factory); return; } const providerDefinition = { group: true, factories: [factory] }; this.providers.set(token, providerDefinition); } provideSingleToken(token, factory, options) { if (this.providers.has(token)) { const existingProvider = this.providers.get(token); if (existingProvider.group !== token._.group) { throw new Error( `Trying to re-provide single-type provider ${token.toString()} as group-type provider` ); } if (!options.override) { throw new Error( "Trying to re-provide single-type provider for " + token.toString() ); } } this.providers.set(token, { group: false, factory }); } }; _Module.DEFAULT_PROVIDE_OPTIONS = { override: false }; var Module = _Module; var createModule = () => { return new Module(); }; // src/container.ts var ProvideScope = /* @__PURE__ */ ((ProvideScope2) => { ProvideScope2["TRANSIENT"] = "transient"; ProvideScope2["SINGLETON"] = "singleton"; return ProvideScope2; })(ProvideScope || {}); var Container = class _Container extends Module { constructor(parentContainer, injectionItem) { super(parentContainer?.moduleName, parentContainer?.providers); this.instantiatedSingleSingletonProviders = parentContainer?.instantiatedSingleSingletonProviders ?? /* @__PURE__ */ new Map(); this.instantiatedGroupSingletonProviders = parentContainer?.instantiatedGroupSingletonProviders ?? /* @__PURE__ */ new Map(); this.injectionStack = injectionItem ? [...parentContainer?.injectionStack ?? [], injectionItem] : []; } static createEmpty() { return new _Container(); } async inject(token, scope = "singleton" /* SINGLETON */) { const normalizedToken = "token" in token ? token.token : token; if (this.injectionStack.includes(normalizedToken)) { throw new Error( `Provider ${normalizedToken.toString()} is already being instantiated. This error can be caused by either a circular dependency or not awaiting the inject calls` ); } if (normalizedToken._.group) { const result2 = await this.injectGroup( normalizedToken, scope ); return result2; } const result = await this.injectSingle( normalizedToken, scope ); return result; } async injectSingle(token, scope) { if (scope === "singleton" /* SINGLETON */) { const instantiatedProvider = this.instantiatedSingleSingletonProviders.get(token); if (instantiatedProvider) { return instantiatedProvider; } } const definition = this.providers.get(token); if (!definition) { throw new Error( "No factory available for the specified token " + token.toString() ); } if (token._.group !== definition.group) { throw new Error( `Trying to inject group-type provider ${token.toString()} as single-type provider` ); } const result = await definition.factory(new _Container(this, token)); if (scope === "singleton" /* SINGLETON */) { this.instantiatedSingleSingletonProviders.set(token, result); } return result; } async injectGroup(token, scope) { if (scope === "singleton" /* SINGLETON */) { const instantiatedProviders = this.instantiatedGroupSingletonProviders.get(token); if (instantiatedProviders) { return instantiatedProviders; } } const definition = this.providers.get(token); if (!definition) { return []; } if (token._.group !== definition.group) { throw new Error( `Trying to inject single-type provider ${token.toString()} as group-type provider` ); } const result = []; for (const factory of definition.factories) { result.push(await factory(new _Container(this, token))); } if (scope === "singleton" /* SINGLETON */) { this.instantiatedGroupSingletonProviders.set(token, result); } return result; } }; var createContainer = () => { return Container.createEmpty(); }; // src/helpers.ts var createProviderToken = (_factory, name) => { const symbol = Symbol(name); const metadata = { provided: void 0, group: false }; return Object.assign(symbol, { _: metadata }); }; var createGroupProviderToken = (name) => { const symbol = Symbol(name); const metadata = { provided: void 0, group: true }; return Object.assign(symbol, { _: metadata }); }; var defineProviderFactory = (factory) => factory; var defineStaticProviderFactory = (staticValue) => () => staticValue; var attachProviderToken = (factory, token) => { return Object.assign(factory, { token }); }; function defineStaticProvider(staticValue, token) { return defineProvider(defineStaticProviderFactory(staticValue), token); } function defineProvider(factory, tokenOrName) { const token = typeof tokenOrName === "string" || !tokenOrName ? createProviderToken(factory, tokenOrName) : tokenOrName; return Object.assign(factory, { token }); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Container, Module, ProvideScope, attachProviderToken, createContainer, createGroupProviderToken, createModule, createProviderToken, defineProvider, defineProviderFactory, defineStaticProvider, defineStaticProviderFactory }); //# sourceMappingURL=index.cjs.map