@teqfw/di 0.30.0 → 0.30.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/README.md +137 -43
- package/RELEASE.md +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
# @teqfw/di
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
5
|
|
|
6
|
-
**This library exclusively supports ES6 modules.**
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
`@teqfw/di` is a dependency injection container for standard JavaScript. This library is compatible with both browser
|
|
8
|
+
and Node.js environments.
|
|
9
|
+
|
|
10
|
+
**This library only supports ES6 modules ([the live demo](https://flancer64.github.io/demo-di-app/)).**
|
|
11
|
+
|
|
12
|
+
More samples:
|
|
13
|
+
|
|
14
|
+
* [demo-wa-esm-openai](https://github.com/flancer64/demo-wa-esm-openai)
|
|
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)
|
|
19
|
+
|
|
20
|
+
This library is primarily designed to simplify the binding of code objects with minimal manual configuration required
|
|
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:
|
|
11
23
|
|
|
12
24
|
```js
|
|
13
25
|
export default class App_Main {
|
|
@@ -23,7 +35,7 @@ export default class App_Main {
|
|
|
23
35
|
}
|
|
24
36
|
```
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
Corresponding files would look like this:
|
|
27
39
|
|
|
28
40
|
```
|
|
29
41
|
./src/
|
|
@@ -35,7 +47,7 @@ The files corresponded to this case:
|
|
|
35
47
|
./Main.js
|
|
36
48
|
```
|
|
37
49
|
|
|
38
|
-
|
|
50
|
+
Setting up object mapping is fairly simple:
|
|
39
51
|
|
|
40
52
|
```js
|
|
41
53
|
import Container from '@teqfw/di';
|
|
@@ -46,26 +58,42 @@ resolver.addNamespaceRoot('App_', '/path/to/src'); // or 'https://cdn.jsdelivr.n
|
|
|
46
58
|
const app = await container.get('App_Main$');
|
|
47
59
|
```
|
|
48
60
|
|
|
49
|
-
|
|
61
|
+
While it could potentially be used with TypeScript, the current algorithm for composing
|
|
62
|
+
dependency identifiers, designed for JavaScript, may not be suitable for TypeScript. A different approach for composing
|
|
63
|
+
identifiers and mapping them to the corresponding objects in the transpiled codebase would be required, which is beyond
|
|
64
|
+
the current scope of the package.
|
|
50
65
|
|
|
51
|
-
##
|
|
66
|
+
## Key Features
|
|
52
67
|
|
|
53
|
-
* **Late Binding**:
|
|
54
|
-
modularity, manageability, and clear separation of concerns.
|
|
55
|
-
* **
|
|
56
|
-
* **Interface Usage in
|
|
57
|
-
|
|
58
|
-
* **Object Wrapping**:
|
|
68
|
+
* **Late Binding**: Experience all the usual benefits of late binding at runtime including flexibility, testability,
|
|
69
|
+
modularity, manageability, and a clear separation of concerns.
|
|
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).
|
|
59
74
|
|
|
60
75
|
## Installation
|
|
61
76
|
|
|
62
|
-
|
|
77
|
+
Installation instructions for Node.js:
|
|
63
78
|
|
|
64
79
|
```shell
|
|
65
80
|
$ npm i --save @teqfw/di
|
|
66
81
|
```
|
|
67
82
|
|
|
68
|
-
|
|
83
|
+
```js
|
|
84
|
+
import Container from '@teqfw/di';
|
|
85
|
+
import {platform} from 'node:process';
|
|
86
|
+
|
|
87
|
+
/** @type {TeqFw_Di_Container} */
|
|
88
|
+
const container = new Container();
|
|
89
|
+
/** @type {TeqFw_Di_Container_Resolver} */
|
|
90
|
+
const resolver = res.getResolver();
|
|
91
|
+
resolver.setWindowsEnv(platform === 'win32');
|
|
92
|
+
resolver.addNamespaceRoot('App_', '...');
|
|
93
|
+
const app = await container.get('App_Main$');
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Installation instructions for Web as ESM (~5Kb):
|
|
69
97
|
|
|
70
98
|
```html
|
|
71
99
|
|
|
@@ -74,16 +102,21 @@ Web as ESM (~5Kb):
|
|
|
74
102
|
|
|
75
103
|
/** @type {TeqFw_Di_Container} */
|
|
76
104
|
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$');
|
|
77
110
|
...
|
|
78
111
|
</script>
|
|
79
112
|
```
|
|
80
113
|
|
|
81
|
-
Web as UMD (~5Kb):
|
|
114
|
+
Installation instructions for Web as UMD (~5Kb):
|
|
82
115
|
|
|
83
116
|
```html
|
|
84
117
|
|
|
85
118
|
<script src="https://cdn.jsdelivr.net/npm/@teqfw/di@latest/dist/umd.js"></script>
|
|
86
|
-
<script>
|
|
119
|
+
<script type="module">
|
|
87
120
|
const {default: Container} = window.TeqFw_Di_Container;
|
|
88
121
|
/** @type {TeqFw_Di_Container} */
|
|
89
122
|
const container = new Container();
|
|
@@ -91,23 +124,83 @@ Web as UMD (~5Kb):
|
|
|
91
124
|
</script>
|
|
92
125
|
```
|
|
93
126
|
|
|
94
|
-
##
|
|
127
|
+
## Dependency ID Types
|
|
128
|
+
|
|
129
|
+
Different Dependency IDs can be used for different imports, such as:
|
|
95
130
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
131
|
+
### Import whole module as ES module
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
// App_Service
|
|
135
|
+
import * as Service from './App/Service.js';
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Import default export as is
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
// App_Service.default
|
|
142
|
+
import {default} from './App/Service.js';
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Import named export as is
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
// App_Service.name
|
|
149
|
+
import {name} from './App/Service.js';
|
|
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
|
+
```
|
|
160
|
+
|
|
161
|
+
### Create a new default export as Instance for each dependency
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
// App_Service$$
|
|
165
|
+
import {default as Factory} from './App/Service.js';
|
|
166
|
+
|
|
167
|
+
return Factory({/* deps */});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Use named export as singleton.
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
// App_Service.name$
|
|
174
|
+
import {name} from './App/Service.js';
|
|
175
|
+
|
|
176
|
+
return res ?? (res = name({/* deps */}));
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Create a new named export as instance
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
// App_Service.name$$
|
|
183
|
+
import {name} from './App/Service.js';
|
|
184
|
+
|
|
185
|
+
return name({/* deps */});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Add custom wrappers to created objects in postprocessing
|
|
189
|
+
|
|
190
|
+
```js
|
|
191
|
+
// App_Service.name$$(proxy)
|
|
192
|
+
import {name} from './App/Service.js';
|
|
193
|
+
|
|
194
|
+
const res = name({/* deps */});
|
|
195
|
+
return proxy(res); // use a handler on the postprocessing
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Brief overview
|
|
106
199
|
|
|
107
200
|
```js
|
|
108
201
|
export default class App_Main {
|
|
109
|
-
|
|
110
|
-
|
|
202
|
+
constructor(
|
|
203
|
+
{
|
|
111
204
|
App_Service: EsModule,
|
|
112
205
|
'App_Service.default': defaultExportAsIs,
|
|
113
206
|
'App_Service.name': namedExportAsIs,
|
|
@@ -116,18 +209,19 @@ export default class App_Main {
|
|
|
116
209
|
'App_Service.name$': namedExportAsSingleton,
|
|
117
210
|
'App_Service.name$$': namedExportAsInstance,
|
|
118
211
|
'App_Service.name(factory)': factoryToCreateInstancesFromNamedExport,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
212
|
+
}
|
|
213
|
+
) {
|
|
214
|
+
const {default: SrvDef, name: SrvName} = EsModule; // deconstruct the module and access the exports
|
|
215
|
+
}
|
|
123
216
|
|
|
124
217
|
}
|
|
125
218
|
```
|
|
126
219
|
|
|
127
|
-
##
|
|
220
|
+
## Summary
|
|
128
221
|
|
|
129
|
-
`@teqfw/di`
|
|
130
|
-
browser and Node.js
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
and
|
|
222
|
+
The `@teqfw/di` module provides a Dependency Injection feature for JavaScript, which requires minimal manual setup. This
|
|
223
|
+
library is functional in both browser and Node.js settings. The module utilizes late binding and an object container
|
|
224
|
+
methodology in JavaScript applications. Furthermore, it equips users with the ability to alter object behaviors through
|
|
225
|
+
pseudo-interfaces and wrappers. As a result, architectural solutions from other programming languages - namely Java,
|
|
226
|
+
PHP, and C# - can be harnessed effectively. This also contributes significantly by maximizing the efficiency of npm
|
|
227
|
+
packages and ES6 modules in JavaScript applications, especially within the Node.js environment.
|
package/RELEASE.md
CHANGED