@teqfw/di 2.6.2 → 2.8.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/src/Parser.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  /**
4
4
  * @namespace TeqFw_Di_Parser
5
- * @description CDC parser that builds dependency identity DTOs.
5
+ * @description Dependency Specifier parser that builds dependency identity DTOs.
6
6
  */
7
7
 
8
8
  import TeqFw_Di_Enum_Composition from './Enum/Composition.mjs';
@@ -11,7 +11,7 @@ import TeqFw_Di_Enum_Platform from './Enum/Platform.mjs';
11
11
  import {Factory as TeqFw_Di_Dto_DepId_Factory} from './Dto/DepId.mjs';
12
12
 
13
13
  /**
14
- * Parser for CDC identifiers into frozen dependency identity DTO.
14
+ * Parser for Dependency Specifiers into frozen dependency identity DTOs.
15
15
  */
16
16
  export default class TeqFw_Di_Parser {
17
17
  /**
@@ -26,7 +26,7 @@ export default class TeqFw_Di_Parser {
26
26
  /**
27
27
  * Detects platform prefix and strips it from the source string.
28
28
  *
29
- * @param {string} source CDC source without validation.
29
+ * @param {string} source Dependency Specifier source without validation.
30
30
  * @returns {{platform: typeof TeqFw_Di_Enum_Platform[keyof typeof TeqFw_Di_Enum_Platform], source: string}}
31
31
  */
32
32
  const detectPlatform = function (source) {
@@ -49,7 +49,7 @@ export default class TeqFw_Di_Parser {
49
49
  /**
50
50
  * Parses lifecycle and wrapper suffix from the source string.
51
51
  *
52
- * @param {string} source CDC source without platform prefix.
52
+ * @param {string} source Dependency Specifier source without platform prefix.
53
53
  * @param {typeof TeqFw_Di_Enum_Platform[keyof typeof TeqFw_Di_Enum_Platform]} platform
54
54
  * @returns {{core: string, life: typeof TeqFw_Di_Enum_Life[keyof typeof TeqFw_Di_Enum_Life] | null, lifecycleDeclared: boolean, wrappers: string[]}}
55
55
  */
@@ -89,7 +89,7 @@ export default class TeqFw_Di_Parser {
89
89
  /**
90
90
  * Splits module and export names from canonical core string.
91
91
  *
92
- * @param {string} core CDC core without lifecycle suffix.
92
+ * @param {string} core Dependency Specifier core without lifecycle suffix.
93
93
  * @returns {{moduleName: string, exportName: string|null}}
94
94
  */
95
95
  const parseModuleExport = function (core) {
@@ -139,20 +139,20 @@ export default class TeqFw_Di_Parser {
139
139
  };
140
140
 
141
141
  /**
142
- * Parses one CDC identifier and returns normalized frozen dependency DTO.
142
+ * Parses one Dependency Specifier and returns a normalized frozen dependency DTO.
143
143
  *
144
- * @param {string} cdc CDC identifier string.
144
+ * @param {string} specifier Dependency Specifier string.
145
145
  * @returns {TeqFw_Di_DepId__DTO}
146
146
  */
147
- this.parse = function (cdc) {
148
- if (logger) logger.log(`Parser.parse: input='${cdc}'.`);
149
- if (typeof cdc !== 'string') throw new Error('CDC must be a string.');
150
- if (cdc.length === 0) throw new Error('CDC must be non-empty.');
151
- if (!/^[\x00-\x7F]+$/.test(cdc)) throw new Error('CDC must be ASCII.');
147
+ this.parse = function (specifier) {
148
+ if (logger) logger.log(`Parser.parse: input='${specifier}'.`);
149
+ if (typeof specifier !== 'string') throw new Error('Dependency Specifier must be a string.');
150
+ if (specifier.length === 0) throw new Error('Dependency Specifier must be non-empty.');
151
+ if (!/^[\x00-\x7F]+$/.test(specifier)) throw new Error('Dependency Specifier must be ASCII.');
152
152
 
153
153
  /** @type {string} */
154
- const origin = cdc;
155
- const detected = detectPlatform(cdc);
154
+ const origin = specifier;
155
+ const detected = detectPlatform(specifier);
156
156
  const platform = detected.platform;
157
157
  const source = detected.source;
158
158
  if (source.length === 0) throw new Error('moduleName must be non-empty.');
@@ -163,10 +163,10 @@ export default class TeqFw_Di_Parser {
163
163
  /** @type {typeof TeqFw_Di_Enum_Composition[keyof typeof TeqFw_Di_Enum_Composition]} */
164
164
  let composition = TeqFw_Di_Enum_Composition.AS_IS;
165
165
  let exportName = split.exportName;
166
- if (exportName !== null) {
167
- composition = TeqFw_Di_Enum_Composition.FACTORY;
168
- } else if (lifecycle.lifecycleDeclared) {
169
- exportName = 'default';
166
+ if (lifecycle.lifecycleDeclared) {
167
+ if (exportName === null) {
168
+ exportName = 'default';
169
+ }
170
170
  composition = TeqFw_Di_Enum_Composition.FACTORY;
171
171
  }
172
172
 
package/types.d.ts CHANGED
@@ -1,10 +1,15 @@
1
1
  declare global {
2
+ type TeqFw_Di_Node_Registry_Namespace = import("./src/Node/Registry/Namespace.mjs").default;
2
3
  type TeqFw_Di_Config_NamespaceRegistry = import("./src/Config/NamespaceRegistry.mjs").default;
4
+ type TeqFw_Di_Node_Registry_Namespace_Entry = Readonly<{prefix: string, dirAbs: string, ext: string}>;
5
+ type TeqFw_Di_Node_Registry_Package = import("./src/Node/Registry/Package.mjs").default;
6
+ type TeqFw_Di_Node_Registry_Package_Record = Readonly<{name: string, rootAbs: string, rootReal: string, packageJson: Readonly<Record<string, unknown>>, dependencies: ReadonlyArray<string>}>;
3
7
  type TeqFw_Di_Container = import("./src/Container.mjs").default;
4
- type TeqFw_Di_Container_Instantiate_Instantiator = import("./src/Container/Instantiate.mjs").default;
5
- type TeqFw_Di_Container_Lifecycle_Registry = import("./src/Container/Lifecycle.mjs").default;
6
- type TeqFw_Di_Container_Resolve_GraphResolver = import("./src/Container/GraphResolver.mjs").default;
7
- type TeqFw_Di_Container_Wrapper_Executor = import("./src/Container/Executor.mjs").default;
8
+ type TeqFw_Di_Container_Instantiate = import("./src/Container/Instantiate.mjs").default;
9
+ type TeqFw_Di_Container_Lifecycle = import("./src/Container/Lifecycle.mjs").default;
10
+ type TeqFw_Di_Container_Postprocess_Context = Readonly<{depId: TeqFw_Di_DepId__DTO}>;
11
+ type TeqFw_Di_Container_GraphResolver = import("./src/Container/GraphResolver.mjs").default;
12
+ type TeqFw_Di_Container_Executor = import("./src/Container/Executor.mjs").default;
8
13
  type TeqFw_Di_Parser = import("./src/Parser.mjs").default;
9
14
  type TeqFw_Di_DepId = import("./src/Dto/DepId.mjs").default;
10
15
  type TeqFw_Di_DepId__DTO = import("./src/Dto/DepId.mjs").default;
package/ai/concepts.md DELETED
@@ -1,25 +0,0 @@
1
- # concepts.md
2
-
3
- Version: 20260606
4
-
5
- ## Late Binding
6
-
7
- Dependencies are resolved at runtime rather than through direct static imports between application modules. This keeps modules independent of concrete implementations and moves dependency binding into the container.
8
-
9
- ## Runtime Linker
10
-
11
- The container acts as a runtime linker for ES modules. It interprets CDC identifiers, resolves modules, selects exports, and produces linked values for callers.
12
-
13
- ## Dependency Contracts
14
-
15
- Dependencies are declared through CDC strings and module-level `__deps__` descriptors. Together they form the contract between module code and runtime composition.
16
-
17
- The canonical `__deps__` form is hierarchical and keyed by export name.
18
-
19
- ## Namespace Mapping
20
-
21
- Logical module identifiers are translated into module-specifier bases through namespace roots. This keeps dependency addressing independent from concrete filesystem paths or URL locations.
22
-
23
- ## Immutable Linked Values
24
-
25
- Values returned by the container are frozen after linking. Consumers should treat them as stable resolved values rather than mutable construction targets.
package/ai/usage.md DELETED
@@ -1,194 +0,0 @@
1
- # usage.md
2
-
3
- Version: 20260606
4
-
5
- ## Purpose
6
-
7
- This document shows canonical usage patterns for the container. Examples are intentionally short and prioritize supported, recommended forms over convenience shorthand.
8
-
9
- ## Canonical Module Descriptor
10
-
11
- The canonical form of `__deps__` is hierarchical and keyed by export name.
12
-
13
- ```js
14
- // @ts-check
15
-
16
- export const __deps__ = {
17
- default: {
18
- cast: "App_Helper_Cast$",
19
- },
20
- };
21
-
22
- export default class App_Root {
23
- /**
24
- * @param {{cast: (value: unknown) => string}} deps
25
- */
26
- constructor({ cast }) {
27
- return {
28
- configure(params = {}) {
29
- return {
30
- name: cast(params.name ?? "app"),
31
- };
32
- },
33
- };
34
- }
35
- }
36
- ```
37
-
38
- Dependency module:
39
-
40
- ```js
41
- // @ts-check
42
-
43
- export default function App_Helper_Cast() {
44
- return function cast(value) {
45
- return String(value);
46
- };
47
- }
48
- ```
49
-
50
- Rules:
51
-
52
- - the hierarchical export-scoped form is canonical;
53
- - each export entry maps constructor dependency names to CDC identifiers;
54
- - if `__deps__` is omitted, the module has no declared dependencies;
55
- - dependencies are resolved recursively before instantiation.
56
-
57
- ## Canonical Container Setup
58
-
59
- The container is configured in the composition root before the first resolution.
60
-
61
- ```js
62
- import path from "node:path";
63
- import { fileURLToPath } from "node:url";
64
- import Container from "@teqfw/di";
65
-
66
- const __filename = fileURLToPath(import.meta.url);
67
- const __dirname = path.dirname(__filename);
68
-
69
- const container = new Container();
70
- container.addNamespaceRoot("App_", path.resolve(__dirname, "./src/App"), ".mjs");
71
- ```
72
-
73
- Namespace roots may also use URL-backed module-specifier bases:
74
-
75
- ```js
76
- container.addNamespaceRoot("App_", "https://cdn.example.com/app", ".mjs");
77
- ```
78
-
79
- ## Resolve Root Dependency
80
-
81
- Applications typically resolve one root dependency and let the container build the full object graph.
82
-
83
- ```js
84
- const root = await container.get("App_Root$");
85
- console.log(root.configure({name: 123}).name);
86
- console.log(Object.isFrozen(root));
87
- ```
88
-
89
- ## Named Export
90
-
91
- Named exports use the `__ExportName` segment in the CDC and the same hierarchical `__deps__` structure.
92
-
93
- ```js
94
- export const __deps__ = {
95
- default: {
96
- cast: "App_Helper_Cast$",
97
- },
98
- Factory: {
99
- cast: "App_Helper_Cast$",
100
- },
101
- };
102
-
103
- export default class RuntimeWrapper {
104
- constructor() {
105
- return {mode: "runtime"};
106
- }
107
- }
108
-
109
- export class Factory {
110
- constructor({ cast }) {
111
- this.configure = function (params = {}) {
112
- return {
113
- mode: "factory",
114
- name: cast(params.name ?? "app"),
115
- };
116
- };
117
- }
118
- }
119
- ```
120
-
121
- Resolution examples:
122
-
123
- ```js
124
- const runtime = await container.get("App_Module$");
125
- const factory = await container.get("App_Module__Factory$");
126
- ```
127
-
128
- ## Singleton And Transient
129
-
130
- Common lifecycle-based compositions:
131
-
132
- ```txt
133
- App_Service$
134
- App_Task$$
135
- App_Task$$$
136
- ```
137
-
138
- - `$` creates and reuses a singleton instance;
139
- - `$$` creates a new instance for each request;
140
- - `$$$` is a transient alias in the current implementation.
141
-
142
- ## Wrappers
143
-
144
- Wrapper exports are selected by CDC suffixes and are applied after postprocess hooks.
145
-
146
- ```txt
147
- App_Service$$_wrapLog_wrapTrace
148
- ```
149
-
150
- This pattern is useful when runtime behavior should be decorated without changing the service module contract.
151
-
152
- ## Platform Modules
153
-
154
- CDC may refer to platform modules directly.
155
-
156
- ```txt
157
- node:fs
158
- npm:@humanfs/core
159
- node:worker_threads
160
- ```
161
-
162
- These forms resolve the selected platform module export as-is unless a lifecycle marker is explicitly added.
163
-
164
- ## Non-Canonical Shorthand
165
-
166
- A flat `__deps__` object is a supported shorthand for default-export-only modules, but it is not the canonical model.
167
-
168
- ```js
169
- export const __deps__ = {
170
- cast: "App_Helper_Cast$",
171
- };
172
-
173
- export default class App_Short {
174
- constructor({ cast }) {
175
- this.cast = cast;
176
- }
177
- }
178
- ```
179
-
180
- Prefer the hierarchical form for new integrations and for any module that exposes named exports.
181
-
182
- ## Empty Descriptor
183
-
184
- Modules with no declared dependencies omit `__deps__` entirely.
185
-
186
- ```js
187
- export default class App_Empty {
188
- constructor() {
189
- this.ready = function () {
190
- return true;
191
- };
192
- }
193
- }
194
- ```