@teqfw/di 1.3.0 → 2.0.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/CHANGELOG.md +8 -0
- package/README.md +173 -259
- package/dist/esm.js +1 -1
- package/dist/umd.js +1 -1
- package/package.json +16 -10
- package/src/AGENTS.md +177 -0
- package/src/Config/NamespaceRegistry.mjs +210 -0
- package/src/Container/Instantiate/ExportSelector.mjs +39 -0
- package/src/Container/Instantiate/Instantiator.mjs +143 -0
- package/src/Container/Lifecycle/Registry.mjs +81 -0
- package/src/Container/Resolve/GraphResolver.mjs +119 -0
- package/src/Container/Resolver.mjs +175 -0
- package/src/Container/Wrapper/Executor.mjs +71 -0
- package/src/Container.mjs +380 -0
- package/src/Def/Parser.mjs +146 -0
- package/src/Dto/DepId.mjs +131 -0
- package/src/Dto/Resolver/Config/Namespace.mjs +48 -0
- package/src/Dto/Resolver/Config.mjs +58 -0
- package/src/Enum/Composition.mjs +11 -0
- package/src/Enum/Life.mjs +11 -0
- package/src/Enum/Platform.mjs +12 -0
- package/src/Internal/Logger.mjs +54 -0
- package/types.d.ts +53 -26
- package/src/Api/Container/Config.js +0 -73
- package/src/Api/Container/Parser/Chunk.js +0 -27
- package/src/Api/Container/Parser.js +0 -34
- package/src/Api/Container/PostProcessor/Chunk.js +0 -17
- package/src/Api/Container/PostProcessor.js +0 -29
- package/src/Api/Container/PreProcessor/Chunk.js +0 -19
- package/src/Api/Container/PreProcessor.js +0 -27
- package/src/Api/Container/Resolver.js +0 -18
- package/src/Api/Container.js +0 -19
- package/src/Container/A/Composer/A/SpecParser.js +0 -86
- package/src/Container/A/Composer.js +0 -69
- package/src/Container/A/Parser/Chunk/Def.js +0 -69
- package/src/Container/A/Parser/Chunk/V02X.js +0 -66
- package/src/Container/Config.js +0 -93
- package/src/Container/Parser.js +0 -48
- package/src/Container/PostProcessor.js +0 -32
- package/src/Container/PreProcessor.js +0 -34
- package/src/Container/Resolver.js +0 -80
- package/src/Container.js +0 -187
- package/src/Defs.js +0 -22
- package/src/DepId.js +0 -52
- package/src/Pre/Replace.js +0 -80
- package/teqfw.json +0 -8
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 2.0.0 - 2026-02-27
|
|
4
|
+
|
|
5
|
+
- Started a new changelog lineage for generation 2 of `@teqfw/di`.
|
|
6
|
+
- Replaced legacy v1 implementation with the new architecture.
|
|
7
|
+
- Promoted `src2/` to `src/` and `test2/` to `test/` as the primary code and test layout.
|
|
8
|
+
- Updated project configuration and type paths to the new directory structure.
|
package/README.md
CHANGED
|
@@ -3,348 +3,262 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
|
|
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.
|
|
9
|
-
>
|
|
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.**
|
|
15
|
-
|
|
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.
|
|
6
|
+
Deterministic runtime DI container for native ES modules.
|
|
18
7
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## Design Philosophy
|
|
22
|
-
|
|
23
|
-
This library is a component of the **TeqFW platform**, an experimental framework grounded in the principles of modular
|
|
24
|
-
monolith design, long-term maintainability, late binding, and immutability-first logic composition.
|
|
25
|
-
|
|
26
|
-
To explore the conceptual background, see: **[TeqFW Philosophy](./PHILOSOPHY.md)**.
|
|
27
|
-
|
|
28
|
-
---
|
|
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
|
-
---
|
|
8
|
+
`@teqfw/di` uses explicit dependency contracts (CDC strings) and module-level dependency descriptors (`__deps__`).
|
|
9
|
+
It does not infer dependencies from constructor signatures.
|
|
40
10
|
|
|
41
|
-
##
|
|
11
|
+
## Version Line
|
|
42
12
|
|
|
43
|
-
|
|
13
|
+
This branch is the v2 line.
|
|
44
14
|
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
- [demo-wa-esm-openai](https://github.com/flancer64/demo-wa-esm-openai): Integrates OpenAI with ES6 modules.
|
|
48
|
-
- [pwa-wallet](https://github.com/flancer64/pwa-wallet): A progressive web application wallet showcasing the library's
|
|
49
|
-
modularity.
|
|
50
|
-
- [spa-remote-console](https://github.com/flancer64/spa-remote-console): Demonstrates remote console functionality in a
|
|
51
|
-
single-page application.
|
|
52
|
-
- [demo-webauthn-pubkey](https://github.com/flancer64/demo-webauthn-pubkey): Uses Web Authentication (WebAuthn) with
|
|
53
|
-
public key credentials.
|
|
54
|
-
- [tg-bot-habr-demo-grammy](https://github.com/flancer64/tg-bot-habr-demo-grammy): A Telegram bot demo built with the
|
|
55
|
-
grammY library.
|
|
15
|
+
- package version: `2.0.0`
|
|
16
|
+
- changelog starts from `2.0.0`
|
|
56
17
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
---
|
|
18
|
+
## Installation
|
|
60
19
|
|
|
61
|
-
|
|
20
|
+
```bash
|
|
21
|
+
npm install @teqfw/di
|
|
22
|
+
```
|
|
62
23
|
|
|
63
|
-
|
|
64
|
-
configuring the container, and finally retrieving the main object with injected dependencies.
|
|
24
|
+
## Quick Start
|
|
65
25
|
|
|
66
|
-
###
|
|
26
|
+
### 1. Define modules with `__deps__`
|
|
67
27
|
|
|
68
|
-
|
|
69
|
-
as the container can be configured to work with any layout (e.g., within `/home/user/project/`):
|
|
28
|
+
`src/App/Child.mjs`
|
|
70
29
|
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
./Sale.js
|
|
76
|
-
./Config.js
|
|
77
|
-
./Logger.js
|
|
78
|
-
./Main.js
|
|
30
|
+
```js
|
|
31
|
+
export default function App_Child() {
|
|
32
|
+
return { name: "child" };
|
|
33
|
+
}
|
|
79
34
|
```
|
|
80
35
|
|
|
81
|
-
|
|
82
|
-
|
|
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.
|
|
36
|
+
`src/App/Root.mjs`
|
|
87
37
|
|
|
88
38
|
```js
|
|
89
|
-
export
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
39
|
+
export const __deps__ = {
|
|
40
|
+
child: "App_Child$",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default function App_Root({ child }) {
|
|
44
|
+
return {
|
|
45
|
+
name: "root",
|
|
46
|
+
child,
|
|
47
|
+
};
|
|
98
48
|
}
|
|
99
49
|
```
|
|
100
50
|
|
|
101
|
-
###
|
|
102
|
-
|
|
103
|
-
Next, set up the container and configure it to use the correct namespace and path for your dependencies:
|
|
51
|
+
### 2. Configure container in composition root
|
|
104
52
|
|
|
105
53
|
```js
|
|
54
|
+
import path from "node:path";
|
|
55
|
+
import { fileURLToPath } from "node:url";
|
|
106
56
|
import Container from "@teqfw/di";
|
|
107
57
|
|
|
108
|
-
|
|
109
|
-
const
|
|
58
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
59
|
+
const __dirname = path.dirname(__filename);
|
|
110
60
|
|
|
111
|
-
|
|
112
|
-
|
|
61
|
+
const container = new Container();
|
|
62
|
+
container.addNamespaceRoot("App_", path.resolve(__dirname, "./src/App"), ".mjs");
|
|
113
63
|
|
|
114
|
-
|
|
115
|
-
|
|
64
|
+
const root = await container.get("App_Root$");
|
|
65
|
+
console.log(root.name); // root
|
|
66
|
+
console.log(root.child.name); // child
|
|
67
|
+
console.log(Object.isFrozen(root)); // true
|
|
116
68
|
```
|
|
117
69
|
|
|
118
|
-
|
|
70
|
+
## Dependency Descriptor (`__deps__`)
|
|
119
71
|
|
|
120
|
-
|
|
72
|
+
`__deps__` is a static module export:
|
|
121
73
|
|
|
122
74
|
```js
|
|
123
|
-
|
|
124
|
-
|
|
75
|
+
export const __deps__ = {
|
|
76
|
+
localName: "Some_CDC",
|
|
77
|
+
};
|
|
125
78
|
```
|
|
126
79
|
|
|
127
|
-
|
|
80
|
+
Rules used by container runtime:
|
|
128
81
|
|
|
129
|
-
|
|
82
|
+
- if `__deps__` is missing: module has zero dependencies
|
|
83
|
+
- keys are local argument names passed into factory/class constructor
|
|
84
|
+
- values are CDC strings
|
|
85
|
+
- dependencies are resolved recursively before instantiation
|
|
130
86
|
|
|
131
|
-
|
|
87
|
+
## CDC Grammar (Default Profile)
|
|
132
88
|
|
|
133
|
-
|
|
134
|
-
`register(depId, obj)` method:
|
|
89
|
+
Surface form:
|
|
135
90
|
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
container.register("App_Service_Customer$", mockCustomerService);
|
|
91
|
+
```text
|
|
92
|
+
[PlatformPrefix]ModuleName[__ExportName][LifecycleAndWrappers]
|
|
139
93
|
```
|
|
140
94
|
|
|
141
|
-
|
|
142
|
-
logic. Overrides are allowed only in test mode, ensuring clean separation of concerns.
|
|
95
|
+
Where:
|
|
143
96
|
|
|
144
|
-
|
|
97
|
+
- `PlatformPrefix`: `node_` | `npm_` | omitted (`teq` by default)
|
|
98
|
+
- `Export segment`: `__ExportName`
|
|
99
|
+
- `Lifecycle marker`: `$` | `$$` | `$$$`
|
|
100
|
+
- `Wrappers`: `_<wrapperId>` suffixes after lifecycle marker
|
|
145
101
|
|
|
146
|
-
|
|
147
|
-
`process`. This is useful for isolating side effects and simulating system behavior:
|
|
102
|
+
Examples:
|
|
148
103
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
104
|
+
- `App_Service` - whole module (`as-is`)
|
|
105
|
+
- `App_Service$` - default export as factory with lifecycle marker
|
|
106
|
+
- `App_Service__build$$` - named export `build` with lifecycle marker
|
|
107
|
+
- `App_Service$$_wrapLog_wrapTrace` - wrapper chain in declared order
|
|
108
|
+
- `node_fs` - Node builtin
|
|
109
|
+
- `npm_lodash` - npm package
|
|
110
|
+
|
|
111
|
+
Notes:
|
|
112
|
+
|
|
113
|
+
- explicit `teq_` prefix is forbidden
|
|
114
|
+
- wrappers without lifecycle marker are invalid
|
|
115
|
+
- parser is deterministic and fail-fast
|
|
154
116
|
|
|
155
|
-
|
|
117
|
+
## Public API
|
|
156
118
|
|
|
157
119
|
```js
|
|
158
|
-
container
|
|
159
|
-
join: (...args) => args.join("/"),
|
|
160
|
-
resolve: (p) => `/abs/${p}`,
|
|
161
|
-
});
|
|
120
|
+
const container = new Container();
|
|
162
121
|
```
|
|
163
122
|
|
|
164
|
-
|
|
165
|
-
isolated, and deterministic unit tests — even for logic that relies on the filesystem or path resolution.
|
|
123
|
+
Builder stage methods (only before first `get`):
|
|
166
124
|
|
|
167
|
-
|
|
125
|
+
- `setParser(parser)`
|
|
126
|
+
- `addNamespaceRoot(prefix, target, defaultExt)`
|
|
127
|
+
- `addPreprocess(fn)`
|
|
128
|
+
- `addPostprocess(fn)`
|
|
129
|
+
- `enableLogging()`
|
|
130
|
+
- `enableTestMode()`
|
|
131
|
+
- `register(cdc, mock)` (only in test mode)
|
|
168
132
|
|
|
169
|
-
|
|
133
|
+
Resolution:
|
|
170
134
|
|
|
171
|
-
|
|
172
|
-
extensive flexibility and configurability. This allows the library to adapt seamlessly to a wide range of project needs.
|
|
173
|
-
Here’s what makes it stand out:
|
|
135
|
+
- `await container.get(cdc)`
|
|
174
136
|
|
|
175
|
-
|
|
176
|
-
signatures. This basic functionality works out of the box but can be fully customized if needed.
|
|
137
|
+
Behavioral guarantees:
|
|
177
138
|
|
|
178
|
-
-
|
|
179
|
-
|
|
139
|
+
- configuration is locked after first `get`
|
|
140
|
+
- fail-fast pipeline
|
|
141
|
+
- deterministic linking under identical contracts and config
|
|
142
|
+
- produced values are frozen
|
|
143
|
+
- container enters failed state after fatal linking error
|
|
180
144
|
|
|
181
|
-
|
|
182
|
-
source locations effortlessly. This makes the library adaptable to any project structure or file layout.
|
|
145
|
+
## Wrappers
|
|
183
146
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
predictable application behavior.
|
|
147
|
+
Wrappers are postprocess plugins registered during container configuration.
|
|
148
|
+
They are activated by wrapper markers in the CDC string and applied to the produced value after instantiation.
|
|
187
149
|
|
|
188
|
-
|
|
189
|
-
enabling local overrides or adjustments in functionality. This is especially useful for larger projects, where
|
|
190
|
-
different teams may tailor dependencies to their specific requirements. The default preprocessing can also be replaced
|
|
191
|
-
to suit more precise needs.
|
|
150
|
+
Wrappers:
|
|
192
151
|
|
|
193
|
-
- **
|
|
194
|
-
|
|
195
|
-
|
|
152
|
+
- are **container-level plugins**
|
|
153
|
+
- are **not module exports**
|
|
154
|
+
- are applied in declared order
|
|
155
|
+
- must return synchronously
|
|
156
|
+
- run before lifecycle enforcement and freeze
|
|
196
157
|
|
|
197
|
-
|
|
198
|
-
|
|
158
|
+
Surface form:
|
|
159
|
+
|
|
160
|
+
```text
|
|
161
|
+
ModuleName$$_wrapperA_wrapperB
|
|
162
|
+
```
|
|
199
163
|
|
|
200
|
-
|
|
201
|
-
|
|
164
|
+
Wrappers are part of the dependency contract (CDC).
|
|
165
|
+
They declaratively modify how a resolved value behaves.
|
|
202
166
|
|
|
203
167
|
---
|
|
204
168
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
### For Node.js
|
|
169
|
+
### Example: Logging Wrapper
|
|
208
170
|
|
|
209
|
-
|
|
171
|
+
Suppose we want to log all method calls of a service without modifying the service itself.
|
|
210
172
|
|
|
211
|
-
|
|
212
|
-
npm install @teqfw/di
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Then, import and initialize the container:
|
|
173
|
+
#### Service module
|
|
216
174
|
|
|
217
175
|
```js
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
176
|
+
export default function App_Service() {
|
|
177
|
+
return {
|
|
178
|
+
sum(a, b) {
|
|
179
|
+
return a + b;
|
|
180
|
+
},
|
|
181
|
+
multiply(a, b) {
|
|
182
|
+
return a * b;
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
222
186
|
```
|
|
223
187
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
To use `@teqfw/di` in a browser environment with ES modules, include it as follows (~5KB):
|
|
188
|
+
#### Container configuration
|
|
227
189
|
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
190
|
+
```js
|
|
191
|
+
container.addPostprocessWrapper("logIO", (value) => {
|
|
192
|
+
return new Proxy(value, {
|
|
193
|
+
get(target, prop, receiver) {
|
|
194
|
+
const original = Reflect.get(target, prop, receiver);
|
|
195
|
+
|
|
196
|
+
if (typeof original !== "function") {
|
|
197
|
+
return original;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return function (...args) {
|
|
201
|
+
console.log(`[CALL] ${String(prop)} ->`, args);
|
|
202
|
+
const result = original.apply(this, args);
|
|
203
|
+
console.log(`[RETURN] ${String(prop)} ->`, result);
|
|
204
|
+
return result;
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
});
|
|
235
209
|
```
|
|
236
210
|
|
|
237
|
-
|
|
211
|
+
#### Request
|
|
238
212
|
|
|
239
|
-
|
|
213
|
+
```js
|
|
214
|
+
const service = await container.get("App_Service$$_logIO");
|
|
240
215
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
/** @type {TeqFw_Di_Container} */
|
|
245
|
-
const container = new window.TeqFw_Di_Container();
|
|
246
|
-
</script>
|
|
216
|
+
service.sum(2, 3);
|
|
217
|
+
// [CALL] sum -> [2, 3]
|
|
218
|
+
// [RETURN] sum -> 5
|
|
247
219
|
```
|
|
248
220
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
## Using the Container
|
|
252
|
-
|
|
253
|
-
### In Node.js
|
|
254
|
-
|
|
255
|
-
1. **Configure Dependency Mapping**: Configure the resolver to detect the platform environment. Then, set up namespace
|
|
256
|
-
roots to map dependency IDs to their source paths.
|
|
257
|
-
|
|
258
|
-
```js
|
|
259
|
-
import { platform } from "node:process";
|
|
221
|
+
The module remains unaware of logging.
|
|
222
|
+
The wrapper applies cross-cutting behavior declaratively through CDC.
|
|
260
223
|
|
|
261
|
-
|
|
262
|
-
resolver.setWindowsEnv(platform === "win32"); // Adjusts for Windows environment if needed
|
|
263
|
-
resolver.addNamespaceRoot("App_", "/path/to/src");
|
|
264
|
-
```
|
|
224
|
+
This allows:
|
|
265
225
|
|
|
266
|
-
|
|
226
|
+
- tracing
|
|
227
|
+
- metrics collection
|
|
228
|
+
- access control
|
|
229
|
+
- behavioral instrumentation
|
|
267
230
|
|
|
268
|
-
|
|
269
|
-
const app = await container.get("App_Main$");
|
|
270
|
-
```
|
|
231
|
+
without modifying business logic or module structure.
|
|
271
232
|
|
|
272
|
-
|
|
233
|
+
Wrappers therefore act as a declarative DI-level AOP mechanism.
|
|
273
234
|
|
|
274
|
-
|
|
275
|
-
needed.
|
|
276
|
-
|
|
277
|
-
```js
|
|
278
|
-
const resolver = container.getResolver();
|
|
279
|
-
resolver.addNamespaceRoot("App_", "https://cdn.jsdelivr.net/npm/@flancer64/demo-di-app@0.2/src");
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
2. **Retrieve Singleton Instances**: Retrieve the main application instance as a singleton asynchronously:
|
|
283
|
-
|
|
284
|
-
```js
|
|
285
|
-
const app = await container.get("App_Main$");
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
With these steps, the container is configured to automatically resolve and inject dependencies based on your setup,
|
|
289
|
-
whether in Node.js or in a browser environment.
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Dependency ID Types
|
|
294
|
-
|
|
295
|
-
`@teqfw/di` supports various dependency ID formats to match different import styles and object requirements. Here’s a
|
|
296
|
-
quick reference:
|
|
297
|
-
|
|
298
|
-
| Dependency ID | Import Style | Description |
|
|
299
|
-
| --------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
|
|
300
|
-
| `App_Service` | `import * as Service from './App/Service.js';` | Imports the entire module as an ES module. |
|
|
301
|
-
| `App_Service.default` | `import {default} from './App/Service.js';` | Imports the default export as-is. |
|
|
302
|
-
| `App_Service.name` | `import {name} from './App/Service.js';` | Imports a named export as-is. |
|
|
303
|
-
| `App_Service$` | `import {default as Factory} from './App/Service.js';` | Uses default export as a singleton for the container. |
|
|
304
|
-
| `App_Service$$` | `import {default as Factory} from './App/Service.js';` | Creates a new instance from the default export for each dependency. |
|
|
305
|
-
| `App_Service.name$` | `import {name} from './App/Service.js';` | Uses a named export as a singleton. |
|
|
306
|
-
| `App_Service.name$$` | `import {name} from './App/Service.js';` | Creates a new instance from a named export for each dependency. |
|
|
307
|
-
| `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()`. |
|
|
308
|
-
|
|
309
|
-
### Example Usage
|
|
310
|
-
|
|
311
|
-
Here’s an example showing a class with multiple dependencies, each using different dependency IDs:
|
|
235
|
+
## Test Mode and Mocks
|
|
312
236
|
|
|
313
237
|
```js
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
}
|
|
327
|
-
}
|
|
238
|
+
container.enableTestMode();
|
|
239
|
+
container.register("App_Service$", { name: "mock-service" });
|
|
328
240
|
```
|
|
329
241
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
## Summary
|
|
242
|
+
Mock lookup uses canonical parsed dependency identity and is applied before resolver/instantiation.
|
|
333
243
|
|
|
334
|
-
|
|
335
|
-
With its flexible dependency mapping, customizable ID configurations, and support for dynamic object creation,
|
|
336
|
-
`@teqfw/di` empowers developers to build modular, testable, and scalable codebases.
|
|
244
|
+
## Browser Usage
|
|
337
245
|
|
|
338
|
-
|
|
339
|
-
functionality that you can further adapt to fit your project’s unique requirements. Feel free to explore and extend the
|
|
340
|
-
library as needed to create your ideal development environment.
|
|
246
|
+
ESM via jsDelivr:
|
|
341
247
|
|
|
342
|
-
|
|
343
|
-
|
|
248
|
+
```html
|
|
249
|
+
<script type="module">
|
|
250
|
+
import Container from "https://cdn.jsdelivr.net/npm/@teqfw/di@2/+esm";
|
|
251
|
+
const container = new Container();
|
|
252
|
+
</script>
|
|
253
|
+
```
|
|
344
254
|
|
|
345
|
-
|
|
346
|
-
- **LinkedIn**: [LinkedIn Profile](https://www.linkedin.com/in/aleksandrs-gusevs-011ba928/)
|
|
255
|
+
## Documentation Source
|
|
347
256
|
|
|
348
|
-
|
|
257
|
+
Normative docs live in `ctx/`:
|
|
349
258
|
|
|
350
|
-
|
|
259
|
+
- product overview: `ctx/docs/product/overview.md`
|
|
260
|
+
- default CDC profile: `ctx/docs/product/default-cdc-profile.md`
|
|
261
|
+
- grammar: `ctx/docs/architecture/cdc-profile/default/grammar.md`
|
|
262
|
+
- transformation: `ctx/docs/architecture/cdc-profile/default/transformation.md`
|
|
263
|
+
- validation: `ctx/docs/architecture/cdc-profile/default/validation.md`
|
|
264
|
+
- container contract: `ctx/docs/code/components/container.md`
|
package/dist/esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e={CA:"A",CF:"F",LI:"I",LS:"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.origin))throw new Error(`Circular dependency for '${o.origin}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.origin],{[o.exportName]:l}=s;if(o.composition===e.CF){if("function"==typeof l){const s=n(l);s.length&&(c=`Deps for object '${o.origin}' are: ${JSON.stringify(s)}`,t&&console.log(c));const r={};for(const e of s)r[e]=await i.get(e,a);const u=e.isClass(l)?new l(r):l(r);return u instanceof Promise?await u:u}return Object.assign({},l)}return l}return s;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;isNodeModule;life;moduleName;origin;wrappers=[]}const c=/^(node:)?(@?[A-Za-z0-9_-]+\/?[A-Za-z0-9_-]*)(([.#])?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?$/;class a{canParse(){return!0}parse(t){const o=new i;o.origin=t;const s=c.exec(t);if(s&&(o.isNodeModule=Boolean(s[1]),o.moduleName=s[2].replace(/^node:/,""),"."===s[4]||"#"===s[4]?"$"===s[6]||"$$"===s[6]?(o.composition=e.CF,o.exportName=s[5],o.life="$"===s[6]?e.LS:e.LI):(o.composition=e.CA,o.life=e.LS,o.exportName=""!==s[5]?s[5]:"default"):"$"===s[6]||"$$"===s[6]?(o.composition=e.CF,o.exportName="default",o.life="$"===s[6]?e.LS:e.LI):(o.composition=void 0,o.exportName=void 0,o.life=void 0),s[10]&&(o.wrappers=s[10].split(","))),o.composition===e.CA&&o.life===e.LI)throw new Error(`Export is not a function and should be used as a singleton only: '${o.origin}'.`);return o}}class l{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 u{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 d="ext",p="ns",h="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]={[d]:r??"js",[p]:s,[h]: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][h],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 g(e){return`${e.moduleName}#${e.exportName}`}class ${constructor(){let t=new r,o=!1,s=new l,n=new f,i=new u,c=!1;const a={},d={},p={};let h=new m;function $(){o&&console.log(...arguments)}this.get=async function(o,r=[]){$(`Object '${o}' is requested.`);const l=s.parse(o),u=i.modify(l,r);if(u.life===e.LS){const e=g(u);if(d[e])return $(`Existing singleton '${e}' is returned.`),d[e]}if(u.isNodeModule&&c){const e=u.origin;if(p[e])return $(`Existing nodejs lib '${e}' is returned.`),p[e]}let f;a[u.moduleName]||($(`ES6 module '${u.moduleName}' is not resolved yet`),a[u.moduleName]=h.resolve(u.moduleName));const m=a[u.moduleName];try{f=await import(m),$(`ES6 module '${u.moduleName}' is loaded from '${m}'.`)}catch(e){throw console.error(e?.message,`Object key: "${o}".`,`Path: "${m}".`,`Stack: ${JSON.stringify(r)}`),e}let w=await t.create(u,f,r,this);var y;if(null===(y=w)||"object"!=typeof y&&"function"!=typeof y||"[object Module]"===Object.prototype.toString.call(y)||Object.isFrozen(y)||Object.freeze(w),w=await n.modify(w,u,r),$(`Object '${o}' is created.`),u.life===e.LS){const e=g(u);d[e]=w,$(`Object '${o}' is saved as singleton.`)}return w},this.enableTestMode=function(){c=!0,$("Test mode enabled")},this.getParser=()=>s,this.getPreProcessor=()=>i,this.getPostProcessor=()=>n,this.getResolver=()=>h,this.register=function(t,o){if(!c)throw new Error("Use enableTestMode() to allow it");if(!t||!o)throw new Error("Both params are required");const n=s.parse(t);if(n.life!==e.LS&&!n.isNodeModule)throw new Error(`Only node modules & singletons can be registered: '${t}'`);if(n.life===e.LS){const e=g(n);if(d[e])throw new Error(`'${t}' is already registered`);d[e]=o}else if(n.isNodeModule){const e=n.origin;if(p[e])throw new Error(`'${t}' is already registered`);p[e]=o}$(`'${t}' is registered`)},this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>s=e,this.setPreProcessor=e=>i=e,this.setPostProcessor=e=>n=e,this.setResolver=e=>h=e}}export{$ as default};
|
|
1
|
+
const e={AS_IS:"A",FACTORY:"F"},t={SINGLETON:"S",TRANSIENT:"T"},o={TEQ:"teq",NODE:"node",NPM:"npm"},r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e,t){const o=e&&"object"==typeof e?e:{},c=new l;c.moduleName="string"==typeof o.moduleName?o.moduleName:"";const p="string"==typeof o.platform?o.platform:void 0;c.platform=p&&i.has(p)?p:r;let f=null;null===o.exportName?f=null:"string"==typeof o.exportName&&(f=o.exportName),c.exportName=f;const u="string"==typeof o.composition?o.composition:void 0;c.composition=u&&s.has(u)?u:n;const m="string"==typeof o.life?o.life:void 0;return c.life=m&&a.has(m)?m:null,c.wrappers=Array.isArray(o.wrappers)?o.wrappers.filter(e=>"string"==typeof e):[],c.origin="string"==typeof o.origin?o.origin:"",!0===t?.immutable&&(Object.freeze(c.wrappers),Object.freeze(c)),c}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const m=u.indexOf("__"),d=u.lastIndexOf("__");if(-1!==m&&m!==d)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==m){if(g=u.slice(0,m),w=u.slice(m+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s},{immutable:!0});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e,t){const o=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{},n=new f;return n.prefix="string"==typeof o.prefix?o.prefix:void 0,n.target="string"==typeof o.target?o.target:void 0,n.defaultExt="string"==typeof o.defaultExt?o.defaultExt:void 0,!0===r.immutable&&Object.freeze(n),n}};class m{namespaces;nodeModulesRoot}class d{constructor(){const e=new u;this.create=function(t,o){const r=t&&"object"==typeof t?t:{},n=o&&"object"==typeof o?o:{},i=new m,s=Array.isArray(r.namespaces)?r.namespaces:[];return i.namespaces=s.map(t=>e.create(t,n)),i.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,!0===n.immutable&&(Object.freeze(i.namespaces),Object.freeze(i)),i}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(function(e){if(null==e)return!1;const t=typeof e;return("object"===t||"function"===t)&&"function"==typeof e.then}(t))throw new Error("Factory composition must return synchronously (non-thenable).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){if(null==e)return!1;const t=typeof e;if("object"!==t&&"function"!==t)return!1;return"function"==typeof e.then},t=function(e){return"function"==typeof e};this.execute=function(o,r,n){let i=r;const s=o.wrappers;for(const o of s){if(!(o in n))throw new Error(`Wrapper '${o}' is not found in module namespace.`);const r=n[o];if(!t(r))throw new Error(`Wrapper '${o}' must be callable.`);if(i=r(i),e(i))throw new Error(`Wrapper '${o}' must return synchronously (non-thenable).`)}return i}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});class x{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map;let i=!1,s=!1,a=new p;const l=new d;let c,f,u,m=E;const x=new h,C=new y,b=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},v=function(e){if(null==e)return e;const t=typeof e;return"object"!==t&&"function"!==t||"[object Module]"===Object.prototype.toString.call(e)||Object.isFrozen(e)||Object.freeze(e),e},I=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},j=function(e){s&&m.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){I(),j("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){I(),j("addPostprocess()."),o.push(e)},this.setParser=function(e){I(),a=e,"function"==typeof a.setLogger&&a.setLogger(s?m:null),j("setParser().")},this.addNamespaceRoot=function(e,t,o){I(),j(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){I(),j("enableTestMode()."),i=!0},this.enableLogging=function(){I(),s||(s=!0,m=new N,"function"==typeof a.setLogger&&a.setLogger(m),m.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(I(),j(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const o=a.parse(e);n.set(_(o),t)},this.get=async function(s){if("failed"===e)throw m.error(`Container.get: rejected in failed state cdc='${s}'.`),new Error("Container is in failed state.");let p="start";try{m.log(`Container.get: cdc='${s}'.`),function(){if("notConfigured"!==e)return;m.log("Container.transition: notConfigured -> operational."),e="operational";const t=l.create({namespaces:r},{immutable:!0});"function"==typeof a.setLogger&&a.setLogger(m),c=new g({config:t,logger:m}),f=new w({parser:a,resolver:c,logger:m}),u=new $(m)}(),m.log(`Container.state: '${e}'.`),p="parse",m.log("Container.pipeline: parse:entry.");const d=a.parse(s);m.log(`Container.pipeline: parse:exit '${d.platform}::${d.moduleName}'.`),p="preprocess",m.log("Container.pipeline: preprocess:entry.");const h=function(e){let o=e;for(const e of t)o=e(o);return o}(d);if(m.log(`Container.pipeline: preprocess:exit '${h.platform}::${h.moduleName}'.`),!0===i){p="mock",m.log("Container.pipeline: mock-lookup:entry.");const e=_(h);if(n.has(e)){m.log(`Container.pipeline: mock-lookup:hit '${e}'.`),p="freeze",m.log("Container.pipeline: freeze:entry.");const t=v(n.get(e));return m.log("Container.pipeline: freeze:exit."),m.log("Container.pipeline: return:success."),t}m.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else m.log("Container.pipeline: mock-lookup:disabled.");p="resolve",m.log("Container.pipeline: resolve:entry.");const y=await f.resolve(h);m.log(`Container.pipeline: resolve:exit nodes=${y.size}.`);const N=new Map,E=function(e){if(N.has(e))return N.get(e);if(!y.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=y.get(e);p="lifecycle",m.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=u.apply(t.depId,function(){p="instantiate",m.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=a.parse(r);e[t]=E(b(n))}const n=x.instantiate(t.depId,t.namespace,e);m.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p="postprocess",m.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);m.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=C.execute(t.depId,i,t.namespace);p="freeze",m.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const l=v(s);return m.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),l});return m.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),N.set(e,r),r},I=E(b(h));return m.log("Container.pipeline: return:success."),I}catch(t){throw m.error(`Container.pipeline: failed at stage='${p}'.`,t),m.log("Container.transition: operational -> failed."),e="failed",t}}}}export{x 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={CA:"A",CF:"F",LI:"I",LS:"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.origin))throw new Error(`Circular dependency for '${o.origin}'. Parents are: ${JSON.stringify(r)}`);if(o.exportName){const a=[...r,o.origin],{[o.exportName]:l}=n;if(o.composition===e.CF){if("function"==typeof l){const n=s(l);n.length&&(c=`Deps for object '${o.origin}' are: ${JSON.stringify(n)}`,t&&console.log(c));const r={};for(const e of n)r[e]=await i.get(e,a);const u=e.isClass(l)?new l(r):l(r);return u instanceof Promise?await u:u}return Object.assign({},l)}return l}return n;var c},this.setDebug=function(e){t=e}}}class i{exportName;composition;isNodeModule;life;moduleName;origin;wrappers=[]}const c=/^(node:)?(@?[A-Za-z0-9_-]+\/?[A-Za-z0-9_-]*)(([.#])?([A-Za-z0-9_]*)((\$)?(\$)?)?)?(\(([A-Za-z0-9_,]*)\))?$/;class a{canParse(){return!0}parse(t){const o=new i;o.origin=t;const n=c.exec(t);if(n&&(o.isNodeModule=Boolean(n[1]),o.moduleName=n[2].replace(/^node:/,""),"."===n[4]||"#"===n[4]?"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName=n[5],o.life="$"===n[6]?e.LS:e.LI):(o.composition=e.CA,o.life=e.LS,o.exportName=""!==n[5]?n[5]:"default"):"$"===n[6]||"$$"===n[6]?(o.composition=e.CF,o.exportName="default",o.life="$"===n[6]?e.LS:e.LI):(o.composition=void 0,o.exportName=void 0,o.life=void 0),n[10]&&(o.wrappers=n[10].split(","))),o.composition===e.CA&&o.life===e.LI)throw new Error(`Export is not a function and should be used as a singleton only: '${o.origin}'.`);return o}}class l{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 u{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 d="ext",p="ns",h="root";class m{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]={[d]:r??"js",[p]:n,[h]: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][h],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 g(e){return`${e.moduleName}#${e.exportName}`}return class{constructor(){let t=new r,o=!1,n=new l,s=new f,i=new u,c=!1;const a={},d={},p={};let h=new m;function w(){o&&console.log(...arguments)}this.get=async function(o,r=[]){w(`Object '${o}' is requested.`);const l=n.parse(o),u=i.modify(l,r);if(u.life===e.LS){const e=g(u);if(d[e])return w(`Existing singleton '${e}' is returned.`),d[e]}if(u.isNodeModule&&c){const e=u.origin;if(p[e])return w(`Existing nodejs lib '${e}' is returned.`),p[e]}let f;a[u.moduleName]||(w(`ES6 module '${u.moduleName}' is not resolved yet`),a[u.moduleName]=h.resolve(u.moduleName));const m=a[u.moduleName];try{f=await import(m),w(`ES6 module '${u.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(u,f,r,this);var y;if(null===(y=$)||"object"!=typeof y&&"function"!=typeof y||"[object Module]"===Object.prototype.toString.call(y)||Object.isFrozen(y)||Object.freeze($),$=await s.modify($,u,r),w(`Object '${o}' is created.`),u.life===e.LS){const e=g(u);d[e]=$,w(`Object '${o}' is saved as singleton.`)}return $},this.enableTestMode=function(){c=!0,w("Test mode enabled")},this.getParser=()=>n,this.getPreProcessor=()=>i,this.getPostProcessor=()=>s,this.getResolver=()=>h,this.register=function(t,o){if(!c)throw new Error("Use enableTestMode() to allow it");if(!t||!o)throw new Error("Both params are required");const s=n.parse(t);if(s.life!==e.LS&&!s.isNodeModule)throw new Error(`Only node modules & singletons can be registered: '${t}'`);if(s.life===e.LS){const e=g(s);if(d[e])throw new Error(`'${t}' is already registered`);d[e]=o}else if(s.isNodeModule){const e=s.origin;if(p[e])throw new Error(`'${t}' is already registered`);p[e]=o}w(`'${t}' is registered`)},this.setDebug=function(e){o=e,t.setDebug(e)},this.setParser=e=>n=e,this.setPreProcessor=e=>i=e,this.setPostProcessor=e=>s=e,this.setResolver=e=>h=e}}});
|
|
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";const e={AS_IS:"A",FACTORY:"F"},t={SINGLETON:"S",TRANSIENT:"T"},o={TEQ:"teq",NODE:"node",NPM:"npm"},r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e,t){const o=e&&"object"==typeof e?e:{},c=new l;c.moduleName="string"==typeof o.moduleName?o.moduleName:"";const p="string"==typeof o.platform?o.platform:void 0;c.platform=p&&i.has(p)?p:r;let f=null;null===o.exportName?f=null:"string"==typeof o.exportName&&(f=o.exportName),c.exportName=f;const u="string"==typeof o.composition?o.composition:void 0;c.composition=u&&s.has(u)?u:n;const m="string"==typeof o.life?o.life:void 0;return c.life=m&&a.has(m)?m:null,c.wrappers=Array.isArray(o.wrappers)?o.wrappers.filter(e=>"string"==typeof e):[],c.origin="string"==typeof o.origin?o.origin:"",!0===t?.immutable&&(Object.freeze(c.wrappers),Object.freeze(c)),c}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const m=u.indexOf("__"),d=u.lastIndexOf("__");if(-1!==m&&m!==d)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==m){if(g=u.slice(0,m),w=u.slice(m+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s},{immutable:!0});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e,t){const o=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{},n=new f;return n.prefix="string"==typeof o.prefix?o.prefix:void 0,n.target="string"==typeof o.target?o.target:void 0,n.defaultExt="string"==typeof o.defaultExt?o.defaultExt:void 0,!0===r.immutable&&Object.freeze(n),n}};class m{namespaces;nodeModulesRoot}class d{constructor(){const e=new u;this.create=function(t,o){const r=t&&"object"==typeof t?t:{},n=o&&"object"==typeof o?o:{},i=new m,s=Array.isArray(r.namespaces)?r.namespaces:[];return i.namespaces=s.map(t=>e.create(t,n)),i.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,!0===n.immutable&&(Object.freeze(i.namespaces),Object.freeze(i)),i}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(function(e){if(null==e)return!1;const t=typeof e;return("object"===t||"function"===t)&&"function"==typeof e.then}(t))throw new Error("Factory composition must return synchronously (non-thenable).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){if(null==e)return!1;const t=typeof e;if("object"!==t&&"function"!==t)return!1;return"function"==typeof e.then},t=function(e){return"function"==typeof e};this.execute=function(o,r,n){let i=r;const s=o.wrappers;for(const o of s){if(!(o in n))throw new Error(`Wrapper '${o}' is not found in module namespace.`);const r=n[o];if(!t(r))throw new Error(`Wrapper '${o}' must be callable.`);if(i=r(i),e(i))throw new Error(`Wrapper '${o}' must return synchronously (non-thenable).`)}return i}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});return class{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map;let i=!1,s=!1,a=new p;const l=new d;let c,f,u,m=E;const x=new h,b=new y,C=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},v=function(e){if(null==e)return e;const t=typeof e;return"object"!==t&&"function"!==t||"[object Module]"===Object.prototype.toString.call(e)||Object.isFrozen(e)||Object.freeze(e),e},I=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},j=function(e){s&&m.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){I(),j("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){I(),j("addPostprocess()."),o.push(e)},this.setParser=function(e){I(),a=e,"function"==typeof a.setLogger&&a.setLogger(s?m:null),j("setParser().")},this.addNamespaceRoot=function(e,t,o){I(),j(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){I(),j("enableTestMode()."),i=!0},this.enableLogging=function(){I(),s||(s=!0,m=new N,"function"==typeof a.setLogger&&a.setLogger(m),m.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(I(),j(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const o=a.parse(e);n.set(_(o),t)},this.get=async function(s){if("failed"===e)throw m.error(`Container.get: rejected in failed state cdc='${s}'.`),new Error("Container is in failed state.");let p="start";try{m.log(`Container.get: cdc='${s}'.`),function(){if("notConfigured"!==e)return;m.log("Container.transition: notConfigured -> operational."),e="operational";const t=l.create({namespaces:r},{immutable:!0});"function"==typeof a.setLogger&&a.setLogger(m),c=new g({config:t,logger:m}),f=new w({parser:a,resolver:c,logger:m}),u=new $(m)}(),m.log(`Container.state: '${e}'.`),p="parse",m.log("Container.pipeline: parse:entry.");const d=a.parse(s);m.log(`Container.pipeline: parse:exit '${d.platform}::${d.moduleName}'.`),p="preprocess",m.log("Container.pipeline: preprocess:entry.");const h=function(e){let o=e;for(const e of t)o=e(o);return o}(d);if(m.log(`Container.pipeline: preprocess:exit '${h.platform}::${h.moduleName}'.`),!0===i){p="mock",m.log("Container.pipeline: mock-lookup:entry.");const e=_(h);if(n.has(e)){m.log(`Container.pipeline: mock-lookup:hit '${e}'.`),p="freeze",m.log("Container.pipeline: freeze:entry.");const t=v(n.get(e));return m.log("Container.pipeline: freeze:exit."),m.log("Container.pipeline: return:success."),t}m.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else m.log("Container.pipeline: mock-lookup:disabled.");p="resolve",m.log("Container.pipeline: resolve:entry.");const y=await f.resolve(h);m.log(`Container.pipeline: resolve:exit nodes=${y.size}.`);const N=new Map,E=function(e){if(N.has(e))return N.get(e);if(!y.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=y.get(e);p="lifecycle",m.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=u.apply(t.depId,function(){p="instantiate",m.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=a.parse(r);e[t]=E(C(n))}const n=x.instantiate(t.depId,t.namespace,e);m.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p="postprocess",m.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);m.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=b.execute(t.depId,i,t.namespace);p="freeze",m.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const l=v(s);return m.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),l});return m.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),N.set(e,r),r},I=E(C(h));return m.log("Container.pipeline: return:success."),I}catch(t){throw m.error(`Container.pipeline: failed at stage='${p}'.`,t),m.log("Container.transition: operational -> failed."),e="failed",t}}}}});
|