ditox 2.4.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,14 +31,6 @@ The package can be used as [UMD](https://github.com/umdjs/umd) module. Use
31
31
  </script>
32
32
  ```
33
33
 
34
- Using in Deno environment:
35
-
36
- ```ts
37
- import {createContainer} from 'https://deno.land/x/ditox/mod.ts';
38
-
39
- const container = createContainer();
40
- ```
41
-
42
34
  ## General description
43
35
 
44
36
  DI pattern in general allows to declare and construct a code graph of an
@@ -127,7 +119,7 @@ container.bindFactory(
127
119
  const logger = container.get(LOGGER_TOKEN);
128
120
 
129
121
  // Resolve a value, it throws `ResolverError` in case a value is not found.
130
- const userService = container.resolve(userService);
122
+ const userService = container.resolve(USER_SERVICE_TOKEN);
131
123
 
132
124
  // Remove a value from the container.
133
125
  container.remove(LOGGER_TOKEN);
@@ -164,15 +156,15 @@ Ditox.js supports managing the lifetime of values which are produced by
164
156
  factories. There are the following types:
165
157
 
166
158
  - `singleton` - **This is the default**. The value is created and cached by the
167
- container which registered the factory.
168
- - `scoped` - The value is created and cached by the container which starts
169
- resolving.
159
+ most distant parent container which owns the factory function.
160
+ - `scoped` - The value is created and cached by the nearest container which owns
161
+ the factory function.
170
162
  - `transient` - The value is created every time it is resolved.
171
163
 
172
164
  ### `singleton`
173
165
 
174
166
  **This is the default scope**. "Singleton" allows to cache a produced value by a
175
- parent container which registered the factory:
167
+ most distant parent container which registered the factory function:
176
168
 
177
169
  ```js
178
170
  import {creatContainer, token} from 'ditox';
@@ -69,8 +69,8 @@ type FactoryScope = 'scoped' | 'singleton' | 'transient';
69
69
  * Options for factory binding.
70
70
  *
71
71
  * `scope` types:
72
- * - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
73
- * - `scoped` - The value is created and cached by the container which starts resolving.
72
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
73
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
74
74
  * - `transient` - The value is created every time it is resolved.
75
75
  *
76
76
  * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.
@@ -316,16 +316,17 @@ type ModuleDeclaration<T extends Module<AnyObject>> = {
316
316
  * Options for module binding.
317
317
  *
318
318
  * `scope` types:
319
- * - `singleton` - **This is the default**. The module is created and cached by the container which registered the factory.
320
- * - `scoped` - The module is created and cached by the container which starts resolving.
319
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
320
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
321
321
  */
322
322
  type BindModuleOptions = {
323
323
  scope?: 'scoped' | 'singleton';
324
324
  };
325
- type ModuleBindingEntry = ModuleDeclaration<AnyObject> | {
325
+ type ModuleDeclarationWithOptions = {
326
326
  module: ModuleDeclaration<AnyObject>;
327
327
  options: BindModuleOptions;
328
328
  };
329
+ type ModuleBindingEntry = ModuleDeclaration<AnyObject> | ModuleDeclarationWithOptions;
329
330
  /**
330
331
  * Binds the dependency module to the container
331
332
  * @param container - Dependency container.
@@ -1,2 +1,2 @@
1
- function o(o){var n="string"==typeof o?{description:o}:o;return{symbol:(null==n?void 0:n.key)?Symbol.for(n.key):Symbol(null==n?void 0:n.description)}}function n(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}}var t=function(o,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n}||function(o,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(o[t]=n[t])},t(o,n)};var r=function(){return r=Object.assign||function(o){for(var n,t=1,r=arguments.length;t<r;t++)for(var e in n=arguments[t])Object.prototype.hasOwnProperty.call(n,e)&&(o[e]=n[e]);return o},r.apply(this,arguments)};function e(o,n,t){if(t||2===arguments.length)for(var r,e=0,i=n.length;e<i;e++)!r&&e in n||(r||(r=Array.prototype.slice.call(n,0,e)),r[e]=n[e]);return o.concat(r||Array.prototype.slice.call(n))}var i=function(o){function n(n){var t=this.constructor,r=o.call(this,n)||this;return Object.setPrototypeOf(r,t.prototype),r.name="ResolverError",r}return function(o,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(n,o),n}(Error),u=o("ditox.Container"),l=o("ditox.ParentContainer"),c=o("ditox.Resolver"),a=Symbol(),s=function(){throw new Error("FAKE_FACTORY")},f="singleton",y=o("ditox.FactoriesMap");function p(o){return o.symbol===u.symbol||o.symbol===l.symbol||o.symbol===c.symbol}function v(o){var n=new Map,t=new Map,r={bindValue:function(o,t){p(o)||n.set(o.symbol,t)},bindFactory:function(o,n,r){p(o)||t.set(o.symbol,{factory:n,options:r})},remove:function(o){var r;if(!p(o)){var e=null===(r=t.get(o.symbol))||void 0===r?void 0:r.options;e&&v(o.symbol,e),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&v(n,o.options)})),n.clear(),t.clear(),d()},hasToken:function(r){var e;return n.has(r.symbol)||t.has(r.symbol)||null!==(e=null==o?void 0:o.hasToken(r))&&void 0!==e&&e},get:function(o){var n=e(o,r);return n!==a?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=e(o,r);if(t!==a)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function e(e,i){var u=n.get(e.symbol),l=void 0!==u||n.has(e.symbol);if(l&&i===r)return u;var y,p,v=t.get(e.symbol);if(v&&v.factory!==s)switch(y=v.options,null!==(p=null==y?void 0:y.scope)&&void 0!==p?p:f){case"singleton":if(l)return u;if(null==o?void 0:o.hasToken(e))break;var d=v.factory(r);return r.bindValue(e,d),d;case"scoped":var b=v.factory(i);return i.bindValue(e,b),i!==r&&i.bindFactory(e,s,v.options),b;case"transient":return v.factory(i)}if(l)return u;var m=null==o?void 0:o.get(c);return m?m(e,i):a}function v(o,t){var r=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(r){var e=n.get(o);(void 0!==e||n.has(o))&&r(e)}}function d(){n.set(u.symbol,r),n.set(c.symbol,e),n.set(y.symbol,t),o&&n.set(l.symbol,o)}return d(),r}function d(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function b(o,n,t){var r,i=e(e([],null!==(r=o.get(n))&&void 0!==r?r:[],!0),[t],!1);o.bindValue(n,i)}function m(o,n){if(d(n))return o.get(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.get(n[r])})),t}function h(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return m(o,n)}))}function g(o,n){if(d(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.resolve(n[r])})),t}function O(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return g(o,n)}))}function w(o){for(var n=this,t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];return function(r){var i=O.apply(void 0,e([r],t,!1));return o.apply(n,i)}}function k(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return w.apply(void 0,e([function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];return new(o.bind.apply(o,e([void 0],n,!1)))}],n,!1))}function E(o,n,t){var r=n.token,e=n.imports,i=n.factory,u=n.beforeBinding,l=n.afterBinding,c=n.exports,a=null==t?void 0:t.scope;u&&u(o),e&&j(o,e);var s=new Set;c&&Object.keys(c).forEach((function(n){var t=c[n];t&&(s.add(t),o.bindFactory(t,w((function(o){return o[n]}),r),{scope:a}))}));o.bindFactory(r,i,{scope:a,onRemoved:function(n){n.destroy&&n.destroy(),s.forEach((function(n){return o.remove(n)})),s.clear()}}),l&&l(o)}function j(o,n){n.forEach((function(n){"module"in n?E(o,n.module,n.options):E(o,n)}))}function _(n){var t;return r(r({},n),{token:null!==(t=n.token)&&void 0!==t?t:o()})}function x(o){return _({factory:function(){return{}},imports:o})}export{i as ResolverError,E as bindModule,j as bindModules,b as bindMultiValue,v as createContainer,_ as declareModule,x as declareModuleBindings,w as injectable,k as injectableClass,d as isToken,n as optional,g as resolveValue,O as resolveValues,o as token,m as tryResolveValue,h as tryResolveValues};
1
+ function o(o){var n="string"==typeof o?{description:o}:o;return{symbol:(null==n?void 0:n.key)?Symbol.for(n.key):Symbol(null==n?void 0:n.description)}}function n(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}}var t=function(o,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n}||function(o,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(o[t]=n[t])},t(o,n)};var r=function(){return r=Object.assign||function(o){for(var n,t=1,r=arguments.length;t<r;t++)for(var e in n=arguments[t])Object.prototype.hasOwnProperty.call(n,e)&&(o[e]=n[e]);return o},r.apply(this,arguments)};function e(o,n,t){if(t||2===arguments.length)for(var r,e=0,i=n.length;e<i;e++)!r&&e in n||(r||(r=Array.prototype.slice.call(n,0,e)),r[e]=n[e]);return o.concat(r||Array.prototype.slice.call(n))}var i=function(o){function n(n){var t=this.constructor,r=o.call(this,n)||this;return Object.setPrototypeOf(r,t.prototype),r.name="ResolverError",r}return function(o,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}(n,o),n}(Error),l=o("ditox.Container"),u=o("ditox.ParentContainer"),a=o("ditox.Resolver"),c=Symbol(),s="singleton",f=o("ditox.FactoriesMap");function v(o){return o.symbol===l.symbol||o.symbol===u.symbol||o.symbol===a.symbol}function p(o){var n=new Map,t=new Map,r={bindValue:function(o,t){v(o)||n.set(o.symbol,t)},bindFactory:function(o,n,r){v(o)||t.set(o.symbol,{factory:n,options:r})},remove:function(o){var r;if(!v(o)){var e=null===(r=t.get(o.symbol))||void 0===r?void 0:r.options;e&&p(o.symbol,e),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&p(n,o.options)})),n.clear(),t.clear(),y()},hasToken:function(r){var e;return n.has(r.symbol)||t.has(r.symbol)||null!==(e=null==o?void 0:o.hasToken(r))&&void 0!==e&&e},get:function(o){var n=e(o,r);return n!==c?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=e(o,r);if(t!==c)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function e(e,i){var l=n.get(e.symbol),u=void 0!==l||n.has(e.symbol);if(u&&i===r)return l;var f,v,p=t.get(e.symbol);if(p)switch(f=p.options,null!==(v=null==f?void 0:f.scope)&&void 0!==v?v:s){case"singleton":if(u)return l;if(null==o?void 0:o.hasToken(e))break;var y=p.factory(r);return r.bindValue(e,y),y;case"scoped":if(u)return l;var d=p.factory(r);return r.bindValue(e,d),d;case"transient":return p.factory(i)}if(u)return l;var m=null==o?void 0:o.get(a);return m?m(e,i):c}function p(o,t){var r=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(r){var e=n.get(o);(void 0!==e||n.has(o))&&r(e)}}function y(){n.set(l.symbol,r),n.set(a.symbol,e),n.set(f.symbol,t),o&&n.set(u.symbol,o)}return y(),r}function y(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function d(o,n,t){var r,i=e(e([],null!==(r=o.get(n))&&void 0!==r?r:[],!0),[t],!1);o.bindValue(n,i)}function m(o,n){if(y(n))return o.get(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.get(n[r])})),t}function b(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return m(o,n)}))}function h(o,n){if(y(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.resolve(n[r])})),t}function g(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return h(o,n)}))}function O(o){for(var n=this,t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];return function(r){var i=g.apply(void 0,e([r],t,!1));return o.apply(n,i)}}function k(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return O.apply(void 0,e([function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];return new(o.bind.apply(o,e([void 0],n,!1)))}],n,!1))}function w(o,n,t){for(var r,e,i,l={module:n,options:null!=t?t:{}},u=new Set([l]),a=[l],c=0;c<a.length;){null===(r=(v="module"in(f=a[c])?f.module:f).imports)||void 0===r||r.forEach((function(o){u.has(o)||(u.add(o),a.push(o))})),c++}for(var s=0;s<a.length;s++){null===(e=(v="module"in(f=a[s])?f.module:f).beforeBinding)||void 0===e||e.call(v,o)}for(s=0;s<a.length;s++){j(o,f=a[s])}for(s=a.length-1;s>=0;s--){var f,v;null===(i=(v="module"in(f=a[s])?f.module:f).afterBinding)||void 0===i||i.call(v,o)}}function j(o,n){var t,r;"module"in n?(t=n.module,r=n.options):t=n;var e=null==r?void 0:r.scope,i=new Set,l=t.exports;l&&Object.keys(l).forEach((function(n){var r=l[n];r&&(i.add(r),o.bindFactory(r,O((function(o){return o[n]}),t.token),{scope:e}))}));o.bindFactory(t.token,t.factory,{scope:e,onRemoved:function(n){n.destroy&&n.destroy(),i.forEach((function(n){return o.remove(n)})),i.clear()}})}function E(o,n){n.forEach((function(n){"module"in n?w(o,n.module,n.options):w(o,n)}))}function _(n){var t;return r(r({},n),{token:null!==(t=n.token)&&void 0!==t?t:o()})}function x(o){return _({factory:function(){return{}},imports:o})}export{i as ResolverError,w as bindModule,E as bindModules,d as bindMultiValue,p as createContainer,_ as declareModule,x as declareModuleBindings,O as injectable,k as injectableClass,y as isToken,n as optional,h as resolveValue,g as resolveValues,o as token,m as tryResolveValue,b as tryResolveValues};
2
2
  //# sourceMappingURL=index.js.map
@@ -13,8 +13,8 @@ export type FactoryScope = 'scoped' | 'singleton' | 'transient';
13
13
  * Options for factory binding.
14
14
  *
15
15
  * `scope` types:
16
- * - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
17
- * - `scoped` - The value is created and cached by the container which starts resolving.
16
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
17
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
18
18
  * - `transient` - The value is created every time it is resolved.
19
19
  *
20
20
  * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.
@@ -67,8 +67,6 @@ export declare const RESOLVER: Token<Resolver>;
67
67
  /** @internal */
68
68
  declare const NOT_FOUND: unique symbol;
69
69
  /** @internal */
70
- export declare const FAKE_FACTORY: () => never;
71
- /** @internal */
72
70
  type FactoryContext<T> = {
73
71
  factory: (container: Container) => T;
74
72
  options?: FactoryOptions<T>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createContainer = exports.FACTORIES_MAP = exports.FAKE_FACTORY = exports.RESOLVER = exports.PARENT_CONTAINER = exports.CONTAINER = exports.ResolverError = void 0;
3
+ exports.createContainer = exports.FACTORIES_MAP = exports.RESOLVER = exports.PARENT_CONTAINER = exports.CONTAINER = exports.ResolverError = void 0;
4
4
  const tokens_1 = require("./tokens");
5
5
  /**
6
6
  * ResolverError is thrown by the resolver when a token is not found in a container.
@@ -22,11 +22,6 @@ exports.RESOLVER = (0, tokens_1.token)('ditox.Resolver');
22
22
  /** @internal */
23
23
  const NOT_FOUND = Symbol();
24
24
  /** @internal */
25
- const FAKE_FACTORY = () => {
26
- throw new Error('FAKE_FACTORY');
27
- };
28
- exports.FAKE_FACTORY = FAKE_FACTORY;
29
- /** @internal */
30
25
  const DEFAULT_SCOPE = 'singleton';
31
26
  /** @internal */
32
27
  exports.FACTORIES_MAP = (0, tokens_1.token)('ditox.FactoriesMap');
@@ -129,7 +124,7 @@ function createContainer(parentContainer) {
129
124
  return value;
130
125
  }
131
126
  const factoryContext = factories.get(token.symbol);
132
- if (factoryContext && factoryContext.factory !== exports.FAKE_FACTORY) {
127
+ if (factoryContext) {
133
128
  const scope = getScope(factoryContext.options);
134
129
  switch (scope) {
135
130
  case 'singleton': {
@@ -147,14 +142,15 @@ function createContainer(parentContainer) {
147
142
  }
148
143
  }
149
144
  case 'scoped': {
150
- // Create a value within the origin container and cache it.
151
- const value = factoryContext.factory(origin);
152
- origin.bindValue(token, value);
153
- if (origin !== container) {
154
- // Bind a fake factory with actual options to make onRemoved() works.
155
- origin.bindFactory(token, exports.FAKE_FACTORY, factoryContext.options);
145
+ if (hasValue) {
146
+ return value;
147
+ }
148
+ else {
149
+ // Create a value within the factory's container and cache it.
150
+ const value = factoryContext.factory(container);
151
+ container.bindValue(token, value);
152
+ return value;
156
153
  }
157
- return value;
158
154
  }
159
155
  case 'transient': {
160
156
  // Create a value within the origin container and don't cache it.
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":";;;AAAA,qCAAsC;AAEtC;;GAEG;AACH,MAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAND,sCAMC;AAsED,gBAAgB;AACH,QAAA,SAAS,GAAqB,IAAA,cAAK,EAAC,iBAAiB,CAAC,CAAC;AACpE,gBAAgB;AACH,QAAA,gBAAgB,GAAqB,IAAA,cAAK,EACrD,uBAAuB,CACxB,CAAC;AACF,gBAAgB;AACH,QAAA,QAAQ,GAAoB,IAAA,cAAK,EAAC,gBAAgB,CAAC,CAAC;AAEjE,gBAAgB;AAChB,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC;AAE3B,gBAAgB;AAChB,MAAM,aAAa,GAAiB,WAAW,CAAC;AAchD,gBAAgB;AACH,QAAA,aAAa,GAAwB,IAAA,cAAK,EAAC,oBAAoB,CAAC,CAAC;AAK9E,gBAAgB;AAChB,SAAS,QAAQ,CAAI,OAA2B;;IAC9C,OAAO,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,mCAAI,aAAa,CAAC;AACzC,CAAC;AAED,gBAAgB;AAChB,SAAS,YAAY,CAAI,OAA0B;IACjD,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS;QAChC,OAAO,CAAC,KAAK,KAAK,QAAQ;QAC1B,OAAO,CAAC,KAAK,KAAK,WAAW;QAC7B,CAAC,CAAC,OAAO,CAAC,SAAS;QACnB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,gBAAgB;AAChB,SAAS,eAAe,CAAI,KAAe;IACzC,OAAO,CACL,KAAK,CAAC,MAAM,KAAK,iBAAS,CAAC,MAAM;QACjC,KAAK,CAAC,MAAM,KAAK,wBAAgB,CAAC,MAAM;QACxC,KAAK,CAAC,MAAM,KAAK,gBAAQ,CAAC,MAAM,CACjC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,eAA2B;IACzD,MAAM,MAAM,GAAc,IAAI,GAAG,EAAe,CAAC;IACjD,MAAM,SAAS,GAAiB,IAAI,GAAG,EAA+B,CAAC;IAEvE,MAAM,SAAS,GAAc;QAC3B,SAAS,CAAI,KAAe,EAAE,KAAQ;YACpC,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE;gBAC1B,OAAO;aACR;YAED,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QAED,WAAW,CACT,KAAe,EACf,OAAoC,EACpC,OAA2B;YAE3B,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE;gBAC1B,OAAO;aACR;YAED,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAC,OAAO,EAAE,OAAO,EAAC,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,CAAI,KAAe;;YACvB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE;gBAC1B,OAAO;aACR;YAED,MAAM,OAAO,GAAG,MAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,0CAAE,OAAO,CAAC;YACrD,IAAI,OAAO,EAAE;gBACX,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACzC;YAED,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5B,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAED,SAAS;YACP,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE;gBACzC,IAAI,OAAO,CAAC,OAAO,EAAE;oBACnB,gBAAgB,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;iBAChD;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,kBAAkB,EAAE,CAAC;QACvB,CAAC;QAED,QAAQ,CAAC,KAAqB;;YAC5B,OAAO,CACL,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;gBACxB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;gBAC3B,CAAC,MAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,CAAC,KAAK,CAAC,mCAAI,KAAK,CAAC,CAC5C,CAAC;QACJ,CAAC;QAED,GAAG,CAAI,KAAe;YACpB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,OAAO,KAAK,CAAC;aACd;YAED,IAAI,KAAK,CAAC,UAAU,EAAE;gBACpB,OAAO,KAAK,CAAC,aAAa,CAAC;aAC5B;YAED,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,CAAI,KAAe;;YACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,OAAO,KAAK,CAAC;aACd;YAED,IAAI,KAAK,CAAC,UAAU,EAAE;gBACpB,OAAO,KAAK,CAAC,aAAa,CAAC;aAC5B;YAED,MAAM,IAAI,aAAa,CACrB,UAAU,MAAA,KAAK,CAAC,MAAM,CAAC,WAAW,mCAAI,EAAE,mBAAmB,CAC5D,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,SAAS,QAAQ,CACf,KAAe,EACf,MAAiB;QAEjB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEjE,IAAI,QAAQ,IAAI,MAAM,KAAK,SAAS,EAAE;YACpC,OAAO,KAAK,CAAC;SACd;QAED,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,cAAc,EAAE;YAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAE/C,QAAQ,KAAK,EAAE;gBACb,KAAK,WAAW,CAAC,CAAC;oBAChB,IAAI,QAAQ,EAAE;wBACZ,OAAO,KAAK,CAAC;qBACd;yBAAM,IAAI,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;wBAC3C,MAAM;qBACP;yBAAM;wBACL,yEAAyE;wBACzE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;wBAChD,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;wBAClC,OAAO,KAAK,CAAC;qBACd;iBACF;gBAED,KAAK,QAAQ,CAAC,CAAC;oBACb,IAAI,QAAQ,EAAE;wBACZ,OAAO,KAAK,CAAC;qBACd;yBAAM;wBACL,8DAA8D;wBAC9D,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;wBAChD,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;wBAClC,OAAO,KAAK,CAAC;qBACd;iBACF;gBAED,KAAK,WAAW,CAAC,CAAC;oBAChB,iEAAiE;oBACjE,OAAO,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;iBACvC;aACF;SACF;QAED,IAAI,QAAQ,EAAE;YACZ,OAAO,KAAK,CAAC;SACd;QAED,MAAM,cAAc,GAAG,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,GAAG,CAAC,gBAAQ,CAAC,CAAC;QACtD,IAAI,cAAc,EAAE;YAClB,OAAO,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SACtC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,SAAS,gBAAgB,CACvB,WAAmB,EACnB,OAA0B;QAE1B,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,SAAS,EAAE;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE;gBAClD,SAAS,CAAC,KAAK,CAAC,CAAC;aAClB;SACF;IACH,CAAC;IAED,SAAS,kBAAkB;QACzB,MAAM,CAAC,GAAG,CAAC,iBAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,gBAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,qBAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAE5C,IAAI,eAAe,EAAE;YACnB,MAAM,CAAC,GAAG,CAAC,wBAAgB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;SACtD;IACH,CAAC;IAED,kBAAkB,EAAE,CAAC;IACrB,OAAO,SAAS,CAAC;AACnB,CAAC;AA5KD,0CA4KC"}
@@ -59,16 +59,17 @@ export type AnyModuleDeclaration = ModuleDeclaration<Module<AnyObject>>;
59
59
  * Options for module binding.
60
60
  *
61
61
  * `scope` types:
62
- * - `singleton` - **This is the default**. The module is created and cached by the container which registered the factory.
63
- * - `scoped` - The module is created and cached by the container which starts resolving.
62
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
63
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
64
64
  */
65
65
  export type BindModuleOptions = {
66
66
  scope?: 'scoped' | 'singleton';
67
67
  };
68
- export type ModuleBindingEntry = ModuleDeclaration<AnyObject> | {
68
+ type ModuleDeclarationWithOptions = {
69
69
  module: ModuleDeclaration<AnyObject>;
70
70
  options: BindModuleOptions;
71
71
  };
72
+ export type ModuleBindingEntry = ModuleDeclaration<AnyObject> | ModuleDeclarationWithOptions;
72
73
  /**
73
74
  * Binds the dependency module to the container
74
75
  * @param container - Dependency container.
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.declareModuleBindings = exports.declareModule = exports.bindModules = exports.bindModule = void 0;
4
- const utils_1 = require("./utils");
5
4
  const tokens_1 = require("./tokens");
5
+ const utils_1 = require("./utils");
6
6
  /**
7
7
  * Binds the dependency module to the container
8
8
  * @param container - Dependency container.
@@ -15,41 +15,75 @@ const tokens_1 = require("./tokens");
15
15
  * ```
16
16
  */
17
17
  function bindModule(container, moduleDeclaration, options) {
18
- const { token, imports, factory, beforeBinding, afterBinding } = moduleDeclaration;
19
- const exports = moduleDeclaration.exports;
20
- const scope = options === null || options === void 0 ? void 0 : options.scope;
21
- if (beforeBinding) {
22
- beforeBinding(container);
18
+ var _a, _b, _c;
19
+ const rootEntry = {
20
+ module: moduleDeclaration,
21
+ options: options !== null && options !== void 0 ? options : {},
22
+ };
23
+ const bfsVisits = new Set([rootEntry]);
24
+ const bfsQueue = [rootEntry];
25
+ let bfsIndex = 0;
26
+ while (bfsIndex < bfsQueue.length) {
27
+ const entry = bfsQueue[bfsIndex];
28
+ const m = 'module' in entry ? entry.module : entry;
29
+ (_a = m.imports) === null || _a === void 0 ? void 0 : _a.forEach((depEntry) => {
30
+ if (!bfsVisits.has(depEntry)) {
31
+ bfsVisits.add(depEntry);
32
+ bfsQueue.push(depEntry);
33
+ }
34
+ });
35
+ bfsIndex++;
36
+ }
37
+ for (let i = 0; i < bfsQueue.length; i++) {
38
+ const entry = bfsQueue[i];
39
+ const m = 'module' in entry ? entry.module : entry;
40
+ (_b = m.beforeBinding) === null || _b === void 0 ? void 0 : _b.call(m, container);
41
+ }
42
+ for (let i = 0; i < bfsQueue.length; i++) {
43
+ const entry = bfsQueue[i];
44
+ bindModuleEntry(container, entry);
23
45
  }
24
- if (imports) {
25
- bindModules(container, imports);
46
+ for (let i = bfsQueue.length - 1; i >= 0; i--) {
47
+ const entry = bfsQueue[i];
48
+ const m = 'module' in entry ? entry.module : entry;
49
+ (_c = m.afterBinding) === null || _c === void 0 ? void 0 : _c.call(m, container);
26
50
  }
51
+ }
52
+ exports.bindModule = bindModule;
53
+ function bindModuleEntry(container, entry) {
54
+ let module;
55
+ let options;
56
+ if ('module' in entry) {
57
+ module = entry.module;
58
+ options = entry.options;
59
+ }
60
+ else {
61
+ module = entry;
62
+ }
63
+ const scope = options === null || options === void 0 ? void 0 : options.scope;
27
64
  const exportedValueTokens = new Set();
28
- if (exports) {
29
- const keys = Object.keys(exports);
65
+ const moduleExports = module.exports;
66
+ if (moduleExports) {
67
+ const keys = Object.keys(moduleExports);
30
68
  keys.forEach((valueKey) => {
31
- const valueToken = exports[valueKey];
69
+ const valueToken = moduleExports[valueKey];
32
70
  if (valueToken) {
33
71
  exportedValueTokens.add(valueToken);
34
- container.bindFactory(valueToken, (0, utils_1.injectable)((module) => module[valueKey], token), { scope });
72
+ container.bindFactory(valueToken, (0, utils_1.injectable)((module) => module[valueKey], module.token), { scope });
35
73
  }
36
74
  });
37
75
  }
38
- container.bindFactory(token, factory, {
76
+ container.bindFactory(module.token, module.factory, {
39
77
  scope,
40
- onRemoved: (module) => {
41
- if (module.destroy) {
42
- module.destroy();
78
+ onRemoved: (moduleInstance) => {
79
+ if (moduleInstance.destroy) {
80
+ moduleInstance.destroy();
43
81
  }
44
82
  exportedValueTokens.forEach((valueToken) => container.remove(valueToken));
45
83
  exportedValueTokens.clear();
46
84
  },
47
85
  });
48
- if (afterBinding) {
49
- afterBinding(container);
50
- }
51
86
  }
52
- exports.bindModule = bindModule;
53
87
  /**
54
88
  * Binds dependency modules to the container
55
89
  *
@@ -1 +1 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/modules.ts"],"names":[],"mappings":";;;AACA,mCAAmC;AACnC,qCAAsC;AAuFtC;;;;;;;;;;GAUG;AACH,SAAgB,UAAU,CACxB,SAAoB,EACpB,iBAAuC,EACvC,OAA2B;IAE3B,MAAM,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAC,GAC1D,iBAAiB,CAAC;IACpB,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC;IAE1C,MAAM,KAAK,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAC;IAE7B,IAAI,aAAa,EAAE;QACjB,aAAa,CAAC,SAAS,CAAC,CAAC;KAC1B;IAED,IAAI,OAAO,EAAE;QACX,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KACjC;IAED,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEtD,IAAI,OAAO,EAAE;QACX,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAElC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YACxB,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,UAAU,EAAE;gBACd,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAEpC,SAAS,CAAC,WAAW,CACnB,UAAU,EACV,IAAA,kBAAU,EAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,EAC/C,EAAC,KAAK,EAAC,CACR,CAAC;aACH;QACH,CAAC,CAAC,CAAC;KACJ;IAED,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE;QACpC,KAAK;QACL,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACpB,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,CAAC,OAAO,EAAE,CAAC;aAClB;YAED,mBAAmB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1E,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC9B,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,YAAY,EAAE;QAChB,YAAY,CAAC,SAAS,CAAC,CAAC;KACzB;AACH,CAAC;AArDD,gCAqDC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,SAAoB,EACpB,OAA0C;IAE1C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,IAAI,QAAQ,IAAI,KAAK,EAAE;YACrB,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;SACpD;aAAM;YACL,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAXD,kCAWC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,aAAa,CAC3B,WAC8C;;IAE9C,OAAO,EAAC,GAAG,WAAW,EAAE,KAAK,EAAE,MAAA,WAAW,CAAC,KAAK,mCAAI,IAAA,cAAK,GAAE,EAAC,CAAC;AAC/D,CAAC;AALD,sCAKC;AAED;;;;GAIG;AACH,SAAgB,qBAAqB,CACnC,OAA0C;IAE1C,OAAO,aAAa,CAAC;QACnB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;AACL,CAAC;AAPD,sDAOC"}
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/modules.ts"],"names":[],"mappings":"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"}
@@ -13,8 +13,8 @@ export type FactoryScope = 'scoped' | 'singleton' | 'transient';
13
13
  * Options for factory binding.
14
14
  *
15
15
  * `scope` types:
16
- * - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
17
- * - `scoped` - The value is created and cached by the container which starts resolving.
16
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
17
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
18
18
  * - `transient` - The value is created every time it is resolved.
19
19
  *
20
20
  * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.
@@ -67,8 +67,6 @@ export declare const RESOLVER: Token<Resolver>;
67
67
  /** @internal */
68
68
  declare const NOT_FOUND: unique symbol;
69
69
  /** @internal */
70
- export declare const FAKE_FACTORY: () => never;
71
- /** @internal */
72
70
  type FactoryContext<T> = {
73
71
  factory: (container: Container) => T;
74
72
  options?: FactoryOptions<T>;
@@ -18,10 +18,6 @@ export const RESOLVER = token('ditox.Resolver');
18
18
  /** @internal */
19
19
  const NOT_FOUND = Symbol();
20
20
  /** @internal */
21
- export const FAKE_FACTORY = () => {
22
- throw new Error('FAKE_FACTORY');
23
- };
24
- /** @internal */
25
21
  const DEFAULT_SCOPE = 'singleton';
26
22
  /** @internal */
27
23
  export const FACTORIES_MAP = token('ditox.FactoriesMap');
@@ -124,7 +120,7 @@ export function createContainer(parentContainer) {
124
120
  return value;
125
121
  }
126
122
  const factoryContext = factories.get(token.symbol);
127
- if (factoryContext && factoryContext.factory !== FAKE_FACTORY) {
123
+ if (factoryContext) {
128
124
  const scope = getScope(factoryContext.options);
129
125
  switch (scope) {
130
126
  case 'singleton': {
@@ -142,14 +138,15 @@ export function createContainer(parentContainer) {
142
138
  }
143
139
  }
144
140
  case 'scoped': {
145
- // Create a value within the origin container and cache it.
146
- const value = factoryContext.factory(origin);
147
- origin.bindValue(token, value);
148
- if (origin !== container) {
149
- // Bind a fake factory with actual options to make onRemoved() works.
150
- origin.bindFactory(token, FAKE_FACTORY, factoryContext.options);
141
+ if (hasValue) {
142
+ return value;
143
+ }
144
+ else {
145
+ // Create a value within the factory's container and cache it.
146
+ const value = factoryContext.factory(container);
147
+ container.bindValue(token, value);
148
+ return value;
151
149
  }
152
- return value;
153
150
  }
154
151
  case 'transient': {
155
152
  // Create a value within the origin container and don't cache it.
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
@@ -59,16 +59,17 @@ export type AnyModuleDeclaration = ModuleDeclaration<Module<AnyObject>>;
59
59
  * Options for module binding.
60
60
  *
61
61
  * `scope` types:
62
- * - `singleton` - **This is the default**. The module is created and cached by the container which registered the factory.
63
- * - `scoped` - The module is created and cached by the container which starts resolving.
62
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
63
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
64
64
  */
65
65
  export type BindModuleOptions = {
66
66
  scope?: 'scoped' | 'singleton';
67
67
  };
68
- export type ModuleBindingEntry = ModuleDeclaration<AnyObject> | {
68
+ type ModuleDeclarationWithOptions = {
69
69
  module: ModuleDeclaration<AnyObject>;
70
70
  options: BindModuleOptions;
71
71
  };
72
+ export type ModuleBindingEntry = ModuleDeclaration<AnyObject> | ModuleDeclarationWithOptions;
72
73
  /**
73
74
  * Binds the dependency module to the container
74
75
  * @param container - Dependency container.
@@ -1,5 +1,5 @@
1
- import { injectable } from './utils';
2
1
  import { token } from './tokens';
2
+ import { injectable } from './utils';
3
3
  /**
4
4
  * Binds the dependency module to the container
5
5
  * @param container - Dependency container.
@@ -12,39 +12,73 @@ import { token } from './tokens';
12
12
  * ```
13
13
  */
14
14
  export function bindModule(container, moduleDeclaration, options) {
15
- const { token, imports, factory, beforeBinding, afterBinding } = moduleDeclaration;
16
- const exports = moduleDeclaration.exports;
17
- const scope = options === null || options === void 0 ? void 0 : options.scope;
18
- if (beforeBinding) {
19
- beforeBinding(container);
15
+ var _a, _b, _c;
16
+ const rootEntry = {
17
+ module: moduleDeclaration,
18
+ options: options !== null && options !== void 0 ? options : {},
19
+ };
20
+ const bfsVisits = new Set([rootEntry]);
21
+ const bfsQueue = [rootEntry];
22
+ let bfsIndex = 0;
23
+ while (bfsIndex < bfsQueue.length) {
24
+ const entry = bfsQueue[bfsIndex];
25
+ const m = 'module' in entry ? entry.module : entry;
26
+ (_a = m.imports) === null || _a === void 0 ? void 0 : _a.forEach((depEntry) => {
27
+ if (!bfsVisits.has(depEntry)) {
28
+ bfsVisits.add(depEntry);
29
+ bfsQueue.push(depEntry);
30
+ }
31
+ });
32
+ bfsIndex++;
33
+ }
34
+ for (let i = 0; i < bfsQueue.length; i++) {
35
+ const entry = bfsQueue[i];
36
+ const m = 'module' in entry ? entry.module : entry;
37
+ (_b = m.beforeBinding) === null || _b === void 0 ? void 0 : _b.call(m, container);
20
38
  }
21
- if (imports) {
22
- bindModules(container, imports);
39
+ for (let i = 0; i < bfsQueue.length; i++) {
40
+ const entry = bfsQueue[i];
41
+ bindModuleEntry(container, entry);
23
42
  }
43
+ for (let i = bfsQueue.length - 1; i >= 0; i--) {
44
+ const entry = bfsQueue[i];
45
+ const m = 'module' in entry ? entry.module : entry;
46
+ (_c = m.afterBinding) === null || _c === void 0 ? void 0 : _c.call(m, container);
47
+ }
48
+ }
49
+ function bindModuleEntry(container, entry) {
50
+ let module;
51
+ let options;
52
+ if ('module' in entry) {
53
+ module = entry.module;
54
+ options = entry.options;
55
+ }
56
+ else {
57
+ module = entry;
58
+ }
59
+ const scope = options === null || options === void 0 ? void 0 : options.scope;
24
60
  const exportedValueTokens = new Set();
25
- if (exports) {
26
- const keys = Object.keys(exports);
61
+ const moduleExports = module.exports;
62
+ if (moduleExports) {
63
+ const keys = Object.keys(moduleExports);
27
64
  keys.forEach((valueKey) => {
28
- const valueToken = exports[valueKey];
65
+ const valueToken = moduleExports[valueKey];
29
66
  if (valueToken) {
30
67
  exportedValueTokens.add(valueToken);
31
- container.bindFactory(valueToken, injectable((module) => module[valueKey], token), { scope });
68
+ container.bindFactory(valueToken, injectable((module) => module[valueKey], module.token), { scope });
32
69
  }
33
70
  });
34
71
  }
35
- container.bindFactory(token, factory, {
72
+ container.bindFactory(module.token, module.factory, {
36
73
  scope,
37
- onRemoved: (module) => {
38
- if (module.destroy) {
39
- module.destroy();
74
+ onRemoved: (moduleInstance) => {
75
+ if (moduleInstance.destroy) {
76
+ moduleInstance.destroy();
40
77
  }
41
78
  exportedValueTokens.forEach((valueToken) => container.remove(valueToken));
42
79
  exportedValueTokens.clear();
43
80
  },
44
81
  });
45
- if (afterBinding) {
46
- afterBinding(container);
47
- }
48
82
  }
49
83
  /**
50
84
  * Binds dependency modules to the container
@@ -1 +1 @@
1
- {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/modules.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAQ,KAAK,EAAC,MAAM,UAAU,CAAC;AAuFtC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CACxB,SAAoB,EACpB,iBAAuC,EACvC,OAA2B;IAE3B,MAAM,EAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAC,GAC1D,iBAAiB,CAAC;IACpB,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC;IAE1C,MAAM,KAAK,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,KAAK,CAAC;IAE7B,IAAI,aAAa,EAAE;QACjB,aAAa,CAAC,SAAS,CAAC,CAAC;KAC1B;IAED,IAAI,OAAO,EAAE;QACX,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KACjC;IAED,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEtD,IAAI,OAAO,EAAE;QACX,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAElC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YACxB,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,UAAU,EAAE;gBACd,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAEpC,SAAS,CAAC,WAAW,CACnB,UAAU,EACV,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,EAC/C,EAAC,KAAK,EAAC,CACR,CAAC;aACH;QACH,CAAC,CAAC,CAAC;KACJ;IAED,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE;QACpC,KAAK;QACL,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACpB,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,CAAC,OAAO,EAAE,CAAC;aAClB;YAED,mBAAmB,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC1E,mBAAmB,CAAC,KAAK,EAAE,CAAC;QAC9B,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,YAAY,EAAE;QAChB,YAAY,CAAC,SAAS,CAAC,CAAC;KACzB;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,SAAoB,EACpB,OAA0C;IAE1C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,IAAI,QAAQ,IAAI,KAAK,EAAE;YACrB,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;SACpD;aAAM;YACL,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,aAAa,CAC3B,WAC8C;;IAE9C,OAAO,EAAC,GAAG,WAAW,EAAE,KAAK,EAAE,MAAA,WAAW,CAAC,KAAK,mCAAI,KAAK,EAAE,EAAC,CAAC;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA0C;IAE1C,OAAO,aAAa,CAAC;QACnB,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"modules.js","sourceRoot":"","sources":["../../src/modules.ts"],"names":[],"mappings":"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"}
@@ -69,8 +69,8 @@ type FactoryScope = 'scoped' | 'singleton' | 'transient';
69
69
  * Options for factory binding.
70
70
  *
71
71
  * `scope` types:
72
- * - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
73
- * - `scoped` - The value is created and cached by the container which starts resolving.
72
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
73
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
74
74
  * - `transient` - The value is created every time it is resolved.
75
75
  *
76
76
  * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.
@@ -316,16 +316,17 @@ type ModuleDeclaration<T extends Module<AnyObject>> = {
316
316
  * Options for module binding.
317
317
  *
318
318
  * `scope` types:
319
- * - `singleton` - **This is the default**. The module is created and cached by the container which registered the factory.
320
- * - `scoped` - The module is created and cached by the container which starts resolving.
319
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
320
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
321
321
  */
322
322
  type BindModuleOptions = {
323
323
  scope?: 'scoped' | 'singleton';
324
324
  };
325
- type ModuleBindingEntry = ModuleDeclaration<AnyObject> | {
325
+ type ModuleDeclarationWithOptions = {
326
326
  module: ModuleDeclaration<AnyObject>;
327
327
  options: BindModuleOptions;
328
328
  };
329
+ type ModuleBindingEntry = ModuleDeclaration<AnyObject> | ModuleDeclarationWithOptions;
329
330
  /**
330
331
  * Binds the dependency module to the container
331
332
  * @param container - Dependency container.
package/dist/umd/index.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(o,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((o="undefined"!=typeof globalThis?globalThis:o||self).Ditox={})}(this,(function(o){"use strict";function n(o){var n="string"==typeof o?{description:o}:o;return{symbol:(null==n?void 0:n.key)?Symbol.for(n.key):Symbol(null==n?void 0:n.description)}}var t=function(o,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n}||function(o,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(o[t]=n[t])},t(o,n)};var e=function(){return e=Object.assign||function(o){for(var n,t=1,e=arguments.length;t<e;t++)for(var r in n=arguments[t])Object.prototype.hasOwnProperty.call(n,r)&&(o[r]=n[r]);return o},e.apply(this,arguments)};function r(o,n,t){if(t||2===arguments.length)for(var e,r=0,i=n.length;r<i;r++)!e&&r in n||(e||(e=Array.prototype.slice.call(n,0,r)),e[r]=n[r]);return o.concat(e||Array.prototype.slice.call(n))}var i=function(o){function n(n){var t=this.constructor,e=o.call(this,n)||this;return Object.setPrototypeOf(e,t.prototype),e.name="ResolverError",e}return function(o,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function e(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(e.prototype=n.prototype,new e)}(n,o),n}(Error),l=n("ditox.Container"),u=n("ditox.ParentContainer"),a=n("ditox.Resolver"),s=Symbol(),c=function(){throw new Error("FAKE_FACTORY")},f="singleton",y=n("ditox.FactoriesMap");function p(o){return o.symbol===l.symbol||o.symbol===u.symbol||o.symbol===a.symbol}function d(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function v(o,n){if(d(n))return o.get(n);var t={};return Object.keys(n).forEach((function(e){return t[e]=o.get(n[e])})),t}function b(o,n){if(d(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(e){return t[e]=o.resolve(n[e])})),t}function m(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return b(o,n)}))}function h(o){for(var n=this,t=[],e=1;e<arguments.length;e++)t[e-1]=arguments[e];return function(e){var i=m.apply(void 0,r([e],t,!1));return o.apply(n,i)}}function g(o,n,t){var e=n.token,r=n.imports,i=n.factory,l=n.beforeBinding,u=n.afterBinding,a=n.exports,s=null==t?void 0:t.scope;l&&l(o),r&&O(o,r);var c=new Set;a&&Object.keys(a).forEach((function(n){var t=a[n];t&&(c.add(t),o.bindFactory(t,h((function(o){return o[n]}),e),{scope:s}))}));o.bindFactory(e,i,{scope:s,onRemoved:function(n){n.destroy&&n.destroy(),c.forEach((function(n){return o.remove(n)})),c.clear()}}),u&&u(o)}function O(o,n){n.forEach((function(n){"module"in n?g(o,n.module,n.options):g(o,n)}))}function k(o){var t;return e(e({},o),{token:null!==(t=o.token)&&void 0!==t?t:n()})}o.ResolverError=i,o.bindModule=g,o.bindModules=O,o.bindMultiValue=function(o,n,t){var e,i=r(r([],null!==(e=o.get(n))&&void 0!==e?e:[],!0),[t],!1);o.bindValue(n,i)},o.createContainer=function(o){var n=new Map,t=new Map,e={bindValue:function(o,t){p(o)||n.set(o.symbol,t)},bindFactory:function(o,n,e){p(o)||t.set(o.symbol,{factory:n,options:e})},remove:function(o){var e;if(!p(o)){var r=null===(e=t.get(o.symbol))||void 0===e?void 0:e.options;r&&d(o.symbol,r),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&d(n,o.options)})),n.clear(),t.clear(),v()},hasToken:function(e){var r;return n.has(e.symbol)||t.has(e.symbol)||null!==(r=null==o?void 0:o.hasToken(e))&&void 0!==r&&r},get:function(o){var n=r(o,e);return n!==s?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=r(o,e);if(t!==s)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function r(r,i){var l=n.get(r.symbol),u=void 0!==l||n.has(r.symbol);if(u&&i===e)return l;var y,p,d=t.get(r.symbol);if(d&&d.factory!==c)switch(y=d.options,null!==(p=null==y?void 0:y.scope)&&void 0!==p?p:f){case"singleton":if(u)return l;if(null==o?void 0:o.hasToken(r))break;var v=d.factory(e);return e.bindValue(r,v),v;case"scoped":var b=d.factory(i);return i.bindValue(r,b),i!==e&&i.bindFactory(r,c,d.options),b;case"transient":return d.factory(i)}if(u)return l;var m=null==o?void 0:o.get(a);return m?m(r,i):s}function d(o,t){var e=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(e){var r=n.get(o);(void 0!==r||n.has(o))&&e(r)}}function v(){n.set(l.symbol,e),n.set(a.symbol,r),n.set(y.symbol,t),o&&n.set(u.symbol,o)}return v(),e},o.declareModule=k,o.declareModuleBindings=function(o){return k({factory:function(){return{}},imports:o})},o.injectable=h,o.injectableClass=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return h.apply(void 0,r([function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];return new(o.bind.apply(o,r([void 0],n,!1)))}],n,!1))},o.isToken=d,o.optional=function(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}},o.resolveValue=b,o.resolveValues=m,o.token=n,o.tryResolveValue=v,o.tryResolveValues=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return v(o,n)}))}}));
1
+ !function(o,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((o="undefined"!=typeof globalThis?globalThis:o||self).Ditox={})}(this,(function(o){"use strict";function n(o){var n="string"==typeof o?{description:o}:o;return{symbol:(null==n?void 0:n.key)?Symbol.for(n.key):Symbol(null==n?void 0:n.description)}}var t=function(o,n){return t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(o,n){o.__proto__=n}||function(o,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(o[t]=n[t])},t(o,n)};var e=function(){return e=Object.assign||function(o){for(var n,t=1,e=arguments.length;t<e;t++)for(var r in n=arguments[t])Object.prototype.hasOwnProperty.call(n,r)&&(o[r]=n[r]);return o},e.apply(this,arguments)};function r(o,n,t){if(t||2===arguments.length)for(var e,r=0,i=n.length;r<i;r++)!e&&r in n||(e||(e=Array.prototype.slice.call(n,0,r)),e[r]=n[r]);return o.concat(e||Array.prototype.slice.call(n))}var i=function(o){function n(n){var t=this.constructor,e=o.call(this,n)||this;return Object.setPrototypeOf(e,t.prototype),e.name="ResolverError",e}return function(o,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function e(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(e.prototype=n.prototype,new e)}(n,o),n}(Error),l=n("ditox.Container"),u=n("ditox.ParentContainer"),a=n("ditox.Resolver"),s=Symbol(),c="singleton",f=n("ditox.FactoriesMap");function d(o){return o.symbol===l.symbol||o.symbol===u.symbol||o.symbol===a.symbol}function p(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function v(o,n){if(p(n))return o.get(n);var t={};return Object.keys(n).forEach((function(e){return t[e]=o.get(n[e])})),t}function y(o,n){if(p(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(e){return t[e]=o.resolve(n[e])})),t}function b(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return y(o,n)}))}function m(o){for(var n=this,t=[],e=1;e<arguments.length;e++)t[e-1]=arguments[e];return function(e){var i=b.apply(void 0,r([e],t,!1));return o.apply(n,i)}}function h(o,n,t){for(var e,r,i,l={module:n,options:null!=t?t:{}},u=new Set([l]),a=[l],s=0;s<a.length;){null===(e=(d="module"in(f=a[s])?f.module:f).imports)||void 0===e||e.forEach((function(o){u.has(o)||(u.add(o),a.push(o))})),s++}for(var c=0;c<a.length;c++){null===(r=(d="module"in(f=a[c])?f.module:f).beforeBinding)||void 0===r||r.call(d,o)}for(c=0;c<a.length;c++){g(o,f=a[c])}for(c=a.length-1;c>=0;c--){var f,d;null===(i=(d="module"in(f=a[c])?f.module:f).afterBinding)||void 0===i||i.call(d,o)}}function g(o,n){var t,e;"module"in n?(t=n.module,e=n.options):t=n;var r=null==e?void 0:e.scope,i=new Set,l=t.exports;l&&Object.keys(l).forEach((function(n){var e=l[n];e&&(i.add(e),o.bindFactory(e,m((function(o){return o[n]}),t.token),{scope:r}))}));o.bindFactory(t.token,t.factory,{scope:r,onRemoved:function(n){n.destroy&&n.destroy(),i.forEach((function(n){return o.remove(n)})),i.clear()}})}function k(o){var t;return e(e({},o),{token:null!==(t=o.token)&&void 0!==t?t:n()})}o.ResolverError=i,o.bindModule=h,o.bindModules=function(o,n){n.forEach((function(n){"module"in n?h(o,n.module,n.options):h(o,n)}))},o.bindMultiValue=function(o,n,t){var e,i=r(r([],null!==(e=o.get(n))&&void 0!==e?e:[],!0),[t],!1);o.bindValue(n,i)},o.createContainer=function(o){var n=new Map,t=new Map,e={bindValue:function(o,t){d(o)||n.set(o.symbol,t)},bindFactory:function(o,n,e){d(o)||t.set(o.symbol,{factory:n,options:e})},remove:function(o){var e;if(!d(o)){var r=null===(e=t.get(o.symbol))||void 0===e?void 0:e.options;r&&p(o.symbol,r),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&p(n,o.options)})),n.clear(),t.clear(),v()},hasToken:function(e){var r;return n.has(e.symbol)||t.has(e.symbol)||null!==(r=null==o?void 0:o.hasToken(e))&&void 0!==r&&r},get:function(o){var n=r(o,e);return n!==s?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=r(o,e);if(t!==s)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function r(r,i){var l=n.get(r.symbol),u=void 0!==l||n.has(r.symbol);if(u&&i===e)return l;var f,d,p=t.get(r.symbol);if(p)switch(f=p.options,null!==(d=null==f?void 0:f.scope)&&void 0!==d?d:c){case"singleton":if(u)return l;if(null==o?void 0:o.hasToken(r))break;var v=p.factory(e);return e.bindValue(r,v),v;case"scoped":if(u)return l;var y=p.factory(e);return e.bindValue(r,y),y;case"transient":return p.factory(i)}if(u)return l;var b=null==o?void 0:o.get(a);return b?b(r,i):s}function p(o,t){var e=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(e){var r=n.get(o);(void 0!==r||n.has(o))&&e(r)}}function v(){n.set(l.symbol,e),n.set(a.symbol,r),n.set(f.symbol,t),o&&n.set(u.symbol,o)}return v(),e},o.declareModule=k,o.declareModuleBindings=function(o){return k({factory:function(){return{}},imports:o})},o.injectable=m,o.injectableClass=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return m.apply(void 0,r([function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];return new(o.bind.apply(o,r([void 0],n,!1)))}],n,!1))},o.isToken=p,o.optional=function(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}},o.resolveValue=y,o.resolveValues=b,o.token=n,o.tryResolveValue=v,o.tryResolveValues=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return v(o,n)}))}}));
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ditox",
3
- "version": "2.4.0",
3
+ "version": "3.0.0",
4
4
  "description": "Dependency injection for modular web applications",
5
5
  "license": "MIT",
6
6
  "author": "Mikhail Nasyrov <mikhail@mnasyrov.com> (https://github.com/mnasyrov)",
@@ -45,12 +45,11 @@
45
45
  ],
46
46
  "scripts": {
47
47
  "clean": "shx rm -rf dist lib",
48
- "test-deno": "npm run build:rollup && deno test test-deno",
49
48
  "build": "npm run build:cjs && npm run build:esm && npm run build:rollup",
50
49
  "build:cjs": "tsc -p tsconfig.build.json --outDir dist/cjs --module commonjs",
51
50
  "build:esm": "tsc -p tsconfig.build.json --outDir dist/esm --module es2015",
52
51
  "build:rollup": "rollup -c",
53
52
  "typedoc": "typedoc"
54
53
  },
55
- "gitHead": "5513ee17c51764aad180d434c1728f680e563e06"
54
+ "gitHead": "886d98ce7e8c78ba1392b36651f4e242f611a637"
56
55
  }
@@ -1,13 +1,11 @@
1
1
  import {
2
2
  CONTAINER,
3
3
  createContainer,
4
- FACTORIES_MAP,
5
- FAKE_FACTORY,
6
4
  PARENT_CONTAINER,
7
5
  ResolverError,
8
6
  } from './container';
9
- import {injectable} from './utils';
10
7
  import {optional, token} from './tokens';
8
+ import {injectable} from './utils';
11
9
 
12
10
  const NUMBER = token<number>('number');
13
11
  const STRING = token<string>('string');
@@ -120,24 +118,40 @@ describe('Container', () => {
120
118
  scope: 'scoped',
121
119
  });
122
120
 
123
- expect(container.get(NUMBER)).toBe(21);
124
- expect(container.get(NUMBER)).toBe(21);
125
- expect(parent.get(NUMBER)).toBe(12);
126
- expect(container.get(NUMBER)).toBe(21);
121
+ expect(container.get(NUMBER)).toBe(11);
122
+ expect(container.get(NUMBER)).toBe(11);
123
+ expect(parent.get(NUMBER)).toBe(11);
124
+ expect(container.get(NUMBER)).toBe(11);
125
+
126
+ expect(factory).toBeCalledTimes(1);
127
+ });
128
+
129
+ it('should inherit a factory with "scoped" scope', async () => {
130
+ const parentParent = createContainer();
131
+ let counter = 0;
132
+ const factory = jest.fn(() => ++counter);
133
+
134
+ parentParent.bindFactory(NUMBER, factory);
135
+
136
+ expect(parentParent.get(NUMBER)).toBe(1);
137
+
138
+ const parent = createContainer(parentParent);
139
+
140
+ parent.bindFactory(NUMBER, injectable(factory), {
141
+ scope: 'scoped',
142
+ });
143
+
144
+ expect(parent.get(NUMBER)).toBe(2);
145
+
146
+ const container = createContainer(parent);
147
+
148
+ expect(container.get(NUMBER)).toBe(2);
149
+ expect(parent.get(NUMBER)).toBe(2);
127
150
 
128
151
  expect(factory).toBeCalledTimes(2);
129
152
 
130
- // Check for using the internal FAKE_FACTORY
131
- const internalFactories = container.resolve(FACTORIES_MAP);
132
- const fakeContext = internalFactories.get(NUMBER.symbol);
133
- expect(fakeContext?.factory).toBe(FAKE_FACTORY);
134
- expect(() => fakeContext?.factory?.(container)).toThrowError(
135
- 'FAKE_FACTORY',
136
- );
137
- const internalOnRemoved =
138
- fakeContext?.options?.scope === 'scoped' &&
139
- fakeContext?.options?.onRemoved;
140
- expect(internalOnRemoved).toBeUndefined();
153
+ container.removeAll();
154
+ expect(parent.get(NUMBER)).toBe(2);
141
155
  });
142
156
 
143
157
  it('should bind a factory with "singleton" scope by default', () => {
@@ -165,6 +179,9 @@ describe('Container', () => {
165
179
  const container1 = createContainer(parent);
166
180
  const container2 = createContainer(parent);
167
181
  const container3 = createContainer(parent);
182
+ const childContainer1 = createContainer(container1);
183
+ const childContainer2 = createContainer(container2);
184
+ const childContainer3 = createContainer(container3);
168
185
 
169
186
  const START = token<number>();
170
187
  parent.bindValue(START, 0);
@@ -178,13 +195,33 @@ describe('Container', () => {
178
195
  scope: 'scoped',
179
196
  });
180
197
 
181
- expect(container1.get(NUMBER)).toBe(11);
198
+ container1.bindFactory(NUMBER, injectable(factory, START), {
199
+ scope: 'scoped',
200
+ });
201
+
202
+ container2.bindFactory(NUMBER, injectable(factory, START), {
203
+ scope: 'scoped',
204
+ });
205
+
206
+ container3.bindFactory(NUMBER, injectable(factory, START), {
207
+ scope: 'scoped',
208
+ });
209
+
210
+ childContainer1.bindValue(START, 1);
211
+ childContainer2.bindValue(START, 2);
212
+ childContainer3.bindValue(START, 3);
213
+
182
214
  expect(container1.get(NUMBER)).toBe(11);
183
215
  expect(container2.get(NUMBER)).toBe(22);
184
- expect(parent.get(NUMBER)).toBe(3);
216
+ expect(container3.get(NUMBER)).toBe(33);
217
+ expect(parent.get(NUMBER)).toBe(4);
185
218
  expect(container1.get(NUMBER)).toBe(11);
186
219
  expect(container2.get(NUMBER)).toBe(22);
187
- expect(container3.get(NUMBER)).toBe(34);
220
+ expect(container3.get(NUMBER)).toBe(33);
221
+
222
+ expect(childContainer1.get(NUMBER)).toBe(11);
223
+ expect(childContainer2.get(NUMBER)).toBe(22);
224
+ expect(childContainer3.get(NUMBER)).toBe(33);
188
225
 
189
226
  expect(factory).toBeCalledTimes(4);
190
227
  });
@@ -284,25 +321,13 @@ describe('Container', () => {
284
321
  parent.bindFactory(NUMBER, factory, {scope: 'scoped', onRemoved});
285
322
 
286
323
  expect(parent.get(NUMBER)).toBe(1);
287
- expect(container.get(NUMBER)).toBe(2);
288
-
289
- // Check for using the internal FAKE_FACTORY
290
- const internalFactories = container.resolve(FACTORIES_MAP);
291
- const fakeContext = internalFactories.get(NUMBER.symbol);
292
- expect(fakeContext?.factory).toBe(FAKE_FACTORY);
293
- expect(() => fakeContext?.factory?.(container)).toThrowError(
294
- 'FAKE_FACTORY',
295
- );
296
- const internalOnRemoved =
297
- fakeContext?.options?.scope === 'scoped' &&
298
- fakeContext?.options?.onRemoved;
299
- expect(internalOnRemoved).toBe(onRemoved);
324
+ expect(container.get(NUMBER)).toBe(1);
300
325
 
301
326
  // Continue the main test
302
327
  parent.remove(NUMBER);
303
328
  container.remove(NUMBER);
304
329
  expect(onRemoved).toHaveBeenNthCalledWith(1, 1);
305
- expect(onRemoved).toHaveBeenNthCalledWith(2, 2);
330
+ expect(onRemoved).toHaveBeenCalledTimes(1);
306
331
  });
307
332
 
308
333
  it('should remove "transient" factory in case its value has never been resolved', () => {
package/src/container.ts CHANGED
@@ -20,8 +20,8 @@ export type FactoryScope = 'scoped' | 'singleton' | 'transient';
20
20
  * Options for factory binding.
21
21
  *
22
22
  * `scope` types:
23
- * - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
24
- * - `scoped` - The value is created and cached by the container which starts resolving.
23
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
24
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
25
25
  * - `transient` - The value is created every time it is resolved.
26
26
  *
27
27
  * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.
@@ -91,11 +91,6 @@ export const RESOLVER: Token<Resolver> = token('ditox.Resolver');
91
91
  /** @internal */
92
92
  const NOT_FOUND = Symbol();
93
93
 
94
- /** @internal */
95
- export const FAKE_FACTORY = (): never => {
96
- throw new Error('FAKE_FACTORY');
97
- };
98
-
99
94
  /** @internal */
100
95
  const DEFAULT_SCOPE: FactoryScope = 'singleton';
101
96
 
@@ -247,7 +242,7 @@ export function createContainer(parentContainer?: Container): Container {
247
242
  }
248
243
 
249
244
  const factoryContext = factories.get(token.symbol);
250
- if (factoryContext && factoryContext.factory !== FAKE_FACTORY) {
245
+ if (factoryContext) {
251
246
  const scope = getScope(factoryContext.options);
252
247
 
253
248
  switch (scope) {
@@ -265,16 +260,14 @@ export function createContainer(parentContainer?: Container): Container {
265
260
  }
266
261
 
267
262
  case 'scoped': {
268
- // Create a value within the origin container and cache it.
269
- const value = factoryContext.factory(origin);
270
- origin.bindValue(token, value);
271
-
272
- if (origin !== container) {
273
- // Bind a fake factory with actual options to make onRemoved() works.
274
- origin.bindFactory(token, FAKE_FACTORY, factoryContext.options);
263
+ if (hasValue) {
264
+ return value;
265
+ } else {
266
+ // Create a value within the factory's container and cache it.
267
+ const value = factoryContext.factory(container);
268
+ container.bindValue(token, value);
269
+ return value;
275
270
  }
276
-
277
- return value;
278
271
  }
279
272
 
280
273
  case 'transient': {
@@ -7,8 +7,8 @@ import {
7
7
  Module,
8
8
  ModuleDeclaration,
9
9
  } from './modules';
10
- import {injectable} from './utils';
11
10
  import {token} from './tokens';
11
+ import {injectable} from './utils';
12
12
 
13
13
  describe('bindModule()', () => {
14
14
  type TestQueries = {getValue: () => number};
@@ -107,8 +107,8 @@ describe('bindModule()', () => {
107
107
  const container = createContainer(parent);
108
108
 
109
109
  bindModule(parent, MODULE, {scope: 'scoped'});
110
- expect(parent.get(MODULE_TOKEN)).not.toBe(container.get(MODULE_TOKEN));
111
- expect(parent.get(QUERIES_TOKEN)).not.toBe(container.get(QUERIES_TOKEN));
110
+ expect(parent.get(MODULE_TOKEN)).toBe(container.get(MODULE_TOKEN));
111
+ expect(parent.get(QUERIES_TOKEN)).toBe(container.get(QUERIES_TOKEN));
112
112
  });
113
113
 
114
114
  it('should remove "singleton" module when a container is cleaning', () => {
@@ -149,11 +149,12 @@ describe('bindModule()', () => {
149
149
  parent.resolve(MODULE_TOKEN);
150
150
  container.resolve(MODULE_TOKEN);
151
151
 
152
- parent.removeAll();
153
- expect(destroy).toBeCalledTimes(1);
154
-
155
152
  destroy.mockClear();
156
153
  container.removeAll();
154
+ expect(destroy).toBeCalledTimes(0);
155
+
156
+ destroy.mockClear();
157
+ parent.removeAll();
157
158
  expect(destroy).toBeCalledTimes(1);
158
159
  });
159
160
 
@@ -227,6 +228,68 @@ describe('bindModule()', () => {
227
228
  expect(container.resolve(ARG_TOKEN)).toBe('12');
228
229
  expect(container.resolve(RESULT_TOKEN)).toBe('123');
229
230
  });
231
+
232
+ it('should call beforeBinding() and afterBinding() in deep-first order', () => {
233
+ const route: string[] = [];
234
+
235
+ const declareTestModule = (
236
+ id: string,
237
+ imports?: ModuleDeclaration<Record<string, any>>[],
238
+ ) =>
239
+ declareModule({
240
+ imports,
241
+ beforeBinding: () => route.push(`${id}:before`),
242
+ factory: (container) => {
243
+ imports?.forEach((m) => container.resolve(m.token));
244
+ route.push(`${id}:factory`);
245
+ return {};
246
+ },
247
+ afterBinding: () => route.push(`${id}:after`),
248
+ });
249
+
250
+ /**
251
+ * m1
252
+ * / | \
253
+ * m2 m3 m4
254
+ * / \ \ |
255
+ * m5 m6 m7
256
+ */
257
+ const m7 = declareTestModule('m7');
258
+ const m6 = declareTestModule('m6');
259
+ const m5 = declareTestModule('m5');
260
+ const m4 = declareTestModule('m4', [m7]);
261
+ const m3 = declareTestModule('m3', [m7]);
262
+ const m2 = declareTestModule('m2', [m5, m6]);
263
+ const m1 = declareTestModule('m1', [m2, m3, m4]);
264
+
265
+ const container = createContainer();
266
+ bindModule(container, m1);
267
+ container.resolve(m1.token);
268
+
269
+ expect(route).toEqual([
270
+ 'm1:before',
271
+ 'm2:before',
272
+ 'm3:before',
273
+ 'm4:before',
274
+ 'm5:before',
275
+ 'm6:before',
276
+ 'm7:before',
277
+ 'm7:after',
278
+ 'm6:after',
279
+ 'm5:after',
280
+ 'm4:after',
281
+ 'm3:after',
282
+ 'm2:after',
283
+ 'm1:after',
284
+ 'm5:factory',
285
+ 'm6:factory',
286
+ 'm2:factory',
287
+ 'm7:factory',
288
+ 'm3:factory',
289
+ 'm4:factory',
290
+ 'm1:factory',
291
+ ]);
292
+ });
230
293
  });
231
294
 
232
295
  describe('bindModules()', () => {
package/src/modules.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import {Container} from './container';
2
- import {injectable} from './utils';
3
2
  import {Token, token} from './tokens';
3
+ import {injectable} from './utils';
4
4
 
5
5
  type AnyObject = Record<string, any>;
6
6
  type EmptyObject = Record<string, never>;
@@ -73,19 +73,21 @@ export type AnyModuleDeclaration = ModuleDeclaration<Module<AnyObject>>;
73
73
  * Options for module binding.
74
74
  *
75
75
  * `scope` types:
76
- * - `singleton` - **This is the default**. The module is created and cached by the container which registered the factory.
77
- * - `scoped` - The module is created and cached by the container which starts resolving.
76
+ * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
77
+ * - `scoped` - The value is created and cached by the nearest container which owns the factory function.
78
78
  */
79
79
  export type BindModuleOptions = {
80
80
  scope?: 'scoped' | 'singleton';
81
81
  };
82
82
 
83
+ type ModuleDeclarationWithOptions = {
84
+ module: ModuleDeclaration<AnyObject>;
85
+ options: BindModuleOptions;
86
+ };
87
+
83
88
  export type ModuleBindingEntry =
84
89
  | ModuleDeclaration<AnyObject>
85
- | {
86
- module: ModuleDeclaration<AnyObject>;
87
- options: BindModuleOptions;
88
- };
90
+ | ModuleDeclarationWithOptions;
89
91
 
90
92
  /**
91
93
  * Binds the dependency module to the container
@@ -103,54 +105,94 @@ export function bindModule<T extends Module<AnyObject>>(
103
105
  moduleDeclaration: ModuleDeclaration<T>,
104
106
  options?: BindModuleOptions,
105
107
  ): void {
106
- const {token, imports, factory, beforeBinding, afterBinding} =
107
- moduleDeclaration;
108
- const exports = moduleDeclaration.exports;
108
+ const rootEntry: ModuleBindingEntry = {
109
+ module: moduleDeclaration,
110
+ options: options ?? {},
111
+ };
109
112
 
110
- const scope = options?.scope;
113
+ const bfsVisits = new Set<ModuleBindingEntry>([rootEntry]);
114
+ const bfsQueue: ModuleBindingEntry[] = [rootEntry];
115
+
116
+ let bfsIndex = 0;
117
+ while (bfsIndex < bfsQueue.length) {
118
+ const entry = bfsQueue[bfsIndex];
119
+
120
+ const m = 'module' in entry ? entry.module : entry;
121
+
122
+ m.imports?.forEach((depEntry) => {
123
+ if (!bfsVisits.has(depEntry)) {
124
+ bfsVisits.add(depEntry);
125
+ bfsQueue.push(depEntry);
126
+ }
127
+ });
128
+
129
+ bfsIndex++;
130
+ }
131
+
132
+ for (let i = 0; i < bfsQueue.length; i++) {
133
+ const entry = bfsQueue[i];
134
+ const m = 'module' in entry ? entry.module : entry;
135
+ m.beforeBinding?.(container);
136
+ }
111
137
 
112
- if (beforeBinding) {
113
- beforeBinding(container);
138
+ for (let i = 0; i < bfsQueue.length; i++) {
139
+ const entry = bfsQueue[i];
140
+ bindModuleEntry(container, entry);
114
141
  }
115
142
 
116
- if (imports) {
117
- bindModules(container, imports);
143
+ for (let i = bfsQueue.length - 1; i >= 0; i--) {
144
+ const entry = bfsQueue[i];
145
+ const m = 'module' in entry ? entry.module : entry;
146
+ m.afterBinding?.(container);
147
+ }
148
+ }
149
+
150
+ function bindModuleEntry(
151
+ container: Container,
152
+ entry: ModuleBindingEntry,
153
+ ): void {
154
+ let module: ModuleDeclaration<AnyObject>;
155
+ let options: BindModuleOptions | undefined;
156
+
157
+ if ('module' in entry) {
158
+ module = entry.module;
159
+ options = entry.options;
160
+ } else {
161
+ module = entry;
118
162
  }
119
163
 
164
+ const scope = options?.scope;
120
165
  const exportedValueTokens = new Set<Token<unknown>>();
166
+ const moduleExports = module.exports;
121
167
 
122
- if (exports) {
123
- const keys = Object.keys(exports);
168
+ if (moduleExports) {
169
+ const keys = Object.keys(moduleExports);
124
170
 
125
171
  keys.forEach((valueKey) => {
126
- const valueToken = exports[valueKey];
172
+ const valueToken = moduleExports[valueKey];
127
173
  if (valueToken) {
128
174
  exportedValueTokens.add(valueToken);
129
175
 
130
176
  container.bindFactory(
131
177
  valueToken,
132
- injectable((module) => module[valueKey], token),
178
+ injectable((module) => module[valueKey], module.token),
133
179
  {scope},
134
180
  );
135
181
  }
136
182
  });
137
183
  }
138
184
 
139
- container.bindFactory(token, factory, {
185
+ container.bindFactory(module.token, module.factory, {
140
186
  scope,
141
- onRemoved: (module) => {
142
- if (module.destroy) {
143
- module.destroy();
187
+ onRemoved: (moduleInstance) => {
188
+ if (moduleInstance.destroy) {
189
+ moduleInstance.destroy();
144
190
  }
145
191
 
146
192
  exportedValueTokens.forEach((valueToken) => container.remove(valueToken));
147
193
  exportedValueTokens.clear();
148
194
  },
149
195
  });
150
-
151
- if (afterBinding) {
152
- afterBinding(container);
153
- }
154
196
  }
155
197
 
156
198
  /**