@teqfw/di 1.1.3 → 1.3.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 +107 -113
- package/package.json +5 -7
- package/src/Api/Container/Config.js +73 -0
- package/src/Api/Container/Parser/Chunk.js +7 -3
- package/src/Api/Container/Parser.js +10 -4
- package/src/Api/Container/PostProcessor.js +8 -4
- package/src/Api/Container/PreProcessor/Chunk.js +4 -2
- package/src/Api/Container/PreProcessor.js +7 -3
- package/src/Api/Container/Resolver.js +4 -2
- package/src/Api/Container.js +19 -0
- package/src/Container/Config.js +93 -0
- package/src/Container/Resolver.js +1 -1
- package/types.d.ts +32 -21
- package/CHANGELOG.md +0 -39
package/README.md
CHANGED
|
@@ -3,31 +3,18 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
> [!
|
|
7
|
-
>
|
|
6
|
+
> [!WARNING]
|
|
7
|
+
> This branch contains the **legacy v1 line** of `@teqfw/di`.
|
|
8
|
+
> The code here is **manually authored** and is kept for compatibility with existing integrations and previously delivered solutions.
|
|
8
9
|
>
|
|
9
|
-
>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Unlike typical object containers, `@teqfw/di` requires no manual registration of objects, instead mapping dependency IDs
|
|
16
|
-
directly to their source paths for greater simplicity. However, for advanced use cases—such as unit testing—it is
|
|
17
|
-
possible to explicitly register singleton objects using the `register(depId, obj)` method (available only in test mode).
|
|
18
|
-
This allows controlled substitution of dependencies without altering the main codebase.
|
|
19
|
-
|
|
20
|
-
**This library is specifically optimized for ES6 modules, ensuring top performance and compatibility. It does not
|
|
21
|
-
support CommonJS, AMD, UMD, or other module formats.**
|
|
22
|
-
|
|
23
|
-
To increase robustness, all instances created by the container are automatically **frozen** using `Object.freeze()`.
|
|
24
|
-
This guarantees immutability of the returned objects, helping prevent accidental modifications and ensuring predictable
|
|
25
|
-
behavior at runtime.
|
|
10
|
+
> Active development has moved to the main branch:
|
|
11
|
+
> **https://github.com/teqfw/di/tree/main**
|
|
12
|
+
>
|
|
13
|
+
> The new container generation is built through an AI-agent workflow and follows a different architecture and dependency model.
|
|
14
|
+
> **Backward compatibility with this v1 line is not guaranteed.**
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
transpiles the source code to ES6 modules for proper functionality. With this setup, TypeScript users can effectively
|
|
30
|
-
leverage the benefits of this library without any additional configuration.
|
|
16
|
+
`@teqfw/di` v1 is a lightweight dependency injection container for standard JavaScript, enabling late binding of code
|
|
17
|
+
objects with minimal manual configuration. It integrates in both browser and Node.js environments for modularity and testing.
|
|
31
18
|
|
|
32
19
|
---
|
|
33
20
|
|
|
@@ -40,6 +27,17 @@ To explore the conceptual background, see: **[TeqFW Philosophy](./PHILOSOPHY.md)
|
|
|
40
27
|
|
|
41
28
|
---
|
|
42
29
|
|
|
30
|
+
## Dependency Declaration Model
|
|
31
|
+
|
|
32
|
+
In `@teqfw/di`, dependencies are declared **exclusively in the constructor (or factory) signature**.
|
|
33
|
+
A component defines its dependencies using a **single object parameter**, where each property name
|
|
34
|
+
is a dependency identifier interpreted by the container.
|
|
35
|
+
|
|
36
|
+
The container analyzes the constructor signature, resolves all declared identifiers **before object
|
|
37
|
+
creation**, and invokes the constructor with a fully populated argument object. Created objects are isolated from the container.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
43
41
|
## Samples
|
|
44
42
|
|
|
45
43
|
Explore `@teqfw/di` in action through the following demo applications:
|
|
@@ -70,41 +68,42 @@ configuring the container, and finally retrieving the main object with injected
|
|
|
70
68
|
Here’s an example of how files might be organized in a project. This structure can vary depending on your project needs,
|
|
71
69
|
as the container can be configured to work with any layout (e.g., within `/home/user/project/`):
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
```text
|
|
72
|
+
./src/
|
|
73
|
+
./Service/
|
|
74
|
+
./Customer.js
|
|
75
|
+
./Sale.js
|
|
76
|
+
./Config.js
|
|
77
|
+
./Logger.js
|
|
78
|
+
./Main.js
|
|
79
|
+
```
|
|
82
80
|
|
|
83
81
|
### Step 2: Declare Dependencies
|
|
84
82
|
|
|
85
|
-
In your code, declare dependencies by specifying them as keys in the constructor.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
83
|
+
In your code, declare dependencies by specifying them as keys in the constructor. This is the only supported
|
|
84
|
+
way to declare dependencies in `@teqfw/di`. Dependency identifiers here follow a namespace style similar to PHP
|
|
85
|
+
Zend 1, which is used by default in this library. You can also implement a custom parser if you prefer a
|
|
86
|
+
different naming convention or mapping strategy.
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
export default class App_Main {
|
|
90
|
+
constructor({
|
|
91
|
+
App_Config$: config,
|
|
92
|
+
App_Logger$: logger,
|
|
93
|
+
App_Service_Customer$: servCustomer,
|
|
94
|
+
App_Service_Sale$: servSale,
|
|
95
|
+
}) {
|
|
96
|
+
/* ... */
|
|
97
|
+
}
|
|
99
98
|
}
|
|
100
|
-
|
|
99
|
+
```
|
|
101
100
|
|
|
102
101
|
### Step 3: Configure the Container
|
|
103
102
|
|
|
104
103
|
Next, set up the container and configure it to use the correct namespace and path for your dependencies:
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
```js
|
|
106
|
+
import Container from "@teqfw/di";
|
|
108
107
|
|
|
109
108
|
// Create a new instance of the container
|
|
110
109
|
const container = new Container();
|
|
@@ -113,17 +112,17 @@ const container = new Container();
|
|
|
113
112
|
const resolver = container.getResolver();
|
|
114
113
|
|
|
115
114
|
// Define the namespace root for dependencies, allowing the container to resolve identifiers like 'App_*'
|
|
116
|
-
resolver.addNamespaceRoot(
|
|
117
|
-
|
|
115
|
+
resolver.addNamespaceRoot("App_", "/home/user/project/src");
|
|
116
|
+
```
|
|
118
117
|
|
|
119
118
|
### Step 4: Retrieve the Main Object with Dependencies
|
|
120
119
|
|
|
121
120
|
Finally, retrieve your main application instance. The container automatically injects all declared dependencies:
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const app = await container.get(
|
|
126
|
-
|
|
122
|
+
```js
|
|
123
|
+
// Retrieve the main application instance as a singleton asynchronously
|
|
124
|
+
const app = await container.get("App_Main$");
|
|
125
|
+
```
|
|
127
126
|
|
|
128
127
|
---
|
|
129
128
|
|
|
@@ -136,7 +135,7 @@ When test mode is enabled via `container.enableTestMode()`, you can manually reg
|
|
|
136
135
|
|
|
137
136
|
```js
|
|
138
137
|
container.enableTestMode();
|
|
139
|
-
container.register(
|
|
138
|
+
container.register("App_Service_Customer$", mockCustomerService);
|
|
140
139
|
```
|
|
141
140
|
|
|
142
141
|
This makes it easy to substitute real implementations with mocks or stubs during tests, without altering production
|
|
@@ -148,17 +147,17 @@ A powerful feature of `@teqfw/di` is the ability to mock **Node.js built-in libr
|
|
|
148
147
|
`process`. This is useful for isolating side effects and simulating system behavior:
|
|
149
148
|
|
|
150
149
|
```js
|
|
151
|
-
container.register(
|
|
152
|
-
|
|
150
|
+
container.register("node:fs", {
|
|
151
|
+
existsSync: (path) => path.endsWith(".html"),
|
|
153
152
|
});
|
|
154
153
|
```
|
|
155
154
|
|
|
156
155
|
You can also register mocks for custom logic or environment-specific behavior:
|
|
157
156
|
|
|
158
157
|
```js
|
|
159
|
-
container.register(
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
container.register("node:path", {
|
|
159
|
+
join: (...args) => args.join("/"),
|
|
160
|
+
resolve: (p) => `/abs/${p}`,
|
|
162
161
|
});
|
|
163
162
|
```
|
|
164
163
|
|
|
@@ -173,9 +172,8 @@ isolated, and deterministic unit tests — even for logic that relies on the fil
|
|
|
173
172
|
extensive flexibility and configurability. This allows the library to adapt seamlessly to a wide range of project needs.
|
|
174
173
|
Here’s what makes it stand out:
|
|
175
174
|
|
|
176
|
-
- **Automatic Dependency Resolution**: The library
|
|
177
|
-
|
|
178
|
-
box but can be fully customized if needed.
|
|
175
|
+
- **Automatic Dependency Resolution**: The library resolves and injects dependencies by interpreting constructor
|
|
176
|
+
signatures. This basic functionality works out of the box but can be fully customized if needed.
|
|
179
177
|
|
|
180
178
|
- **Flexible Dependency ID Configuration**: With customizable parsers and chunks, you can define unique ID schemes for
|
|
181
179
|
dependencies, making it easy to adapt the library to specific naming conventions or custom mapping rules.
|
|
@@ -210,45 +208,43 @@ be easily customized to meet unique project demands.
|
|
|
210
208
|
|
|
211
209
|
To install `@teqfw/di` in a Node.js environment, use the following command:
|
|
212
210
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
```shell
|
|
212
|
+
npm install @teqfw/di
|
|
213
|
+
```
|
|
216
214
|
|
|
217
215
|
Then, import and initialize the container:
|
|
218
216
|
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
```js
|
|
218
|
+
import Container from "@teqfw/di";
|
|
221
219
|
|
|
222
220
|
/** @type {TeqFw_Di_Container} */
|
|
223
221
|
const container = new Container();
|
|
224
|
-
|
|
222
|
+
```
|
|
225
223
|
|
|
226
224
|
### For the Browser (ESM Module)
|
|
227
225
|
|
|
228
226
|
To use `@teqfw/di` in a browser environment with ES modules, include it as follows (~5KB):
|
|
229
227
|
|
|
230
|
-
|
|
231
|
-
|
|
228
|
+
```html
|
|
232
229
|
<script type="module">
|
|
233
|
-
|
|
230
|
+
import Container from "https://cdn.jsdelivr.net/npm/@teqfw/di@latest/+esm";
|
|
234
231
|
|
|
235
|
-
|
|
236
|
-
|
|
232
|
+
/** @type {TeqFw_Di_Container} */
|
|
233
|
+
const container = new Container();
|
|
237
234
|
</script>
|
|
238
|
-
|
|
235
|
+
```
|
|
239
236
|
|
|
240
237
|
### For the Browser (UMD Module)
|
|
241
238
|
|
|
242
239
|
Alternatively, you can use the UMD version in the browser (~5KB):
|
|
243
240
|
|
|
244
|
-
|
|
245
|
-
|
|
241
|
+
```html
|
|
246
242
|
<script src="https://cdn.jsdelivr.net/npm/@teqfw/di@latest/dist/umd.js"></script>
|
|
247
243
|
<script>
|
|
248
|
-
|
|
249
|
-
|
|
244
|
+
/** @type {TeqFw_Di_Container} */
|
|
245
|
+
const container = new window.TeqFw_Di_Container();
|
|
250
246
|
</script>
|
|
251
|
-
|
|
247
|
+
```
|
|
252
248
|
|
|
253
249
|
---
|
|
254
250
|
|
|
@@ -259,35 +255,35 @@ Alternatively, you can use the UMD version in the browser (~5KB):
|
|
|
259
255
|
1. **Configure Dependency Mapping**: Configure the resolver to detect the platform environment. Then, set up namespace
|
|
260
256
|
roots to map dependency IDs to their source paths.
|
|
261
257
|
|
|
262
|
-
|
|
263
|
-
|
|
258
|
+
```js
|
|
259
|
+
import { platform } from "node:process";
|
|
264
260
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
261
|
+
const resolver = container.getResolver();
|
|
262
|
+
resolver.setWindowsEnv(platform === "win32"); // Adjusts for Windows environment if needed
|
|
263
|
+
resolver.addNamespaceRoot("App_", "/path/to/src");
|
|
264
|
+
```
|
|
269
265
|
|
|
270
266
|
2. **Retrieve Singleton Instances**: Retrieve the main application instance as a singleton asynchronously:
|
|
271
267
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
```js
|
|
269
|
+
const app = await container.get("App_Main$");
|
|
270
|
+
```
|
|
275
271
|
|
|
276
272
|
### In the Browser
|
|
277
273
|
|
|
278
274
|
1. **Configure Dependency Mapping**: Set up namespace roots to map dependency IDs to their source paths, using URLs as
|
|
279
275
|
needed.
|
|
280
276
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
277
|
+
```js
|
|
278
|
+
const resolver = container.getResolver();
|
|
279
|
+
resolver.addNamespaceRoot("App_", "https://cdn.jsdelivr.net/npm/@flancer64/demo-di-app@0.2/src");
|
|
280
|
+
```
|
|
285
281
|
|
|
286
282
|
2. **Retrieve Singleton Instances**: Retrieve the main application instance as a singleton asynchronously:
|
|
287
283
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
284
|
+
```js
|
|
285
|
+
const app = await container.get("App_Main$");
|
|
286
|
+
```
|
|
291
287
|
|
|
292
288
|
With these steps, the container is configured to automatically resolve and inject dependencies based on your setup,
|
|
293
289
|
whether in Node.js or in a browser environment.
|
|
@@ -300,7 +296,7 @@ whether in Node.js or in a browser environment.
|
|
|
300
296
|
quick reference:
|
|
301
297
|
|
|
302
298
|
| Dependency ID | Import Style | Description |
|
|
303
|
-
|
|
299
|
+
| --------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
|
|
304
300
|
| `App_Service` | `import * as Service from './App/Service.js';` | Imports the entire module as an ES module. |
|
|
305
301
|
| `App_Service.default` | `import {default} from './App/Service.js';` | Imports the default export as-is. |
|
|
306
302
|
| `App_Service.name` | `import {name} from './App/Service.js';` | Imports a named export as-is. |
|
|
@@ -316,20 +312,18 @@ Here’s an example showing a class with multiple dependencies, each using diffe
|
|
|
316
312
|
|
|
317
313
|
```js
|
|
318
314
|
export default class App_Main {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const {default: SrvDef, name: SrvName} = EsModule; // Deconstruct the module and access the exports
|
|
332
|
-
}
|
|
315
|
+
constructor({
|
|
316
|
+
App_Service: EsModule,
|
|
317
|
+
"App_Service.default": defaultExportAsIs,
|
|
318
|
+
"App_Service.name": namedExportAsIs,
|
|
319
|
+
App_Service$: defaultExportAsSingleton,
|
|
320
|
+
App_Service$$: defaultExportAsInstance,
|
|
321
|
+
"App_Service.name$": namedExportAsSingleton,
|
|
322
|
+
"App_Service.name$$": namedExportAsInstance,
|
|
323
|
+
"App_Service.name(factory)": factoryToCreateInstancesFromNamedExport,
|
|
324
|
+
}) {
|
|
325
|
+
const { default: SrvDef, name: SrvName } = EsModule; // Deconstruct the module and access the exports
|
|
326
|
+
}
|
|
333
327
|
}
|
|
334
328
|
```
|
|
335
329
|
|
|
@@ -353,4 +347,4 @@ channels:
|
|
|
353
347
|
|
|
354
348
|
You can also leave suggestions, feedback, and feature requests directly on GitHub by opening an issue in the repository.
|
|
355
349
|
|
|
356
|
-
Happy coding!
|
|
350
|
+
Happy coding!
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teqfw/di",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Dependency Injection container for ES6 modules that works in both browser and Node.js apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency injection",
|
|
@@ -23,9 +23,6 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"dist/",
|
|
25
25
|
"src/",
|
|
26
|
-
"CHANGELOG.md",
|
|
27
|
-
"LICENSE",
|
|
28
|
-
"README.md",
|
|
29
26
|
"teqfw.json",
|
|
30
27
|
"types.d.ts"
|
|
31
28
|
],
|
|
@@ -48,15 +45,16 @@
|
|
|
48
45
|
},
|
|
49
46
|
"scripts": {
|
|
50
47
|
"rollup": "rollup -c",
|
|
51
|
-
"eslint": "eslint './src/**/*.js'",
|
|
52
|
-
"test": "node --test"
|
|
48
|
+
"eslint": "npx eslint './src/**/*.js'",
|
|
49
|
+
"test:unit": "node --test"
|
|
53
50
|
},
|
|
54
51
|
"devDependencies": {
|
|
55
52
|
"@eslint/js": "^9.33.0",
|
|
56
53
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
57
54
|
"@rollup/plugin-terser": "^0.4.4",
|
|
58
55
|
"eslint": "^9.33.0",
|
|
59
|
-
"rollup": "^4.47.1"
|
|
56
|
+
"rollup": "^4.47.1",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
60
58
|
},
|
|
61
59
|
"engines": {
|
|
62
60
|
"node": ">=20"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public configuration API of the DI container.
|
|
3
|
+
*
|
|
4
|
+
* This is not executable code, it is just for documentation purposes (similar to .h files in the C/C++ language).
|
|
5
|
+
* @interface
|
|
6
|
+
*/
|
|
7
|
+
export default class TeqFw_Di_Api_Container_Config {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns the parser configurator.
|
|
11
|
+
*
|
|
12
|
+
* @returns {TeqFw_Di_Api_Container_Parser}
|
|
13
|
+
*/
|
|
14
|
+
parser() {
|
|
15
|
+
throw new Error('TeqFw_Di_Api_Container_Config#parser is abstract.');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Returns the pre-processor configurator.
|
|
20
|
+
*
|
|
21
|
+
* @returns {TeqFw_Di_Api_Container_PreProcessor}
|
|
22
|
+
*/
|
|
23
|
+
preProcessor() {
|
|
24
|
+
throw new Error('TeqFw_Di_Api_Container_Config#preProcessor is abstract.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns the post-processor configurator.
|
|
29
|
+
*
|
|
30
|
+
* @returns {TeqFw_Di_Api_Container_PostProcessor}
|
|
31
|
+
*/
|
|
32
|
+
postProcessor() {
|
|
33
|
+
throw new Error('TeqFw_Di_Api_Container_Config#postProcessor is abstract.');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns the resolver configurator.
|
|
38
|
+
*
|
|
39
|
+
* @returns {TeqFw_Di_Api_Container_Resolver}
|
|
40
|
+
*/
|
|
41
|
+
resolver() {
|
|
42
|
+
throw new Error('TeqFw_Di_Api_Container_Config#resolver is abstract.');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Enables test mode.
|
|
47
|
+
*
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
enableTestMode() {
|
|
51
|
+
throw new Error('TeqFw_Di_Api_Container_Config#enableTestMode is abstract.');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Registers a singleton or a Node.js module replacement in test mode.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} depId
|
|
58
|
+
* @param {object} obj
|
|
59
|
+
* @returns {void}
|
|
60
|
+
*/
|
|
61
|
+
register(depId, obj) {
|
|
62
|
+
throw new Error('TeqFw_Di_Api_Container_Config#register is abstract.');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Finalizes configuration and returns a runtime container instance.
|
|
67
|
+
*
|
|
68
|
+
* @returns {TeqFw_Di_Api_Container}
|
|
69
|
+
*/
|
|
70
|
+
finalize() {
|
|
71
|
+
throw new Error('TeqFw_Di_Api_Container_Config#finalize is abstract.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -12,12 +12,16 @@ export default class TeqFw_Di_Api_Container_Parser_Chunk {
|
|
|
12
12
|
* @param {string} depId
|
|
13
13
|
* @returns {boolean}
|
|
14
14
|
*/
|
|
15
|
-
canParse(depId) {
|
|
15
|
+
canParse(depId) {
|
|
16
|
+
throw new Error('TeqFw_Di_Api_Container_Parser_Chunk#canParse is abstract.');
|
|
17
|
+
}
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Parses a string ID for a runtime dependency and returns structured data (DTO).
|
|
19
21
|
* @param {string} depId
|
|
20
22
|
* @returns {TeqFw_Di_DepId}
|
|
21
23
|
*/
|
|
22
|
-
parse(depId) {
|
|
23
|
-
|
|
24
|
+
parse(depId) {
|
|
25
|
+
throw new Error('TeqFw_Di_Api_Container_Parser_Chunk#parse is abstract.');
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -10,19 +10,25 @@ export default class TeqFw_Di_Api_Container_Parser {
|
|
|
10
10
|
*
|
|
11
11
|
* @param {TeqFw_Di_Api_Container_Parser_Chunk} chunk
|
|
12
12
|
*/
|
|
13
|
-
addChunk(chunk) {
|
|
13
|
+
addChunk(chunk) {
|
|
14
|
+
throw new Error('TeqFw_Di_Api_Container_Parser#addChunk is abstract.');
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Parse given dependency ID and return structured data as DTO.
|
|
17
19
|
* @param {string} depId
|
|
18
20
|
* @returns {TeqFw_Di_DepId}
|
|
19
21
|
*/
|
|
20
|
-
parse(depId) {
|
|
22
|
+
parse(depId) {
|
|
23
|
+
throw new Error('TeqFw_Di_Api_Container_Parser#parse is abstract.');
|
|
24
|
+
}
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
* Sets the default chunk of the parser.
|
|
24
28
|
*
|
|
25
29
|
* @param {TeqFw_Di_Api_Container_Parser_Chunk} chunk
|
|
26
30
|
*/
|
|
27
|
-
setDefaultChunk(chunk) {
|
|
28
|
-
|
|
31
|
+
setDefaultChunk(chunk) {
|
|
32
|
+
throw new Error('TeqFw_Di_Api_Container_Parser#setDefaultChunk is abstract.');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -10,16 +10,20 @@ export default class TeqFw_Di_Api_Container_PostProcessor {
|
|
|
10
10
|
*
|
|
11
11
|
* @param {TeqFw_Di_Api_Container_PostProcessor_Chunk} chunk
|
|
12
12
|
*/
|
|
13
|
-
addChunk(chunk) {
|
|
13
|
+
addChunk(chunk) {
|
|
14
|
+
throw new Error('TeqFw_Di_Api_Container_PostProcessor#addChunk is abstract.');
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Modifies the result of the object composition.
|
|
17
19
|
*
|
|
18
20
|
* @param {*} obj - The result object to be modified.
|
|
19
21
|
* @param {TeqFw_Di_DepId} depId - The original depID DTO.
|
|
20
|
-
* @param {string[]} - The stack of parent IDs.
|
|
22
|
+
* @param {string[]} stack - The stack of parent IDs.
|
|
21
23
|
* @returns {Promise<*>}
|
|
22
24
|
*/
|
|
23
|
-
modify(obj, depId, stack) {
|
|
25
|
+
modify(obj, depId, stack) {
|
|
26
|
+
throw new Error('TeqFw_Di_Api_Container_PostProcessor#modify is abstract.');
|
|
27
|
+
}
|
|
24
28
|
|
|
25
|
-
}
|
|
29
|
+
}
|
|
@@ -13,5 +13,7 @@ export default class TeqFw_Di_Api_Container_PreProcessor_Chunk {
|
|
|
13
13
|
* @param {string[]} stack - stack of parents depIds
|
|
14
14
|
* @returns {TeqFw_Di_DepId}
|
|
15
15
|
*/
|
|
16
|
-
modify(depId, originalId, stack) {
|
|
17
|
-
|
|
16
|
+
modify(depId, originalId, stack) {
|
|
17
|
+
throw new Error('TeqFw_Di_Api_Container_PreProcessor_Chunk#modify is abstract.');
|
|
18
|
+
}
|
|
19
|
+
};
|
|
@@ -10,7 +10,9 @@ export default class TeqFw_Di_Api_Container_PreProcessor {
|
|
|
10
10
|
*
|
|
11
11
|
* @param {TeqFw_Di_Api_Container_PreProcessor_Chunk} chunk
|
|
12
12
|
*/
|
|
13
|
-
addChunk(chunk) {
|
|
13
|
+
addChunk(chunk) {
|
|
14
|
+
throw new Error('TeqFw_Di_Api_Container_PreProcessor#addChunk is abstract.');
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Modify parsed depID and return it.
|
|
@@ -18,6 +20,8 @@ export default class TeqFw_Di_Api_Container_PreProcessor {
|
|
|
18
20
|
* @param {string[]} stack - The stack of parent IDs.
|
|
19
21
|
* @returns {TeqFw_Di_DepId} -
|
|
20
22
|
*/
|
|
21
|
-
modify(depId, stack) {
|
|
23
|
+
modify(depId, stack) {
|
|
24
|
+
throw new Error('TeqFw_Di_Api_Container_PreProcessor#modify is abstract.');
|
|
25
|
+
}
|
|
22
26
|
|
|
23
|
-
}
|
|
27
|
+
}
|
|
@@ -11,6 +11,8 @@ export default class TeqFw_Di_Api_Container_Resolver {
|
|
|
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
|
-
resolve(moduleName) {
|
|
14
|
+
resolve(moduleName) {
|
|
15
|
+
throw new Error('TeqFw_Di_Api_Container_Resolver#resolve is abstract.');
|
|
16
|
+
}
|
|
15
17
|
|
|
16
|
-
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public runtime API of the DI container.
|
|
3
|
+
*
|
|
4
|
+
* This is not executable code, it is just for documentation purposes (similar to .h files in the C/C++ language).
|
|
5
|
+
* @interface
|
|
6
|
+
*/
|
|
7
|
+
export default class TeqFw_Di_Api_Container {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a dependency by its identifier and returns the result.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} depId
|
|
13
|
+
* @param {string[]} [stack]
|
|
14
|
+
* @returns {Promise<*>}
|
|
15
|
+
*/
|
|
16
|
+
get(depId, stack) {
|
|
17
|
+
throw new Error('TeqFw_Di_Api_Container#get is abstract.');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import Container from '../Container.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runtime configuration facade for the DI container.
|
|
5
|
+
*
|
|
6
|
+
* @implements {TeqFw_Di_Api_Container_Config}
|
|
7
|
+
*/
|
|
8
|
+
export default class TeqFw_Di_Container_Config {
|
|
9
|
+
constructor() {
|
|
10
|
+
// VARS
|
|
11
|
+
const _container = new Container();
|
|
12
|
+
let _finalized = false;
|
|
13
|
+
|
|
14
|
+
// FUNCS
|
|
15
|
+
function assertNotFinalized() {
|
|
16
|
+
if (_finalized) throw new Error('Container configuration is finalized.');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// INSTANCE METHODS
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Returns the parser configurator.
|
|
23
|
+
*
|
|
24
|
+
* @returns {TeqFw_Di_Api_Container_Parser}
|
|
25
|
+
*/
|
|
26
|
+
this.parser = function () {
|
|
27
|
+
assertNotFinalized();
|
|
28
|
+
return _container.getParser();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns the pre-processor configurator.
|
|
33
|
+
*
|
|
34
|
+
* @returns {TeqFw_Di_Api_Container_PreProcessor}
|
|
35
|
+
*/
|
|
36
|
+
this.preProcessor = function () {
|
|
37
|
+
assertNotFinalized();
|
|
38
|
+
return _container.getPreProcessor();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the post-processor configurator.
|
|
43
|
+
*
|
|
44
|
+
* @returns {TeqFw_Di_Api_Container_PostProcessor}
|
|
45
|
+
*/
|
|
46
|
+
this.postProcessor = function () {
|
|
47
|
+
assertNotFinalized();
|
|
48
|
+
return _container.getPostProcessor();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Returns the resolver configurator.
|
|
53
|
+
*
|
|
54
|
+
* @returns {TeqFw_Di_Api_Container_Resolver}
|
|
55
|
+
*/
|
|
56
|
+
this.resolver = function () {
|
|
57
|
+
assertNotFinalized();
|
|
58
|
+
return _container.getResolver();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Enables test mode.
|
|
63
|
+
*
|
|
64
|
+
* @returns {void}
|
|
65
|
+
*/
|
|
66
|
+
this.enableTestMode = function () {
|
|
67
|
+
assertNotFinalized();
|
|
68
|
+
_container.enableTestMode();
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Registers a singleton or a Node.js module replacement in test mode.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} depId
|
|
75
|
+
* @param {object} obj
|
|
76
|
+
* @returns {void}
|
|
77
|
+
*/
|
|
78
|
+
this.register = function (depId, obj) {
|
|
79
|
+
assertNotFinalized();
|
|
80
|
+
_container.register(depId, obj);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Finalizes configuration and returns a runtime container instance.
|
|
85
|
+
*
|
|
86
|
+
* @returns {TeqFw_Di_Api_Container}
|
|
87
|
+
*/
|
|
88
|
+
this.finalize = function () {
|
|
89
|
+
_finalized = true;
|
|
90
|
+
return _container;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
package/types.d.ts
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
|
|
1
3
|
declare global {
|
|
2
|
-
type
|
|
3
|
-
type
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
type
|
|
7
|
-
type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type
|
|
11
|
-
type
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
type
|
|
15
|
-
type
|
|
16
|
-
type
|
|
17
|
-
type
|
|
18
|
-
type
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
type TeqFw_Di_Api_Container = InstanceType<typeof import('./src/Api/Container.js').default>;
|
|
5
|
+
type TeqFw_Di_Api_Container_Config = InstanceType<typeof import('./src/Api/Container/Config.js').default>;
|
|
6
|
+
type TeqFw_Di_Api_Container_Parser = InstanceType<typeof import('./src/Api/Container/Parser.js').default>;
|
|
7
|
+
type TeqFw_Di_Api_Container_Parser_Chunk = InstanceType<typeof import('./src/Api/Container/Parser/Chunk.js').default>;
|
|
8
|
+
type TeqFw_Di_Api_Container_PostProcessor = InstanceType<typeof import('./src/Api/Container/PostProcessor.js').default>;
|
|
9
|
+
type TeqFw_Di_Api_Container_PostProcessor_Chunk = InstanceType<
|
|
10
|
+
typeof import('./src/Api/Container/PostProcessor/Chunk.js').default
|
|
11
|
+
>;
|
|
12
|
+
type TeqFw_Di_Api_Container_PreProcessor = InstanceType<typeof import('./src/Api/Container/PreProcessor.js').default>;
|
|
13
|
+
type TeqFw_Di_Api_Container_PreProcessor_Chunk = InstanceType<
|
|
14
|
+
typeof import('./src/Api/Container/PreProcessor/Chunk.js').default
|
|
15
|
+
>;
|
|
16
|
+
type TeqFw_Di_Api_Container_Resolver = InstanceType<typeof import('./src/Api/Container/Resolver.js').default>;
|
|
17
|
+
type TeqFw_Di_Container = InstanceType<typeof import('./src/Container.js').default>;
|
|
18
|
+
type TeqFw_Di_Container_A_Composer = InstanceType<typeof import('./src/Container/A/Composer.js').default>;
|
|
19
|
+
type TeqFw_Di_Container_A_Composer_A_SpecParser = typeof import('./src/Container/A/Composer/A/SpecParser.js').default;
|
|
20
|
+
type TeqFw_Di_Container_A_Parser_Chunk_Def = InstanceType<
|
|
21
|
+
typeof import('./src/Container/A/Parser/Chunk/Def.js').default
|
|
22
|
+
>;
|
|
23
|
+
type TeqFw_Di_Container_A_Parser_Chunk_V02X = InstanceType<
|
|
24
|
+
typeof import('./src/Container/A/Parser/Chunk/V02X.js').default
|
|
25
|
+
>;
|
|
26
|
+
type TeqFw_Di_Container_Config = InstanceType<typeof import('./src/Container/Config.js').default>;
|
|
27
|
+
type TeqFw_Di_Container_Parser = InstanceType<typeof import('./src/Container/Parser.js').default>;
|
|
28
|
+
type TeqFw_Di_Container_PostProcessor = InstanceType<typeof import('./src/Container/PostProcessor.js').default>;
|
|
29
|
+
type TeqFw_Di_Container_PreProcessor = InstanceType<typeof import('./src/Container/PreProcessor.js').default>;
|
|
30
|
+
type TeqFw_Di_Container_Resolver = InstanceType<typeof import('./src/Container/Resolver.js').default>;
|
|
31
|
+
type TeqFw_Di_Defs = typeof import('./src/Defs.js').default;
|
|
32
|
+
type TeqFw_Di_DepId = InstanceType<typeof import('./src/DepId.js').default>;
|
|
33
|
+
type TeqFw_Di_Pre_Replace = InstanceType<typeof import('./src/Pre/Replace.js').default>;
|
|
21
34
|
}
|
|
22
|
-
|
|
23
|
-
export {};
|
package/CHANGELOG.md
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 1.1.3
|
|
4
|
-
|
|
5
|
-
- Added global type declarations to `types.d.ts` to match the type map architecture rules.
|
|
6
|
-
|
|
7
|
-
## 1.1.2
|
|
8
|
-
|
|
9
|
-
- Moved architecture diagrams into `ctx/img/` and updated the context map accordingly.
|
|
10
|
-
- Clarified type map rules to require global namespace declarations for IDE type resolution.
|
|
11
|
-
|
|
12
|
-
## 1.1.1
|
|
13
|
-
|
|
14
|
-
- Added missing published files (`CHANGELOG.md`, `teqfw.json`, `types.d.ts`) and declared `types.d.ts` in `package.json`.
|
|
15
|
-
|
|
16
|
-
## 1.1.0
|
|
17
|
-
|
|
18
|
-
- Added ADSM cognitive context documentation and reporting structure under `ctx/`.
|
|
19
|
-
- Added type map documentation and a `types.d.ts` namespace-to-source mapping for IDE support.
|
|
20
|
-
- Updated `.npmignore` to ignore `output.md` artifacts.
|
|
21
|
-
|
|
22
|
-
## 1.0.2
|
|
23
|
-
|
|
24
|
-
- Added ability to import the Replace preprocessor chunk via package subpath (`./pre/replace`).
|
|
25
|
-
- Updated `.npmignore` to exclude development artifacts (`ctx/`, logs, test files) and ensure clean npm package contents.
|
|
26
|
-
- Improved ignore patterns to prevent accidental publication of internal files.
|
|
27
|
-
|
|
28
|
-
## 1.0.1
|
|
29
|
-
|
|
30
|
-
- Prepare npm package for publication.
|
|
31
|
-
- Add distribution build outputs to package files and specify entry points.
|
|
32
|
-
|
|
33
|
-
## 1.0.0
|
|
34
|
-
|
|
35
|
-
- Started changelog for version 1.0.0.
|
|
36
|
-
- Added AGENTS.md with English-only guidelines and link to PHILOSOPHY.md.
|
|
37
|
-
- Switched tests from Mocha to Node's built-in runner.
|
|
38
|
-
- Updated package scripts and removed Mocha dependency.
|
|
39
|
-
- Documented breaking changes for v1.0.0: the container can no longer access itself, configuration must occur in the Composition Root, and legacy versions live in the `forerunner` branch.
|