b-ioc-js
Version:
A magic free, dirt simple IoC container for Javascript.
141 lines • 4.99 kB
JavaScript
/**
* IoC Module
* @module b-ioc-js
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: Object.getOwnPropertyDescriptor(all, name).get
});
}
_export(exports, {
get bind () {
return bind;
},
get clear () {
return clear;
},
get getBindings () {
return getBindings;
},
get getSingletons () {
return getSingletons;
},
get make () {
return make;
},
get singleton () {
return singleton;
},
get use () {
return use;
}
});
_export_star(require("./types.js"), exports);
function _export_star(from, to) {
Object.keys(from).forEach(function(k) {
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
Object.defineProperty(to, k, {
enumerable: true,
get: function() {
return from[k];
}
});
}
});
return from;
}
function _type_of(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
var bindings = {};
var resolvedBindings = {};
var singletons = {};
var resolvedSingletons = {};
function isString(obj) {
return Object.prototype.toString.call(obj) === '[object String]';
}
function isObject(obj) {
var type = typeof obj === "undefined" ? "undefined" : _type_of(obj);
return type === 'function' || type === 'object' && !!obj;
}
function isFunction(obj) {
return typeof obj === 'function' || false;
}
function inObject(key, obj) {
// biome-ignore lint/suspicious/noPrototypeBuiltins: Legacy
return obj.hasOwnProperty(key);
}
function getBindings() {
return bindings;
}
function getSingletons() {
return singletons;
}
function clear() {
bindings = {};
resolvedBindings = {};
singletons = {};
resolvedSingletons = {};
}
function bind(binding, closure) {
if (inObject(binding, bindings) || inObject(binding, singletons)) throw new Error("Binding: ".concat(binding, " already binded."));
if (!isFunction(closure)) throw new Error("Binding: ".concat(binding, " does not implement a factory."));
bindings[binding] = closure;
}
function singleton(binding, closure) {
if (inObject(binding, singletons) || inObject(binding, bindings)) throw new Error("Singleton: ".concat(binding, " already binded."));
singletons[binding] = closure;
}
function use(binding) {
// biome-ignore lint/complexity/noArguments: Apply arguments
var args = Array.prototype.slice.call(arguments, 1);
// first check bindings
if (inObject(binding, bindings)) {
if (resolvedBindings[binding]) {
throw new Error("Cyclic dependency detected in binding: ".concat(binding, "."));
}
resolvedBindings[binding] = true;
var instance = bindings[binding].apply(null, args);
resolvedBindings[binding] = false;
return instance;
}
// then check singletons
if (inObject(binding, singletons)) {
if (!inObject(binding, resolvedSingletons)) {
// we are not guarenteed to receive a factory function for a singleton
if (isFunction(singletons[binding])) resolvedSingletons[binding] = singletons[binding].apply(null, args);
else resolvedSingletons[binding] = singletons[binding];
}
return resolvedSingletons[binding];
}
// finally check node_modules
throw new Error("Binding: ".concat(binding, " not found."));
}
function make(Obj) {
if (!isFunction(Obj)) throw new Error(".make implementation error, expected function got: ".concat(typeof Obj === "undefined" ? "undefined" : _type_of(Obj)));
if (!Obj.inject) throw new Error(".make requires ".concat(Obj.constructor.name, " to have a static inject method."));
var dependencies = Obj.inject();
if (dependencies.length === 0) return new Obj();
var resolved = [];
dependencies.forEach(function(dependency) {
if (!isString(dependency) && !isObject(dependency)) {
throw new Error('static .inject implementation error, a string or object is required.');
}
// string based binding
if (isString(dependency)) resolved.push(exports.use(dependency));
// binding you want to pass args to
if (isObject(dependency)) {
dependency.args.unshift(dependency.key);
resolved.push(exports.use.apply(null, dependency.args));
}
});
return new (Function.prototype.bind.apply(Obj, [
null
].concat(resolved)))();
}
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }