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 +121 -10
- package/dist/browser/index.d.ts +9 -4
- package/dist/browser/index.js +1 -1
- package/dist/cjs/container.d.ts +9 -4
- package/dist/cjs/container.js +38 -13
- package/dist/cjs/container.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/container.d.ts +9 -4
- package/dist/esm/container.js +37 -12
- package/dist/esm/container.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/umd/index.d.ts +9 -4
- package/dist/umd/index.js +1 -1
- package/package.json +2 -2
- package/src/container.test.ts +72 -17
- package/src/container.ts +58 -12
- package/src/index.ts +6 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Please see the documentation at [ditox.js.org](https://ditox.js.org)
|
|
|
9
9
|
[](https://www.npmjs.com/package/ditox)
|
|
10
10
|
[](https://github.com/mnasyrov/ditox/stargazers)
|
|
11
11
|
[](https://www.npmjs.com/package/ditox)
|
|
12
|
-
[](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
|
|
13
13
|
[](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
|
|
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
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
|
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 =
|
|
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
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
127
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
123
128
|
*/
|
|
124
|
-
declare function createContainer(
|
|
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/browser/index.js
CHANGED
|
@@ -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),
|
|
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
|
package/dist/cjs/container.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
90
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
86
91
|
*/
|
|
87
|
-
export declare function createContainer(
|
|
92
|
+
export declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
|
|
88
93
|
export {};
|
package/dist/cjs/container.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
|
52
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
53
53
|
*/
|
|
54
|
-
function createContainer(
|
|
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
|
-
(
|
|
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 (
|
|
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
|
-
|
|
165
|
-
|
|
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 (
|
|
184
|
-
values.set(exports.
|
|
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":";;;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;
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/esm/container.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
90
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
86
91
|
*/
|
|
87
|
-
export declare function createContainer(
|
|
92
|
+
export declare function createContainer(parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>): Container;
|
|
88
93
|
export {};
|
package/dist/esm/container.js
CHANGED
|
@@ -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
|
|
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 ===
|
|
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
|
|
48
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
49
49
|
*/
|
|
50
|
-
export function createContainer(
|
|
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
|
-
(
|
|
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 (
|
|
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
|
-
|
|
161
|
-
|
|
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 (
|
|
180
|
-
values.set(
|
|
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":"AAAA,OAAO,EAAQ,KAAK,EAAC,MAAM,UAAU,CAAC;AAEtC;;GAEG;AACH,MAAM,OAAO,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;
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/umd/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
127
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
123
128
|
*/
|
|
124
|
-
declare function createContainer(
|
|
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(
|
|
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.
|
|
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": "
|
|
54
|
+
"gitHead": "493e9ba9fcb36feea88e3948a23a4249a119d03e"
|
|
55
55
|
}
|
package/src/container.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CONTAINER,
|
|
3
3
|
createContainer,
|
|
4
|
-
|
|
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(
|
|
45
|
+
container.bindValue(PARENT_CONTAINERS, [custom]);
|
|
46
46
|
|
|
47
47
|
expect(container.get(CONTAINER)).toBe(container);
|
|
48
|
-
expect(container.get(
|
|
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
|
-
|
|
269
|
-
container.bindFactory(
|
|
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(
|
|
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(
|
|
360
|
+
container.remove(PARENT_CONTAINERS);
|
|
362
361
|
|
|
363
362
|
expect(container.get(CONTAINER)).toBe(container);
|
|
364
|
-
expect(container.get(
|
|
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(
|
|
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(
|
|
506
|
-
expect(result).
|
|
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(
|
|
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(
|
|
601
|
-
expect(result).
|
|
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(
|
|
605
|
+
expect(() => container.resolve(PARENT_CONTAINERS)).toThrowError(
|
|
607
606
|
new ResolverError(
|
|
608
|
-
`Token "${
|
|
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
|
|
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
|
|
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 ===
|
|
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
|
|
149
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
144
150
|
*/
|
|
145
|
-
export function createContainer(
|
|
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
|
-
(
|
|
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 (
|
|
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
|
-
|
|
285
|
-
|
|
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 (
|
|
311
|
-
values.set(
|
|
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 {
|
|
5
|
+
export type {
|
|
6
|
+
FactoryScope,
|
|
7
|
+
FactoryOptions,
|
|
8
|
+
Container,
|
|
9
|
+
ContainerResolver,
|
|
10
|
+
} from './container';
|
|
6
11
|
|
|
7
12
|
export {
|
|
8
13
|
isToken,
|