| function Factory (layout) { | ||
| this.deps = Object.assign({}, this.constructor.deps) | ||
| if (! layout) { | ||
| layout = layoutFromDeps(this.deps) | ||
| } | ||
| else { | ||
| var deps = this.deps | ||
| Object.getOwnPropertyNames(layout) | ||
| .forEach(function(name) { | ||
| if (! deps.hasOwnProperty(name)) { | ||
| throw new Error('Unknown dependency in layout "' + name + '"') | ||
| } | ||
| }) | ||
| } | ||
| this.layout = layout | ||
| this.defaults = this.constructor.defaults | ||
| } | ||
| function layoutFromDeps(deps) { | ||
| var layout = {} | ||
| Object.getOwnPropertyNames(deps) | ||
| .forEach(function(name) { | ||
| layout[name] = name | ||
| }) | ||
| return layout | ||
| } | ||
| Factory.deps = {} | ||
| Factory.defaults = {} | ||
| Factory.prototype.start = function() {} | ||
| Factory.prototype.stop = function() {} | ||
| function assembleFactory(start, stop) { | ||
| if (typeof start !== 'function') { | ||
| throw new Error('Arugment `start` should be a function') | ||
| } | ||
| if (stop && typeof stop !== 'function') { | ||
| throw new Error('Arugment `stop` should be undefined or a function') | ||
| } | ||
| function SimpleFactory() { | ||
| Factory.apply(this, arguments) | ||
| } | ||
| Object.setPrototypeOf(SimpleFactory.prototype, Factory.prototype) | ||
| SimpleFactory.defaults = {} | ||
| SimpleFactory.prototype.start = start | ||
| if (stop) { | ||
| SimpleFactory.prototype.stop = stop | ||
| } | ||
| return SimpleFactory | ||
| } | ||
| Factory.from = function from(source) { | ||
| return Object.assign( | ||
| assembleFactory(source.start, source.stop), | ||
| { | ||
| defaults: source.defaults || {}, | ||
| deps: source.deps || {}, | ||
| } | ||
| ) | ||
| } | ||
| exports.Factory = Factory | ||
| exports.assembleFactory = assembleFactory |
+2
-2
| { | ||
| "name": "singular", | ||
| "version": "3.5.0-beta1", | ||
| "version": "3.6.0-beta1", | ||
| "description": "Application dependency injection manager", | ||
@@ -18,3 +18,3 @@ "dependencies": { | ||
| "@testup/core": "^0.1.2", | ||
| "allow-publish-tag": "^1.0.1" | ||
| "allow-publish-tag": "^2.1.1" | ||
| }, | ||
@@ -21,0 +21,0 @@ "engines": { |
+17
-12
| var toposort = require('toposort') | ||
| var ModuleFactory = require('./module') | ||
| var Factory = require('./factory').Factory | ||
@@ -25,10 +25,6 @@ function Singular(options) { | ||
| .forEach(function(name) { | ||
| if (name in this.scope === false) { | ||
| this.scope[name] = {} | ||
| } | ||
| this._registerModule(name, modules[name]) | ||
| }, this) | ||
| this.order = toposort(getNodesFromModules(this.modules)) | ||
| .slice(1) | ||
| .reverse() | ||
| this.order = getInitializationOrder(this.modules) | ||
| } | ||
@@ -57,2 +53,6 @@ | ||
| this._registerModule(name, module) | ||
| } | ||
| Singular.prototype._registerModule = function(name, module) { | ||
| this.modules[name] = module | ||
@@ -239,7 +239,14 @@ this.scope[name] = {} | ||
| Singular.prototype.wait = function() { | ||
| return new Promise((resolve) => { | ||
| this._resolveOnStop = [...this._resolveOnStop, resolve] | ||
| var self = this | ||
| return new Promise(function (resolve) { | ||
| this._resolveOnStop = self._resolveOnStop.concat(resolve) | ||
| }) | ||
| } | ||
| function getInitializationOrder(modules) { | ||
| return toposort(getNodesFromModules(modules)) | ||
| .slice(1) | ||
| .reverse() | ||
| } | ||
| function getNodesFromModules(modules) { | ||
@@ -273,4 +280,2 @@ var nodes = [] | ||
| Singular.ModuleFactory = ModuleFactory | ||
| // Added for backward compatibility | ||
| Singular.Module = ModuleFactory | ||
| Singular.Factory = Factory |
@@ -9,3 +9,3 @@ const assert = require('assert') | ||
| const Class = class TestModule extends Singular.Module { | ||
| const Class = class TestFactory extends Singular.Factory { | ||
| static get defaults() { | ||
@@ -302,2 +302,21 @@ return defaults | ||
| }) | ||
| describe('Singular.Factory.from()', () => { | ||
| it('should create functional module factory', () => { | ||
| const factory = Singular.Factory.from({ | ||
| start: () => 'factory works', | ||
| }) | ||
| const singular = new Singular({ | ||
| modules: { | ||
| test: new factory(), | ||
| }, | ||
| }) | ||
| return singular.start() | ||
| .then((scope) => { | ||
| assert.equal(scope.test, 'factory works', 'module is initialized') | ||
| }) | ||
| }) | ||
| }) | ||
| }) |
| function ModuleFactory (layout) { | ||
| this.deps = Object.assign({}, this.constructor.deps) | ||
| if (! layout) { | ||
| layout = layoutFromDeps(this.deps) | ||
| } | ||
| else { | ||
| var deps = this.deps | ||
| Object.getOwnPropertyNames(layout) | ||
| .forEach(function(name) { | ||
| if (! deps.hasOwnProperty(name)) { | ||
| throw new Error('Unknown dependency in layout "' + name + '"') | ||
| } | ||
| }) | ||
| } | ||
| this.layout = layout | ||
| this.defaults = this.constructor.defaults | ||
| } | ||
| function layoutFromDeps(deps) { | ||
| var layout = {} | ||
| Object.getOwnPropertyNames(deps) | ||
| .forEach(function(name) { | ||
| layout[name] = name | ||
| }) | ||
| return layout | ||
| } | ||
| ModuleFactory.deps = {} | ||
| ModuleFactory.defaults = {} | ||
| ModuleFactory.prototype.start = function() {} | ||
| ModuleFactory.prototype.stop = function() {} | ||
| module.exports = ModuleFactory |
18856
7.62%578
8.85%