ditox 3.0.0 → 3.2.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
@@ -9,7 +9,7 @@ Please see the documentation at [ditox.js.org](https://ditox.js.org)
9
9
  [![npm](https://img.shields.io/npm/v/ditox)](https://www.npmjs.com/package/ditox)
10
10
  [![stars](https://img.shields.io/github/stars/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/stargazers)
11
11
  [![types](https://img.shields.io/npm/types/ditox)](https://www.npmjs.com/package/ditox)
12
- [![licence](https://img.shields.io/github/license/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
12
+ [![license](https://img.shields.io/github/license/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
13
13
  [![coverage](https://coveralls.io/repos/github/mnasyrov/ditox/badge)](https://coveralls.io/github/mnasyrov/ditox)
14
14
 
15
15
  ## Installation
@@ -25,7 +25,7 @@ The package can be used as [UMD](https://github.com/umdjs/umd) module. Use
25
25
  [ditox](https://www.jsdelivr.com/package/npm/ditox):
26
26
 
27
27
  ```html
28
- <script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js" />
28
+ <script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js"></script>
29
29
  <script>
30
30
  const container = Ditox.createContainer();
31
31
  </script>
@@ -71,7 +71,7 @@ class UserService {
71
71
  }
72
72
 
73
73
  // Define tokens for injections.
74
- const STORAGE_TOKEN = token < UserService > 'Token description for debugging';
74
+ const STORAGE_TOKEN = token('Token description for debugging');
75
75
  const LOGGER_TOKEN = token();
76
76
  const USER_SERVICE_TOKEN = token();
77
77
 
@@ -130,11 +130,11 @@ container.removeAll();
130
130
 
131
131
  ## Container Hierarchy
132
132
 
133
- Ditox.js supports "parent-child" hierarchy. If the child container cannot to
133
+ Ditox.js supports a "parent-child" hierarchy. If the child container cannot
134
134
  resolve a token, it asks the parent container to resolve it:
135
135
 
136
136
  ```js
137
- import {creatContainer, token} from 'ditox';
137
+ import {createContainer, token} from 'ditox';
138
138
 
139
139
  const V1_TOKEN = token();
140
140
  const V2_TOKEN = token();
@@ -150,6 +150,36 @@ container.resolve(V1_TOKEN); // 10
150
150
  container.resolve(V2_TOKEN); // 21
151
151
  ```
152
152
 
153
+ ### Multiple parent containers
154
+
155
+ A container can have multiple parent containers. Pass an array of parents when
156
+ creating a container. During resolution, parents are queried from left to right,
157
+ and the first parent that provides the token wins.
158
+
159
+ ```js
160
+ import {createContainer, token} from 'ditox';
161
+
162
+ const VALUE = token();
163
+
164
+ // Create two parents
165
+ const p1 = createContainer();
166
+ const p2 = createContainer();
167
+
168
+ // Case 1: Only the second parent provides the token
169
+ p2.bindValue(VALUE, 'from-p2');
170
+ const child = createContainer([p1, p2]);
171
+ child.get(VALUE); // 'from-p2' (found in the second parent)
172
+
173
+ // Case 2: Both parents provide the token — order matters (left-to-right)
174
+ p1.bindValue(VALUE, 'from-p1');
175
+ const child2 = createContainer([p1, p2]);
176
+ child2.resolve(VALUE); // 'from-p1' (first parent wins)
177
+
178
+ // The child can still override parents
179
+ child2.bindValue(VALUE, 'from-child');
180
+ child2.resolve(VALUE); // 'from-child'
181
+ ```
182
+
153
183
  ## Factory Lifetimes
154
184
 
155
185
  Ditox.js supports managing the lifetime of values which are produced by
@@ -167,7 +197,7 @@ factories. There are the following types:
167
197
  most distant parent container which registered the factory function:
168
198
 
169
199
  ```js
170
- import {creatContainer, token} from 'ditox';
200
+ import {createContainer, token} from 'ditox';
171
201
 
172
202
  const TAG_TOKEN = token();
173
203
  const LOGGER_TOKEN = token();
@@ -198,7 +228,7 @@ services which can be disposed. For example, a context during HTTP request
198
228
  handling, or other unit of work:
199
229
 
200
230
  ```js
201
- import {creatContainer, token} from 'ditox';
231
+ import {createContainer, token} from 'ditox';
202
232
 
203
233
  const TAG_TOKEN = token();
204
234
  const LOGGER_TOKEN = token();
@@ -227,7 +257,7 @@ container1.removeAll();
227
257
 
228
258
  ### `transient`
229
259
 
230
- "Transient" makes to a produce values by the factory for each resolving:
260
+ "Transient" makes the factory produce a new value for each resolution:
231
261
 
232
262
  ```js
233
263
  import {createContainer, token} from 'ditox';
@@ -299,7 +329,7 @@ const container = createContainer();
299
329
  // bind a single module
300
330
  bindModule(container, LOGGER_MODULE);
301
331
 
302
- // or bind multiple depenendency modules
332
+ // or bind multiple dependency modules
303
333
  bindModules(container, [DATABASE_MODULE, CONFIG_MODULE, API_MODULE]);
304
334
  ```
305
335
 
@@ -320,9 +350,90 @@ const LOGGER_MODULE = declareModule<LoggerModule>({
320
350
  },
321
351
  });
322
352
 
323
- const APP_MODULE = declareModuleBinding([LOGGER_MODULE, DATABASE_MODULE]);
353
+ const APP_MODULE = declareModuleBindings([LOGGER_MODULE, DATABASE_MODULE]);
324
354
  ```
325
355
 
356
+ ## API Reference
357
+
358
+ - Tokens
359
+
360
+ - token<T>(options?: { key?: string; description?: string } | string):
361
+ Token<T>
362
+ - Creates a new binding token. Use `key` to create shareable tokens via
363
+ `Symbol.for(key)`; otherwise a descriptive `Symbol(description)` is
364
+ created
365
+ - optional<T>(token: Token<T>, optionalValue?: T): OptionalToken<T |
366
+ undefined>
367
+ - Marks the token as optional and provides a default value for resolution
368
+ when not bound
369
+ - Types: Token<T>, RequiredToken<T>, OptionalToken<T>
370
+
371
+ - Container
372
+
373
+ - createContainer(parent?: Container | ReadonlyArray<Container>): Container
374
+ - Creates a new container optionally linked to one or more parents; parents
375
+ are queried left-to-right
376
+ - class ResolverError extends Error
377
+ - Thrown by `resolve()` when a token is not found and no optional default
378
+ exists
379
+ - type FactoryScope = 'scoped' | 'singleton' | 'transient'
380
+ - type FactoryOptions<T>
381
+ - For 'scoped' | 'singleton': { scope?: 'scoped' | 'singleton'; onRemoved?:
382
+ (value: T) => void }
383
+ - For 'transient': { scope: 'transient' }
384
+ - type Container API
385
+ - bindValue<T>(token: Token<T>, value: T): void — bind a concrete value
386
+ - bindFactory<T>(token: Token<T>, factory: (container: Container) => T,
387
+ options?: FactoryOptions<T>): void — bind a factory with lifetime options
388
+ - hasToken(token: Token<unknown>): boolean — check token presence in
389
+ hierarchy
390
+ - get<T>(token: Token<T>): T | undefined — try resolve or return undefined;
391
+ optional tokens return their default
392
+ - resolve<T>(token: Token<T>): T — resolve or throw ResolverError; optional
393
+ tokens return their default
394
+ - remove<T>(token: Token<T>): void — remove binding; for scoped/singleton
395
+ factories calls `onRemoved` if provided
396
+ - removeAll(): void — remove all bindings and call `onRemoved` for
397
+ applicable factories
398
+
399
+ - Utilities
400
+
401
+ - isToken<T>(value: unknown): value is Token<T> — checks if a value looks like
402
+ a token
403
+ - bindMultiValue<T>(container: Container, token: Token<ReadonlyArray<T>>,
404
+ value: T): void — appends a value to an array token
405
+ - tryResolveValue(container: Container, tokenOrMap): value | object — resolves
406
+ or returns undefined for missing tokens; supports an object map of tokens
407
+ - tryResolveValues(container: Container, ...tokenOrMaps): array — batched
408
+ variant of tryResolveValue
409
+ - resolveValue(container: Container, tokenOrMap): value | object — resolves or
410
+ throws on missing tokens; supports an object map of tokens
411
+ - resolveValues(container: Container, ...tokenOrMaps): array — batched variant
412
+ of resolveValue
413
+ - injectable(factory, ...tokens): (container: Container) => Result — decorates
414
+ a factory to receive resolved values as arguments
415
+ - injectableClass(Class, ...tokens): (container: Container) => Instance —
416
+ decorates a class constructor to receive resolved values
417
+
418
+ - Modules
419
+ - Types
420
+ - Module<Props = {}> — a module object: exported values plus optional
421
+ destroy(): void
422
+ - ModuleDeclaration<T extends Module> — declarative description of a module
423
+ - BindModuleOptions — { scope?: 'scoped' | 'singleton' }
424
+ - ModuleBindingEntry — ModuleDeclaration or { module, options }
425
+ - bindModule(container: Container, module: ModuleDeclaration<T>, options?:
426
+ BindModuleOptions): void
427
+ - Binds a module; exported values are bound via factories; module factory
428
+ respects scope; calls destroy() and removes exports on unbind
429
+ - bindModules(container: Container, modules:
430
+ ReadonlyArray<ModuleBindingEntry>): void — binds multiple modules
431
+ - declareModule(declaration): ModuleDeclaration<T>
432
+ - Creates a module declaration; generates a token if not provided
433
+ - declareModuleBindings(modules: ReadonlyArray<ModuleBindingEntry>):
434
+ ModuleDeclaration<Module>
435
+ - Declares an anonymous module that binds the provided modules
436
+
326
437
  ---
327
438
 
328
439
  This project is licensed under the
@@ -102,7 +102,7 @@ type Container = {
102
102
  */
103
103
  get<T>(token: Token<T>): T | undefined;
104
104
  /**
105
- * Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
105
+ * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.
106
106
  */
107
107
  resolve<T>(token: Token<T>): T;
108
108
  /**
@@ -114,14 +114,19 @@ type Container = {
114
114
  */
115
115
  removeAll(): void;
116
116
  };
117
+ /**
118
+ * A subset of Container interface that provides read-only access to dependency resolution.
119
+ * This type is used for parent containers to allow token resolution without exposing mutation methods.
120
+ */
121
+ type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;
117
122
  /**
118
123
  * Creates a new dependency container.
119
124
  *
120
125
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
121
126
  *
122
- * @param parentContainer - Optional parent container.
127
+ * @param parentArg - Optional parent container or an array of containers.
123
128
  */
124
- declare function createContainer(parentContainer?: Container): Container;
129
+ declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
125
130
 
126
131
  type ValuesProps = {
127
132
  [key: string]: unknown;
@@ -376,4 +381,4 @@ declare function declareModule<T extends Module<AnyObject>>(declaration: Omit<Mo
376
381
  */
377
382
  declare function declareModuleBindings(modules: ReadonlyArray<ModuleBindingEntry>): ModuleDeclaration<Module>;
378
383
 
379
- export { BindModuleOptions, Container, FactoryOptions, FactoryScope, Module, ModuleBindingEntry, ModuleDeclaration, OptionalToken, RequiredToken, ResolverError, Token, bindModule, bindModules, bindMultiValue, createContainer, declareModule, declareModuleBindings, injectable, injectableClass, isToken, optional, resolveValue, resolveValues, token, tryResolveValue, tryResolveValues };
384
+ export { BindModuleOptions, Container, ContainerResolver, FactoryOptions, FactoryScope, Module, ModuleBindingEntry, ModuleDeclaration, OptionalToken, RequiredToken, ResolverError, Token, bindModule, bindModules, bindMultiValue, createContainer, declareModule, declareModuleBindings, injectable, injectableClass, isToken, optional, resolveValue, resolveValues, token, tryResolveValue, tryResolveValues };
@@ -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),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};
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"),a=o("ditox.Resolver"),c=Symbol(),s="singleton",f=o("ditox.FactoriesMap");function p(o){return o.symbol===u.symbol||o.symbol===l.symbol||o.symbol===a.symbol}function v(o){var n=o?Array.isArray(o)?e([],o,!0):[o]:void 0,t=new Map,r=new Map,v={bindValue:function(o,n){p(o)||t.set(o.symbol,n)},bindFactory:function(o,n,t){p(o)||r.set(o.symbol,{factory:n,options:t})},remove:function(o){var n;if(!p(o)){var e=null===(n=r.get(o.symbol))||void 0===n?void 0:n.options;e&&m(o.symbol,e),t.delete(o.symbol),r.delete(o.symbol)}},removeAll:function(){r.forEach((function(o,n){o.options&&m(n,o.options)})),t.clear(),r.clear(),b()},hasToken:function(o){return t.has(o.symbol)||r.has(o.symbol)||y(n,o)},get:function(o){var n=d(o,v);return n!==c?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=d(o,v);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 d(o,e){var i=t.get(o.symbol),u=void 0!==i||t.has(o.symbol);if(u&&e===v)return i;var l,f,p=r.get(o.symbol);if(p)switch(l=p.options,null!==(f=null==l?void 0:l.scope)&&void 0!==f?f:s){case"singleton":if(u)return i;if(y(n,o))break;var d=p.factory(v);return v.bindValue(o,d),d;case"scoped":if(u)return i;var m=p.factory(v);return v.bindValue(o,m),m;case"transient":return p.factory(e)}return u?i:n?function(o,n,t){for(var r=0,e=o;r<e.length;r++){var i=e[r].get(a);if(i){var u=i(n,t);if(u!==c)return u}}return c}(n,o,e):c}function m(o,n){var r=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(n);if(r){var e=t.get(o);(void 0!==e||t.has(o))&&r(e)}}function b(){t.set(u.symbol,v),t.set(a.symbol,d),t.set(f.symbol,r),n&&t.set(l.symbol,n)}return b(),v}function y(o,n){if(!o)return!1;for(var t=0;t<o.length;t++)if(o[t].hasToken(n))return!0;return!1}function d(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function m(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 b(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 b(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 k(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 w(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return k.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 j(o,n,t){for(var r,e,i,u={module:n,options:null!=t?t:{}},l=new Set([u]),a=[u],c=0;c<a.length;){null===(r=(p="module"in(f=a[c])?f.module:f).imports)||void 0===r||r.forEach((function(o){l.has(o)||(l.add(o),a.push(o))})),c++}for(var s=0;s<a.length;s++){null===(e=(p="module"in(f=a[s])?f.module:f).beforeBinding)||void 0===e||e.call(p,o)}for(s=0;s<a.length;s++){E(o,f=a[s])}for(s=a.length-1;s>=0;s--){var f,p;null===(i=(p="module"in(f=a[s])?f.module:f).afterBinding)||void 0===i||i.call(p,o)}}function E(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,u=t.exports;u&&Object.keys(u).forEach((function(n){var r=u[n];r&&(i.add(r),o.bindFactory(r,k((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 _(o,n){n.forEach((function(n){"module"in n?j(o,n.module,n.options):j(o,n)}))}function x(n){var t;return r(r({},n),{token:null!==(t=n.token)&&void 0!==t?t:o()})}function V(o){return x({factory:function(){return{}},imports:o})}export{i as ResolverError,j as bindModule,_ as bindModules,m as bindMultiValue,v as createContainer,x as declareModule,V as declareModuleBindings,k as injectable,w as injectableClass,d as isToken,n as optional,g as resolveValue,O as resolveValues,o as token,b as tryResolveValue,h as tryResolveValues};
2
2
  //# sourceMappingURL=index.js.map
@@ -46,7 +46,7 @@ export type Container = {
46
46
  */
47
47
  get<T>(token: Token<T>): T | undefined;
48
48
  /**
49
- * Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
49
+ * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.
50
50
  */
51
51
  resolve<T>(token: Token<T>): T;
52
52
  /**
@@ -58,10 +58,15 @@ export type Container = {
58
58
  */
59
59
  removeAll(): void;
60
60
  };
61
+ /**
62
+ * A subset of Container interface that provides read-only access to dependency resolution.
63
+ * This type is used for parent containers to allow token resolution without exposing mutation methods.
64
+ */
65
+ export type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;
61
66
  /** @internal */
62
67
  export declare const CONTAINER: Token<Container>;
63
68
  /** @internal */
64
- export declare const PARENT_CONTAINER: Token<Container>;
69
+ export declare const PARENT_CONTAINERS: Token<ReadonlyArray<Container>>;
65
70
  /** @internal */
66
71
  export declare const RESOLVER: Token<Resolver>;
67
72
  /** @internal */
@@ -82,7 +87,7 @@ type Resolver = <T>(token: Token<T>, origin: Container) => T | typeof NOT_FOUND;
82
87
  *
83
88
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
84
89
  *
85
- * @param parentContainer - Optional parent container.
90
+ * @param parentArg - Optional parent container or an array of containers.
86
91
  */
87
- export declare function createContainer(parentContainer?: Container): Container;
92
+ export declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
88
93
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createContainer = exports.FACTORIES_MAP = exports.RESOLVER = exports.PARENT_CONTAINER = exports.CONTAINER = exports.ResolverError = void 0;
3
+ exports.createContainer = exports.FACTORIES_MAP = exports.RESOLVER = exports.PARENT_CONTAINERS = 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.
@@ -16,7 +16,7 @@ exports.ResolverError = ResolverError;
16
16
  /** @internal */
17
17
  exports.CONTAINER = (0, tokens_1.token)('ditox.Container');
18
18
  /** @internal */
19
- exports.PARENT_CONTAINER = (0, tokens_1.token)('ditox.ParentContainer');
19
+ exports.PARENT_CONTAINERS = (0, tokens_1.token)('ditox.ParentContainer');
20
20
  /** @internal */
21
21
  exports.RESOLVER = (0, tokens_1.token)('ditox.Resolver');
22
22
  /** @internal */
@@ -41,7 +41,7 @@ function getOnRemoved(options) {
41
41
  /** @internal */
42
42
  function isInternalToken(token) {
43
43
  return (token.symbol === exports.CONTAINER.symbol ||
44
- token.symbol === exports.PARENT_CONTAINER.symbol ||
44
+ token.symbol === exports.PARENT_CONTAINERS.symbol ||
45
45
  token.symbol === exports.RESOLVER.symbol);
46
46
  }
47
47
  /**
@@ -49,9 +49,14 @@ function isInternalToken(token) {
49
49
  *
50
50
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
51
51
  *
52
- * @param parentContainer - Optional parent container.
52
+ * @param parentArg - Optional parent container or an array of containers.
53
53
  */
54
- function createContainer(parentContainer) {
54
+ function createContainer(parentArg) {
55
+ const parents = parentArg
56
+ ? Array.isArray(parentArg)
57
+ ? [...parentArg]
58
+ : [parentArg]
59
+ : undefined;
55
60
  const values = new Map();
56
61
  const factories = new Map();
57
62
  const container = {
@@ -90,10 +95,9 @@ function createContainer(parentContainer) {
90
95
  bindInternalTokens();
91
96
  },
92
97
  hasToken(token) {
93
- var _a;
94
98
  return (values.has(token.symbol) ||
95
99
  factories.has(token.symbol) ||
96
- ((_a = parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.hasToken(token)) !== null && _a !== void 0 ? _a : false));
100
+ parentContainersHaveToken(parents, token));
97
101
  },
98
102
  get(token) {
99
103
  const value = resolver(token, container);
@@ -131,7 +135,7 @@ function createContainer(parentContainer) {
131
135
  if (hasValue) {
132
136
  return value;
133
137
  }
134
- else if (parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.hasToken(token)) {
138
+ else if (parentContainersHaveToken(parents, token)) {
135
139
  break;
136
140
  }
137
141
  else {
@@ -161,9 +165,8 @@ function createContainer(parentContainer) {
161
165
  if (hasValue) {
162
166
  return value;
163
167
  }
164
- const parentResolver = parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.get(exports.RESOLVER);
165
- if (parentResolver) {
166
- return parentResolver(token, origin);
168
+ if (parents) {
169
+ return parentContainersResolveToken(parents, token, origin);
167
170
  }
168
171
  return NOT_FOUND;
169
172
  }
@@ -180,12 +183,34 @@ function createContainer(parentContainer) {
180
183
  values.set(exports.CONTAINER.symbol, container);
181
184
  values.set(exports.RESOLVER.symbol, resolver);
182
185
  values.set(exports.FACTORIES_MAP.symbol, factories);
183
- if (parentContainer) {
184
- values.set(exports.PARENT_CONTAINER.symbol, parentContainer);
186
+ if (parents) {
187
+ values.set(exports.PARENT_CONTAINERS.symbol, parents);
185
188
  }
186
189
  }
187
190
  bindInternalTokens();
188
191
  return container;
189
192
  }
190
193
  exports.createContainer = createContainer;
194
+ function parentContainersHaveToken(parents, token) {
195
+ if (!parents)
196
+ return false;
197
+ for (let i = 0; i < parents.length; i++) {
198
+ if (parents[i].hasToken(token)) {
199
+ return true;
200
+ }
201
+ }
202
+ return false;
203
+ }
204
+ function parentContainersResolveToken(parents, token, origin) {
205
+ for (const parentContainer of parents) {
206
+ const parentResolver = parentContainer.get(exports.RESOLVER);
207
+ if (parentResolver) {
208
+ const resolved = parentResolver(token, origin);
209
+ if (resolved !== NOT_FOUND) {
210
+ return resolved;
211
+ }
212
+ }
213
+ }
214
+ return NOT_FOUND;
215
+ }
191
216
  //# sourceMappingURL=container.js.map
@@ -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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"}
@@ -1,7 +1,7 @@
1
1
  export { token, optional } from './tokens';
2
2
  export type { RequiredToken, OptionalToken, Token } from './tokens';
3
3
  export { ResolverError, createContainer } from './container';
4
- export type { FactoryScope, FactoryOptions, Container } from './container';
4
+ export type { FactoryScope, FactoryOptions, Container, ContainerResolver, } from './container';
5
5
  export { isToken, bindMultiValue, tryResolveValue, tryResolveValues, resolveValue, resolveValues, injectable, injectableClass, } from './utils';
6
6
  export { bindModule, bindModules, declareModule, declareModuleBindings, } from './modules';
7
7
  export type { Module, ModuleDeclaration, BindModuleOptions, ModuleBindingEntry, } from './modules';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAyC;AAAjC,+FAAA,KAAK,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAGvB,yCAA2D;AAAnD,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAGtC,iCASiB;AARf,gGAAA,OAAO,OAAA;AACP,uGAAA,cAAc,OAAA;AACd,wGAAA,eAAe,OAAA;AACf,yGAAA,gBAAgB,OAAA;AAChB,qGAAA,YAAY,OAAA;AACZ,sGAAA,aAAa,OAAA;AACb,mGAAA,UAAU,OAAA;AACV,wGAAA,eAAe,OAAA;AAGjB,qCAKmB;AAJjB,qGAAA,UAAU,OAAA;AACV,sGAAA,WAAW,OAAA;AACX,wGAAA,aAAa,OAAA;AACb,gHAAA,qBAAqB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAyC;AAAjC,+FAAA,KAAK,OAAA;AAAE,kGAAA,QAAQ,OAAA;AAGvB,yCAA2D;AAAnD,0GAAA,aAAa,OAAA;AAAE,4GAAA,eAAe,OAAA;AAQtC,iCASiB;AARf,gGAAA,OAAO,OAAA;AACP,uGAAA,cAAc,OAAA;AACd,wGAAA,eAAe,OAAA;AACf,yGAAA,gBAAgB,OAAA;AAChB,qGAAA,YAAY,OAAA;AACZ,sGAAA,aAAa,OAAA;AACb,mGAAA,UAAU,OAAA;AACV,wGAAA,eAAe,OAAA;AAGjB,qCAKmB;AAJjB,qGAAA,UAAU,OAAA;AACV,sGAAA,WAAW,OAAA;AACX,wGAAA,aAAa,OAAA;AACb,gHAAA,qBAAqB,OAAA"}
@@ -46,7 +46,7 @@ export type Container = {
46
46
  */
47
47
  get<T>(token: Token<T>): T | undefined;
48
48
  /**
49
- * Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
49
+ * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.
50
50
  */
51
51
  resolve<T>(token: Token<T>): T;
52
52
  /**
@@ -58,10 +58,15 @@ export type Container = {
58
58
  */
59
59
  removeAll(): void;
60
60
  };
61
+ /**
62
+ * A subset of Container interface that provides read-only access to dependency resolution.
63
+ * This type is used for parent containers to allow token resolution without exposing mutation methods.
64
+ */
65
+ export type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;
61
66
  /** @internal */
62
67
  export declare const CONTAINER: Token<Container>;
63
68
  /** @internal */
64
- export declare const PARENT_CONTAINER: Token<Container>;
69
+ export declare const PARENT_CONTAINERS: Token<ReadonlyArray<Container>>;
65
70
  /** @internal */
66
71
  export declare const RESOLVER: Token<Resolver>;
67
72
  /** @internal */
@@ -82,7 +87,7 @@ type Resolver = <T>(token: Token<T>, origin: Container) => T | typeof NOT_FOUND;
82
87
  *
83
88
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
84
89
  *
85
- * @param parentContainer - Optional parent container.
90
+ * @param parentArg - Optional parent container or an array of containers.
86
91
  */
87
- export declare function createContainer(parentContainer?: Container): Container;
92
+ export declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
88
93
  export {};
@@ -12,7 +12,7 @@ export class ResolverError extends Error {
12
12
  /** @internal */
13
13
  export const CONTAINER = token('ditox.Container');
14
14
  /** @internal */
15
- export const PARENT_CONTAINER = token('ditox.ParentContainer');
15
+ export const PARENT_CONTAINERS = token('ditox.ParentContainer');
16
16
  /** @internal */
17
17
  export const RESOLVER = token('ditox.Resolver');
18
18
  /** @internal */
@@ -37,7 +37,7 @@ function getOnRemoved(options) {
37
37
  /** @internal */
38
38
  function isInternalToken(token) {
39
39
  return (token.symbol === CONTAINER.symbol ||
40
- token.symbol === PARENT_CONTAINER.symbol ||
40
+ token.symbol === PARENT_CONTAINERS.symbol ||
41
41
  token.symbol === RESOLVER.symbol);
42
42
  }
43
43
  /**
@@ -45,9 +45,14 @@ function isInternalToken(token) {
45
45
  *
46
46
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
47
47
  *
48
- * @param parentContainer - Optional parent container.
48
+ * @param parentArg - Optional parent container or an array of containers.
49
49
  */
50
- export function createContainer(parentContainer) {
50
+ export function createContainer(parentArg) {
51
+ const parents = parentArg
52
+ ? Array.isArray(parentArg)
53
+ ? [...parentArg]
54
+ : [parentArg]
55
+ : undefined;
51
56
  const values = new Map();
52
57
  const factories = new Map();
53
58
  const container = {
@@ -86,10 +91,9 @@ export function createContainer(parentContainer) {
86
91
  bindInternalTokens();
87
92
  },
88
93
  hasToken(token) {
89
- var _a;
90
94
  return (values.has(token.symbol) ||
91
95
  factories.has(token.symbol) ||
92
- ((_a = parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.hasToken(token)) !== null && _a !== void 0 ? _a : false));
96
+ parentContainersHaveToken(parents, token));
93
97
  },
94
98
  get(token) {
95
99
  const value = resolver(token, container);
@@ -127,7 +131,7 @@ export function createContainer(parentContainer) {
127
131
  if (hasValue) {
128
132
  return value;
129
133
  }
130
- else if (parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.hasToken(token)) {
134
+ else if (parentContainersHaveToken(parents, token)) {
131
135
  break;
132
136
  }
133
137
  else {
@@ -157,9 +161,8 @@ export function createContainer(parentContainer) {
157
161
  if (hasValue) {
158
162
  return value;
159
163
  }
160
- const parentResolver = parentContainer === null || parentContainer === void 0 ? void 0 : parentContainer.get(RESOLVER);
161
- if (parentResolver) {
162
- return parentResolver(token, origin);
164
+ if (parents) {
165
+ return parentContainersResolveToken(parents, token, origin);
163
166
  }
164
167
  return NOT_FOUND;
165
168
  }
@@ -176,11 +179,33 @@ export function createContainer(parentContainer) {
176
179
  values.set(CONTAINER.symbol, container);
177
180
  values.set(RESOLVER.symbol, resolver);
178
181
  values.set(FACTORIES_MAP.symbol, factories);
179
- if (parentContainer) {
180
- values.set(PARENT_CONTAINER.symbol, parentContainer);
182
+ if (parents) {
183
+ values.set(PARENT_CONTAINERS.symbol, parents);
181
184
  }
182
185
  }
183
186
  bindInternalTokens();
184
187
  return container;
185
188
  }
189
+ function parentContainersHaveToken(parents, token) {
190
+ if (!parents)
191
+ return false;
192
+ for (let i = 0; i < parents.length; i++) {
193
+ if (parents[i].hasToken(token)) {
194
+ return true;
195
+ }
196
+ }
197
+ return false;
198
+ }
199
+ function parentContainersResolveToken(parents, token, origin) {
200
+ for (const parentContainer of parents) {
201
+ const parentResolver = parentContainer.get(RESOLVER);
202
+ if (parentResolver) {
203
+ const resolved = parentResolver(token, origin);
204
+ if (resolved !== NOT_FOUND) {
205
+ return resolved;
206
+ }
207
+ }
208
+ }
209
+ return NOT_FOUND;
210
+ }
186
211
  //# sourceMappingURL=container.js.map
@@ -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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"}
@@ -1,7 +1,7 @@
1
1
  export { token, optional } from './tokens';
2
2
  export type { RequiredToken, OptionalToken, Token } from './tokens';
3
3
  export { ResolverError, createContainer } from './container';
4
- export type { FactoryScope, FactoryOptions, Container } from './container';
4
+ export type { FactoryScope, FactoryOptions, Container, ContainerResolver, } from './container';
5
5
  export { isToken, bindMultiValue, tryResolveValue, tryResolveValues, resolveValue, resolveValues, injectable, injectableClass, } from './utils';
6
6
  export { bindModule, bindModules, declareModule, declareModuleBindings, } from './modules';
7
7
  export type { Module, ModuleDeclaration, BindModuleOptions, ModuleBindingEntry, } from './modules';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAC,aAAa,EAAE,eAAe,EAAC,MAAM,aAAa,CAAC;AAG3D,OAAO,EACL,OAAO,EACP,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,GACtB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAC,aAAa,EAAE,eAAe,EAAC,MAAM,aAAa,CAAC;AAQ3D,OAAO,EACL,OAAO,EACP,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,UAAU,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,GACtB,MAAM,WAAW,CAAC"}
@@ -102,7 +102,7 @@ type Container = {
102
102
  */
103
103
  get<T>(token: Token<T>): T | undefined;
104
104
  /**
105
- * Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
105
+ * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.
106
106
  */
107
107
  resolve<T>(token: Token<T>): T;
108
108
  /**
@@ -114,14 +114,19 @@ type Container = {
114
114
  */
115
115
  removeAll(): void;
116
116
  };
117
+ /**
118
+ * A subset of Container interface that provides read-only access to dependency resolution.
119
+ * This type is used for parent containers to allow token resolution without exposing mutation methods.
120
+ */
121
+ type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;
117
122
  /**
118
123
  * Creates a new dependency container.
119
124
  *
120
125
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
121
126
  *
122
- * @param parentContainer - Optional parent container.
127
+ * @param parentArg - Optional parent container or an array of containers.
123
128
  */
124
- declare function createContainer(parentContainer?: Container): Container;
129
+ declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
125
130
 
126
131
  type ValuesProps = {
127
132
  [key: string]: unknown;
@@ -376,4 +381,4 @@ declare function declareModule<T extends Module<AnyObject>>(declaration: Omit<Mo
376
381
  */
377
382
  declare function declareModuleBindings(modules: ReadonlyArray<ModuleBindingEntry>): ModuleDeclaration<Module>;
378
383
 
379
- export { BindModuleOptions, Container, FactoryOptions, FactoryScope, Module, ModuleBindingEntry, ModuleDeclaration, OptionalToken, RequiredToken, ResolverError, Token, bindModule, bindModules, bindMultiValue, createContainer, declareModule, declareModuleBindings, injectable, injectableClass, isToken, optional, resolveValue, resolveValues, token, tryResolveValue, tryResolveValues };
384
+ export { BindModuleOptions, Container, ContainerResolver, FactoryOptions, FactoryScope, Module, ModuleBindingEntry, ModuleDeclaration, OptionalToken, RequiredToken, ResolverError, Token, bindModule, bindModules, bindMultiValue, createContainer, declareModule, declareModuleBindings, injectable, injectableClass, isToken, optional, resolveValue, resolveValues, token, tryResolveValue, tryResolveValues };
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="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)}))}}));
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,n){if(!o)return!1;for(var t=0;t<o.length;t++)if(o[t].hasToken(n))return!0;return!1}function y(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function v(o,n){if(y(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(y(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){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++){O(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 O(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,h((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=g,o.bindModules=function(o,n){n.forEach((function(n){"module"in n?g(o,n.module,n.options):g(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=o?Array.isArray(o)?r([],o,!0):[o]:void 0,t=new Map,e=new Map,y={bindValue:function(o,n){d(o)||t.set(o.symbol,n)},bindFactory:function(o,n,t){d(o)||e.set(o.symbol,{factory:n,options:t})},remove:function(o){var n;if(!d(o)){var r=null===(n=e.get(o.symbol))||void 0===n?void 0:n.options;r&&b(o.symbol,r),t.delete(o.symbol),e.delete(o.symbol)}},removeAll:function(){e.forEach((function(o,n){o.options&&b(n,o.options)})),t.clear(),e.clear(),m()},hasToken:function(o){return t.has(o.symbol)||e.has(o.symbol)||p(n,o)},get:function(o){var n=v(o,y);return n!==s?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=v(o,y);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 v(o,r){var i=t.get(o.symbol),l=void 0!==i||t.has(o.symbol);if(l&&r===y)return i;var u,f,d=e.get(o.symbol);if(d)switch(u=d.options,null!==(f=null==u?void 0:u.scope)&&void 0!==f?f:c){case"singleton":if(l)return i;if(p(n,o))break;var v=d.factory(y);return y.bindValue(o,v),v;case"scoped":if(l)return i;var b=d.factory(y);return y.bindValue(o,b),b;case"transient":return d.factory(r)}return l?i:n?function(o,n,t){for(var e=0,r=o;e<r.length;e++){var i=r[e].get(a);if(i){var l=i(n,t);if(l!==s)return l}}return s}(n,o,r):s}function b(o,n){var e=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(n);if(e){var r=t.get(o);(void 0!==r||t.has(o))&&e(r)}}function m(){t.set(l.symbol,y),t.set(a.symbol,v),t.set(f.symbol,e),n&&t.set(u.symbol,n)}return m(),y},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=y,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)}))}}));
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ditox",
3
- "version": "3.0.0",
3
+ "version": "3.2.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)",
@@ -51,5 +51,5 @@
51
51
  "build:rollup": "rollup -c",
52
52
  "typedoc": "typedoc"
53
53
  },
54
- "gitHead": "886d98ce7e8c78ba1392b36651f4e242f611a637"
54
+ "gitHead": "493e9ba9fcb36feea88e3948a23a4249a119d03e"
55
55
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  CONTAINER,
3
3
  createContainer,
4
- PARENT_CONTAINER,
4
+ PARENT_CONTAINERS,
5
5
  ResolverError,
6
6
  } from './container';
7
7
  import {optional, token} from './tokens';
@@ -42,10 +42,10 @@ describe('Container', () => {
42
42
 
43
43
  const custom = createContainer();
44
44
  container.bindValue(CONTAINER, custom);
45
- container.bindValue(PARENT_CONTAINER, custom);
45
+ container.bindValue(PARENT_CONTAINERS, [custom]);
46
46
 
47
47
  expect(container.get(CONTAINER)).toBe(container);
48
- expect(container.get(PARENT_CONTAINER)).toBe(parent);
48
+ expect(container.get(PARENT_CONTAINERS)).toEqual([parent]);
49
49
  });
50
50
  });
51
51
 
@@ -265,12 +265,11 @@ describe('Container', () => {
265
265
  const parent = createContainer();
266
266
  const container = createContainer(parent);
267
267
 
268
- const factory = () => createContainer();
269
- container.bindFactory(CONTAINER, factory);
270
- container.bindFactory(PARENT_CONTAINER, factory);
268
+ container.bindFactory(CONTAINER, () => createContainer());
269
+ container.bindFactory(PARENT_CONTAINERS, () => [createContainer()]);
271
270
 
272
271
  expect(container.get(CONTAINER)).toBe(container);
273
- expect(container.get(PARENT_CONTAINER)).toBe(parent);
272
+ expect(container.get(PARENT_CONTAINERS)).toEqual([parent]);
274
273
  });
275
274
  });
276
275
 
@@ -358,10 +357,10 @@ describe('Container', () => {
358
357
  const container = createContainer(parent);
359
358
 
360
359
  container.remove(CONTAINER);
361
- container.remove(PARENT_CONTAINER);
360
+ container.remove(PARENT_CONTAINERS);
362
361
 
363
362
  expect(container.get(CONTAINER)).toBe(container);
364
- expect(container.get(PARENT_CONTAINER)).toBe(parent);
363
+ expect(container.get(PARENT_CONTAINERS)).toEqual([parent]);
365
364
  });
366
365
  });
367
366
 
@@ -414,7 +413,7 @@ describe('Container', () => {
414
413
  container.removeAll();
415
414
 
416
415
  expect(container.get(CONTAINER)).toBe(container);
417
- expect(container.get(PARENT_CONTAINER)).toBe(parent);
416
+ expect(container.get(PARENT_CONTAINERS)).toEqual([parent]);
418
417
  });
419
418
  });
420
419
 
@@ -502,13 +501,13 @@ describe('Container', () => {
502
501
  it('should return the parent container for PARENT_CONTAINER token', () => {
503
502
  const parent = createContainer();
504
503
  const container = createContainer(parent);
505
- const result = container.get(PARENT_CONTAINER);
506
- expect(result).toBe(parent);
504
+ const result = container.get(PARENT_CONTAINERS);
505
+ expect(result).toEqual([parent]);
507
506
  });
508
507
 
509
508
  it('should return "undefined" for PARENT_CONTAINER token in case there is no parent container', () => {
510
509
  const container = createContainer();
511
- const result = container.get(PARENT_CONTAINER);
510
+ const result = container.get(PARENT_CONTAINERS);
512
511
  expect(result).toBeUndefined();
513
512
  });
514
513
 
@@ -597,15 +596,15 @@ describe('Container', () => {
597
596
  it('should resolve PARENT_CONTAINER as the parent container', () => {
598
597
  const parent = createContainer();
599
598
  const container = createContainer(parent);
600
- const result = container.get(PARENT_CONTAINER);
601
- expect(result).toBe(parent);
599
+ const result = container.get(PARENT_CONTAINERS);
600
+ expect(result).toEqual([parent]);
602
601
  });
603
602
 
604
603
  it('should throw ResolverError for PARENT_CONTAINER token in case there is no parent container', () => {
605
604
  const container = createContainer();
606
- expect(() => container.resolve(PARENT_CONTAINER)).toThrowError(
605
+ expect(() => container.resolve(PARENT_CONTAINERS)).toThrowError(
607
606
  new ResolverError(
608
- `Token "${PARENT_CONTAINER.symbol.description}" is not provided`,
607
+ `Token "${PARENT_CONTAINERS.symbol.description}" is not provided`,
609
608
  ),
610
609
  );
611
610
  });
@@ -633,4 +632,60 @@ describe('Container', () => {
633
632
  expect(container.resolve(t2)).toBe(1);
634
633
  });
635
634
  });
635
+
636
+ describe('multiple parent containers', () => {
637
+ it('should expose all parent containers in order via PARENT_CONTAINERS', () => {
638
+ const p1 = createContainer();
639
+ const p2 = createContainer();
640
+ const child = createContainer([p1, p2]);
641
+
642
+ expect(child.get(PARENT_CONTAINERS)).toEqual([p1, p2]);
643
+ });
644
+
645
+ it('get(): should return a value from the first parent that provides it', () => {
646
+ const p1 = createContainer();
647
+ const p2 = createContainer();
648
+ p1.bindValue(NUMBER, 1);
649
+ p2.bindValue(NUMBER, 2);
650
+
651
+ const child = createContainer([p1, p2]);
652
+ expect(child.get(NUMBER)).toBe(1);
653
+ });
654
+
655
+ it('get(): should return a value from the next parent when previous parents do not provide it', () => {
656
+ const p1 = createContainer();
657
+ const p2 = createContainer();
658
+ p2.bindValue(NUMBER, 2);
659
+
660
+ const child = createContainer([p1, p2]);
661
+ expect(child.get(NUMBER)).toBe(2);
662
+ });
663
+
664
+ it('resolve(): should resolve a value from the first parent that provides it', () => {
665
+ const p1 = createContainer();
666
+ const p2 = createContainer();
667
+ p1.bindValue(NUMBER, 1);
668
+ p2.bindValue(NUMBER, 2);
669
+
670
+ const child = createContainer([p1, p2]);
671
+ expect(child.resolve(NUMBER)).toBe(1);
672
+ });
673
+
674
+ it('resolve(): should resolve a value from the next parent when previous parents do not provide it', () => {
675
+ const p1 = createContainer();
676
+ const p2 = createContainer();
677
+ p2.bindValue(NUMBER, 2);
678
+
679
+ const child = createContainer([p1, p2]);
680
+ expect(child.resolve(NUMBER)).toBe(2);
681
+ });
682
+
683
+ it('resolve(): should throw if none of the parents provide the value', () => {
684
+ const p1 = createContainer();
685
+ const p2 = createContainer();
686
+ const child = createContainer([p1, p2]);
687
+
688
+ expect(() => child.resolve(NUMBER)).toThrow(ResolverError);
689
+ });
690
+ });
636
691
  });
package/src/container.ts CHANGED
@@ -64,7 +64,7 @@ export type Container = {
64
64
  get<T>(token: Token<T>): T | undefined;
65
65
 
66
66
  /**
67
- * Returns a resolved value by the token, or throws `ResolverError` in case the token is not found.
67
+ * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.
68
68
  */
69
69
  resolve<T>(token: Token<T>): T;
70
70
 
@@ -79,10 +79,16 @@ export type Container = {
79
79
  removeAll(): void;
80
80
  };
81
81
 
82
+ /**
83
+ * A subset of Container interface that provides read-only access to dependency resolution.
84
+ * This type is used for parent containers to allow token resolution without exposing mutation methods.
85
+ */
86
+ export type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;
87
+
82
88
  /** @internal */
83
89
  export const CONTAINER: Token<Container> = token('ditox.Container');
84
90
  /** @internal */
85
- export const PARENT_CONTAINER: Token<Container> = token(
91
+ export const PARENT_CONTAINERS: Token<ReadonlyArray<Container>> = token(
86
92
  'ditox.ParentContainer',
87
93
  );
88
94
  /** @internal */
@@ -130,7 +136,7 @@ function getOnRemoved<T>(options: FactoryOptions<T>) {
130
136
  function isInternalToken<T>(token: Token<T>): boolean {
131
137
  return (
132
138
  token.symbol === CONTAINER.symbol ||
133
- token.symbol === PARENT_CONTAINER.symbol ||
139
+ token.symbol === PARENT_CONTAINERS.symbol ||
134
140
  token.symbol === RESOLVER.symbol
135
141
  );
136
142
  }
@@ -140,9 +146,17 @@ function isInternalToken<T>(token: Token<T>): boolean {
140
146
  *
141
147
  * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
142
148
  *
143
- * @param parentContainer - Optional parent container.
149
+ * @param parentArg - Optional parent container or an array of containers.
144
150
  */
145
- export function createContainer(parentContainer?: Container): Container {
151
+ export function createContainer(
152
+ parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>,
153
+ ): Container {
154
+ const parents: ReadonlyArray<ContainerResolver> | undefined = parentArg
155
+ ? Array.isArray(parentArg)
156
+ ? [...parentArg]
157
+ : [parentArg]
158
+ : undefined;
159
+
146
160
  const values: ValuesMap = new Map<symbol, any>();
147
161
  const factories: FactoriesMap = new Map<symbol, FactoryContext<any>>();
148
162
 
@@ -197,7 +211,7 @@ export function createContainer(parentContainer?: Container): Container {
197
211
  return (
198
212
  values.has(token.symbol) ||
199
213
  factories.has(token.symbol) ||
200
- (parentContainer?.hasToken(token) ?? false)
214
+ parentContainersHaveToken(parents, token)
201
215
  );
202
216
  },
203
217
 
@@ -249,7 +263,7 @@ export function createContainer(parentContainer?: Container): Container {
249
263
  case 'singleton': {
250
264
  if (hasValue) {
251
265
  return value;
252
- } else if (parentContainer?.hasToken(token)) {
266
+ } else if (parentContainersHaveToken(parents, token)) {
253
267
  break;
254
268
  } else {
255
269
  // Cache the value in the same container where the factory is registered.
@@ -281,9 +295,8 @@ export function createContainer(parentContainer?: Container): Container {
281
295
  return value;
282
296
  }
283
297
 
284
- const parentResolver = parentContainer?.get(RESOLVER);
285
- if (parentResolver) {
286
- return parentResolver(token, origin);
298
+ if (parents) {
299
+ return parentContainersResolveToken(parents, token, origin);
287
300
  }
288
301
 
289
302
  return NOT_FOUND;
@@ -307,11 +320,44 @@ export function createContainer(parentContainer?: Container): Container {
307
320
  values.set(RESOLVER.symbol, resolver);
308
321
  values.set(FACTORIES_MAP.symbol, factories);
309
322
 
310
- if (parentContainer) {
311
- values.set(PARENT_CONTAINER.symbol, parentContainer);
323
+ if (parents) {
324
+ values.set(PARENT_CONTAINERS.symbol, parents);
312
325
  }
313
326
  }
314
327
 
315
328
  bindInternalTokens();
316
329
  return container;
317
330
  }
331
+
332
+ function parentContainersHaveToken<T>(
333
+ parents: ReadonlyArray<ContainerResolver> | undefined,
334
+ token: Token<T>,
335
+ ): boolean {
336
+ if (!parents) return false;
337
+
338
+ for (let i = 0; i < parents.length; i++) {
339
+ if (parents[i].hasToken(token)) {
340
+ return true;
341
+ }
342
+ }
343
+
344
+ return false;
345
+ }
346
+
347
+ function parentContainersResolveToken<T>(
348
+ parents: ReadonlyArray<ContainerResolver>,
349
+ token: Token<T>,
350
+ origin: Container,
351
+ ): T | typeof NOT_FOUND {
352
+ for (const parentContainer of parents) {
353
+ const parentResolver = parentContainer.get(RESOLVER);
354
+ if (parentResolver) {
355
+ const resolved = parentResolver(token, origin);
356
+ if (resolved !== NOT_FOUND) {
357
+ return resolved;
358
+ }
359
+ }
360
+ }
361
+
362
+ return NOT_FOUND;
363
+ }
package/src/index.ts CHANGED
@@ -2,7 +2,12 @@ export {token, optional} from './tokens';
2
2
  export type {RequiredToken, OptionalToken, Token} from './tokens';
3
3
 
4
4
  export {ResolverError, createContainer} from './container';
5
- export type {FactoryScope, FactoryOptions, Container} from './container';
5
+ export type {
6
+ FactoryScope,
7
+ FactoryOptions,
8
+ Container,
9
+ ContainerResolver,
10
+ } from './container';
6
11
 
7
12
  export {
8
13
  isToken,