ditox 2.3.0 → 2.3.1

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Mikhail Nasyrov
3
+ Copyright (c) 2023 Mikhail Nasyrov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,66 +1,37 @@
1
- # Ditox.js
1
+ # ditox package
2
2
 
3
3
  <img alt="lemon" src="https://raw.githubusercontent.com/mnasyrov/ditox/master/lemon.svg" width="120" />
4
4
 
5
- Powerful dependency injection container for building modular apps.
5
+ **Dependency injection for modular web applications**
6
6
 
7
- [![npm](https://img.shields.io/npm/v/ditox.svg)](https://www.npmjs.com/package/ditox)
8
- [![downloads](https://img.shields.io/npm/dt/ditox.svg)](https://www.npmjs.com/package/ditox)
9
- [![types](https://img.shields.io/npm/types/ditox.svg)](https://www.npmjs.com/package/ditox)
10
- [![licence](https://img.shields.io/github/license/mnasyrov/ditox.svg)](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
11
- [![Coverage Status](https://coveralls.io/repos/github/mnasyrov/ditox/badge.svg)](https://coveralls.io/github/mnasyrov/ditox)
7
+ Please see the documentation at [ditox.js.org](https://ditox.js.org)
12
8
 
13
- ## Table of Contents
14
-
15
- <!-- toc -->
16
-
17
- - [Features](#features)
18
- - [Installation](#installation)
19
- - [Usage](#usage)
20
- - [Container Hierarchy](#container-hierarchy)
21
- - [Factory Lifetimes](#factory-lifetimes)
22
- * [`singleton`](#singleton)
23
- * [`scoped`](#scoped)
24
- * [`transient`](#transient)
25
- - [Dependency modules](#dependency-modules)
26
- - [API References](#api-references)
27
-
28
- <!-- tocstop -->
29
-
30
- ## Features
31
-
32
- - Simple and functional API
33
- - Container hierarchy
34
- - Scoped containers
35
- - Dependency modules
36
- - Multi-value tokens
37
- - Typescript typings
38
- - Supports Node.js, Deno and browsers
9
+ [![npm](https://img.shields.io/npm/v/ditox)](https://www.npmjs.com/package/ditox)
10
+ [![stars](https://img.shields.io/github/stars/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/stargazers)
11
+ [![types](https://img.shields.io/npm/types/ditox)](https://www.npmjs.com/package/ditox)
12
+ [![licence](https://img.shields.io/github/license/mnasyrov/ditox)](https://github.com/mnasyrov/ditox/blob/master/LICENSE)
13
+ [![coverage](https://coveralls.io/repos/github/mnasyrov/ditox/badge)](https://coveralls.io/github/mnasyrov/ditox)
39
14
 
40
15
  ## Installation
41
16
 
42
- Install with `npm`
43
-
44
- ```
45
- npm install ditox --save
46
- ```
47
-
48
- Or `yarn`
17
+ You can use the following command to install this package:
49
18
 
50
- ```
51
- yarn add ditox
19
+ ```shell
20
+ npm install --save ditox
52
21
  ```
53
22
 
54
- You can also use the [UMD](https://github.com/umdjs/umd) build from `unpkg`
23
+ The package can be used as [UMD](https://github.com/umdjs/umd) module. Use
24
+ [jsdelivr.com](https://jsdelivr.com) CDN site to load
25
+ [ditox](https://www.jsdelivr.com/package/npm/ditox):
55
26
 
56
27
  ```html
57
- <script src="https://unpkg.com/ditox/dist/index.browser.js" />
28
+ <script src="//cdn.jsdelivr.net/npm/ditox/dist/umd/index.js" />
58
29
  <script>
59
30
  const container = Ditox.createContainer();
60
31
  </script>
61
32
  ```
62
33
 
63
- Usage with Deno:
34
+ Using in Deno environment:
64
35
 
65
36
  ```ts
66
37
  import {createContainer} from 'https://deno.land/x/ditox/mod.ts';
@@ -68,17 +39,32 @@ import {createContainer} from 'https://deno.land/x/ditox/mod.ts';
68
39
  const container = createContainer();
69
40
  ```
70
41
 
71
- ## Usage
42
+ ## General description
43
+
44
+ DI pattern in general allows to declare and construct a code graph of an
45
+ application. It can be described by following phases:
46
+
47
+ 1. Code declaration phase:
48
+
49
+ - Defining public API and types of business layer
50
+ - Creation of injection tokens
51
+ - Declaring DI modules
52
+
53
+ 2. Binding phase:
54
+
55
+ - Creation of a container
56
+ - Binding values, factories and modules to the container
57
+
58
+ 3. Runtime phase:
72
59
 
73
- Ditox.js works with containers, tokens, values and value factories.
74
- There are no class decorators, field injectors and other magic stuff. Only explicit binding and resolving.
60
+ - Running the code
61
+ - Values are constructed by registered factories
75
62
 
76
- In general, all you need is to do the following:
63
+ Diagram:
77
64
 
78
- - Create binding tokens.
79
- - Create a container.
80
- - Register values and factories in the container using the tokens.
81
- - Resolve the tokens and use the provided values.
65
+ <img alt="diagram" src="../../media/diagram.svg" width="800" />
66
+
67
+ ## Usage Example
82
68
 
83
69
  ```js
84
70
  import {createContainer, injectable, optional, token} from 'ditox';
@@ -93,42 +79,41 @@ class UserService {
93
79
  }
94
80
 
95
81
  // Define tokens for injections.
96
- // Token can be optional to provide default values.
97
- const TOKENS = {
98
- StorageConfig: optional(token(), {name: 'default storage'}),
99
- Storage: token('Token description for debugging'),
100
- Logger: token(),
101
- UserService: token(),
102
- };
82
+ const STORAGE_TOKEN = token < UserService > 'Token description for debugging';
83
+ const LOGGER_TOKEN = token();
84
+ const USER_SERVICE_TOKEN = token();
85
+
86
+ // Token can be optional with a default value.
87
+ const STORAGE_CONFIG_TOKEN = optional(token(), {name: 'default storage'});
103
88
 
104
89
  // Create the container.
105
90
  const container = createContainer();
106
91
 
107
92
  // Provide a value to the container.
108
- container.bindValue(TOKENS.StorageConfig, {name: 'custom storage'});
93
+ container.bindValue(STORAGE_CONFIG_TOKEN, {name: 'custom storage'});
109
94
 
110
95
  // Dynamic values are provided by factories.
111
96
 
112
97
  // A factory can be decorated with `injectable()` to resolve its arguments.
113
98
  // By default, a factory has `singleton` lifetime.
114
99
  container.bindFactory(
115
- TOKENS.Storage,
116
- injectable(createStorage, TOKENS.StorageConfig),
100
+ STORAGE_TOKEN,
101
+ injectable(createStorage, STORAGE_CONFIG_TOKEN),
117
102
  );
118
103
 
119
104
  // A factory can have `transient` lifetime to create a value on each resolving.
120
- container.bindFactory(TOKENS.Logger, createLogger, {scope: 'transient'});
105
+ container.bindFactory(LOGGER_TOKEN, createLogger, {scope: 'transient'});
121
106
 
122
107
  // A class can be injected by `injectableClass()` which calls its constructor
123
108
  // with injected dependencies as arguments.
124
109
  container.bindFactory(
125
- TOKENS.UserService,
110
+ USER_SERVICE_TOKEN,
126
111
  injectable(
127
112
  (storage, logger) => new UserService(storage, logger),
128
- TOKENS.Storage,
113
+ STORAGE_TOKEN,
129
114
  // A token can be made optional to resolve with a default value
130
115
  // when it is not found during resolving.
131
- optional(TOKENS.Logger),
116
+ optional(LOGGER_TOKEN),
132
117
  ),
133
118
  {
134
119
  // `scoped` and `singleton` scopes can have `onRemoved` callback.
@@ -139,13 +124,13 @@ container.bindFactory(
139
124
  );
140
125
 
141
126
  // Get a value from the container, it returns `undefined` in case a value is not found.
142
- const logger = container.get(TOKENS.Logger);
127
+ const logger = container.get(LOGGER_TOKEN);
143
128
 
144
129
  // Resolve a value, it throws `ResolverError` in case a value is not found.
145
- const userService = container.resolve(TOKENS.userService);
130
+ const userService = container.resolve(userService);
146
131
 
147
132
  // Remove a value from the container.
148
- container.remove(TOKENS.Logger);
133
+ container.remove(LOGGER_TOKEN);
149
134
 
150
135
  // Clean up the container.
151
136
  container.removeAll();
@@ -153,86 +138,96 @@ container.removeAll();
153
138
 
154
139
  ## Container Hierarchy
155
140
 
156
- Ditox.js supports "parent-child" hierarchy. If the child container cannot to resolve a token, it asks the parent container to resolve it:
141
+ Ditox.js supports "parent-child" hierarchy. If the child container cannot to
142
+ resolve a token, it asks the parent container to resolve it:
157
143
 
158
144
  ```js
159
145
  import {creatContainer, token} from 'ditox';
160
146
 
161
- const V1 = token();
162
- const V2 = token();
147
+ const V1_TOKEN = token();
148
+ const V2_TOKEN = token();
163
149
 
164
150
  const parent = createContainer();
165
- parent.bindValue(V1, 10);
166
- parent.bindValue(V2, 20);
151
+ parent.bindValue(V1_TOKEN, 10);
152
+ parent.bindValue(V2_TOKEN, 20);
167
153
 
168
154
  const container = createContainer(parent);
169
- container.bindValue(V2, 21);
155
+ container.bindValue(V2_TOKEN, 21);
170
156
 
171
- container.resolve(V1); // 10
172
- container.resolve(V2); // 21
157
+ container.resolve(V1_TOKEN); // 10
158
+ container.resolve(V2_TOKEN); // 21
173
159
  ```
174
160
 
175
161
  ## Factory Lifetimes
176
162
 
177
- Ditox.js supports managing the lifetime of values which are produced by factories.
178
- There are the following types:
163
+ Ditox.js supports managing the lifetime of values which are produced by
164
+ factories. There are the following types:
179
165
 
180
- - `singleton` - **This is the default**. The value is created and cached by the container which registered the factory.
181
- - `scoped` - The value is created and cached by the container which starts resolving.
166
+ - `singleton` - **This is the default**. The value is created and cached by the
167
+ container which registered the factory.
168
+ - `scoped` - The value is created and cached by the container which starts
169
+ resolving.
182
170
  - `transient` - The value is created every time it is resolved.
183
171
 
184
172
  ### `singleton`
185
173
 
186
- **This is the default scope**. "Singleton" allows to cache a produced value by a parent container which registered the factory:
174
+ **This is the default scope**. "Singleton" allows to cache a produced value by a
175
+ parent container which registered the factory:
187
176
 
188
177
  ```js
189
178
  import {creatContainer, token} from 'ditox';
190
179
 
191
- const TAG = token();
192
- const LOGGER = token();
180
+ const TAG_TOKEN = token();
181
+ const LOGGER_TOKEN = token();
193
182
 
194
183
  const createLogger = (tag) => (message) => console.log(`[${tag}] ${message}`);
195
184
 
196
185
  const parent = createContainer();
197
- parent.bindValue(TAG, 'parent');
198
- parent.bindFactory(LOGGER, injectable(createLogger, TAG), {scope: 'singleton'});
186
+ parent.bindValue(TAG_TOKEN, 'parent');
187
+ parent.bindFactory(LOGGER_TOKEN, injectable(createLogger, TAG_TOKEN), {
188
+ scope: 'singleton',
189
+ });
199
190
 
200
191
  const container1 = createContainer(parent);
201
- container1.bindValue(TAG, 'container1');
192
+ container1.bindValue(TAG_TOKEN, 'container1');
202
193
 
203
194
  const container2 = createContainer(parent);
204
- container2.bindValue(TAG, 'container2');
195
+ container2.bindValue(TAG_TOKEN, 'container2');
205
196
 
206
- parent.resolve(LOGGER)('xyz'); // [parent] xyz
207
- container1.resolve(LOGGER)('foo'); // [parent] foo
208
- container2.resolve(LOGGER)('bar'); // [parent] bar
197
+ parent.resolve(LOGGER_TOKEN)('xyz'); // [parent] xyz
198
+ container1.resolve(LOGGER_TOKEN)('foo'); // [parent] foo
199
+ container2.resolve(LOGGER_TOKEN)('bar'); // [parent] bar
209
200
  ```
210
201
 
211
202
  ### `scoped`
212
203
 
213
- "Scoped" lifetime allows to have sub-containers with own instances of some services which can be disposed. For example, a context during HTTP request handling, or other unit of work:
204
+ "Scoped" lifetime allows to have sub-containers with own instances of some
205
+ services which can be disposed. For example, a context during HTTP request
206
+ handling, or other unit of work:
214
207
 
215
208
  ```js
216
209
  import {creatContainer, token} from 'ditox';
217
210
 
218
- const TAG = token();
219
- const LOGGER = token();
211
+ const TAG_TOKEN = token();
212
+ const LOGGER_TOKEN = token();
220
213
 
221
214
  const createLogger = (tag) => (message) => console.log(`[${tag}] ${message}`);
222
215
 
223
216
  const parent = createContainer();
224
217
  // `scoped` is default scope and can be omitted.
225
- parent.bindFactory(LOGGER, injectable(createLogger, TAG), {scope: 'scoped'});
218
+ parent.bindFactory(LOGGER_TOKEN, injectable(createLogger, TAG_TOKEN), {
219
+ scope: 'scoped',
220
+ });
226
221
 
227
222
  const container1 = createContainer(parent);
228
- container1.bindValue(TAG, 'container1');
223
+ container1.bindValue(TAG_TOKEN, 'container1');
229
224
 
230
225
  const container2 = createContainer(parent);
231
- container2.bindValue(TAG, 'container2');
226
+ container2.bindValue(TAG_TOKEN, 'container2');
232
227
 
233
- parent.resolve(LOGGER)('xyz'); // throws ResolverError, the parent does not have TAG value.
234
- container1.resolve(LOGGER)('foo'); // [container1] foo
235
- container2.resolve(LOGGER)('bar'); // [container2] bar
228
+ parent.resolve(LOGGER_TOKEN)('xyz'); // throws ResolverError, the parent does not have TAG value.
229
+ container1.resolve(LOGGER_TOKEN)('foo'); // [container1] foo
230
+ container2.resolve(LOGGER_TOKEN)('bar'); // [container2] bar
236
231
 
237
232
  // Dispose a container.
238
233
  container1.removeAll();
@@ -243,43 +238,54 @@ container1.removeAll();
243
238
  "Transient" makes to a produce values by the factory for each resolving:
244
239
 
245
240
  ```js
246
- import {creatContainer, token} from 'ditox';
241
+ import {createContainer, token} from 'ditox';
247
242
 
248
- const TAG = token();
249
- const LOGGER = token();
243
+ const TAG_TOKEN = token();
244
+ const LOGGER_TOKEN = token();
250
245
 
251
246
  const createLogger = (tag) => (message) => console.log(`[${tag}] ${message}`);
252
247
 
253
248
  const parent = createContainer();
254
- parent.bindValue(TAG, 'parent');
255
- parent.bindFactory(LOGGER, injectable(createLogger, TAG), {scope: 'singleton'});
249
+ parent.bindValue(TAG_TOKEN, 'parent');
250
+ parent.bindFactory(LOGGER_TOKEN, injectable(createLogger, TAG_TOKEN), {
251
+ scope: 'transient',
252
+ });
256
253
 
257
254
  const container1 = createContainer(parent);
258
- container1.bindValue(TAG, 'container1');
255
+ container1.bindValue(TAG_TOKEN, 'container1');
259
256
 
260
257
  const container2 = createContainer(parent);
261
- container2.bindValue(TAG, 'container2');
258
+ container2.bindValue(TAG_TOKEN, 'container2');
262
259
 
263
- parent.resolve(LOGGER)('xyz'); // [parent] xyz
264
- container1.resolve(LOGGER)('foo'); // [container1] foo
265
- container2.resolve(LOGGER)('bar'); // [container2] bar
260
+ parent.resolve(LOGGER_TOKEN)('xyz'); // [parent] xyz
261
+ container1.resolve(LOGGER_TOKEN)('foo'); // [container1] foo
262
+ container2.resolve(LOGGER_TOKEN)('bar'); // [container2] bar
266
263
 
267
- parent.bindValue(TAG, 'parent-rebind');
268
- parent.resolve(LOGGER)('xyz'); // [parent-rebind] xyz
264
+ parent.bindValue(TAG_TOKEN, 'parent-rebind');
265
+ parent.resolve(LOGGER_TOKEN)('xyz'); // [parent-rebind] xyz
269
266
  ```
270
267
 
271
- ## Dependency modules
268
+ ## Dependency Modules
272
269
 
273
- Dependencies can be organized as modules in declarative way with `ModuleDeclaration`.
274
- It is useful for providing pieces of functionality from libraries to an app which depends on them.
270
+ Dependencies can be organized as modules in declarative way with
271
+ `ModuleDeclaration`. It is useful for providing pieces of functionality from
272
+ libraries to an app which depends on them.
273
+
274
+ ```typescript
275
+ import {Module, ModuleDeclaration, token} from 'ditox';
276
+ import {TRANSPORT_TOKEN} from './transport';
277
+
278
+ export type Logger = {log: (message: string) => void};
279
+ export const LOGGER_TOKEN = token<Logger>();
275
280
 
276
- ```ts
277
281
  type LoggerModule = Module<{logger: Logger}>;
278
282
 
279
- const LOGGER_MODULE_TOKEN = token<LoggerModule>;
283
+ const LOGGER_MODULE_TOKEN = token<LoggerModule>();
280
284
 
281
285
  const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {
286
+ // An optional explicit token for a module itself
282
287
  token: LOGGER_MODULE_TOKEN,
288
+
283
289
  factory: (container) => {
284
290
  const transport = container.resolve(TRANSPORT_TOKEN).open();
285
291
  return {
@@ -295,7 +301,7 @@ const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {
295
301
 
296
302
  Later such module declarations can be bound to a container:
297
303
 
298
- ```ts
304
+ ```typescript
299
305
  const container = createContainer();
300
306
 
301
307
  // bind a single module
@@ -305,13 +311,16 @@ bindModule(container, LOGGER_MODULE);
305
311
  bindModules(container, [DATABASE_MODULE, CONFIG_MODULE, API_MODULE]);
306
312
  ```
307
313
 
308
- There are utility functions for module declarations:
309
- - `declareModule()` – declare a module as `ModuleDeclaration` however `token` field can be optional for anonymous modules.
310
- - `declareModuleBindings()` – declares an anonymous module with imports. This module binds the provided ones to a container.
314
+ Utility functions for module declarations:
315
+
316
+ - `declareModule()` – declare a module as `ModuleDeclaration` however `token`
317
+ field can be optional for anonymous modules.
318
+ - `declareModuleBindings()` – declares an anonymous module with imports. This
319
+ module binds the provided ones to a container.
311
320
 
312
321
  Example for these functions:
313
322
 
314
- ```ts
323
+ ```typescript
315
324
  const LOGGER_MODULE = declareModule<LoggerModule>({
316
325
  factory: createLoggerModule,
317
326
  exports: {
@@ -322,11 +331,7 @@ const LOGGER_MODULE = declareModule<LoggerModule>({
322
331
  const APP_MODULE = declareModuleBinding([LOGGER_MODULE, DATABASE_MODULE]);
323
332
  ```
324
333
 
325
- ## API References
326
-
327
- - [`ditox`](./docs)
328
- - [`ditox-react`](https://github.com/mnasyrov/ditox/tree/master/packages/ditox-react#readme)
329
-
330
334
  ---
331
335
 
332
- &copy; 2020-2021 [Mikhail Nasyrov](https://github.com/mnasyrov), [MIT license](./LICENSE)
336
+ This project is licensed under the
337
+ [MIT license](https://github.com/mnasyrov/ditox/blob/master/LICENSE).
@@ -1,2 +1,2 @@
1
- var o=function(n,t){return o=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])},o(n,t)};var n=function(){return n=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},n.apply(this,arguments)};function t(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))}function r(o){return{symbol:Symbol(o)}}function e(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}}var i=function(n){function t(o){var t=this.constructor,r=n.call(this,o)||this;return Object.setPrototypeOf(r,t.prototype),r.name="ResolverError",r}return function(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=n}o(n,t),n.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}(t,n),t}(Error),u=r("ditox.Container"),l=r("ditox.ParentContainer"),c=r("ditox.Resolver"),a=Symbol(),s=function(){throw new Error("FAKE_FACTORY")},f=r("ditox.FactoriesMap");function y(o){return o.symbol===u.symbol||o.symbol===l.symbol||o.symbol===c.symbol}function p(o){var n=new Map,t=new Map,r={bindValue:function(o,t){y(o)||n.set(o.symbol,t)},bindFactory:function(o,n,r){y(o)||t.set(o.symbol,{factory:n,options:r})},remove:function(o){var r;if(!y(o)){var e=null===(r=t.get(o.symbol))||void 0===r?void 0:r.options;e&&p(o.symbol,e),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&p(n,o.options)})),n.clear(),t.clear(),v()},hasToken:function(r){var e;return n.has(r.symbol)||t.has(r.symbol)||null!==(e=null==o?void 0:o.hasToken(r))&&void 0!==e&&e},get:function(o){var n=e(o,r);return n!==a?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=e(o,r);if(t!==a)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function e(e,i){var u=n.get(e.symbol),l=void 0!==u||n.has(e.symbol);if(l&&i===r)return u;var f,y,p=t.get(e.symbol);if(p&&p.factory!==s)switch(f=p.options,null!==(y=null==f?void 0:f.scope)&&void 0!==y?y:"singleton"){case"singleton":if(l)return u;if(null==o?void 0:o.hasToken(e))break;var v=p.factory(r);return r.bindValue(e,v),v;case"scoped":var b=p.factory(i);return i.bindValue(e,b),i!==r&&i.bindFactory(e,s,p.options),b;case"transient":return p.factory(i)}if(l)return u;var d=null==o?void 0:o.get(c);return d?d(e,i):a}function p(o,t){var r=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(r){var e=n.get(o);(void 0!==e||n.has(o))&&r(e)}}function v(){n.set(u.symbol,r),n.set(c.symbol,e),n.set(f.symbol,t),o&&n.set(l.symbol,o)}return v(),r}function v(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function b(o,n,r){var e,i=t(t([],null!==(e=o.get(n))&&void 0!==e?e:[],!0),[r],!1);o.bindValue(n,i)}function d(o,n){if(v(n))return o.get(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.get(n[r])})),t}function m(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return d(o,n)}))}function h(o,n){if(v(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.resolve(n[r])})),t}function g(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return h(o,n)}))}function O(o){for(var n=this,r=[],e=1;e<arguments.length;e++)r[e-1]=arguments[e];return function(e){var i=g.apply(void 0,t([e],r,!1));return o.apply(n,i)}}function w(o){for(var n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];return O.apply(void 0,t([function(){for(var n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];return new(o.bind.apply(o,t([void 0],n,!1)))}],n,!1))}function k(o,n,t){var r=n.token,e=n.imports,i=n.factory,u=n.beforeBinding,l=n.afterBinding,c=n.exports,a=null==t?void 0:t.scope;u&&u(o),e&&E(o,e);var s=new Set;c&&Object.keys(c).forEach((function(n){var t=c[n];t&&(s.add(t),o.bindFactory(t,O((function(o){return o[n]}),r),{scope:a}))}));o.bindFactory(r,i,{scope:a,onRemoved:function(n){n.destroy&&n.destroy(),s.forEach((function(n){return o.remove(n)})),s.clear()}}),l&&l(o)}function E(o,n){n.forEach((function(n){"module"in n?k(o,n.module,n.options):k(o,n)}))}function j(o){var t;return n(n({},o),{token:null!==(t=o.token)&&void 0!==t?t:r()})}function _(o){return j({factory:function(){return{}},imports:o})}export{i as ResolverError,k as bindModule,E as bindModules,b as bindMultiValue,p as createContainer,j as declareModule,_ as declareModuleBindings,O as injectable,w as injectableClass,v as isToken,e as optional,h as resolveValue,g as resolveValues,r as token,d as tryResolveValue,m as tryResolveValues};
1
+ var o=function(n,t){return o=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])},o(n,t)};var n=function(){return n=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},n.apply(this,arguments)};function t(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))}function r(o){return{symbol:Symbol(o)}}function e(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}}var i=function(n){function t(o){var t=this.constructor,r=n.call(this,o)||this;return Object.setPrototypeOf(r,t.prototype),r.name="ResolverError",r}return function(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=n}o(n,t),n.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}(t,n),t}(Error),u=r("ditox.Container"),l=r("ditox.ParentContainer"),c=r("ditox.Resolver"),a=Symbol(),s=function(){throw new Error("FAKE_FACTORY")},f="singleton",y=r("ditox.FactoriesMap");function p(o){return o.symbol===u.symbol||o.symbol===l.symbol||o.symbol===c.symbol}function v(o){var n=new Map,t=new Map,r={bindValue:function(o,t){p(o)||n.set(o.symbol,t)},bindFactory:function(o,n,r){p(o)||t.set(o.symbol,{factory:n,options:r})},remove:function(o){var r;if(!p(o)){var e=null===(r=t.get(o.symbol))||void 0===r?void 0:r.options;e&&v(o.symbol,e),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&v(n,o.options)})),n.clear(),t.clear(),b()},hasToken:function(r){var e;return n.has(r.symbol)||t.has(r.symbol)||null!==(e=null==o?void 0:o.hasToken(r))&&void 0!==e&&e},get:function(o){var n=e(o,r);return n!==a?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=e(o,r);if(t!==a)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function e(e,i){var u=n.get(e.symbol),l=void 0!==u||n.has(e.symbol);if(l&&i===r)return u;var y,p,v=t.get(e.symbol);if(v&&v.factory!==s)switch(y=v.options,null!==(p=null==y?void 0:y.scope)&&void 0!==p?p:f){case"singleton":if(l)return u;if(null==o?void 0:o.hasToken(e))break;var b=v.factory(r);return r.bindValue(e,b),b;case"scoped":var d=v.factory(i);return i.bindValue(e,d),i!==r&&i.bindFactory(e,s,v.options),d;case"transient":return v.factory(i)}if(l)return u;var m=null==o?void 0:o.get(c);return m?m(e,i):a}function v(o,t){var r=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(r){var e=n.get(o);(void 0!==e||n.has(o))&&r(e)}}function b(){n.set(u.symbol,r),n.set(c.symbol,e),n.set(y.symbol,t),o&&n.set(l.symbol,o)}return b(),r}function b(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function d(o,n,r){var e,i=t(t([],null!==(e=o.get(n))&&void 0!==e?e:[],!0),[r],!1);o.bindValue(n,i)}function m(o,n){if(b(n))return o.get(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.get(n[r])})),t}function h(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return m(o,n)}))}function g(o,n){if(b(n))return o.resolve(n);var t={};return Object.keys(n).forEach((function(r){return t[r]=o.resolve(n[r])})),t}function O(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return g(o,n)}))}function w(o){for(var n=this,r=[],e=1;e<arguments.length;e++)r[e-1]=arguments[e];return function(e){var i=O.apply(void 0,t([e],r,!1));return o.apply(n,i)}}function k(o){for(var n=[],r=1;r<arguments.length;r++)n[r-1]=arguments[r];return w.apply(void 0,t([function(){for(var n=[],r=0;r<arguments.length;r++)n[r]=arguments[r];return new(o.bind.apply(o,t([void 0],n,!1)))}],n,!1))}function E(o,n,t){var r=n.token,e=n.imports,i=n.factory,u=n.beforeBinding,l=n.afterBinding,c=n.exports,a=null==t?void 0:t.scope;u&&u(o),e&&j(o,e);var s=new Set;c&&Object.keys(c).forEach((function(n){var t=c[n];t&&(s.add(t),o.bindFactory(t,w((function(o){return o[n]}),r),{scope:a}))}));o.bindFactory(r,i,{scope:a,onRemoved:function(n){n.destroy&&n.destroy(),s.forEach((function(n){return o.remove(n)})),s.clear()}}),l&&l(o)}function j(o,n){n.forEach((function(n){"module"in n?E(o,n.module,n.options):E(o,n)}))}function _(o){var t;return n(n({},o),{token:null!==(t=o.token)&&void 0!==t?t:r()})}function x(o){return _({factory:function(){return{}},imports:o})}export{i as ResolverError,E as bindModule,j as bindModules,d as bindMultiValue,v as createContainer,_ as declareModule,x as declareModuleBindings,w as injectable,k as injectableClass,b as isToken,e as optional,g as resolveValue,O as resolveValues,r as token,m as tryResolveValue,h as tryResolveValues};
2
2
  //# sourceMappingURL=index.js.map
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";var n=function(o,t){return n=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])},n(o,t)};var t=function(){return t=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},t.apply(this,arguments)};function e(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))}function r(o){return{symbol:Symbol(o)}}var i=function(o){function t(n){var t=this.constructor,e=o.call(this,n)||this;return Object.setPrototypeOf(e,t.prototype),e.name="ResolverError",e}return function(o,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function e(){this.constructor=o}n(o,t),o.prototype=null===t?Object.create(t):(e.prototype=t.prototype,new e)}(t,o),t}(Error),l=r("ditox.Container"),u=r("ditox.ParentContainer"),a=r("ditox.Resolver"),s=Symbol(),c=function(){throw new Error("FAKE_FACTORY")},f=r("ditox.FactoriesMap");function p(o){return o.symbol===l.symbol||o.symbol===u.symbol||o.symbol===a.symbol}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 d(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 b(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return d(o,n)}))}function m(o){for(var n=this,t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];return function(r){var i=b.apply(void 0,e([r],t,!1));return o.apply(n,i)}}function h(o,n,t){var e=n.token,r=n.imports,i=n.factory,l=n.beforeBinding,u=n.afterBinding,a=n.exports,s=null==t?void 0:t.scope;l&&l(o),r&&g(o,r);var c=new Set;a&&Object.keys(a).forEach((function(n){var t=a[n];t&&(c.add(t),o.bindFactory(t,m((function(o){return o[n]}),e),{scope:s}))}));o.bindFactory(e,i,{scope:s,onRemoved:function(n){n.destroy&&n.destroy(),c.forEach((function(n){return o.remove(n)})),c.clear()}}),u&&u(o)}function g(o,n){n.forEach((function(n){"module"in n?h(o,n.module,n.options):h(o,n)}))}function O(o){var n;return t(t({},o),{token:null!==(n=o.token)&&void 0!==n?n:r()})}o.ResolverError=i,o.bindModule=h,o.bindModules=g,o.bindMultiValue=function(o,n,t){var r,i=e(e([],null!==(r=o.get(n))&&void 0!==r?r:[],!0),[t],!1);o.bindValue(n,i)},o.createContainer=function(o){var n=new Map,t=new Map,e={bindValue:function(o,t){p(o)||n.set(o.symbol,t)},bindFactory:function(o,n,e){p(o)||t.set(o.symbol,{factory:n,options:e})},remove:function(o){var e;if(!p(o)){var r=null===(e=t.get(o.symbol))||void 0===e?void 0:e.options;r&&y(o.symbol,r),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&y(n,o.options)})),n.clear(),t.clear(),v()},hasToken:function(e){var r;return n.has(e.symbol)||t.has(e.symbol)||null!==(r=null==o?void 0:o.hasToken(e))&&void 0!==r&&r},get:function(o){var n=r(o,e);return n!==s?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=r(o,e);if(t!==s)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function r(r,i){var l=n.get(r.symbol),u=void 0!==l||n.has(r.symbol);if(u&&i===e)return l;var f,p,y=t.get(r.symbol);if(y&&y.factory!==c)switch(f=y.options,null!==(p=null==f?void 0:f.scope)&&void 0!==p?p:"singleton"){case"singleton":if(u)return l;if(null==o?void 0:o.hasToken(r))break;var v=y.factory(e);return e.bindValue(r,v),v;case"scoped":var d=y.factory(i);return i.bindValue(r,d),i!==e&&i.bindFactory(r,c,y.options),d;case"transient":return y.factory(i)}if(u)return l;var b=null==o?void 0:o.get(a);return b?b(r,i):s}function y(o,t){var e=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(e){var r=n.get(o);(void 0!==r||n.has(o))&&e(r)}}function v(){n.set(l.symbol,e),n.set(a.symbol,r),n.set(f.symbol,t),o&&n.set(u.symbol,o)}return v(),e},o.declareModule=O,o.declareModuleBindings=function(o){return O({factory:function(){return{}},imports:o})},o.injectable=m,o.injectableClass=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return m.apply(void 0,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))},o.isToken=y,o.optional=function(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}},o.resolveValue=d,o.resolveValues=b,o.token=r,o.tryResolveValue=v,o.tryResolveValues=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return v(o,n)}))}}));
1
+ !function(o,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((o="undefined"!=typeof globalThis?globalThis:o||self).Ditox={})}(this,(function(o){"use strict";var n=function(o,t){return n=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])},n(o,t)};var t=function(){return t=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},t.apply(this,arguments)};function e(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))}function r(o){return{symbol:Symbol(o)}}var i=function(o){function t(n){var t=this.constructor,e=o.call(this,n)||this;return Object.setPrototypeOf(e,t.prototype),e.name="ResolverError",e}return function(o,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function e(){this.constructor=o}n(o,t),o.prototype=null===t?Object.create(t):(e.prototype=t.prototype,new e)}(t,o),t}(Error),l=r("ditox.Container"),u=r("ditox.ParentContainer"),a=r("ditox.Resolver"),s=Symbol(),c=function(){throw new Error("FAKE_FACTORY")},f="singleton",p=r("ditox.FactoriesMap");function y(o){return o.symbol===l.symbol||o.symbol===u.symbol||o.symbol===a.symbol}function v(o){return null!=o&&"object"==typeof o&&"symbol"in o&&"symbol"==typeof o.symbol}function d(o,n){if(v(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(v(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=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];return function(r){var i=m.apply(void 0,e([r],t,!1));return o.apply(n,i)}}function g(o,n,t){var e=n.token,r=n.imports,i=n.factory,l=n.beforeBinding,u=n.afterBinding,a=n.exports,s=null==t?void 0:t.scope;l&&l(o),r&&O(o,r);var c=new Set;a&&Object.keys(a).forEach((function(n){var t=a[n];t&&(c.add(t),o.bindFactory(t,h((function(o){return o[n]}),e),{scope:s}))}));o.bindFactory(e,i,{scope:s,onRemoved:function(n){n.destroy&&n.destroy(),c.forEach((function(n){return o.remove(n)})),c.clear()}}),u&&u(o)}function O(o,n){n.forEach((function(n){"module"in n?g(o,n.module,n.options):g(o,n)}))}function w(o){var n;return t(t({},o),{token:null!==(n=o.token)&&void 0!==n?n:r()})}o.ResolverError=i,o.bindModule=g,o.bindModules=O,o.bindMultiValue=function(o,n,t){var r,i=e(e([],null!==(r=o.get(n))&&void 0!==r?r:[],!0),[t],!1);o.bindValue(n,i)},o.createContainer=function(o){var n=new Map,t=new Map,e={bindValue:function(o,t){y(o)||n.set(o.symbol,t)},bindFactory:function(o,n,e){y(o)||t.set(o.symbol,{factory:n,options:e})},remove:function(o){var e;if(!y(o)){var r=null===(e=t.get(o.symbol))||void 0===e?void 0:e.options;r&&v(o.symbol,r),n.delete(o.symbol),t.delete(o.symbol)}},removeAll:function(){t.forEach((function(o,n){o.options&&v(n,o.options)})),n.clear(),t.clear(),d()},hasToken:function(e){var r;return n.has(e.symbol)||t.has(e.symbol)||null!==(r=null==o?void 0:o.hasToken(e))&&void 0!==r&&r},get:function(o){var n=r(o,e);return n!==s?n:o.isOptional?o.optionalValue:void 0},resolve:function(o){var n,t=r(o,e);if(t!==s)return t;if(o.isOptional)return o.optionalValue;throw new i('Token "'.concat(null!==(n=o.symbol.description)&&void 0!==n?n:"",'" is not provided'))}};function r(r,i){var l=n.get(r.symbol),u=void 0!==l||n.has(r.symbol);if(u&&i===e)return l;var p,y,v=t.get(r.symbol);if(v&&v.factory!==c)switch(p=v.options,null!==(y=null==p?void 0:p.scope)&&void 0!==y?y:f){case"singleton":if(u)return l;if(null==o?void 0:o.hasToken(r))break;var d=v.factory(e);return e.bindValue(r,d),d;case"scoped":var b=v.factory(i);return i.bindValue(r,b),i!==e&&i.bindFactory(r,c,v.options),b;case"transient":return v.factory(i)}if(u)return l;var m=null==o?void 0:o.get(a);return m?m(r,i):s}function v(o,t){var e=function(o){return void 0===o.scope||"scoped"===o.scope||"singleton"===o.scope?o.onRemoved:void 0}(t);if(e){var r=n.get(o);(void 0!==r||n.has(o))&&e(r)}}function d(){n.set(l.symbol,e),n.set(a.symbol,r),n.set(p.symbol,t),o&&n.set(u.symbol,o)}return d(),e},o.declareModule=w,o.declareModuleBindings=function(o){return w({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,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))},o.isToken=v,o.optional=function(o,n){return{symbol:o.symbol,isOptional:!0,optionalValue:n}},o.resolveValue=b,o.resolveValues=m,o.token=r,o.tryResolveValue=d,o.tryResolveValues=function(o){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return n.map((function(n){return d(o,n)}))}}));
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ditox",
3
- "version": "2.3.0",
4
- "description": "Powerful dependency injection container for building modular apps.",
3
+ "version": "2.3.1",
4
+ "description": "Dependency injection for modular web applications",
5
5
  "license": "MIT",
6
6
  "author": "Mikhail Nasyrov <mikhail@mnasyrov.com> (https://github.com/mnasyrov)",
7
7
  "homepage": "https://github.com/mnasyrov/ditox",
@@ -11,11 +11,15 @@
11
11
  "url": "https://github.com/mnasyrov/ditox.git"
12
12
  },
13
13
  "keywords": [
14
- "detox",
15
- "dependency-injection",
14
+ "dependency container",
15
+ "dependency injection",
16
+ "typescript",
17
+ "javascript",
18
+ "npm",
16
19
  "dependency",
17
20
  "injection",
18
21
  "container",
22
+ "module",
19
23
  "ioc",
20
24
  "di"
21
25
  ],
@@ -45,7 +49,8 @@
45
49
  "build": "npm run build:cjs && npm run build:esm && npm run build:rollup",
46
50
  "build:cjs": "tsc -p tsconfig.build.json --outDir dist/cjs --module commonjs",
47
51
  "build:esm": "tsc -p tsconfig.build.json --outDir dist/esm --module es2015",
48
- "build:rollup": "rollup -c"
52
+ "build:rollup": "rollup -c",
53
+ "typedoc": "typedoc"
49
54
  },
50
- "gitHead": "3d34ea7a89e0bb599fa2d9dbfa67e75ec68bfba2"
55
+ "gitHead": "1e10e32350931dba38acc4d00b2cc1cd6d5cffb5"
51
56
  }
package/docs/.nojekyll DELETED
@@ -1 +0,0 @@
1
- TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.