@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
JavaScript
;
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