ditox 3.0.0 → 3.1.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 +30 -0
- package/dist/browser/index.d.ts +3 -3
- package/dist/browser/index.js +1 -1
- package/dist/cjs/container.d.ts +4 -4
- package/dist/cjs/container.js +38 -13
- package/dist/cjs/container.js.map +1 -1
- package/dist/esm/container.d.ts +4 -4
- package/dist/esm/container.js +37 -12
- package/dist/esm/container.js.map +1 -1
- package/dist/umd/index.d.ts +3 -3
- package/dist/umd/index.js +1 -1
- package/package.json +2 -2
- package/src/container.test.ts +72 -17
- package/src/container.ts +52 -12
package/README.md
CHANGED
|
@@ -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
|
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
|
/**
|
|
@@ -119,9 +119,9 @@ type Container = {
|
|
|
119
119
|
*
|
|
120
120
|
* 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
121
|
*
|
|
122
|
-
* @param
|
|
122
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
123
123
|
*/
|
|
124
|
-
declare function createContainer(
|
|
124
|
+
declare function createContainer(parentArg?: Container | ReadonlyArray<Container>): Container;
|
|
125
125
|
|
|
126
126
|
type ValuesProps = {
|
|
127
127
|
[key: string]: unknown;
|
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
|
/**
|
|
@@ -61,7 +61,7 @@ export type Container = {
|
|
|
61
61
|
/** @internal */
|
|
62
62
|
export declare const CONTAINER: Token<Container>;
|
|
63
63
|
/** @internal */
|
|
64
|
-
export declare const
|
|
64
|
+
export declare const PARENT_CONTAINERS: Token<ReadonlyArray<Container>>;
|
|
65
65
|
/** @internal */
|
|
66
66
|
export declare const RESOLVER: Token<Resolver>;
|
|
67
67
|
/** @internal */
|
|
@@ -82,7 +82,7 @@ type Resolver = <T>(token: Token<T>, origin: Container) => T | typeof NOT_FOUND;
|
|
|
82
82
|
*
|
|
83
83
|
* 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
84
|
*
|
|
85
|
-
* @param
|
|
85
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
86
86
|
*/
|
|
87
|
-
export declare function createContainer(
|
|
87
|
+
export declare function createContainer(parentArg?: Container | ReadonlyArray<Container>): Container;
|
|
88
88
|
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;AAsED,gBAAgB;AACH,QAAA,SAAS,GAAqB,IAAA,cAAK,EAAC,iBAAiB,CAAC,CAAC;AACpE,gBAAgB;AACH,QAAA,
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
|
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
|
/**
|
|
@@ -61,7 +61,7 @@ export type Container = {
|
|
|
61
61
|
/** @internal */
|
|
62
62
|
export declare const CONTAINER: Token<Container>;
|
|
63
63
|
/** @internal */
|
|
64
|
-
export declare const
|
|
64
|
+
export declare const PARENT_CONTAINERS: Token<ReadonlyArray<Container>>;
|
|
65
65
|
/** @internal */
|
|
66
66
|
export declare const RESOLVER: Token<Resolver>;
|
|
67
67
|
/** @internal */
|
|
@@ -82,7 +82,7 @@ type Resolver = <T>(token: Token<T>, origin: Container) => T | typeof NOT_FOUND;
|
|
|
82
82
|
*
|
|
83
83
|
* 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
84
|
*
|
|
85
|
-
* @param
|
|
85
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
86
86
|
*/
|
|
87
|
-
export declare function createContainer(
|
|
87
|
+
export declare function createContainer(parentArg?: Container | ReadonlyArray<Container>): Container;
|
|
88
88
|
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;AAsED,gBAAgB;AAChB,MAAM,CAAC,MAAM,SAAS,GAAqB,KAAK,CAAC,iBAAiB,CAAC,CAAC;AACpE,gBAAgB;AAChB,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
|
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
|
/**
|
|
@@ -119,9 +119,9 @@ type Container = {
|
|
|
119
119
|
*
|
|
120
120
|
* 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
121
|
*
|
|
122
|
-
* @param
|
|
122
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
123
123
|
*/
|
|
124
|
-
declare function createContainer(
|
|
124
|
+
declare function createContainer(parentArg?: Container | ReadonlyArray<Container>): Container;
|
|
125
125
|
|
|
126
126
|
type ValuesProps = {
|
|
127
127
|
[key: string]: unknown;
|
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.1.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": "e9d435838d465b1a878d3b7bc5c7cc6e90fd241a"
|
|
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
|
|
|
@@ -82,7 +82,7 @@ export type Container = {
|
|
|
82
82
|
/** @internal */
|
|
83
83
|
export const CONTAINER: Token<Container> = token('ditox.Container');
|
|
84
84
|
/** @internal */
|
|
85
|
-
export const
|
|
85
|
+
export const PARENT_CONTAINERS: Token<ReadonlyArray<Container>> = token(
|
|
86
86
|
'ditox.ParentContainer',
|
|
87
87
|
);
|
|
88
88
|
/** @internal */
|
|
@@ -130,7 +130,7 @@ function getOnRemoved<T>(options: FactoryOptions<T>) {
|
|
|
130
130
|
function isInternalToken<T>(token: Token<T>): boolean {
|
|
131
131
|
return (
|
|
132
132
|
token.symbol === CONTAINER.symbol ||
|
|
133
|
-
token.symbol ===
|
|
133
|
+
token.symbol === PARENT_CONTAINERS.symbol ||
|
|
134
134
|
token.symbol === RESOLVER.symbol
|
|
135
135
|
);
|
|
136
136
|
}
|
|
@@ -140,9 +140,17 @@ function isInternalToken<T>(token: Token<T>): boolean {
|
|
|
140
140
|
*
|
|
141
141
|
* 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
142
|
*
|
|
143
|
-
* @param
|
|
143
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
144
144
|
*/
|
|
145
|
-
export function createContainer(
|
|
145
|
+
export function createContainer(
|
|
146
|
+
parentArg?: Container | ReadonlyArray<Container>,
|
|
147
|
+
): Container {
|
|
148
|
+
const parents: ReadonlyArray<Container> | undefined = parentArg
|
|
149
|
+
? Array.isArray(parentArg)
|
|
150
|
+
? [...parentArg]
|
|
151
|
+
: [parentArg]
|
|
152
|
+
: undefined;
|
|
153
|
+
|
|
146
154
|
const values: ValuesMap = new Map<symbol, any>();
|
|
147
155
|
const factories: FactoriesMap = new Map<symbol, FactoryContext<any>>();
|
|
148
156
|
|
|
@@ -197,7 +205,7 @@ export function createContainer(parentContainer?: Container): Container {
|
|
|
197
205
|
return (
|
|
198
206
|
values.has(token.symbol) ||
|
|
199
207
|
factories.has(token.symbol) ||
|
|
200
|
-
(
|
|
208
|
+
parentContainersHaveToken(parents, token)
|
|
201
209
|
);
|
|
202
210
|
},
|
|
203
211
|
|
|
@@ -249,7 +257,7 @@ export function createContainer(parentContainer?: Container): Container {
|
|
|
249
257
|
case 'singleton': {
|
|
250
258
|
if (hasValue) {
|
|
251
259
|
return value;
|
|
252
|
-
} else if (
|
|
260
|
+
} else if (parentContainersHaveToken(parents, token)) {
|
|
253
261
|
break;
|
|
254
262
|
} else {
|
|
255
263
|
// Cache the value in the same container where the factory is registered.
|
|
@@ -281,9 +289,8 @@ export function createContainer(parentContainer?: Container): Container {
|
|
|
281
289
|
return value;
|
|
282
290
|
}
|
|
283
291
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return parentResolver(token, origin);
|
|
292
|
+
if (parents) {
|
|
293
|
+
return parentContainersResolveToken(parents, token, origin);
|
|
287
294
|
}
|
|
288
295
|
|
|
289
296
|
return NOT_FOUND;
|
|
@@ -307,11 +314,44 @@ export function createContainer(parentContainer?: Container): Container {
|
|
|
307
314
|
values.set(RESOLVER.symbol, resolver);
|
|
308
315
|
values.set(FACTORIES_MAP.symbol, factories);
|
|
309
316
|
|
|
310
|
-
if (
|
|
311
|
-
values.set(
|
|
317
|
+
if (parents) {
|
|
318
|
+
values.set(PARENT_CONTAINERS.symbol, parents);
|
|
312
319
|
}
|
|
313
320
|
}
|
|
314
321
|
|
|
315
322
|
bindInternalTokens();
|
|
316
323
|
return container;
|
|
317
324
|
}
|
|
325
|
+
|
|
326
|
+
function parentContainersHaveToken<T>(
|
|
327
|
+
parents: ReadonlyArray<Container> | undefined,
|
|
328
|
+
token: Token<T>,
|
|
329
|
+
): boolean {
|
|
330
|
+
if (!parents) return false;
|
|
331
|
+
|
|
332
|
+
for (let i = 0; i < parents.length; i++) {
|
|
333
|
+
if (parents[i].hasToken(token)) {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function parentContainersResolveToken<T>(
|
|
342
|
+
parents: ReadonlyArray<Container>,
|
|
343
|
+
token: Token<T>,
|
|
344
|
+
origin: Container,
|
|
345
|
+
): T | typeof NOT_FOUND {
|
|
346
|
+
for (const parentContainer of parents) {
|
|
347
|
+
const parentResolver = parentContainer.get(RESOLVER);
|
|
348
|
+
if (parentResolver) {
|
|
349
|
+
const resolved = parentResolver(token, origin);
|
|
350
|
+
if (resolved !== NOT_FOUND) {
|
|
351
|
+
return resolved;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return NOT_FOUND;
|
|
357
|
+
}
|