@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 CHANGED
@@ -3,31 +3,18 @@
3
3
  ![npms.io](https://img.shields.io/npm/dm/@teqfw/di)
4
4
  ![jsdelivr](https://img.shields.io/jsdelivr/npm/hm/@teqfw/di)
5
5
 
6
- > [!IMPORTANT]
7
- > **Breaking Changes in v1.0.0**
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
- > The library has been stable for a long time and is now promoted to its first major version. To improve security, the Object Container can no longer access itself, so all configuration must occur in the Composition Root. This restriction ensures that third-party plugins cannot override or modify the container's internal functionality. Legacy versions are maintained in the `forerunner` branch, and packages like `@teqfw/core` should depend on `@teqfw/di` versions below `1.0.0`.
10
-
11
- `@teqfw/di` is a lightweight dependency injection container for standard JavaScript, enabling late binding of code
12
- objects with minimal manual configuration. It integrates smoothly in both browser and Node.js environments, supporting
13
- flexibility, modularity, and easier testing for your applications.
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
- While this library is primarily designed for JavaScript, it is also fully compatible with TypeScript. Developers can use
28
- TypeScript to compose dependency identifiers in the same way as in JavaScript. It is important to ensure that TypeScript
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
- ./src/
75
- ./Service/
76
- ./Customer.js
77
- ./Sale.js
78
- ./Config.js
79
- ./Logger.js
80
- ./Main.js
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. Dependency identifiers here follow a
86
- namespace style similar to PHP Zend 1, which is used by default in this library. You can also implement a custom parser
87
- if you prefer a different naming convention or mapping strategy.
88
-
89
- ```js
90
- export default class App_Main {
91
- constructor(
92
- {
93
- App_Config$: config,
94
- App_Logger$: logger,
95
- App_Service_Customer$: servCustomer,
96
- App_Service_Sale$: servSale,
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
- ```js
107
- import Container from '@teqfw/di';
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('App_', '/home/user/project/src');
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
- ```js
124
- // Retrieve the main application instance as a singleton asynchronously
125
- const app = await container.get('App_Main$');
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('App_Service_Customer$', mockCustomerService);
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('node:fs', {
152
- existsSync: (path) => path.endsWith('.html'),
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('node:path', {
160
- join: (...args) => args.join('/'),
161
- resolve: (p) => `/abs/${p}`,
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 simplifies managing complex objects and their dependencies by
177
- automatically resolving and injecting them based on container configuration. This basic functionality works out of the
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
- ```shell
214
- $ npm install @teqfw/di
215
- ```
211
+ ```shell
212
+ npm install @teqfw/di
213
+ ```
216
214
 
217
215
  Then, import and initialize the container:
218
216
 
219
- ```js
220
- import Container from '@teqfw/di';
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
- ```html
231
-
228
+ ```html
232
229
  <script type="module">
233
- import Container from 'https://cdn.jsdelivr.net/npm/@teqfw/di@latest/+esm';
230
+ import Container from "https://cdn.jsdelivr.net/npm/@teqfw/di@latest/+esm";
234
231
 
235
- /** @type {TeqFw_Di_Container} */
236
- const container = new Container();
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
- ```html
245
-
241
+ ```html
246
242
  <script src="https://cdn.jsdelivr.net/npm/@teqfw/di@latest/dist/umd.js"></script>
247
243
  <script>
248
- /** @type {TeqFw_Di_Container} */
249
- const container = new window.TeqFw_Di_Container();
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
- ```js
263
- import { platform } from 'node:process';
258
+ ```js
259
+ import { platform } from "node:process";
264
260
 
265
- const resolver = container.getResolver();
266
- resolver.setWindowsEnv(platform === 'win32'); // Adjusts for Windows environment if needed
267
- resolver.addNamespaceRoot('App_', '/path/to/src');
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
- ```js
273
- const app = await container.get('App_Main$');
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
- ```js
282
- const resolver = container.getResolver();
283
- resolver.addNamespaceRoot('App_', 'https://cdn.jsdelivr.net/npm/@flancer64/demo-di-app@0.2/src');
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
- ```js
289
- const app = await container.get('App_Main$');
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
- constructor(
320
- {
321
- App_Service: EsModule,
322
- 'App_Service.default': defaultExportAsIs,
323
- 'App_Service.name': namedExportAsIs,
324
- App_Service$: defaultExportAsSingleton,
325
- App_Service$$: defaultExportAsInstance,
326
- 'App_Service.name$': namedExportAsSingleton,
327
- 'App_Service.name$$': namedExportAsInstance,
328
- 'App_Service.name(factory)': factoryToCreateInstancesFromNamedExport,
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.1.3",
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
+ }
@@ -21,7 +21,7 @@ const NSS = '_';
21
21
 
22
22
  // MAIN
23
23
  /**
24
- * @implements TeqFw_Di_Api_Container_Resolver
24
+ * @implements {TeqFw_Di_Api_Container_Resolver}
25
25
  */
26
26
  export default class TeqFw_Di_Container_Resolver {
27
27
 
package/types.d.ts CHANGED
@@ -1,23 +1,34 @@
1
+ export {};
2
+
1
3
  declare global {
2
- type TeqFw_Di_Api_Container_Parser = import("./src/Api/Container/Parser.js").default;
3
- type TeqFw_Di_Api_Container_Parser_Chunk = import("./src/Api/Container/Parser/Chunk.js").default;
4
- type TeqFw_Di_Api_Container_PostProcessor = import("./src/Api/Container/PostProcessor.js").default;
5
- type TeqFw_Di_Api_Container_PostProcessor_Chunk = import("./src/Api/Container/PostProcessor/Chunk.js").default;
6
- type TeqFw_Di_Api_Container_PreProcessor = import("./src/Api/Container/PreProcessor.js").default;
7
- type TeqFw_Di_Api_Container_PreProcessor_Chunk = import("./src/Api/Container/PreProcessor/Chunk.js").default;
8
- type TeqFw_Di_Api_Container_Resolver = import("./src/Api/Container/Resolver.js").default;
9
- type TeqFw_Di_Container = import("./src/Container.js").default;
10
- type TeqFw_Di_Container_A_Composer = import("./src/Container/A/Composer.js").default;
11
- type TeqFw_Di_Container_A_Composer_A_SpecParser = import("./src/Container/A/Composer/A/SpecParser.js").default;
12
- type TeqFw_Di_Container_A_Parser_Chunk_Def = import("./src/Container/A/Parser/Chunk/Def.js").default;
13
- type TeqFw_Di_Container_A_Parser_Chunk_V02X = import("./src/Container/A/Parser/Chunk/V02X.js").default;
14
- type TeqFw_Di_Container_Parser = import("./src/Container/Parser.js").default;
15
- type TeqFw_Di_Container_PostProcessor = import("./src/Container/PostProcessor.js").default;
16
- type TeqFw_Di_Container_PreProcessor = import("./src/Container/PreProcessor.js").default;
17
- type TeqFw_Di_Container_Resolver = import("./src/Container/Resolver.js").default;
18
- type TeqFw_Di_Defs = import("./src/Defs.js").default;
19
- type TeqFw_Di_DepId = import("./src/DepId.js").default;
20
- type TeqFw_Di_Pre_Replace = import("./src/Pre/Replace.js").default;
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.