@teqfw/di 2.4.0 → 2.5.1

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.
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Container_Wrapper_Executor
5
+ * @description Applies wrapper pipeline to resolved values.
6
+ */
7
+
3
8
  /**
4
9
  * Wrapper-stage executor.
5
10
  *
@@ -25,7 +30,7 @@ export default class TeqFw_Di_Container_Wrapper_Executor {
25
30
  /**
26
31
  * Applies wrappers in declaration order.
27
32
  *
28
- * @param {TeqFw_Di_DepId$DTO} depId
33
+ * @param {TeqFw_Di_DepId__DTO} depId
29
34
  * @param {unknown} value
30
35
  * @param {object} moduleNamespace
31
36
  * @returns {unknown}
package/src/Container.mjs CHANGED
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Container
5
+ * @description DI container orchestration entry point.
6
+ */
7
+
3
8
  import TeqFw_Di_Def_Parser from './Def/Parser.mjs';
4
9
  import {Factory as TeqFw_Di_Dto_Resolver_Config_Factory} from './Dto/Resolver/Config.mjs';
5
10
  import TeqFw_Di_Resolver from './Container/Resolver.mjs';
@@ -30,11 +35,11 @@ export default class TeqFw_Di_Container {
30
35
  constructor() {
31
36
  /** @type {TeqFw_Di_Container_State} */
32
37
  let state = 'notConfigured';
33
- /** @type {((depId: TeqFw_Di_DepId$DTO) => TeqFw_Di_DepId$DTO)[]} */
38
+ /** @type {((depId: TeqFw_Di_DepId__DTO) => TeqFw_Di_DepId__DTO)[]} */
34
39
  const preprocess = [];
35
40
  /** @type {((value: unknown) => unknown)[]} */
36
41
  const postprocess = [];
37
- /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO[]} */
42
+ /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace__DTO[]} */
38
43
  const namespaceRoots = [];
39
44
  /** @type {Map<string, unknown>} */
40
45
  const mockRegistry = new Map();
@@ -45,7 +50,7 @@ export default class TeqFw_Di_Container {
45
50
 
46
51
  /** @type {TeqFw_Di_Def_Parser} */
47
52
  let parser = new TeqFw_Di_Def_Parser();
48
- /** @type {TeqFw_Di_Dto_Resolver_Config$Factory} */
53
+ /** @type {TeqFw_Di_Dto_Resolver_Config__Factory} */
49
54
  const configFactory = new TeqFw_Di_Dto_Resolver_Config_Factory();
50
55
  /** @type {TeqFw_Di_Resolver|undefined} */
51
56
  let resolver;
@@ -61,7 +66,7 @@ export default class TeqFw_Di_Container {
61
66
  const wrapperExecutor = new TeqFw_Di_Container_Wrapper_Executor();
62
67
 
63
68
  /**
64
- * @param {TeqFw_Di_DepId$DTO} depId
69
+ * @param {TeqFw_Di_DepId__DTO} depId
65
70
  * @returns {string}
66
71
  */
67
72
  const getKey = function (depId) {
@@ -81,7 +86,7 @@ export default class TeqFw_Di_Container {
81
86
  /**
82
87
  * Canonical structural identity excluding `origin`.
83
88
  *
84
- * @param {TeqFw_Di_DepId$DTO} depId
89
+ * @param {TeqFw_Di_DepId__DTO} depId
85
90
  * @returns {string}
86
91
  */
87
92
  const getMockKey = function (depId) {
@@ -138,11 +143,11 @@ export default class TeqFw_Di_Container {
138
143
  /**
139
144
  * Applies ordered preprocess pipeline.
140
145
  *
141
- * @param {TeqFw_Di_DepId$DTO} depId
142
- * @returns {TeqFw_Di_DepId$DTO}
146
+ * @param {TeqFw_Di_DepId__DTO} depId
147
+ * @returns {TeqFw_Di_DepId__DTO}
143
148
  */
144
149
  const applyPreprocess = function (depId) {
145
- /** @type {TeqFw_Di_DepId$DTO} */
150
+ /** @type {TeqFw_Di_DepId__DTO} */
146
151
  let current = depId;
147
152
  for (const fn of preprocess) {
148
153
  current = fn(current);
@@ -167,21 +172,36 @@ export default class TeqFw_Di_Container {
167
172
 
168
173
  /**
169
174
  * @param {object} namespace
170
- * @param {TeqFw_Di_DepId$DTO} depId
175
+ * @param {TeqFw_Di_DepId__DTO} depId
171
176
  * @returns {Record<string, unknown>}
172
177
  */
173
178
  const readDepsDecl = function (namespace, depId) {
174
179
  /** @type {unknown} */
175
180
  const deps = Reflect.get(namespace, '__deps__');
176
181
  if (deps === undefined) return {};
177
- if ((deps !== null) && (typeof deps === 'object') && !Array.isArray(deps)) {
178
- const exportName = depId.exportName === null ? 'default' : depId.exportName;
179
- const exportScoped = Reflect.get(/** @type {object} */ (deps), exportName);
180
- if ((exportScoped !== undefined) && (exportScoped !== null) && (typeof exportScoped === 'object') && !Array.isArray(exportScoped)) {
181
- return /** @type {Record<string, unknown>} */ (exportScoped);
182
+ if ((deps === null) || (typeof deps !== 'object') || Array.isArray(deps)) {
183
+ throw new Error('__deps__ must be a plain object.');
184
+ }
185
+ const exportName = depId.exportName === null ? 'default' : depId.exportName;
186
+ const exportScoped = Reflect.get(/** @type {object} */ (deps), exportName);
187
+ if ((exportScoped !== undefined) && (exportScoped !== null) && (typeof exportScoped === 'object') && !Array.isArray(exportScoped)) {
188
+ const values = Object.values(/** @type {Record<string, unknown>} */ (exportScoped));
189
+ if (!values.every((value) => typeof value === 'string')) {
190
+ throw new Error('__deps__ export entries must map dependency names to CDC strings.');
191
+ }
192
+ return /** @type {Record<string, unknown>} */ (exportScoped);
193
+ }
194
+ if (exportName === 'default') {
195
+ const values = Object.values(/** @type {Record<string, unknown>} */ (deps));
196
+ if (values.every((value) => typeof value === 'string')) {
197
+ return /** @type {Record<string, unknown>} */ (deps);
198
+ }
199
+ if (values.every((value) => (value !== null) && (typeof value === 'object') && !Array.isArray(value))) {
200
+ return {};
182
201
  }
202
+ throw new Error('__deps__ must be either flat or export-scoped.');
183
203
  }
184
- return /** @type {Record<string, unknown>} */ (deps);
204
+ return {};
185
205
  };
186
206
 
187
207
  /**
@@ -223,7 +243,7 @@ export default class TeqFw_Di_Container {
223
243
  /**
224
244
  * Registers preprocess extension before first resolution.
225
245
  *
226
- * @param {(depId: TeqFw_Di_DepId$DTO) => TeqFw_Di_DepId$DTO} fn
246
+ * @param {(depId: TeqFw_Di_DepId__DTO) => TeqFw_Di_DepId__DTO} fn
227
247
  * @returns {void}
228
248
  */
229
249
  this.addPreprocess = function (fn) {
@@ -329,12 +349,12 @@ export default class TeqFw_Di_Container {
329
349
  logger.log(`Container.get: cdc='${cdc}'.`);
330
350
  initializeInfrastructure();
331
351
  logger.log(`Container.state: '${state}'.`);
332
- /** @type {TeqFw_Di_DepId$DTO} */
352
+ /** @type {TeqFw_Di_DepId__DTO} */
333
353
  stage = 'parse';
334
354
  logger.log('Container.pipeline: parse:entry.');
335
355
  const parsed = parser.parse(cdc);
336
356
  logger.log(`Container.pipeline: parse:exit '${parsed.platform}::${parsed.moduleName}'.`);
337
- /** @type {TeqFw_Di_DepId$DTO} */
357
+ /** @type {TeqFw_Di_DepId__DTO} */
338
358
  stage = 'preprocess';
339
359
  logger.log('Container.pipeline: preprocess:entry.');
340
360
  const root = applyPreprocess(parsed);
@@ -356,7 +376,7 @@ export default class TeqFw_Di_Container {
356
376
  } else {
357
377
  logger.log('Container.pipeline: mock-lookup:disabled.');
358
378
  }
359
- /** @type {Map<string, {depId: TeqFw_Di_DepId$DTO, namespace: object}>} */
379
+ /** @type {Map<string, {depId: TeqFw_Di_DepId__DTO, namespace: object}>} */
360
380
  stage = 'resolve';
361
381
  logger.log('Container.pipeline: resolve:entry.');
362
382
  const graph = await graphResolver.resolve(root);
@@ -385,7 +405,7 @@ export default class TeqFw_Di_Container {
385
405
  for (const [name, cdc] of Object.entries(depsDecl)) {
386
406
  /** @type {string} */
387
407
  const childCdc = /** @type {string} */ (cdc);
388
- /** @type {TeqFw_Di_DepId$DTO} */
408
+ /** @type {TeqFw_Di_DepId__DTO} */
389
409
  const childDepId = parser.parse(childCdc);
390
410
  deps[name] = build(getKey(childDepId));
391
411
  }
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Def_Parser
5
+ * @description CDC parser that builds dependency identity DTOs.
6
+ */
7
+
3
8
  import TeqFw_Di_Enum_Composition from '../Enum/Composition.mjs';
4
9
  import TeqFw_Di_Enum_Life from '../Enum/Life.mjs';
5
10
  import TeqFw_Di_Enum_Platform from '../Enum/Platform.mjs';
@@ -13,7 +18,7 @@ export default class TeqFw_Di_Def_Parser {
13
18
  * Creates parser instance.
14
19
  */
15
20
  constructor() {
16
- /** @type {TeqFw_Di_Dto_DepId$Factory} Factory used to construct dependency identity DTO. */
21
+ /** @type {TeqFw_Di_Dto_DepId__Factory} Factory used to construct dependency identity DTO. */
17
22
  const depIdFactory = new TeqFw_Di_Dto_DepId_Factory();
18
23
  /** @type {{log(message: string): void}|null} */
19
24
  let logger = null;
@@ -22,7 +27,7 @@ export default class TeqFw_Di_Def_Parser {
22
27
  * Parses one CDC identifier and returns normalized frozen dependency DTO.
23
28
  *
24
29
  * @param {string} cdc CDC identifier string.
25
- * @returns {TeqFw_Di_DepId$DTO}
30
+ * @returns {TeqFw_Di_DepId__DTO}
26
31
  */
27
32
  this.parse = function (cdc) {
28
33
  if (logger) logger.log(`Parser.parse: input='${cdc}'.`);
@@ -71,7 +76,7 @@ export default class TeqFw_Di_Def_Parser {
71
76
  }
72
77
  } else {
73
78
  if (source.includes('$')) throw new Error('Invalid lifecycle encoding.');
74
- if (/(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(source)) {
79
+ if ((platform !== TeqFw_Di_Enum_Platform.NODE) && /(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(source)) {
75
80
  throw new Error('Wrapper without lifecycle is forbidden.');
76
81
  }
77
82
  }
package/src/Dto/DepId.mjs CHANGED
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Dto_DepId
5
+ * @description Dependency identity DTO and factory.
6
+ */
7
+
3
8
  import TeqFw_Di_Enum_Composition from '../Enum/Composition.mjs';
4
9
  import TeqFw_Di_Enum_Life from '../Enum/Life.mjs';
5
10
  import TeqFw_Di_Enum_Platform from '../Enum/Platform.mjs';
@@ -54,7 +59,7 @@ export class Factory {
54
59
  * Creates normalized frozen dependency identity DTO.
55
60
  *
56
61
  * @param {unknown} [input]
57
- * @returns {TeqFw_Di_DepId$DTO}
62
+ * @returns {TeqFw_Di_DepId__DTO}
58
63
  */
59
64
  create(input) {
60
65
  /** @type {Record<string, unknown>} */
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Dto_Resolver_Config_Namespace
5
+ * @description Resolver namespace rule DTO and factory.
6
+ */
7
+
3
8
  /**
4
9
  * DTO for resolver namespace rule records and its factory.
5
10
  */
@@ -25,14 +30,14 @@ export class Factory {
25
30
  /**
26
31
  * Creates normalized frozen resolver namespace DTO.
27
32
  *
28
- * @param {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace$DTO>|Record<string, unknown>} [input] Source values.
29
- * @returns {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO}
33
+ * @param {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace__DTO>|Record<string, unknown>} [input] Source values.
34
+ * @returns {TeqFw_Di_Dto_Resolver_Config_Namespace__DTO}
30
35
  */
31
36
  create(input) {
32
- /** @type {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace$DTO>|Record<string, unknown>} */
37
+ /** @type {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace__DTO>|Record<string, unknown>} */
33
38
  const source = (input && (typeof input === 'object')) ? input : {};
34
39
 
35
- /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO} */
40
+ /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace__DTO} */
36
41
  const dto = new DTO();
37
42
  dto.prefix = (typeof source.prefix === 'string') ? source.prefix : undefined;
38
43
  dto.target = (typeof source.target === 'string') ? source.target : undefined;
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Dto_Resolver_Config
5
+ * @description Resolver configuration DTO and factory.
6
+ */
7
+
3
8
  import {Factory as TeqFw_Di_Dto_Resolver_Config_Namespace_Factory} from './Config/Namespace.mjs';
4
9
 
5
10
  /**
@@ -10,7 +15,7 @@ import {Factory as TeqFw_Di_Dto_Resolver_Config_Namespace_Factory} from './Confi
10
15
  * Runtime DTO for resolver configuration.
11
16
  */
12
17
  export default class DTO {
13
- /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO[]} Namespace resolution rules. */
18
+ /** @type {TeqFw_Di_Dto_Resolver_Config_Namespace__DTO[]} Namespace resolution rules. */
14
19
  namespaces;
15
20
 
16
21
  /** @type {string|undefined} Optional node_modules root prefix for npm modules. */
@@ -31,14 +36,14 @@ export class Factory {
31
36
  /**
32
37
  * Creates normalized frozen resolver configuration DTO.
33
38
  *
34
- * @param {Partial<TeqFw_Di_Dto_Resolver_Config$DTO>|Record<string, unknown>} [input] Source values.
35
- * @returns {TeqFw_Di_Dto_Resolver_Config$DTO}
39
+ * @param {Partial<TeqFw_Di_Dto_Resolver_Config__DTO>|Record<string, unknown>} [input] Source values.
40
+ * @returns {TeqFw_Di_Dto_Resolver_Config__DTO}
36
41
  */
37
42
  this.create = function (input) {
38
- /** @type {Partial<TeqFw_Di_Dto_Resolver_Config$DTO>|Record<string, unknown>} */
43
+ /** @type {Partial<TeqFw_Di_Dto_Resolver_Config__DTO>|Record<string, unknown>} */
39
44
  const source = (input && (typeof input === 'object')) ? input : {};
40
45
 
41
- /** @type {TeqFw_Di_Dto_Resolver_Config$DTO} */
46
+ /** @type {TeqFw_Di_Dto_Resolver_Config__DTO} */
42
47
  const dto = new DTO();
43
48
  /** @type {unknown[]} */
44
49
  const items = Array.isArray(source.namespaces) ? source.namespaces : [];
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Enum_Composition
5
+ * @description Composition mode enum constants.
6
+ */
7
+
3
8
  /**
4
9
  * Composition mode enum used in dependency identity DTO.
5
10
  */
package/src/Enum/Life.mjs CHANGED
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Enum_Life
5
+ * @description Lifecycle mode enum constants.
6
+ */
7
+
3
8
  /**
4
9
  * Lifecycle mode enum used in dependency identity DTO.
5
10
  */
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Enum_Platform
5
+ * @description Platform selector enum constants.
6
+ */
7
+
3
8
  /**
4
9
  * Platform enum used to resolve module loading strategy.
5
10
  */
@@ -1,5 +1,10 @@
1
1
  // @ts-check
2
2
 
3
+ /**
4
+ * @namespace TeqFw_Di_Internal_Logger
5
+ * @description Internal console logger for diagnostics.
6
+ */
7
+
3
8
  /**
4
9
  * Internal synchronous console logger.
5
10
  *
package/types.d.ts CHANGED
@@ -8,17 +8,17 @@ declare global {
8
8
  type TeqFw_Di_Container_Wrapper_Executor = import("./src/Container/Wrapper/Executor.mjs").default;
9
9
  type TeqFw_Di_Def_Parser = import("./src/Def/Parser.mjs").default;
10
10
  type TeqFw_Di_DepId = import("./src/Dto/DepId.mjs").default;
11
- type TeqFw_Di_DepId$DTO = import("./src/Dto/DepId.mjs").default;
11
+ type TeqFw_Di_DepId__DTO = import("./src/Dto/DepId.mjs").default;
12
12
  type TeqFw_Di_DepId$Factory = InstanceType<typeof import("./src/Dto/DepId.mjs").Factory>;
13
13
  type TeqFw_Di_Dto_DepId = import("./src/Dto/DepId.mjs").default;
14
14
  type TeqFw_Di_Dto_DepId$DTO = import("./src/Dto/DepId.mjs").default;
15
- type TeqFw_Di_Dto_DepId$Factory = InstanceType<typeof import("./src/Dto/DepId.mjs").Factory>;
15
+ type TeqFw_Di_Dto_DepId__Factory = InstanceType<typeof import("./src/Dto/DepId.mjs").Factory>;
16
16
  type TeqFw_Di_Dto_Resolver_Config = import("./src/Dto/Resolver/Config.mjs").default;
17
- type TeqFw_Di_Dto_Resolver_Config$DTO = import("./src/Dto/Resolver/Config.mjs").default;
18
- type TeqFw_Di_Dto_Resolver_Config$Factory = InstanceType<typeof import("./src/Dto/Resolver/Config.mjs").Factory>;
17
+ type TeqFw_Di_Dto_Resolver_Config__DTO = import("./src/Dto/Resolver/Config.mjs").default;
18
+ type TeqFw_Di_Dto_Resolver_Config__Factory = InstanceType<typeof import("./src/Dto/Resolver/Config.mjs").Factory>;
19
19
  type TeqFw_Di_Dto_Resolver_Config_Namespace = import("./src/Dto/Resolver/Config/Namespace.mjs").default;
20
- type TeqFw_Di_Dto_Resolver_Config_Namespace$DTO = import("./src/Dto/Resolver/Config/Namespace.mjs").default;
21
- type TeqFw_Di_Dto_Resolver_Config_Namespace$Factory = InstanceType<typeof import("./src/Dto/Resolver/Config/Namespace.mjs").Factory>;
20
+ type TeqFw_Di_Dto_Resolver_Config_Namespace__DTO = import("./src/Dto/Resolver/Config/Namespace.mjs").default;
21
+ type TeqFw_Di_Dto_Resolver_Config_Namespace__Factory = InstanceType<typeof import("./src/Dto/Resolver/Config/Namespace.mjs").Factory>;
22
22
  type TeqFw_Di_Enum_Composition = typeof import("./src/Enum/Composition.mjs").default;
23
23
  type TeqFw_Di_Enum_Life = typeof import("./src/Enum/Life.mjs").default;
24
24
  type TeqFw_Di_Enum_Platform = typeof import("./src/Enum/Platform.mjs").default;