@teqfw/di 2.0.2 → 2.0.4

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.
@@ -0,0 +1,72 @@
1
+ # container.md
2
+
3
+ Version: 20260307
4
+
5
+ ## Role of the Container
6
+
7
+ The container provides the operational mechanism that links ES modules at runtime. It resolves dependency identifiers, loads modules, instantiates exported factories, and returns fully linked objects. The container serves as the composition root of the system and centralizes all dependency resolution.
8
+
9
+ Application modules do not resolve dependencies themselves and do not construct collaborators directly. Instead, they request dependencies from the container using dependency identifiers.
10
+
11
+ ## Container Responsibilities
12
+
13
+ The container performs the following responsibilities:
14
+
15
+ - interpret dependency identifiers
16
+ - resolve identifiers into module locations
17
+ - load ES modules dynamically
18
+ - instantiate exported factories
19
+ - apply preprocess and postprocess handlers
20
+ - manage object lifecycle semantics
21
+ - freeze linked objects before returning them
22
+
23
+ These responsibilities ensure deterministic runtime linking between modules.
24
+
25
+ ## Dependency Resolution Pipeline
26
+
27
+ When a dependency is requested, the container processes the request through a deterministic pipeline consisting of the following stages:
28
+
29
+ 1. **Parse** — interpret the dependency identifier.
30
+ 2. **Preprocess** — allow registered preprocess handlers to transform the identifier.
31
+ 3. **Resolve** — translate the identifier into a module reference.
32
+ 4. **Instantiate** — load the module and create the object using the selected export.
33
+ 5. **Postprocess** — apply wrapper handlers to the created object.
34
+ 6. **Lifecycle** — apply lifecycle semantics such as singleton caching or instance creation.
35
+ 7. **Freeze** — freeze the resulting object before returning it.
36
+
37
+ This pipeline ensures that all dependencies are created and linked through a consistent process.
38
+
39
+ ## Container API
40
+
41
+ The container exposes a minimal public interface used by application code and configuration code.
42
+
43
+ The core operations are:
44
+
45
+ - **register(identifier, value)** — register a predefined dependency or instance in the container.
46
+ - **get(identifier)** — resolve a dependency identifier and return the linked object.
47
+ - **addPreprocess(handler)** — register a handler that can transform dependency identifiers before resolution.
48
+ - **addPostprocess(handler)** — register a handler that can modify created objects after instantiation.
49
+
50
+ The exact semantics of dependency identifiers are defined in **dependency-id.md**.
51
+
52
+ ## Container State Model
53
+
54
+ The container operates in three states:
55
+
56
+ - **initial** — the container is being configured and dependencies may be registered.
57
+ - **active** — the container resolves dependencies and produces linked objects.
58
+ - **failed** — the container has encountered an unrecoverable error.
59
+
60
+ If an error occurs during dependency resolution or any pipeline stage, the container transitions to the **failed** state. Once the container enters this state, all subsequent dependency requests are rejected.
61
+
62
+ This fail-fast behavior prevents partially linked systems from continuing execution.
63
+
64
+ ## Object Linking and Freezing
65
+
66
+ Objects returned by the container represent linked components of the application. After an object is created and all pipeline stages are completed, the container freezes the object before returning it.
67
+
68
+ Freezing ensures that:
69
+
70
+ - linked objects cannot be modified by consumers
71
+ - shared instances remain stable
72
+ - the container remains the only authority responsible for object construction and linking
@@ -0,0 +1,116 @@
1
+ # dependency-id.md
2
+
3
+ Version: 20260307
4
+
5
+ ## Purpose
6
+
7
+ Dependencies in the container are addressed using **Canonical Dependency Codes (CDC)**. A CDC is a structured identifier interpreted by the container to determine which module must be loaded, which export must be used, and how the resulting object must be instantiated.
8
+
9
+ CDC provides a stable logical addressing mechanism that is independent of file paths and runtime environments.
10
+
11
+ ## Canonical Form
12
+
13
+ A CDC follows the canonical structure:
14
+
15
+ ```txt
16
+ [PlatformPrefix]ModuleName[__ExportName][Lifecycle][WrapperSuffixes]
17
+ ```
18
+
19
+ The components have the following roles:
20
+
21
+ - **PlatformPrefix** — optional prefix identifying a platform module source.
22
+ - **ModuleName** — logical module identifier within a namespace.
23
+ - **ExportName** — optional named export selector.
24
+ - **Lifecycle** — marker defining instantiation semantics.
25
+ - **WrapperSuffixes** — optional sequence of wrapper identifiers.
26
+
27
+ Each CDC is interpreted deterministically by the container.
28
+
29
+ ## Platform Prefix
30
+
31
+ A CDC may reference modules provided by the runtime platform or external packages.
32
+
33
+ The following prefixes are supported:
34
+
35
+ - **`node_`** — reference a built-in Node.js module.
36
+ - **`npm_`** — reference a module from the npm ecosystem.
37
+
38
+ Examples:
39
+
40
+ ```txt
41
+ node_fs$
42
+ npm_lodash$
43
+ ```
44
+
45
+ If no platform prefix is present, the identifier refers to an application module resolved through namespace mapping.
46
+
47
+ ## Module Identification
48
+
49
+ The **ModuleName** identifies the module that provides the dependency. Module identifiers use namespace-based naming and are translated into filesystem paths according to namespace resolution rules described in **container.md**.
50
+
51
+ Identifier segments separated by underscores correspond to directory boundaries in the module path.
52
+
53
+ Example:
54
+
55
+ ```txt
56
+ App_Service_User
57
+ ```
58
+
59
+ maps to a module located at:
60
+
61
+ ```txt
62
+ AppRoot/Service/User.js
63
+ ```
64
+
65
+ ## Export Selection
66
+
67
+ A CDC may reference either the default export of a module or a named export.
68
+
69
+ Named exports are selected using a double underscore separator.
70
+
71
+ Examples:
72
+
73
+ ```txt
74
+ App_Service_User$
75
+ App_Service_User__Factory$
76
+ ```
77
+
78
+ The first identifier resolves the module default export. The second resolves the named export `Factory`.
79
+
80
+ ## Lifecycle Markers
81
+
82
+ Lifecycle markers define how the container instantiates and returns objects.
83
+
84
+ The following markers are supported:
85
+
86
+ - **`$`** — singleton lifecycle; the container creates the object once and returns the same instance for subsequent requests.
87
+ - **`$$`** — factory lifecycle; a new instance is created for each request.
88
+ - **`$$$`** — transient lifecycle; the container delegates lifecycle management entirely to the caller.
89
+
90
+ Lifecycle markers are appended at the end of the identifier.
91
+
92
+ ## Wrapper Suffixes
93
+
94
+ Wrappers allow postprocessing of created objects. Wrapper identifiers are appended after the lifecycle marker and separated by underscores.
95
+
96
+ Example:
97
+
98
+ ```txt
99
+ App_Service_User$$_wrapLog_wrapTrace
100
+ ```
101
+
102
+ In this example the container creates a new instance and applies the wrappers `wrapLog` and `wrapTrace` during the postprocess stage.
103
+
104
+ Wrapper behavior is described in **extensions.md**.
105
+
106
+ ## Resolution Semantics
107
+
108
+ When the container receives a CDC it performs the following interpretation steps:
109
+
110
+ 1. determine the platform prefix and module namespace
111
+ 2. resolve the module identifier into a module location
112
+ 3. select the requested export
113
+ 4. apply lifecycle semantics
114
+ 5. apply wrapper suffixes if present
115
+
116
+ These interpretation steps integrate with the dependency resolution pipeline described in **container.md**.
@@ -0,0 +1,71 @@
1
+ # extensions.md
2
+
3
+ Version: 20260307
4
+
5
+ ## Purpose
6
+
7
+ The container supports controlled extension of the dependency resolution process through **preprocess handlers** and **postprocess wrappers**. These mechanisms allow the behavior of dependency resolution and object creation to be adjusted without modifying container internals.
8
+
9
+ Extensions are registered during container configuration and become part of the deterministic resolution pipeline.
10
+
11
+ ## Extension Points
12
+
13
+ Two extension points are available:
14
+
15
+ - **Preprocess handlers** — transform dependency identifiers before resolution.
16
+ - **Postprocess wrappers** — modify or decorate created objects after instantiation.
17
+
18
+ These extension points correspond to the preprocess and postprocess stages of the container pipeline described in **container.md**.
19
+
20
+ ## Preprocess Handlers
21
+
22
+ Preprocess handlers receive a dependency identifier before it is interpreted by the container. A handler may transform the identifier and return a modified value that continues through the resolution pipeline.
23
+
24
+ Typical uses of preprocess handlers include:
25
+
26
+ - rewriting dependency identifiers
27
+ - applying identifier aliases
28
+ - enforcing project-specific identifier conventions
29
+
30
+ Preprocess handlers operate only on identifiers and do not interact with instantiated objects.
31
+
32
+ ## Postprocess Wrappers
33
+
34
+ Postprocess wrappers operate on objects created by the container. A wrapper receives the instantiated object and may return a modified or decorated version.
35
+
36
+ Wrappers are typically used for:
37
+
38
+ - logging or tracing
39
+ - instrumentation
40
+ - capability injection
41
+ - runtime adaptation of object behavior
42
+
43
+ Wrappers do not modify the dependency resolution logic itself and operate only after object instantiation.
44
+
45
+ ## Wrapper Selection
46
+
47
+ Wrappers are applied when their identifiers appear in a CDC. Wrapper identifiers are appended after the lifecycle marker and separated by underscores.
48
+
49
+ Example:
50
+
51
+ ```txt
52
+ App_Service_User$$_wrapLog_wrapTrace
53
+ ```
54
+
55
+ In this example the container creates a new instance of the dependency and applies the wrappers `wrapLog` and `wrapTrace` during the postprocess stage.
56
+
57
+ ## Execution Order
58
+
59
+ Multiple wrappers may be applied to a single dependency. Wrappers are executed in the order in which they appear in the CDC.
60
+
61
+ Each wrapper receives the object returned by the previous wrapper and may return a new object that becomes the input to the next wrapper.
62
+
63
+ ## Extension Constraints
64
+
65
+ Extensions must satisfy the following constraints:
66
+
67
+ - they must be registered before the container becomes active
68
+ - they must be deterministic and free of side effects that alter container state
69
+ - they must not bypass lifecycle semantics enforced by the container
70
+
71
+ These constraints ensure that extensions do not compromise deterministic dependency resolution.