@teqfw/di 0.30.1 → 0.30.2
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 +193 -139
- package/RELEASE.md +5 -0
- package/dist/esm.js +1 -1
- package/dist/umd.js +1 -1
- package/package.json +1 -1
- package/src/Api/Container/Parser/Chunk.js +2 -2
- package/src/Api/Container/Parser.js +1 -1
- package/src/Api/Container/PostProcessor/Chunk.js +1 -1
- package/src/Api/Container/PostProcessor.js +1 -1
- package/src/Api/Container/PreProcessor/Chunk.js +1 -1
- package/src/Api/Container/PreProcessor.js +1 -1
- package/src/Api/Container/Resolver.js +1 -1
- package/src/Api/Container.js +5 -5
- package/src/Container/A/Composer/A/SpecParser.js +4 -4
- package/src/Container/A/Composer.js +1 -1
- package/src/Container/Resolver.js +1 -1
- package/src/Container.js +2 -2
- package/src/Defs.js +1 -1
package/README.md
CHANGED
|
@@ -3,26 +3,67 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|
|
|
6
|
+
`@teqfw/di` is a lightweight dependency injection container for standard JavaScript, enabling late binding of code
|
|
7
|
+
objects with minimal manual configuration. It integrates smoothly in both browser and Node.js environments, supporting
|
|
8
|
+
flexibility, modularity, and easier testing for your applications.
|
|
6
9
|
|
|
7
|
-
`@teqfw/di`
|
|
8
|
-
|
|
10
|
+
Unlike typical object containers, `@teqfw/di` requires no manual registration of objects, instead mapping dependency IDs
|
|
11
|
+
directly to their source paths for greater simplicity.
|
|
9
12
|
|
|
10
|
-
**This library
|
|
13
|
+
**This library is specifically optimized for ES6 modules, ensuring top performance and compatibility. It does not
|
|
14
|
+
support CommonJS, AMD, UMD, or other module formats.**
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
While this library is primarily designed for JavaScript, it is also fully compatible with TypeScript. Developers can use
|
|
17
|
+
TypeScript to compose dependency identifiers in the same way as in JavaScript. It is important to ensure that TypeScript
|
|
18
|
+
transpiles the source code to ES6 modules for proper functionality. With this setup, TypeScript users can effectively
|
|
19
|
+
leverage the benefits of this library without any additional configuration.
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
* [pwa-wallet](https://github.com/flancer64/pwa-wallet)
|
|
16
|
-
* [spa-remote-console](https://github.com/flancer64/spa-remote-console)
|
|
17
|
-
* [demo-webauthn-pubkey](https://github.com/flancer64/demo-webauthn-pubkey)
|
|
18
|
-
* [tg-bot-habr-demo-grammy](https://github.com/flancer64/tg-bot-habr-demo-grammy)
|
|
21
|
+
## Samples
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
for the object container. All instructions related to connections are encapsulated within the dependency identifiers
|
|
22
|
-
used in constructors or factory functions, as per the constructor injection scheme:
|
|
23
|
+
Explore `@teqfw/di` in action through the following demo applications:
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
- [demo-di-app](https://flancer64.github.io/demo-di-app/): A simple demonstration of dependency injection with
|
|
26
|
+
`@teqfw/di`.
|
|
27
|
+
- [demo-wa-esm-openai](https://github.com/flancer64/demo-wa-esm-openai): Integrates OpenAI with ES6 modules.
|
|
28
|
+
- [pwa-wallet](https://github.com/flancer64/pwa-wallet): A progressive web application wallet showcasing the library's
|
|
29
|
+
modularity.
|
|
30
|
+
- [spa-remote-console](https://github.com/flancer64/spa-remote-console): Demonstrates remote console functionality in a
|
|
31
|
+
single-page application.
|
|
32
|
+
- [demo-webauthn-pubkey](https://github.com/flancer64/demo-webauthn-pubkey): Uses Web Authentication (WebAuthn) with
|
|
33
|
+
public key credentials.
|
|
34
|
+
- [tg-bot-habr-demo-grammy](https://github.com/flancer64/tg-bot-habr-demo-grammy): A Telegram bot demo built with the
|
|
35
|
+
grammY library.
|
|
36
|
+
|
|
37
|
+
These projects offer practical examples and insights into using `@teqfw/di` effectively!
|
|
38
|
+
|
|
39
|
+
## Example of Typical Usage
|
|
40
|
+
|
|
41
|
+
Using `@teqfw/di` typically involves a few simple steps: organizing the file structure, declaring dependencies,
|
|
42
|
+
configuring the container, and finally retrieving the main object with injected dependencies.
|
|
43
|
+
|
|
44
|
+
### Step 1: Organize File Structure
|
|
45
|
+
|
|
46
|
+
Here’s an example of how files might be organized in a project. This structure can vary depending on your project needs,
|
|
47
|
+
as the container can be configured to work with any layout (e.g., within `/home/user/project/`):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
./src/
|
|
51
|
+
./Service/
|
|
52
|
+
./Customer.js
|
|
53
|
+
./Sale.js
|
|
54
|
+
./Config.js
|
|
55
|
+
./Logger.js
|
|
56
|
+
./Main.js
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 2: Declare Dependencies
|
|
60
|
+
|
|
61
|
+
In your code, declare dependencies by defining them as keys in the constructor. Dependency identifiers here follow a
|
|
62
|
+
namespace style similar to PHP Zend 1, which is used by default in this library. You can also implement a custom parser
|
|
63
|
+
if you prefer a different naming convention or mapping strategy.
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
export default class App_Main {
|
|
26
67
|
constructor(
|
|
27
68
|
{
|
|
28
69
|
App_Config$: config,
|
|
@@ -30,177 +71,180 @@ export default class App_Main {
|
|
|
30
71
|
App_Service_Customer$: servCustomer,
|
|
31
72
|
App_Service_Sale$: servSale,
|
|
32
73
|
}
|
|
33
|
-
) { ... }
|
|
34
|
-
|
|
74
|
+
) { /* ... */ }
|
|
35
75
|
}
|
|
36
|
-
```
|
|
76
|
+
```
|
|
37
77
|
|
|
38
|
-
|
|
78
|
+
### Step 3: Configure the Container
|
|
39
79
|
|
|
40
|
-
|
|
41
|
-
./src/
|
|
42
|
-
./Service/
|
|
43
|
-
./Customer.js
|
|
44
|
-
./Sale.js
|
|
45
|
-
./Config.js
|
|
46
|
-
./Logger.js
|
|
47
|
-
./Main.js
|
|
48
|
-
```
|
|
80
|
+
Next, set up the container and configure it to use the correct namespace and path for your dependencies:
|
|
49
81
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
```js
|
|
53
|
-
import Container from '@teqfw/di';
|
|
82
|
+
```js
|
|
83
|
+
import Container from '@teqfw/di';
|
|
54
84
|
|
|
85
|
+
// Create a new instance of the container
|
|
55
86
|
const container = new Container();
|
|
87
|
+
|
|
88
|
+
// Get the resolver from the container
|
|
56
89
|
const resolver = container.getResolver();
|
|
57
|
-
|
|
90
|
+
|
|
91
|
+
// Define the namespace root for dependencies, allowing the container to resolve identifiers like 'App_*'
|
|
92
|
+
resolver.addNamespaceRoot('App_', '/home/user/project/src');
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Step 4: Retrieve the Main Object with Dependencies
|
|
96
|
+
|
|
97
|
+
Finally, retrieve your main application instance. The container automatically injects all declared dependencies:
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
// Retrieve the main application instance as a singleton asynchronously
|
|
58
101
|
const app = await container.get('App_Main$');
|
|
59
|
-
```
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Key Benefits
|
|
105
|
+
|
|
106
|
+
`@teqfw/di` offers the core functionality of any object container — creating objects and injecting dependencies — with
|
|
107
|
+
extensive flexibility and configurability. This allows the library to adapt seamlessly to a wide range of project needs.
|
|
108
|
+
Here’s what makes it stand out:
|
|
109
|
+
|
|
110
|
+
- **Automatic Dependency Resolution**: The library simplifies managing complex objects and their dependencies by
|
|
111
|
+
automatically resolving and injecting them based on container configuration. This basic functionality works out of the
|
|
112
|
+
box but can be fully customized if needed.
|
|
113
|
+
|
|
114
|
+
- **Flexible Dependency ID Configuration**: With customizable parsers and chunks, you can define unique ID schemes for
|
|
115
|
+
dependencies, making it easy to adapt the library to specific naming conventions or custom mapping rules.
|
|
116
|
+
|
|
117
|
+
- **Mapping IDs to Source Modules via Resolvers**: Thanks to resolvers, `@teqfw/di` lets you map dependency IDs to their
|
|
118
|
+
source locations effortlessly. This makes the library adaptable to any project structure or file layout.
|
|
119
|
+
|
|
120
|
+
- **Preprocessing for Enhanced Control**: Built-in preprocessing allows modifying dependencies at the time of creation,
|
|
121
|
+
enabling local overrides or adjustments in functionality. This is especially useful for larger projects, where
|
|
122
|
+
different teams may tailor dependencies to their specific requirements. The default preprocessing can also be replaced
|
|
123
|
+
to suit more precise needs.
|
|
60
124
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
the current scope of the package.
|
|
125
|
+
- **Interfaces and Dependencies Without TypeScript**: `@teqfw/di` allows you to define interfaces using standard
|
|
126
|
+
JavaScript files with JSDoc annotations. The container supports configuring dependencies to replace interfaces with
|
|
127
|
+
project-specific implementations, offering flexibility without requiring TypeScript.
|
|
65
128
|
|
|
66
|
-
|
|
129
|
+
- **Postprocessing for Object Customization**: Use postprocessing to add wrappers or extend created objects. This can be
|
|
130
|
+
valuable for adding factories, logging, or other behavior, tailored to each project’s requirements.
|
|
67
131
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
* **ES6 Modules Integration**: Seamlessly utilize singletons and instances based on ES6 module exports.
|
|
71
|
-
* **Interface Usage in Standard JavaScript**: Take advantage of "interfaces" in standard JavaScript, with the added
|
|
72
|
-
benefit of dependency substitution.
|
|
73
|
-
* **Object Wrapping**: Enhance the functionality of created objects by adding wrappers (postprocessing).
|
|
132
|
+
These features make `@teqfw/di` a powerful, adaptable DI container that not only provides ready-to-use solutions but can
|
|
133
|
+
be easily customized to meet unique project demands.
|
|
74
134
|
|
|
75
135
|
## Installation
|
|
76
136
|
|
|
77
|
-
|
|
137
|
+
### For Node.js
|
|
78
138
|
|
|
79
|
-
|
|
80
|
-
$ npm i --save @teqfw/di
|
|
81
|
-
```
|
|
139
|
+
To install `@teqfw/di` in a Node.js environment, use the following command:
|
|
82
140
|
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
|
|
141
|
+
```shell
|
|
142
|
+
$ npm install @teqfw/di
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then, import and initialize the container:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
import Container from '@teqfw/di';
|
|
86
149
|
|
|
87
150
|
/** @type {TeqFw_Di_Container} */
|
|
88
151
|
const container = new Container();
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
resolver.addNamespaceRoot('App_', '...');
|
|
93
|
-
const app = await container.get('App_Main$');
|
|
94
|
-
```
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### For the Browser (ESM Module)
|
|
95
155
|
|
|
96
|
-
|
|
156
|
+
To use `@teqfw/di` in a browser environment with ES modules, include it as follows (~5KB):
|
|
97
157
|
|
|
98
|
-
```html
|
|
158
|
+
```html
|
|
99
159
|
|
|
100
160
|
<script type="module">
|
|
101
|
-
import
|
|
161
|
+
import Container from 'https://cdn.jsdelivr.net/npm/@teqfw/di@latest/+esm';
|
|
102
162
|
|
|
103
163
|
/** @type {TeqFw_Di_Container} */
|
|
104
164
|
const container = new Container();
|
|
105
|
-
/** @type {TeqFw_Di_Container_Resolver} */
|
|
106
|
-
const resolver = res.getResolver();
|
|
107
|
-
resolver.addNamespaceRoot('App_', 'https://cdn.jsdelivr.net/npm/@flancer64/demo-di-app@0.2/src');
|
|
108
|
-
resolver.addNamespaceRoot('Sample_Lib_', 'https://cdn.jsdelivr.net/npm/@flancer64/demo-di-lib@0.3/src');
|
|
109
|
-
const app = await container.get('App_Main$');
|
|
110
|
-
...
|
|
111
165
|
</script>
|
|
112
|
-
```
|
|
166
|
+
```
|
|
113
167
|
|
|
114
|
-
|
|
168
|
+
### For the Browser (UMD Module)
|
|
115
169
|
|
|
116
|
-
|
|
170
|
+
Alternatively, you can use the UMD version in the browser (~5KB):
|
|
171
|
+
|
|
172
|
+
```html
|
|
117
173
|
|
|
118
174
|
<script src="https://cdn.jsdelivr.net/npm/@teqfw/di@latest/dist/umd.js"></script>
|
|
119
|
-
<script
|
|
175
|
+
<script>
|
|
120
176
|
const {default: Container} = window.TeqFw_Di_Container;
|
|
121
177
|
/** @type {TeqFw_Di_Container} */
|
|
122
178
|
const container = new Container();
|
|
123
|
-
...
|
|
124
179
|
</script>
|
|
125
|
-
```
|
|
180
|
+
```
|
|
126
181
|
|
|
127
|
-
|
|
182
|
+
---
|
|
128
183
|
|
|
129
|
-
|
|
184
|
+
## Using the Container
|
|
130
185
|
|
|
131
|
-
###
|
|
186
|
+
### In Node.js
|
|
132
187
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
import * as Service from './App/Service.js';
|
|
136
|
-
```
|
|
188
|
+
1. **Configure Dependency Mapping**: Configure the resolver to detect the platform environment. Then, set up namespace
|
|
189
|
+
roots to map dependency IDs to their source paths.
|
|
137
190
|
|
|
138
|
-
|
|
191
|
+
```js
|
|
192
|
+
import { platform } from 'node:process';
|
|
139
193
|
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
```
|
|
194
|
+
const resolver = container.getResolver();
|
|
195
|
+
resolver.setWindowsEnv(platform === 'win32'); // Adjusts for Windows environment if needed
|
|
196
|
+
resolver.addNamespaceRoot('App_', '/path/to/src');
|
|
197
|
+
```
|
|
144
198
|
|
|
145
|
-
|
|
199
|
+
2. **Retrieve Singleton Instances**: Retrieve the main application instance as a singleton asynchronously:
|
|
146
200
|
|
|
147
|
-
```js
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Use default export as a singleton for container
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
// App_Service$
|
|
156
|
-
import {default as Factory} from './App/Service.js';
|
|
157
|
-
|
|
158
|
-
return res ?? (res = Factory({/* deps */}));
|
|
159
|
-
```
|
|
201
|
+
```js
|
|
202
|
+
const app = await container.get('App_Main$');
|
|
203
|
+
```
|
|
160
204
|
|
|
161
|
-
###
|
|
205
|
+
### In the Browser
|
|
162
206
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
import {default as Factory} from './App/Service.js';
|
|
207
|
+
1. **Configure Dependency Mapping**: Set up namespace roots to map dependency IDs to their source paths, using URLs as
|
|
208
|
+
needed.
|
|
166
209
|
|
|
167
|
-
|
|
168
|
-
|
|
210
|
+
```js
|
|
211
|
+
const resolver = container.getResolver();
|
|
212
|
+
resolver.addNamespaceRoot('App_', 'https://cdn.jsdelivr.net/npm/@flancer64/demo-di-app@0.2/src');
|
|
213
|
+
```
|
|
169
214
|
|
|
170
|
-
|
|
215
|
+
2. **Retrieve Singleton Instances**: Retrieve the main application instance as a singleton asynchronously:
|
|
171
216
|
|
|
172
|
-
```js
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return res ?? (res = name({/* deps */}));
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Create a new named export as instance
|
|
217
|
+
```js
|
|
218
|
+
const app = await container.get('App_Main$');
|
|
219
|
+
```
|
|
180
220
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
import {name} from './App/Service.js';
|
|
221
|
+
With these steps, the container is configured to automatically resolve and inject dependencies based on your setup,
|
|
222
|
+
whether in Node.js or in a browser environment.
|
|
184
223
|
|
|
185
|
-
|
|
186
|
-
```
|
|
224
|
+
## Dependency ID Types
|
|
187
225
|
|
|
188
|
-
|
|
226
|
+
`@teqfw/di` supports various dependency ID formats to match different import styles and object requirements. Here’s a
|
|
227
|
+
quick reference:
|
|
189
228
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
import
|
|
229
|
+
| Dependency ID | Import Style | Description |
|
|
230
|
+
|-----------------------------|--------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
|
|
231
|
+
| `App_Service` | `import * as Service from './App/Service.js';` | Imports the entire module as an ES module. |
|
|
232
|
+
| `App_Service.default` | `import {default} from './App/Service.js';` | Imports the default export as-is. |
|
|
233
|
+
| `App_Service.name` | `import {name} from './App/Service.js';` | Imports a named export as-is. |
|
|
234
|
+
| `App_Service$` | `import {default as Factory} from './App/Service.js';` | Uses default export as a singleton for the container. |
|
|
235
|
+
| `App_Service$$` | `import {default as Factory} from './App/Service.js';` | Creates a new instance from the default export for each dependency. |
|
|
236
|
+
| `App_Service.name$` | `import {name} from './App/Service.js';` | Uses a named export as a singleton. |
|
|
237
|
+
| `App_Service.name$$` | `import {name} from './App/Service.js';` | Creates a new instance from a named export for each dependency. |
|
|
238
|
+
| `App_Service.name$$(proxy)` | `import {name} from './App/Service.js';` | Applies a custom wrapper to the created object in postprocessing, using a handler function `proxy()`. |
|
|
193
239
|
|
|
194
|
-
|
|
195
|
-
return proxy(res); // use a handler on the postprocessing
|
|
196
|
-
```
|
|
240
|
+
### Example Usage
|
|
197
241
|
|
|
198
|
-
|
|
242
|
+
Here’s an example showing a class with multiple dependencies, each using different dependency IDs:
|
|
199
243
|
|
|
200
244
|
```js
|
|
201
245
|
export default class App_Main {
|
|
202
|
-
|
|
203
|
-
|
|
246
|
+
constructor(
|
|
247
|
+
{
|
|
204
248
|
App_Service: EsModule,
|
|
205
249
|
'App_Service.default': defaultExportAsIs,
|
|
206
250
|
'App_Service.name': namedExportAsIs,
|
|
@@ -209,19 +253,29 @@ export default class App_Main {
|
|
|
209
253
|
'App_Service.name$': namedExportAsSingleton,
|
|
210
254
|
'App_Service.name$$': namedExportAsInstance,
|
|
211
255
|
'App_Service.name(factory)': factoryToCreateInstancesFromNamedExport,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
256
|
+
}
|
|
257
|
+
) {
|
|
258
|
+
const {default: SrvDef, name: SrvName} = EsModule; // Deconstruct the module and access the exports
|
|
259
|
+
}
|
|
217
260
|
}
|
|
218
261
|
```
|
|
219
262
|
|
|
220
263
|
## Summary
|
|
221
264
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
265
|
+
`@teqfw/di` is a versatile and lightweight dependency injection container tailored for modern JavaScript applications.
|
|
266
|
+
With its flexible dependency mapping, customizable ID configurations, and support for dynamic object creation,
|
|
267
|
+
`@teqfw/di` empowers developers to build modular, testable, and scalable codebases.
|
|
268
|
+
|
|
269
|
+
Whether you’re working in Node.js or a browser environment, `@teqfw/di` provides a solid foundation with built-in
|
|
270
|
+
functionality that you can further adapt to fit your project’s unique requirements. You are encouraged to explore and
|
|
271
|
+
extend this library as needed to create your ideal development environment.
|
|
272
|
+
|
|
273
|
+
For any questions, feedback, or collaboration opportunities, please feel free to reach out through the following
|
|
274
|
+
channels:
|
|
275
|
+
|
|
276
|
+
- **Website**: [wiredgeese.com](https://wiredgeese.com)
|
|
277
|
+
- **LinkedIn**: [LinkedIn Profile](https://www.linkedin.com/in/aleksandrs-gusevs-011ba928/)
|
|
278
|
+
|
|
279
|
+
You can also leave suggestions, feedback, and feature requests directly on GitHub by opening an issue in the repository.
|
|
280
|
+
|
|
281
|
+
Happy coding!ges and ES6 modules in JavaScript applications, especially within the Node.js environment.
|
package/RELEASE.md
CHANGED
package/dist/esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function s(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function n(n){return"function"==typeof n?e.isClass(n)?function(e){const t=[],n=e.toString(),r=o.exec(n);return r&&t.push(...s(r[1])),t}(n):function(e){const o=[],n=e.toString(),r=t.exec(n);return r&&o.push(...s(r[2])),o}(n):[]}class r{constructor(){let t=!1;this.create=async function(o,s,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=s;if(o.composition===e.COMP_F){if("function"==typeof u){const s=n(u);s.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(s)}`,t&&console.log(c));const r={};for(const e of s)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return s;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const s=c.exec(t);if(s&&(o.moduleName=s[2],"."===s[5]?"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName=s[6],o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==s[6]?s[6]:"default"):"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),s[11]&&(o.wrappers=s[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let s;for(const e of t)if(e.canParse(o)){s=e.parse(o);break}return s||(s=e?.parse(o)),s},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let s=t;for(const n of e)s=n.modify(s,t,o);return s}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,s){let n=t;for(const t of e)n=t.modify(n,o,s),n instanceof Promise&&(n=await n);return n}}}const p="
|
|
1
|
+
var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function s(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function n(n){return"function"==typeof n?e.isClass(n)?function(e){const t=[],n=e.toString(),r=o.exec(n);return r&&t.push(...s(r[1])),t}(n):function(e){const o=[],n=e.toString(),r=t.exec(n);return r&&o.push(...s(r[2])),o}(n):[]}class r{constructor(){let t=!1;this.create=async function(o,s,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=s;if(o.composition===e.COMP_F){if("function"==typeof u){const s=n(u);s.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(s)}`,t&&console.log(c));const r={};for(const e of s)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return s;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const s=c.exec(t);if(s&&(o.moduleName=s[2],"."===s[5]?"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName=s[6],o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==s[6]?s[6]:"default"):"$"===s[7]||"$$"===s[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===s[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),s[11]&&(o.wrappers=s[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let s;for(const e of t)if(e.canParse(o)){s=e.parse(o);break}return s||(s=e?.parse(o)),s},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let s=t;for(const n of e)s=n.modify(s,t,o);return s}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,s){let n=t;for(const t of e)n=t.modify(n,o,s),n instanceof Promise&&(n=await n);return n}}}const p="root";class m{constructor(){const e={};let t=!1,o=[],s="/";this.addNamespaceRoot=function(s,n,r){const i=(t?n.replace(/^\\/,""):n).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[s]={ext:r??"js",ns:s,[p]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let n,r,i;for(i of o)if(t.startsWith(i)){n=e[i][p],r=e[i].ext;break}if(n&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",s);return`${n}${s}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,s=e?"\\":"/"}}}function d(e){return`${e.moduleName}#${e.exportName}`}class h{constructor(){let t=new r,o=!1,s=new u,n=new l,i=new f;const c={},a={};let p=new m;function h(){o&&console.log(...arguments)}this.get=async function(e){return this.compose(e,[])},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=s.parse(o),l=n.modify(u,r);if(l.life===e.LIFE_S){const e=d(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=p.resolve(l.moduleName));const m=c[l.moduleName];try{f=await import(m),h(`ES6 module '${l.moduleName}' is loaded from '${m}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${m}".`,`Stack: ${JSON.stringify(r)}`),e}let $=await t.create(l,f,r,this);if($=await i.modify($,l,r),h(`Object '${o}' is created.`),l.life===e.LIFE_S){const e=d(l);a[e]=$,h(`Object '${o}' is saved as singleton.`)}return $},this.getParser=()=>s,this.getPreProcessor=()=>n,this.getPostProcessor=()=>i,this.getResolver=()=>p,this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>s=e,this.setPreProcessor=e=>n=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>p=e,a[e.ID]=this}}export{h as default};
|
package/dist/umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TeqFw_Di_Container=t()}(this,(function(){"use strict";var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function n(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function s(s){return"function"==typeof s?e.isClass(s)?function(e){const t=[],s=e.toString(),r=o.exec(s);return r&&t.push(...n(r[1])),t}(s):function(e){const o=[],s=e.toString(),r=t.exec(s);return r&&o.push(...n(r[2])),o}(s):[]}class r{constructor(){let t=!1;this.create=async function(o,n,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=n;if(o.composition===e.COMP_F){if("function"==typeof u){const n=s(u);n.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const n=c.exec(t);if(n&&(o.moduleName=n[2],"."===n[5]?"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName=n[6],o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==n[6]?n[6]:"default"):"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[11]&&(o.wrappers=n[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let n;for(const e of t)if(e.canParse(o)){n=e.parse(o);break}return n||(n=e?.parse(o)),n},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let n=t;for(const s of e)n=s.modify(n,t,o);return n}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,n){let s=t;for(const t of e)s=t.modify(s,o,n),s instanceof Promise&&(s=await s);return s}}}const p="
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TeqFw_Di_Container=t()}(this,(function(){"use strict";var e={COMP_A:"A",COMP_F:"F",ID:"container",ID_FQN:"TeqFw_Di_Container$",LIFE_I:"I",LIFE_S:"S",isClass(e){const t=Object.getOwnPropertyDescriptor(e,"prototype");return t&&!t.writable}};const t=/(function)*\s*\w*\s*\(\s*\{([^\}]*)\}/s,o=/constructor\s*\(\s*\{([^\}]*)\}/s;function n(e){const t=[];try{const o=new Function(`{${e}}`,"return");o(new Proxy({},{get:(e,o)=>t.push(o)}))}catch(t){throw new Error(`Cannot analyze the deps specification:${e}\n\nPlease, be sure that spec does not contain extra ')' in a comments.\n\nError: ${t}`)}return t}function s(s){return"function"==typeof s?e.isClass(s)?function(e){const t=[],s=e.toString(),r=o.exec(s);return r&&t.push(...n(r[1])),t}(s):function(e){const o=[],s=e.toString(),r=t.exec(s);return r&&o.push(...n(r[2])),o}(s):[]}class r{constructor(){let t=!1;this.create=async function(o,n,r,i){if(r.includes(o.value))throw new Error(`Circular dependency for '${o.value}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.value],{[o.exportName]:u}=n;if(o.composition===e.COMP_F){if("function"==typeof u){const n=s(u);n.length&&(c=`Deps for object '${o.value}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.compose(e,a);const l=e.isClass(u)?new u(r):u(r);return l instanceof Promise?await l:l}return Object.assign({},u)}return u}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;life;moduleName;value;wrappers=[]}const c=/^((([A-Z])[A-Za-z0-9_]*)((\.)?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?)$/;class a{canParse(e){return!0}parse(t){const o=new i;o.value=t;const n=c.exec(t);if(n&&(o.moduleName=n[2],"."===n[5]?"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName=n[6],o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=e.COMP_A,o.life=e.LIFE_S,o.exportName=""!==n[6]?n[6]:"default"):"$"===n[7]||"$$"===n[7]?(o.composition=e.COMP_F,o.exportName="default",o.life="$"===n[7]?e.LIFE_S:e.LIFE_I):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[11]&&(o.wrappers=n[11].split(","))),o.composition===e.COMP_A&&o.life===e.LIFE_I)throw new Error(`Export is not a function and should be used as a singleton only: '${o.value}'.`);return o}}class u{constructor(){let e=new a;const t=[];this.addChunk=function(e){t.push(e)},this.parse=function(o){let n;for(const e of t)if(e.canParse(o)){n=e.parse(o);break}return n||(n=e?.parse(o)),n},this.setDefaultChunk=function(t){e=t}}}class l{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=function(t,o){let n=t;for(const s of e)n=s.modify(n,t,o);return n}}}class f{constructor(){const e=[];this.addChunk=function(t){e.push(t)},this.modify=async function(t,o,n){let s=t;for(const t of e)s=t.modify(s,o,n),s instanceof Promise&&(s=await s);return s}}}const p="root";class d{constructor(){const e={};let t=!1,o=[],n="/";this.addNamespaceRoot=function(n,s,r){const i=(t?s.replace(/^\\/,""):s).replace(/\\/g,"/"),c=t?`file://${i}`:i;e[n]={ext:r??"js",ns:n,[p]:c},o=Object.keys(e).sort(((e,t)=>t.localeCompare(e)))},this.resolve=function(t){let s,r,i;for(i of o)if(t.startsWith(i)){s=e[i][p],r=e[i].ext;break}if(s&&r){let e=t.replace(i,"");0===e.indexOf("_")&&(e=e.replace("_",""));const o=e.replaceAll("_",n);return`${s}${n}${o}.${r}`}return t},this.setWindowsEnv=function(e=!0){t=e,n=e?"\\":"/"}}}function m(e){return`${e.moduleName}#${e.exportName}`}return class{constructor(){let t=new r,o=!1,n=new u,s=new l,i=new f;const c={},a={};let p=new d;function h(){o&&console.log(...arguments)}this.get=async function(e){return this.compose(e,[])},this.compose=async function(o,r=[]){if(h(`Object '${o}' is requested.`),o===e.ID||o===e.ID_FQN)return h("Container itself is returned."),a[e.ID];const u=n.parse(o),l=s.modify(u,r);if(l.life===e.LIFE_S){const e=m(l);if(a[e])return h(`Existing singleton '${e}' is returned.`),a[e]}let f;c[l.moduleName]||(h(`ES6 module '${l.moduleName}' is not resolved yet`),c[l.moduleName]=p.resolve(l.moduleName));const d=c[l.moduleName];try{f=await import(d),h(`ES6 module '${l.moduleName}' is loaded from '${d}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${d}".`,`Stack: ${JSON.stringify(r)}`),e}let $=await t.create(l,f,r,this);if($=await i.modify($,l,r),h(`Object '${o}' is created.`),l.life===e.LIFE_S){const e=m(l);a[e]=$,h(`Object '${o}' is saved as singleton.`)}return $},this.getParser=()=>n,this.getPreProcessor=()=>s,this.getPostProcessor=()=>i,this.getResolver=()=>p,this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>n=e,this.setPreProcessor=e=>s=e,this.setPostProcessor=e=>i=e,this.setResolver=e=>p=e,a[e.ID]=this}}}));
|
package/package.json
CHANGED
|
@@ -10,14 +10,14 @@ export default class TeqFw_Di_Api_Container_Parser_Chunk {
|
|
|
10
10
|
* Returns 'true' if this chunk can parse the given dependency ID.
|
|
11
11
|
*
|
|
12
12
|
* @param {string} depId
|
|
13
|
-
* @
|
|
13
|
+
* @returns {boolean}
|
|
14
14
|
*/
|
|
15
15
|
canParse(depId) {};
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Parses a string ID for a runtime dependency and returns structured data (DTO).
|
|
19
19
|
* @param {string} depId
|
|
20
|
-
* @
|
|
20
|
+
* @returns {TeqFw_Di_DepId}
|
|
21
21
|
*/
|
|
22
22
|
parse(depId) {}
|
|
23
23
|
};
|
|
@@ -11,7 +11,7 @@ export default class TeqFw_Di_Api_Container_PostProcessor_Chunk {
|
|
|
11
11
|
* @param {*} obj - created object
|
|
12
12
|
* @param {TeqFw_Di_DepId} originalId - original `depId` DTO
|
|
13
13
|
* @param {string[]} stack - stack of parents depIds
|
|
14
|
-
* @
|
|
14
|
+
* @returns {*} modified object
|
|
15
15
|
*/
|
|
16
16
|
modify(obj, originalId, stack) {}
|
|
17
17
|
};
|
|
@@ -18,7 +18,7 @@ export default class TeqFw_Di_Api_Container_PostProcessor {
|
|
|
18
18
|
* @param {*} obj - The result object to be modified.
|
|
19
19
|
* @param {TeqFw_Di_DepId} depId - The original depID DTO.
|
|
20
20
|
* @param {string[]} - The stack of parent IDs.
|
|
21
|
-
* @
|
|
21
|
+
* @returns {Promise<*>}
|
|
22
22
|
*/
|
|
23
23
|
modify(obj, depId, stack) {}
|
|
24
24
|
|
|
@@ -11,7 +11,7 @@ export default class TeqFw_Di_Api_Container_PreProcessor_Chunk {
|
|
|
11
11
|
* @param {TeqFw_Di_DepId} depId - `depId` DTO after all previous pre-processing steps
|
|
12
12
|
* @param {TeqFw_Di_DepId} originalId - original `depId` DTO
|
|
13
13
|
* @param {string[]} stack - stack of parents depIds
|
|
14
|
-
* @
|
|
14
|
+
* @returns {TeqFw_Di_DepId}
|
|
15
15
|
*/
|
|
16
16
|
modify(depId, originalId, stack) {}
|
|
17
17
|
};
|
|
@@ -16,7 +16,7 @@ export default class TeqFw_Di_Api_Container_PreProcessor {
|
|
|
16
16
|
* Modify parsed depID and return it.
|
|
17
17
|
* @param {TeqFw_Di_DepId} depId - The depID as DTO.
|
|
18
18
|
* @param {string[]} stack - The stack of parent IDs.
|
|
19
|
-
* @
|
|
19
|
+
* @returns {TeqFw_Di_DepId} -
|
|
20
20
|
*/
|
|
21
21
|
modify(depId, stack) {}
|
|
22
22
|
|
|
@@ -9,7 +9,7 @@ export default class TeqFw_Di_Api_Container_Resolver {
|
|
|
9
9
|
/**
|
|
10
10
|
* Convert the module name to the path of the source files .
|
|
11
11
|
* @param {string} moduleName 'Vendor_Package_Module'
|
|
12
|
-
* @
|
|
12
|
+
* @returns {string} '/home/user/app/node_modules/@vendor/package/src/Module.js'
|
|
13
13
|
*/
|
|
14
14
|
resolve(moduleName) {}
|
|
15
15
|
|
package/src/Api/Container.js
CHANGED
|
@@ -9,27 +9,27 @@ export default class TeqFw_Di_Api_Container {
|
|
|
9
9
|
* Gets or creates a runtime object by ID.
|
|
10
10
|
*
|
|
11
11
|
* @param {string} runtimeDepId - The ID of the runtime object.
|
|
12
|
-
* @
|
|
12
|
+
* @returns {Promise<*>} - A promise that resolves to the runtime object.
|
|
13
13
|
*/
|
|
14
14
|
get(runtimeDepId) {};
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* @
|
|
17
|
+
* @returns {TeqFw_Di_Api_Container_Parser}
|
|
18
18
|
*/
|
|
19
19
|
getParser() {};
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* @
|
|
22
|
+
* @returns {TeqFw_Di_Api_Container_PreProcessor}
|
|
23
23
|
*/
|
|
24
24
|
getPreProcessor() {};
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* @
|
|
27
|
+
* @returns {TeqFw_Di_Api_Container_PostProcessor}
|
|
28
28
|
*/
|
|
29
29
|
getPostProcessor() {};
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* @
|
|
32
|
+
* @returns {TeqFw_Di_Container_Resolver} - the default resolver
|
|
33
33
|
*/
|
|
34
34
|
getResolver() {};
|
|
35
35
|
|
|
@@ -17,7 +17,7 @@ const CLASS = /constructor\s*\(\s*\{([^\}]*)\}/s;
|
|
|
17
17
|
* Internal function to analyze extracted parameters.
|
|
18
18
|
*
|
|
19
19
|
* @param {string} params
|
|
20
|
-
* @
|
|
20
|
+
* @returns {string[]}
|
|
21
21
|
* @private
|
|
22
22
|
*/
|
|
23
23
|
function _analyze(params) {
|
|
@@ -41,7 +41,7 @@ function _analyze(params) {
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* @param {Function|Object} exp
|
|
44
|
-
* @
|
|
44
|
+
* @returns {string[]}
|
|
45
45
|
*/
|
|
46
46
|
function _analyzeClass(exp) {
|
|
47
47
|
const res = [];
|
|
@@ -56,7 +56,7 @@ function _analyzeClass(exp) {
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* @param {Function|Object} exp
|
|
59
|
-
* @
|
|
59
|
+
* @returns {string[]}
|
|
60
60
|
*/
|
|
61
61
|
function _analyzeFunc(exp) {
|
|
62
62
|
const res = [];
|
|
@@ -72,7 +72,7 @@ function _analyzeFunc(exp) {
|
|
|
72
72
|
// MAIN
|
|
73
73
|
/**
|
|
74
74
|
* @param {Function|Object} exp
|
|
75
|
-
* @
|
|
75
|
+
* @returns {string[]}
|
|
76
76
|
*/
|
|
77
77
|
export default function (exp) {
|
|
78
78
|
if (typeof exp === 'function') {
|
|
@@ -26,7 +26,7 @@ export default class TeqFw_Di_Container_A_Composer {
|
|
|
26
26
|
* @param {Object} module - imported es6 module
|
|
27
27
|
* @param {string[]} stack - array of the parent objects IDs to prevent dependency loop
|
|
28
28
|
* @param {TeqFw_Di_Container} container - to create dependencies for requested object
|
|
29
|
-
* @
|
|
29
|
+
* @returns {Promise<*>}
|
|
30
30
|
*/
|
|
31
31
|
this.create = async function (depId, module, stack, container) {
|
|
32
32
|
if (stack.includes(depId.value))
|
|
@@ -49,7 +49,7 @@ export default class TeqFw_Di_Container_Resolver {
|
|
|
49
49
|
/**
|
|
50
50
|
* Convert the module name to the path of the source files .
|
|
51
51
|
* @param {string} moduleName 'Vendor_Package_Module'
|
|
52
|
-
* @
|
|
52
|
+
* @returns {string} '/home/user/app/node_modules/@vendor/package/src/Module.js'
|
|
53
53
|
*/
|
|
54
54
|
this.resolve = function (moduleName) {
|
|
55
55
|
let root, ext, ns;
|
package/src/Container.js
CHANGED
|
@@ -13,7 +13,7 @@ import Resolver from './Container/Resolver.js';
|
|
|
13
13
|
/**
|
|
14
14
|
* ID to store singletons in the internal registry.
|
|
15
15
|
* @param {TeqFw_Di_DepId} key
|
|
16
|
-
* @
|
|
16
|
+
* @returns {string}
|
|
17
17
|
*/
|
|
18
18
|
function getSingletonId(key) {
|
|
19
19
|
return `${key.moduleName}#${key.exportName}`;
|
|
@@ -63,7 +63,7 @@ export default class TeqFw_Di_Container {
|
|
|
63
63
|
*
|
|
64
64
|
* @param {string} depId runtime dependency ID
|
|
65
65
|
* @param {string[]} stack set of the depId to detect circular dependencies
|
|
66
|
-
* @
|
|
66
|
+
* @returns {Promise<*>}
|
|
67
67
|
*/
|
|
68
68
|
this.compose = async function (depId, stack = []) {
|
|
69
69
|
log(`Object '${depId}' is requested.`);
|
package/src/Defs.js
CHANGED