@teqfw/di 2.6.2 → 2.7.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.7.0 - 2026-07-10 - As-is injection fix and coverage expansion
4
+
5
+ * Fixed the bug that prevented injecting classes as-is, including named exports resolved without factory wrapping.
6
+ * Aligned container namespace aliases and published type declarations with the actual filesystem layout.
7
+ * Expanded unit and integration coverage for pipeline execution, dependency key generation, dependency declarations, Promise-safe wrappers, and as-is export resolution.
8
+ * Refreshed development dependencies and lockfile metadata before the release.
9
+ * Updated package version metadata to `2.7.0`.
10
+
3
11
  ## 2.6.2 - 2026-06-08 - Documentation alignment and container simplification
4
12
 
5
13
  * Removed the legacy `setParser()` extension point and flattened the internal container implementation layout.
@@ -1,6 +1,6 @@
1
1
  # dependency-id.md
2
2
 
3
- Version: 20260606
3
+ Version: 20260710
4
4
 
5
5
  ## Purpose
6
6
 
@@ -23,7 +23,7 @@ Component order is fixed.
23
23
 
24
24
  - `PlatformPrefix` — optional source selector such as `node:` or `npm:`.
25
25
  - `ModuleName` — logical module identifier inside a namespace.
26
- - `__ExportName` — optional named export selector. Omission means the default export for composition, or whole-module namespace for as-is resolution.
26
+ - `__ExportName` — optional named export selector. With a lifecycle marker, selects the export for factory composition. Without a lifecycle marker, selects the named export for as-is resolution. Omission without a lifecycle marker means the whole-module namespace is resolved as-is.
27
27
  - `Lifecycle` — optional instantiation marker.
28
28
  - `WrapperSuffixes` — optional ordered wrapper export names appended after the lifecycle marker.
29
29
 
@@ -69,11 +69,15 @@ Named exports are selected with a double underscore separator.
69
69
  Examples:
70
70
 
71
71
  ```txt
72
+ App_Service_User
72
73
  App_Service_User$
74
+ App_Service_User__Factory
73
75
  App_Service_User__Factory$
74
76
  ```
75
77
 
78
+ - `App_Service_User` selects the whole module namespace for as-is resolution (no lifecycle marker, no export name).
76
79
  - `App_Service_User$` selects the default export for lifecycle-based composition.
80
+ - `App_Service_User__Factory` selects the named export `Factory` for as-is resolution (no lifecycle marker).
77
81
  - `App_Service_User__Factory$` selects the named export `Factory` for lifecycle-based composition.
78
82
 
79
83
  ## Lifecycle Markers
@@ -130,6 +134,7 @@ Important rules:
130
134
  ```txt
131
135
  App_Math
132
136
  App_Service$
137
+ App_Service__Factory
133
138
  App_Service__Factory$
134
139
  App_Task$$_wrapLog
135
140
  node:fs
@@ -138,8 +143,9 @@ npm:@humanfs/core
138
143
 
139
144
  These examples cover:
140
145
 
141
- - as-is module or export resolution;
146
+ - as-is module resolution (whole namespace);
142
147
  - singleton composition;
143
- - named export composition;
148
+ - named export as-is resolution;
149
+ - named export singleton composition;
144
150
  - transient composition with wrapper exports;
145
151
  - platform module access.
package/ai/package-api.ts CHANGED
@@ -280,25 +280,25 @@ export const PACKAGE_API: PackageApiContract = {
280
280
  reason: 'Internal immutable-core helper. Not exported via package.json.',
281
281
  },
282
282
  {
283
- alias: 'TeqFw_Di_Container_Instantiate_Instantiator',
283
+ alias: 'TeqFw_Di_Container_Instantiate',
284
284
  source: './src/Container/Instantiate.mjs',
285
285
  exposure: 'internal',
286
286
  reason: 'Internal immutable-core helper. Not exported via package.json.',
287
287
  },
288
288
  {
289
- alias: 'TeqFw_Di_Container_Lifecycle_Registry',
289
+ alias: 'TeqFw_Di_Container_Lifecycle',
290
290
  source: './src/Container/Lifecycle.mjs',
291
291
  exposure: 'internal',
292
292
  reason: 'Internal lifecycle cache component. Not exported via package.json.',
293
293
  },
294
294
  {
295
- alias: 'TeqFw_Di_Container_Resolve_GraphResolver',
295
+ alias: 'TeqFw_Di_Container_GraphResolver',
296
296
  source: './src/Container/GraphResolver.mjs',
297
297
  exposure: 'internal',
298
298
  reason: 'Internal graph builder used by Container.get(). Not exported via package.json.',
299
299
  },
300
300
  {
301
- alias: 'TeqFw_Di_Container_Wrapper_Executor',
301
+ alias: 'TeqFw_Di_Container_Executor',
302
302
  source: './src/Container/Executor.mjs',
303
303
  exposure: 'internal',
304
304
  reason: 'Internal wrapper-stage executor. Not exported via package.json.',
package/ai/usage.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # usage.md
2
2
 
3
- Version: 20260606
3
+ Version: 20260710
4
4
 
5
5
  ## Purpose
6
6
 
@@ -125,6 +125,13 @@ const runtime = await container.get("App_Module$");
125
125
  const factory = await container.get("App_Module__Factory$");
126
126
  ```
127
127
 
128
+ Without a lifecycle marker, the export is resolved as-is — the class or function itself, not an instance:
129
+
130
+ ```js
131
+ const FactoryClass = await container.get("App_Module__Factory");
132
+ const factory = new FactoryClass({cast: resolvedCast});
133
+ ```
134
+
128
135
  ## Singleton And Transient
129
136
 
130
137
  Common lifecycle-based compositions:
package/dist/esm.js CHANGED
@@ -1 +1 @@
1
- var e=Object.freeze({AS_IS:"A",FACTORY:"F"});var t=Object.freeze({SINGLETON:"S",TRANSIENT:"T"});var r=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const o=r.TEQ,n=e.AS_IS,i=new Set(Object.values(r)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let c=class{moduleName;platform;exportName;composition;life;wrappers;origin},l=class{create(e){const t=e&&"object"==typeof e?e:{},r=new c;r.moduleName="string"==typeof t.moduleName?t.moduleName:"";const l="string"==typeof t.platform?t.platform:void 0;r.platform=l&&i.has(l)?l:o;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),r.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;r.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return r.life=u&&a.has(u)?u:null,r.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],r.origin="string"==typeof t.origin?t.origin:"",Object.freeze(r.wrappers),Object.freeze(r)}};class p{constructor(){const o=new l;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(!/^[\x00-\x7F]+$/.test(i))throw new Error("CDC must be ASCII.");const s=i,a=function(e){let t=r.TEQ;if(e.startsWith("node:"))return t=r.NODE,{platform:t,source:e.slice(5)};if(e.startsWith("npm:"))return t=r.NPM,{platform:t,source:e.slice(4)};if(e.startsWith("teq:"))throw new Error("Explicit teq: prefix is forbidden.");return{platform:t,source:e}}(i),c=a.platform,l=a.source;if(0===l.length)throw new Error("moduleName must be non-empty.");const p=function(e,o){let n=null,i=!1,s=[],a=e;const c=a.match(/(\${1,3})(?:_[a-z][0-9A-Za-z]*)*$/);if(c){const e=c[1],r=c[0].slice(e.length);if(i=!0,"$"===e)n=t.SINGLETON;else if("$$"===e)n=t.TRANSIENT;else{if("$$$"!==e)throw new Error("Lifecycle marker is invalid.");n=null}return a=a.slice(0,c.index),r.length>0&&(s=r.slice(1).split("_")),{core:a,life:n,lifecycleDeclared:i,wrappers:s}}if(e.includes("$"))throw new Error("Invalid lifecycle encoding.");if(o!==r.NODE&&/(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(e))throw new Error("Wrapper without lifecycle is forbidden.");return{core:a,life:n,lifecycleDeclared:i,wrappers:s}}(l,c),f=function(e){const t=e.indexOf("__"),r=e.lastIndexOf("__");if(-1!==t&&t!==r)throw new Error("Export delimiter must appear at most once.");if(e.startsWith("__")||e.endsWith("__"))throw new Error("Malformed export segment.");let o=e,n=null;if(-1!==t){if(o=e.slice(0,t),n=e.slice(t+2),!n)throw new Error("Export must be non-empty.");if(n.includes("_"))throw new Error("Export must not contain _.");if(n.includes("$"))throw new Error("Export must not contain $.")}return{moduleName:o,exportName:n}}(p.core);!function(e,t){if(!e)throw new Error("moduleName must be non-empty.");if(e.startsWith("_")||e.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(e.includes("__"))throw new Error("moduleName must not contain __.");if(e.includes("$"))throw new Error("moduleName must not contain $.");if(t!==r.NPM){if(t===r.NODE){if(!/^[A-Za-z_][$0-9A-Za-z_/-]*$/.test(e))throw new Error("node moduleName must satisfy the built-in specifier form.")}else if(!/^[A-Za-z_][$0-9A-Za-z_]*$/.test(e))throw new Error("moduleName must satisfy the canonical identifier form.")}else if(!/^[@A-Za-z_][$0-9A-Za-z_./-]*$/.test(e))throw new Error("npm moduleName must satisfy the package specifier form.")}(f.moduleName,c);let u=e.AS_IS,d=f.exportName;null!==d?u=e.FACTORY:p.lifecycleDeclared&&(d="default",u=e.FACTORY);const m=o.create({moduleName:f.moduleName,platform:c,exportName:d,composition:u,life:p.life,wrappers:p.wrappers,origin:s});return n&&n.log(`Parser.parse: produced='${m.platform}::${m.moduleName}'.`),m},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},r=new f;return r.prefix="string"==typeof t.prefix?t.prefix:void 0,r.target="string"==typeof t.target?t.target:void 0,r.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(r)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const r=t&&"object"==typeof t?t:{},o=new d,n=Array.isArray(r.namespaces)?r.namespaces:[];return o.namespaces=n.map(t=>e.create(t)),o.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,Object.freeze(o.namespaces),Object.freeze(o)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:r=null}){const o=new Map,n=e;let i;const s=t,a=r,c=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 r=function(e){let t=null,r=-1;const o=i.namespaces;for(const n of o){const o=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(o)} module='${e}'.`),o&&n.prefix.length>r&&(t=n,r=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),o=t.slice(r.prefix.length).split("_").join("/"),n=(s=o,(c=r.defaultExt)?s.endsWith(c)?s:`${s}${c}`:s);var s,c;const l=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(r.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${l}'.`),l};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 r=e.platform,l=e.moduleName,p=`${r}::${l}`;if(o.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),o.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=c(r,l);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();o.set(p,f);try{return await f}catch(e){throw o.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}function w(e){const t=null===e.exportName?"":e.exportName,r=null===e.life?"":e.life,o=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,r,o].join("::")}function h(e,t){const r=Reflect.get(e,"__deps__");if(void 0===r)return{};if(null===r||"object"!=typeof r||Array.isArray(r))throw new Error("__deps__ must be a plain object.");const o=null===t.exportName?"default":t.exportName,n=Reflect.get(r,o);if(null!=n&&"object"==typeof n&&!Array.isArray(n)){if(!Object.values(n).every(e=>"string"==typeof e))throw new Error("__deps__ export entries must map dependency names to CDC strings.");return n}if("default"===o){const e=Object.values(r);if(e.every(e=>"string"==typeof e))return r;if(e.every(e=>null!==e&&"object"==typeof e&&!Array.isArray(e)))return{};throw new Error("__deps__ must be either flat or export-scoped.")}return{}}class y{constructor({parser:e,resolver:t,logger:r=null}){const o=r,n=w,i=async function(r,s,a,c){const l=n(r);if(a.has(l)){const e=[...c,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const p=n(r);if(!s.has(p)){a.add(l),c.push(l);try{const n=await t.resolve(r);o&&o.log(`GraphResolver.walk: resolved '${p}'.`),s.set(p,{depId:r,namespace:n});const l=h(n,r);for(const t of Object.values(l)){const r=e.parse(t);o&&o.log(`GraphResolver.walk: edge '${p}' -> '${r.platform}::${r.moduleName}'.`),await i(r,s,a,c)}}finally{c.pop(),a.delete(l)}}};this.resolve=async function(e){const t=new Map,r=new Set;return await i(e,t,r,[]),t}}}class ${constructor(){this.instantiate=function(t,r,o){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,r);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(o)}else{t=e(o)}if(t instanceof Promise)throw new Error("Factory composition must return synchronously (non-Promise).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class E{constructor(r=null){const o=new Map,n=r,i=w;this.apply=function(r,s){if(r.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${r.composition}' cache=skip.`),s();if(r.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),s();if(r.life===t.SINGLETON){const e=i(r);if(o.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),o.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=s();return o.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),s()}}}class N{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,r,o){let n=r;const i=t.wrappers;for(const t of i){if(!(t in o))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const r=o[t];if(!e(r))throw new Error(`Wrapper '${t}' must be callable.`);if(n=r(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}const x=new WeakMap;function C(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const r=e;if(x.has(r))return x.get(r);try{return Reflect.get(r,"then"),e}catch{const e=new Proxy(r,{get(e,t,r){if("then"!==t)return Reflect.get(e,t,r)}});return x.set(r,e),e}}class b{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,r){console.error(`${t} ${e}`),r instanceof Error?console.error(r.stack??r.message):void 0!==r&&console.error(r)}}}const v=Object.freeze({log(){},error(){}});class _{constructor(){let e="notConfigured";const t=[],r=[],o=[],n=new Map;let i=!1,s=!1,a=new p;const c=new m;let l,f,u,d=v;const x=new $,_=new N,R=w,I=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;if("[object Module]"===Object.prototype.toString.call(e))return e;if(Object.isFrozen(e))return e;try{Object.freeze(e)}catch(e){d.log(`Container.freeze: skipped (${String(e)}).`)}return e},j=function(e){let r=e;for(const e of t)r=e(r);return r},A=function(e){let t=e;for(const e of r)t=e(t);return t},O=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},z=function(e){s&&d.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){O(),z("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){O(),z("addPostprocess()."),r.push(e)},this.addNamespaceRoot=function(e,t,r){O(),z(`addNamespaceRoot('${e}').`),o.push({prefix:e,target:t,defaultExt:r})},this.enableTestMode=function(){O(),z("enableTestMode()."),i=!0},this.enableLogging=function(){O(),s||(s=!0,d=new b,"function"==typeof a.setLogger&&a.setLogger(d),d.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(O(),z(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const r=a.parse(e);n.set(R(r),t)},this.get=async function(t){if("failed"===e)throw d.error(`Container.get: rejected in failed state cdc='${t}'.`),new Error("Container is in failed state.");try{return function(){if("notConfigured"!==e)return;d.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:o});"function"==typeof a.setLogger&&a.setLogger(d),l=new g({config:t,logger:d}),f=new y({parser:a,resolver:l,logger:d}),u=new E(d)}(),d.log(`Container.state: '${e}'.`),await async function(e,t){const{parser:r,resolver:o,graphResolver:n,lifecycle:i,instantiator:s,wrapperExecutor:a,logger:c,testMode:l,mockRegistry:p,freeze:f,applyPreprocess:u,applyPostprocess:d}=e;if(!o||!n||!i)throw new Error("Container infrastructure is not initialized.");const m=w,g=w;let y="start";try{c.log(`Container.get: cdc='${t}'.`),y="parse",c.log("Container.pipeline: parse:entry.");const e=r.parse(t);c.log(`Container.pipeline: parse:exit '${e.platform}::${e.moduleName}'.`),y="preprocess",c.log("Container.pipeline: preprocess:entry.");const o=u(e);if(c.log(`Container.pipeline: preprocess:exit '${o.platform}::${o.moduleName}'.`),!0===l){y="mock",c.log("Container.pipeline: mock-lookup:entry.");const e=g(o);if(p.has(e)){c.log(`Container.pipeline: mock-lookup:hit '${e}'.`),y="freeze",c.log("Container.pipeline: freeze:entry.");const t=f(p.get(e));return c.log("Container.pipeline: freeze:exit."),c.log("Container.pipeline: return:success."),C(t)}c.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else c.log("Container.pipeline: mock-lookup:disabled.");y="resolve",c.log("Container.pipeline: resolve:entry.");const w=await n.resolve(o);c.log(`Container.pipeline: resolve:exit nodes=${w.size}.`);const $=new Map,E=function(e){if($.has(e))return $.get(e);if(!w.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=w.get(e);y="lifecycle",c.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const o=i.apply(t.depId,function(){y="instantiate",c.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},o=h(t.namespace,t.depId);for(const[t,n]of Object.entries(o)){const o=r.parse(n);e[t]=E(m(o))}const n=s.instantiate(t.depId,t.namespace,e);c.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y="postprocess",c.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=d(n);c.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const l=a.execute(t.depId,i,t.namespace);y="freeze",c.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const p=f(l);return c.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p});return c.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),$.set(e,o),o},N=E(m(o));return c.log("Container.pipeline: return:success."),C(N)}catch(e){throw c.error(`Container.pipeline: failed at stage='${y}'.`,e),e}}({parser:a,resolver:l,graphResolver:f,lifecycle:u,instantiator:x,wrapperExecutor:_,logger:d,testMode:i,mockRegistry:n,freeze:I,applyPreprocess:j,applyPostprocess:A},t)}catch(t){throw d.error("Container.transition: operational -> failed.",t),e="failed",t}}}}export{_ as default};
1
+ var e=Object.freeze({AS_IS:"A",FACTORY:"F"});var t=Object.freeze({SINGLETON:"S",TRANSIENT:"T"});var r=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const o=r.TEQ,n=e.AS_IS,i=new Set(Object.values(r)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let c=class{moduleName;platform;exportName;composition;life;wrappers;origin},l=class{create(e){const t=e&&"object"==typeof e?e:{},r=new c;r.moduleName="string"==typeof t.moduleName?t.moduleName:"";const l="string"==typeof t.platform?t.platform:void 0;r.platform=l&&i.has(l)?l:o;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),r.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;r.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return r.life=u&&a.has(u)?u:null,r.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],r.origin="string"==typeof t.origin?t.origin:"",Object.freeze(r.wrappers),Object.freeze(r)}};class p{constructor(){const o=new l;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(!/^[\x00-\x7F]+$/.test(i))throw new Error("CDC must be ASCII.");const s=i,a=function(e){let t=r.TEQ;if(e.startsWith("node:"))return t=r.NODE,{platform:t,source:e.slice(5)};if(e.startsWith("npm:"))return t=r.NPM,{platform:t,source:e.slice(4)};if(e.startsWith("teq:"))throw new Error("Explicit teq: prefix is forbidden.");return{platform:t,source:e}}(i),c=a.platform,l=a.source;if(0===l.length)throw new Error("moduleName must be non-empty.");const p=function(e,o){let n=null,i=!1,s=[],a=e;const c=a.match(/(\${1,3})(?:_[a-z][0-9A-Za-z]*)*$/);if(c){const e=c[1],r=c[0].slice(e.length);if(i=!0,"$"===e)n=t.SINGLETON;else if("$$"===e)n=t.TRANSIENT;else{if("$$$"!==e)throw new Error("Lifecycle marker is invalid.");n=null}return a=a.slice(0,c.index),r.length>0&&(s=r.slice(1).split("_")),{core:a,life:n,lifecycleDeclared:i,wrappers:s}}if(e.includes("$"))throw new Error("Invalid lifecycle encoding.");if(o!==r.NODE&&/(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(e))throw new Error("Wrapper without lifecycle is forbidden.");return{core:a,life:n,lifecycleDeclared:i,wrappers:s}}(l,c),f=function(e){const t=e.indexOf("__"),r=e.lastIndexOf("__");if(-1!==t&&t!==r)throw new Error("Export delimiter must appear at most once.");if(e.startsWith("__")||e.endsWith("__"))throw new Error("Malformed export segment.");let o=e,n=null;if(-1!==t){if(o=e.slice(0,t),n=e.slice(t+2),!n)throw new Error("Export must be non-empty.");if(n.includes("_"))throw new Error("Export must not contain _.");if(n.includes("$"))throw new Error("Export must not contain $.")}return{moduleName:o,exportName:n}}(p.core);!function(e,t){if(!e)throw new Error("moduleName must be non-empty.");if(e.startsWith("_")||e.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(e.includes("__"))throw new Error("moduleName must not contain __.");if(e.includes("$"))throw new Error("moduleName must not contain $.");if(t!==r.NPM){if(t===r.NODE){if(!/^[A-Za-z_][$0-9A-Za-z_/-]*$/.test(e))throw new Error("node moduleName must satisfy the built-in specifier form.")}else if(!/^[A-Za-z_][$0-9A-Za-z_]*$/.test(e))throw new Error("moduleName must satisfy the canonical identifier form.")}else if(!/^[@A-Za-z_][$0-9A-Za-z_./-]*$/.test(e))throw new Error("npm moduleName must satisfy the package specifier form.")}(f.moduleName,c);let u=e.AS_IS,d=f.exportName;p.lifecycleDeclared&&(null===d&&(d="default"),u=e.FACTORY);const m=o.create({moduleName:f.moduleName,platform:c,exportName:d,composition:u,life:p.life,wrappers:p.wrappers,origin:s});return n&&n.log(`Parser.parse: produced='${m.platform}::${m.moduleName}'.`),m},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},r=new f;return r.prefix="string"==typeof t.prefix?t.prefix:void 0,r.target="string"==typeof t.target?t.target:void 0,r.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(r)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const r=t&&"object"==typeof t?t:{},o=new d,n=Array.isArray(r.namespaces)?r.namespaces:[];return o.namespaces=n.map(t=>e.create(t)),o.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,Object.freeze(o.namespaces),Object.freeze(o)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:r=null}){const o=new Map,n=e;let i;const s=t,a=r,c=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 r=function(e){let t=null,r=-1;const o=i.namespaces;for(const n of o){const o=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(o)} module='${e}'.`),o&&n.prefix.length>r&&(t=n,r=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),o=t.slice(r.prefix.length).split("_").join("/"),n=(s=o,(c=r.defaultExt)?s.endsWith(c)?s:`${s}${c}`:s);var s,c;const l=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(r.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${l}'.`),l};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 r=e.platform,l=e.moduleName,p=`${r}::${l}`;if(o.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),o.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=c(r,l);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();o.set(p,f);try{return await f}catch(e){throw o.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}function w(e){const t=null===e.exportName?"":e.exportName,r=null===e.life?"":e.life,o=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,r,o].join("::")}function h(e,t){const r=Reflect.get(e,"__deps__");if(void 0===r)return{};if(null===r||"object"!=typeof r||Array.isArray(r))throw new Error("__deps__ must be a plain object.");const o=null===t.exportName?"default":t.exportName,n=Reflect.get(r,o);if(null!=n&&"object"==typeof n&&!Array.isArray(n)){if(!Object.values(n).every(e=>"string"==typeof e))throw new Error("__deps__ export entries must map dependency names to CDC strings.");return n}if("default"===o){const e=Object.values(r);if(e.every(e=>"string"==typeof e))return r;if(e.every(e=>null!==e&&"object"==typeof e&&!Array.isArray(e)))return{};throw new Error("__deps__ must be either flat or export-scoped.")}return{}}class y{constructor({parser:e,resolver:t,logger:r=null}){const o=r,n=w,i=async function(r,s,a,c){const l=n(r);if(a.has(l)){const e=[...c,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const p=n(r);if(!s.has(p)){a.add(l),c.push(l);try{const n=await t.resolve(r);o&&o.log(`GraphResolver.walk: resolved '${p}'.`),s.set(p,{depId:r,namespace:n});const l=h(n,r);for(const t of Object.values(l)){const r=e.parse(t);o&&o.log(`GraphResolver.walk: edge '${p}' -> '${r.platform}::${r.moduleName}'.`),await i(r,s,a,c)}}finally{c.pop(),a.delete(l)}}};this.resolve=async function(e){const t=new Map,r=new Set;return await i(e,t,r,[]),t}}}class ${constructor(){this.instantiate=function(t,r,o){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,r);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(o)}else{t=e(o)}if(t instanceof Promise)throw new Error("Factory composition must return synchronously (non-Promise).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class E{constructor(r=null){const o=new Map,n=r,i=w;this.apply=function(r,s){if(r.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${r.composition}' cache=skip.`),s();if(r.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),s();if(r.life===t.SINGLETON){const e=i(r);if(o.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),o.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=s();return o.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),s()}}}class N{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,r,o){let n=r;const i=t.wrappers;for(const t of i){if(!(t in o))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const r=o[t];if(!e(r))throw new Error(`Wrapper '${t}' must be callable.`);if(n=r(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}const x=new WeakMap;function C(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const r=e;if(x.has(r))return x.get(r);try{return Reflect.get(r,"then"),e}catch{const e=new Proxy(r,{get(e,t,r){if("then"!==t)return Reflect.get(e,t,r)}});return x.set(r,e),e}}class b{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,r){console.error(`${t} ${e}`),r instanceof Error?console.error(r.stack??r.message):void 0!==r&&console.error(r)}}}const v=Object.freeze({log(){},error(){}});class _{constructor(){let e="notConfigured";const t=[],r=[],o=[],n=new Map;let i=!1,s=!1,a=new p;const c=new m;let l,f,u,d=v;const x=new $,_=new N,I=w,R=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;if("[object Module]"===Object.prototype.toString.call(e))return e;if(Object.isFrozen(e))return e;try{Object.freeze(e)}catch(e){d.log(`Container.freeze: skipped (${String(e)}).`)}return e},j=function(e){let r=e;for(const e of t)r=e(r);return r},A=function(e){let t=e;for(const e of r)t=e(t);return t},z=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},O=function(e){s&&d.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){z(),O("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){z(),O("addPostprocess()."),r.push(e)},this.addNamespaceRoot=function(e,t,r){z(),O(`addNamespaceRoot('${e}').`),o.push({prefix:e,target:t,defaultExt:r})},this.enableTestMode=function(){z(),O("enableTestMode()."),i=!0},this.enableLogging=function(){z(),s||(s=!0,d=new b,"function"==typeof a.setLogger&&a.setLogger(d),d.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(z(),O(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const r=a.parse(e);n.set(I(r),t)},this.get=async function(t){if("failed"===e)throw d.error(`Container.get: rejected in failed state cdc='${t}'.`),new Error("Container is in failed state.");try{return function(){if("notConfigured"!==e)return;d.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:o});"function"==typeof a.setLogger&&a.setLogger(d),l=new g({config:t,logger:d}),f=new y({parser:a,resolver:l,logger:d}),u=new E(d)}(),d.log(`Container.state: '${e}'.`),await async function(e,t){const{parser:r,resolver:o,graphResolver:n,lifecycle:i,instantiator:s,wrapperExecutor:a,logger:c,testMode:l,mockRegistry:p,freeze:f,applyPreprocess:u,applyPostprocess:d}=e;if(!o||!n||!i)throw new Error("Container infrastructure is not initialized.");const m=w,g=w;let y="start";try{c.log(`Container.get: cdc='${t}'.`),y="parse",c.log("Container.pipeline: parse:entry.");const e=r.parse(t);c.log(`Container.pipeline: parse:exit '${e.platform}::${e.moduleName}'.`),y="preprocess",c.log("Container.pipeline: preprocess:entry.");const o=u(e);if(c.log(`Container.pipeline: preprocess:exit '${o.platform}::${o.moduleName}'.`),!0===l){y="mock",c.log("Container.pipeline: mock-lookup:entry.");const e=g(o);if(p.has(e)){c.log(`Container.pipeline: mock-lookup:hit '${e}'.`),y="freeze",c.log("Container.pipeline: freeze:entry.");const t=f(p.get(e));return c.log("Container.pipeline: freeze:exit."),c.log("Container.pipeline: return:success."),C(t)}c.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else c.log("Container.pipeline: mock-lookup:disabled.");y="resolve",c.log("Container.pipeline: resolve:entry.");const w=await n.resolve(o);c.log(`Container.pipeline: resolve:exit nodes=${w.size}.`);const $=new Map,E=function(e){if($.has(e))return $.get(e);if(!w.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=w.get(e);y="lifecycle",c.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const o=i.apply(t.depId,function(){y="instantiate",c.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},o=h(t.namespace,t.depId);for(const[t,n]of Object.entries(o)){const o=r.parse(n);e[t]=E(m(o))}const n=s.instantiate(t.depId,t.namespace,e);c.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y="postprocess",c.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=d(n);c.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const l=a.execute(t.depId,i,t.namespace);y="freeze",c.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const p=f(l);return c.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p});return c.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),$.set(e,o),o},N=E(m(o));return c.log("Container.pipeline: return:success."),C(N)}catch(e){throw c.error(`Container.pipeline: failed at stage='${y}'.`,e),e}}({parser:a,resolver:l,graphResolver:f,lifecycle:u,instantiator:x,wrapperExecutor:_,logger:d,testMode:i,mockRegistry:n,freeze:R,applyPreprocess:j,applyPostprocess:A},t)}catch(t){throw d.error("Container.transition: operational -> failed.",t),e="failed",t}}}}export{_ 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=Object.freeze({AS_IS:"A",FACTORY:"F"});var t=Object.freeze({SINGLETON:"S",TRANSIENT:"T"});var r=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const o=r.TEQ,n=e.AS_IS,i=new Set(Object.values(r)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let c=class{moduleName;platform;exportName;composition;life;wrappers;origin},l=class{create(e){const t=e&&"object"==typeof e?e:{},r=new c;r.moduleName="string"==typeof t.moduleName?t.moduleName:"";const l="string"==typeof t.platform?t.platform:void 0;r.platform=l&&i.has(l)?l:o;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),r.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;r.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return r.life=u&&a.has(u)?u:null,r.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],r.origin="string"==typeof t.origin?t.origin:"",Object.freeze(r.wrappers),Object.freeze(r)}};class p{constructor(){const o=new l;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(!/^[\x00-\x7F]+$/.test(i))throw new Error("CDC must be ASCII.");const s=i,a=function(e){let t=r.TEQ;if(e.startsWith("node:"))return t=r.NODE,{platform:t,source:e.slice(5)};if(e.startsWith("npm:"))return t=r.NPM,{platform:t,source:e.slice(4)};if(e.startsWith("teq:"))throw new Error("Explicit teq: prefix is forbidden.");return{platform:t,source:e}}(i),c=a.platform,l=a.source;if(0===l.length)throw new Error("moduleName must be non-empty.");const p=function(e,o){let n=null,i=!1,s=[],a=e;const c=a.match(/(\${1,3})(?:_[a-z][0-9A-Za-z]*)*$/);if(c){const e=c[1],r=c[0].slice(e.length);if(i=!0,"$"===e)n=t.SINGLETON;else if("$$"===e)n=t.TRANSIENT;else{if("$$$"!==e)throw new Error("Lifecycle marker is invalid.");n=null}return a=a.slice(0,c.index),r.length>0&&(s=r.slice(1).split("_")),{core:a,life:n,lifecycleDeclared:i,wrappers:s}}if(e.includes("$"))throw new Error("Invalid lifecycle encoding.");if(o!==r.NODE&&/(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(e))throw new Error("Wrapper without lifecycle is forbidden.");return{core:a,life:n,lifecycleDeclared:i,wrappers:s}}(l,c),f=function(e){const t=e.indexOf("__"),r=e.lastIndexOf("__");if(-1!==t&&t!==r)throw new Error("Export delimiter must appear at most once.");if(e.startsWith("__")||e.endsWith("__"))throw new Error("Malformed export segment.");let o=e,n=null;if(-1!==t){if(o=e.slice(0,t),n=e.slice(t+2),!n)throw new Error("Export must be non-empty.");if(n.includes("_"))throw new Error("Export must not contain _.");if(n.includes("$"))throw new Error("Export must not contain $.")}return{moduleName:o,exportName:n}}(p.core);!function(e,t){if(!e)throw new Error("moduleName must be non-empty.");if(e.startsWith("_")||e.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(e.includes("__"))throw new Error("moduleName must not contain __.");if(e.includes("$"))throw new Error("moduleName must not contain $.");if(t!==r.NPM){if(t===r.NODE){if(!/^[A-Za-z_][$0-9A-Za-z_/-]*$/.test(e))throw new Error("node moduleName must satisfy the built-in specifier form.")}else if(!/^[A-Za-z_][$0-9A-Za-z_]*$/.test(e))throw new Error("moduleName must satisfy the canonical identifier form.")}else if(!/^[@A-Za-z_][$0-9A-Za-z_./-]*$/.test(e))throw new Error("npm moduleName must satisfy the package specifier form.")}(f.moduleName,c);let u=e.AS_IS,d=f.exportName;null!==d?u=e.FACTORY:p.lifecycleDeclared&&(d="default",u=e.FACTORY);const m=o.create({moduleName:f.moduleName,platform:c,exportName:d,composition:u,life:p.life,wrappers:p.wrappers,origin:s});return n&&n.log(`Parser.parse: produced='${m.platform}::${m.moduleName}'.`),m},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},r=new f;return r.prefix="string"==typeof t.prefix?t.prefix:void 0,r.target="string"==typeof t.target?t.target:void 0,r.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(r)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const r=t&&"object"==typeof t?t:{},o=new d,n=Array.isArray(r.namespaces)?r.namespaces:[];return o.namespaces=n.map(t=>e.create(t)),o.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,Object.freeze(o.namespaces),Object.freeze(o)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:r=null}){const o=new Map,n=e;let i;const s=t,a=r,c=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 r=function(e){let t=null,r=-1;const o=i.namespaces;for(const n of o){const o=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(o)} module='${e}'.`),o&&n.prefix.length>r&&(t=n,r=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),o=t.slice(r.prefix.length).split("_").join("/"),n=(s=o,(c=r.defaultExt)?s.endsWith(c)?s:`${s}${c}`:s);var s,c;const l=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(r.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${l}'.`),l};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 r=e.platform,l=e.moduleName,p=`${r}::${l}`;if(o.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),o.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=c(r,l);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();o.set(p,f);try{return await f}catch(e){throw o.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}function w(e){const t=null===e.exportName?"":e.exportName,r=null===e.life?"":e.life,o=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,r,o].join("::")}function h(e,t){const r=Reflect.get(e,"__deps__");if(void 0===r)return{};if(null===r||"object"!=typeof r||Array.isArray(r))throw new Error("__deps__ must be a plain object.");const o=null===t.exportName?"default":t.exportName,n=Reflect.get(r,o);if(null!=n&&"object"==typeof n&&!Array.isArray(n)){if(!Object.values(n).every(e=>"string"==typeof e))throw new Error("__deps__ export entries must map dependency names to CDC strings.");return n}if("default"===o){const e=Object.values(r);if(e.every(e=>"string"==typeof e))return r;if(e.every(e=>null!==e&&"object"==typeof e&&!Array.isArray(e)))return{};throw new Error("__deps__ must be either flat or export-scoped.")}return{}}class y{constructor({parser:e,resolver:t,logger:r=null}){const o=r,n=w,i=async function(r,s,a,c){const l=n(r);if(a.has(l)){const e=[...c,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const p=n(r);if(!s.has(p)){a.add(l),c.push(l);try{const n=await t.resolve(r);o&&o.log(`GraphResolver.walk: resolved '${p}'.`),s.set(p,{depId:r,namespace:n});const l=h(n,r);for(const t of Object.values(l)){const r=e.parse(t);o&&o.log(`GraphResolver.walk: edge '${p}' -> '${r.platform}::${r.moduleName}'.`),await i(r,s,a,c)}}finally{c.pop(),a.delete(l)}}};this.resolve=async function(e){const t=new Map,r=new Set;return await i(e,t,r,[]),t}}}class ${constructor(){this.instantiate=function(t,r,o){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,r);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(o)}else{t=e(o)}if(t instanceof Promise)throw new Error("Factory composition must return synchronously (non-Promise).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class x{constructor(r=null){const o=new Map,n=r,i=w;this.apply=function(r,s){if(r.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${r.composition}' cache=skip.`),s();if(r.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),s();if(r.life===t.SINGLETON){const e=i(r);if(o.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),o.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=s();return o.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),s()}}}class E{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,r,o){let n=r;const i=t.wrappers;for(const t of i){if(!(t in o))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const r=o[t];if(!e(r))throw new Error(`Wrapper '${t}' must be callable.`);if(n=r(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}const N=new WeakMap;function b(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const r=e;if(N.has(r))return N.get(r);try{return Reflect.get(r,"then"),e}catch{const e=new Proxy(r,{get(e,t,r){if("then"!==t)return Reflect.get(e,t,r)}});return N.set(r,e),e}}class C{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,r){console.error(`${t} ${e}`),r instanceof Error?console.error(r.stack??r.message):void 0!==r&&console.error(r)}}}const v=Object.freeze({log(){},error(){}});return class{constructor(){let e="notConfigured";const t=[],r=[],o=[],n=new Map;let i=!1,s=!1,a=new p;const c=new m;let l,f,u,d=v;const N=new $,_=new E,R=w,j=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;if("[object Module]"===Object.prototype.toString.call(e))return e;if(Object.isFrozen(e))return e;try{Object.freeze(e)}catch(e){d.log(`Container.freeze: skipped (${String(e)}).`)}return e},I=function(e){let r=e;for(const e of t)r=e(r);return r},A=function(e){let t=e;for(const e of r)t=e(t);return t},O=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},z=function(e){s&&d.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){O(),z("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){O(),z("addPostprocess()."),r.push(e)},this.addNamespaceRoot=function(e,t,r){O(),z(`addNamespaceRoot('${e}').`),o.push({prefix:e,target:t,defaultExt:r})},this.enableTestMode=function(){O(),z("enableTestMode()."),i=!0},this.enableLogging=function(){O(),s||(s=!0,d=new C,"function"==typeof a.setLogger&&a.setLogger(d),d.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(O(),z(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const r=a.parse(e);n.set(R(r),t)},this.get=async function(t){if("failed"===e)throw d.error(`Container.get: rejected in failed state cdc='${t}'.`),new Error("Container is in failed state.");try{return function(){if("notConfigured"!==e)return;d.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:o});"function"==typeof a.setLogger&&a.setLogger(d),l=new g({config:t,logger:d}),f=new y({parser:a,resolver:l,logger:d}),u=new x(d)}(),d.log(`Container.state: '${e}'.`),await async function(e,t){const{parser:r,resolver:o,graphResolver:n,lifecycle:i,instantiator:s,wrapperExecutor:a,logger:c,testMode:l,mockRegistry:p,freeze:f,applyPreprocess:u,applyPostprocess:d}=e;if(!o||!n||!i)throw new Error("Container infrastructure is not initialized.");const m=w,g=w;let y="start";try{c.log(`Container.get: cdc='${t}'.`),y="parse",c.log("Container.pipeline: parse:entry.");const e=r.parse(t);c.log(`Container.pipeline: parse:exit '${e.platform}::${e.moduleName}'.`),y="preprocess",c.log("Container.pipeline: preprocess:entry.");const o=u(e);if(c.log(`Container.pipeline: preprocess:exit '${o.platform}::${o.moduleName}'.`),!0===l){y="mock",c.log("Container.pipeline: mock-lookup:entry.");const e=g(o);if(p.has(e)){c.log(`Container.pipeline: mock-lookup:hit '${e}'.`),y="freeze",c.log("Container.pipeline: freeze:entry.");const t=f(p.get(e));return c.log("Container.pipeline: freeze:exit."),c.log("Container.pipeline: return:success."),b(t)}c.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else c.log("Container.pipeline: mock-lookup:disabled.");y="resolve",c.log("Container.pipeline: resolve:entry.");const w=await n.resolve(o);c.log(`Container.pipeline: resolve:exit nodes=${w.size}.`);const $=new Map,x=function(e){if($.has(e))return $.get(e);if(!w.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=w.get(e);y="lifecycle",c.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const o=i.apply(t.depId,function(){y="instantiate",c.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},o=h(t.namespace,t.depId);for(const[t,n]of Object.entries(o)){const o=r.parse(n);e[t]=x(m(o))}const n=s.instantiate(t.depId,t.namespace,e);c.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y="postprocess",c.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=d(n);c.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const l=a.execute(t.depId,i,t.namespace);y="freeze",c.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const p=f(l);return c.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p});return c.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),$.set(e,o),o},E=x(m(o));return c.log("Container.pipeline: return:success."),b(E)}catch(e){throw c.error(`Container.pipeline: failed at stage='${y}'.`,e),e}}({parser:a,resolver:l,graphResolver:f,lifecycle:u,instantiator:N,wrapperExecutor:_,logger:d,testMode:i,mockRegistry:n,freeze:j,applyPreprocess:I,applyPostprocess:A},t)}catch(t){throw d.error("Container.transition: operational -> failed.",t),e="failed",t}}}}});
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=Object.freeze({AS_IS:"A",FACTORY:"F"});var t=Object.freeze({SINGLETON:"S",TRANSIENT:"T"});var r=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const o=r.TEQ,n=e.AS_IS,i=new Set(Object.values(r)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let c=class{moduleName;platform;exportName;composition;life;wrappers;origin},l=class{create(e){const t=e&&"object"==typeof e?e:{},r=new c;r.moduleName="string"==typeof t.moduleName?t.moduleName:"";const l="string"==typeof t.platform?t.platform:void 0;r.platform=l&&i.has(l)?l:o;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),r.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;r.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return r.life=u&&a.has(u)?u:null,r.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],r.origin="string"==typeof t.origin?t.origin:"",Object.freeze(r.wrappers),Object.freeze(r)}};class p{constructor(){const o=new l;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(!/^[\x00-\x7F]+$/.test(i))throw new Error("CDC must be ASCII.");const s=i,a=function(e){let t=r.TEQ;if(e.startsWith("node:"))return t=r.NODE,{platform:t,source:e.slice(5)};if(e.startsWith("npm:"))return t=r.NPM,{platform:t,source:e.slice(4)};if(e.startsWith("teq:"))throw new Error("Explicit teq: prefix is forbidden.");return{platform:t,source:e}}(i),c=a.platform,l=a.source;if(0===l.length)throw new Error("moduleName must be non-empty.");const p=function(e,o){let n=null,i=!1,s=[],a=e;const c=a.match(/(\${1,3})(?:_[a-z][0-9A-Za-z]*)*$/);if(c){const e=c[1],r=c[0].slice(e.length);if(i=!0,"$"===e)n=t.SINGLETON;else if("$$"===e)n=t.TRANSIENT;else{if("$$$"!==e)throw new Error("Lifecycle marker is invalid.");n=null}return a=a.slice(0,c.index),r.length>0&&(s=r.slice(1).split("_")),{core:a,life:n,lifecycleDeclared:i,wrappers:s}}if(e.includes("$"))throw new Error("Invalid lifecycle encoding.");if(o!==r.NODE&&/(?:^|[^_])_[a-z][0-9A-Za-z]*$/.test(e))throw new Error("Wrapper without lifecycle is forbidden.");return{core:a,life:n,lifecycleDeclared:i,wrappers:s}}(l,c),f=function(e){const t=e.indexOf("__"),r=e.lastIndexOf("__");if(-1!==t&&t!==r)throw new Error("Export delimiter must appear at most once.");if(e.startsWith("__")||e.endsWith("__"))throw new Error("Malformed export segment.");let o=e,n=null;if(-1!==t){if(o=e.slice(0,t),n=e.slice(t+2),!n)throw new Error("Export must be non-empty.");if(n.includes("_"))throw new Error("Export must not contain _.");if(n.includes("$"))throw new Error("Export must not contain $.")}return{moduleName:o,exportName:n}}(p.core);!function(e,t){if(!e)throw new Error("moduleName must be non-empty.");if(e.startsWith("_")||e.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(e.includes("__"))throw new Error("moduleName must not contain __.");if(e.includes("$"))throw new Error("moduleName must not contain $.");if(t!==r.NPM){if(t===r.NODE){if(!/^[A-Za-z_][$0-9A-Za-z_/-]*$/.test(e))throw new Error("node moduleName must satisfy the built-in specifier form.")}else if(!/^[A-Za-z_][$0-9A-Za-z_]*$/.test(e))throw new Error("moduleName must satisfy the canonical identifier form.")}else if(!/^[@A-Za-z_][$0-9A-Za-z_./-]*$/.test(e))throw new Error("npm moduleName must satisfy the package specifier form.")}(f.moduleName,c);let u=e.AS_IS,d=f.exportName;p.lifecycleDeclared&&(null===d&&(d="default"),u=e.FACTORY);const m=o.create({moduleName:f.moduleName,platform:c,exportName:d,composition:u,life:p.life,wrappers:p.wrappers,origin:s});return n&&n.log(`Parser.parse: produced='${m.platform}::${m.moduleName}'.`),m},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},r=new f;return r.prefix="string"==typeof t.prefix?t.prefix:void 0,r.target="string"==typeof t.target?t.target:void 0,r.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(r)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const r=t&&"object"==typeof t?t:{},o=new d,n=Array.isArray(r.namespaces)?r.namespaces:[];return o.namespaces=n.map(t=>e.create(t)),o.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,Object.freeze(o.namespaces),Object.freeze(o)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:r=null}){const o=new Map,n=e;let i;const s=t,a=r,c=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 r=function(e){let t=null,r=-1;const o=i.namespaces;for(const n of o){const o=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(o)} module='${e}'.`),o&&n.prefix.length>r&&(t=n,r=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),o=t.slice(r.prefix.length).split("_").join("/"),n=(s=o,(c=r.defaultExt)?s.endsWith(c)?s:`${s}${c}`:s);var s,c;const l=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(r.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${l}'.`),l};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 r=e.platform,l=e.moduleName,p=`${r}::${l}`;if(o.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),o.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=c(r,l);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();o.set(p,f);try{return await f}catch(e){throw o.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}function w(e){const t=null===e.exportName?"":e.exportName,r=null===e.life?"":e.life,o=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,r,o].join("::")}function h(e,t){const r=Reflect.get(e,"__deps__");if(void 0===r)return{};if(null===r||"object"!=typeof r||Array.isArray(r))throw new Error("__deps__ must be a plain object.");const o=null===t.exportName?"default":t.exportName,n=Reflect.get(r,o);if(null!=n&&"object"==typeof n&&!Array.isArray(n)){if(!Object.values(n).every(e=>"string"==typeof e))throw new Error("__deps__ export entries must map dependency names to CDC strings.");return n}if("default"===o){const e=Object.values(r);if(e.every(e=>"string"==typeof e))return r;if(e.every(e=>null!==e&&"object"==typeof e&&!Array.isArray(e)))return{};throw new Error("__deps__ must be either flat or export-scoped.")}return{}}class y{constructor({parser:e,resolver:t,logger:r=null}){const o=r,n=w,i=async function(r,s,a,c){const l=n(r);if(a.has(l)){const e=[...c,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const p=n(r);if(!s.has(p)){a.add(l),c.push(l);try{const n=await t.resolve(r);o&&o.log(`GraphResolver.walk: resolved '${p}'.`),s.set(p,{depId:r,namespace:n});const l=h(n,r);for(const t of Object.values(l)){const r=e.parse(t);o&&o.log(`GraphResolver.walk: edge '${p}' -> '${r.platform}::${r.moduleName}'.`),await i(r,s,a,c)}}finally{c.pop(),a.delete(l)}}};this.resolve=async function(e){const t=new Map,r=new Set;return await i(e,t,r,[]),t}}}class ${constructor(){this.instantiate=function(t,r,o){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,r);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(o)}else{t=e(o)}if(t instanceof Promise)throw new Error("Factory composition must return synchronously (non-Promise).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class x{constructor(r=null){const o=new Map,n=r,i=w;this.apply=function(r,s){if(r.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${r.composition}' cache=skip.`),s();if(r.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),s();if(r.life===t.SINGLETON){const e=i(r);if(o.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),o.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=s();return o.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),s()}}}class E{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,r,o){let n=r;const i=t.wrappers;for(const t of i){if(!(t in o))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const r=o[t];if(!e(r))throw new Error(`Wrapper '${t}' must be callable.`);if(n=r(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}const N=new WeakMap;function b(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const r=e;if(N.has(r))return N.get(r);try{return Reflect.get(r,"then"),e}catch{const e=new Proxy(r,{get(e,t,r){if("then"!==t)return Reflect.get(e,t,r)}});return N.set(r,e),e}}class C{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,r){console.error(`${t} ${e}`),r instanceof Error?console.error(r.stack??r.message):void 0!==r&&console.error(r)}}}const v=Object.freeze({log(){},error(){}});return class{constructor(){let e="notConfigured";const t=[],r=[],o=[],n=new Map;let i=!1,s=!1,a=new p;const c=new m;let l,f,u,d=v;const N=new $,_=new E,j=w,I=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;if("[object Module]"===Object.prototype.toString.call(e))return e;if(Object.isFrozen(e))return e;try{Object.freeze(e)}catch(e){d.log(`Container.freeze: skipped (${String(e)}).`)}return e},R=function(e){let r=e;for(const e of t)r=e(r);return r},A=function(e){let t=e;for(const e of r)t=e(t);return t},z=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},O=function(e){s&&d.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){z(),O("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){z(),O("addPostprocess()."),r.push(e)},this.addNamespaceRoot=function(e,t,r){z(),O(`addNamespaceRoot('${e}').`),o.push({prefix:e,target:t,defaultExt:r})},this.enableTestMode=function(){z(),O("enableTestMode()."),i=!0},this.enableLogging=function(){z(),s||(s=!0,d=new C,"function"==typeof a.setLogger&&a.setLogger(d),d.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(z(),O(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const r=a.parse(e);n.set(j(r),t)},this.get=async function(t){if("failed"===e)throw d.error(`Container.get: rejected in failed state cdc='${t}'.`),new Error("Container is in failed state.");try{return function(){if("notConfigured"!==e)return;d.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:o});"function"==typeof a.setLogger&&a.setLogger(d),l=new g({config:t,logger:d}),f=new y({parser:a,resolver:l,logger:d}),u=new x(d)}(),d.log(`Container.state: '${e}'.`),await async function(e,t){const{parser:r,resolver:o,graphResolver:n,lifecycle:i,instantiator:s,wrapperExecutor:a,logger:c,testMode:l,mockRegistry:p,freeze:f,applyPreprocess:u,applyPostprocess:d}=e;if(!o||!n||!i)throw new Error("Container infrastructure is not initialized.");const m=w,g=w;let y="start";try{c.log(`Container.get: cdc='${t}'.`),y="parse",c.log("Container.pipeline: parse:entry.");const e=r.parse(t);c.log(`Container.pipeline: parse:exit '${e.platform}::${e.moduleName}'.`),y="preprocess",c.log("Container.pipeline: preprocess:entry.");const o=u(e);if(c.log(`Container.pipeline: preprocess:exit '${o.platform}::${o.moduleName}'.`),!0===l){y="mock",c.log("Container.pipeline: mock-lookup:entry.");const e=g(o);if(p.has(e)){c.log(`Container.pipeline: mock-lookup:hit '${e}'.`),y="freeze",c.log("Container.pipeline: freeze:entry.");const t=f(p.get(e));return c.log("Container.pipeline: freeze:exit."),c.log("Container.pipeline: return:success."),b(t)}c.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else c.log("Container.pipeline: mock-lookup:disabled.");y="resolve",c.log("Container.pipeline: resolve:entry.");const w=await n.resolve(o);c.log(`Container.pipeline: resolve:exit nodes=${w.size}.`);const $=new Map,x=function(e){if($.has(e))return $.get(e);if(!w.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=w.get(e);y="lifecycle",c.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const o=i.apply(t.depId,function(){y="instantiate",c.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},o=h(t.namespace,t.depId);for(const[t,n]of Object.entries(o)){const o=r.parse(n);e[t]=x(m(o))}const n=s.instantiate(t.depId,t.namespace,e);c.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y="postprocess",c.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=d(n);c.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const l=a.execute(t.depId,i,t.namespace);y="freeze",c.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const p=f(l);return c.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p});return c.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),$.set(e,o),o},E=x(m(o));return c.log("Container.pipeline: return:success."),b(E)}catch(e){throw c.error(`Container.pipeline: failed at stage='${y}'.`,e),e}}({parser:a,resolver:l,graphResolver:f,lifecycle:u,instantiator:N,wrapperExecutor:_,logger:d,testMode:i,mockRegistry:n,freeze:I,applyPreprocess:R,applyPostprocess:A},t)}catch(t){throw d.error("Container.transition: operational -> failed.",t),e="failed",t}}}}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teqfw/di",
3
- "version": "2.6.2",
3
+ "version": "2.7.0",
4
4
  "description": "Dependency Injection container for ES6 modules that works in both browser and Node.js apps.",
5
5
  "keywords": [
6
6
  "dependency injection",
package/src/AGENTS.md CHANGED
@@ -14,16 +14,12 @@ This file defines only implementation-level obligations. It does not redefine ar
14
14
 
15
15
  The following documents are mandatory:
16
16
 
17
- - `ctx/docs/code/structure.md`
18
- - `ctx/docs/code/container.md`
19
- - `ctx/docs/code/resolver.md`
20
- - `ctx/docs/code/parser.md`
21
- - `ctx/docs/code/depid.md`
22
- - `ctx/docs/code/testing.md`
23
- - `ctx/docs/code/jsdoc-spec.md`
24
- - `ctx/docs/code/convention/es6-modules.md`
25
- - `ctx/docs/code/convention/teqfw/dto.md`
26
- - `ctx/docs/code/convention/teqfw/enum.md`
17
+ - `ctx/docs/code/layout/structure.md`
18
+ - `ctx/docs/code/components/container.md`
19
+ - `ctx/docs/code/components/resolver.md`
20
+ - `ctx/docs/code/components/parser.md`
21
+ - `ctx/docs/code/components/depid.md`
22
+ - `ctx/docs/code/layout/testing.md`
27
23
 
28
24
  Agent MUST read and follow them before generating or modifying code.
29
25
 
@@ -33,7 +29,7 @@ Deviation from these documents constitutes non-compliance.
33
29
 
34
30
  Directory layout, namespace mapping, file naming, dependency direction, and static import rules MUST strictly follow:
35
31
 
36
- `ctx/docs/code/structure.md`
32
+ `ctx/docs/code/layout/structure.md`
37
33
 
38
34
  In particular:
39
35
 
@@ -50,7 +46,7 @@ Structural violations are execution errors.
50
46
 
51
47
  JSDoc is mandatory and governed by:
52
48
 
53
- `ctx/docs/code/jsdoc-spec.md`
49
+ `ctx/docs/code/layout/structure.md` (Section 8)
54
50
 
55
51
  All implementation files MUST:
56
52
 
@@ -72,8 +68,8 @@ Absence of required JSDoc constitutes non-compliance.
72
68
 
73
69
  All DTO and Enum implementations MUST strictly follow:
74
70
 
75
- - `ctx/docs/code/convention/teqfw/dto.md`
76
- - `ctx/docs/code/convention/teqfw/enum.md`
71
+ - `ctx/docs/code/components/depid.md`
72
+ - `ctx/docs/code/layout/structure.md`
77
73
 
78
74
  In particular:
79
75
 
@@ -116,7 +112,7 @@ Redundant validation logic constitutes architectural violation.
116
112
 
117
113
  Unit and integration tests MUST follow:
118
114
 
119
- `ctx/docs/code/testing.md`
115
+ `ctx/docs/code/layout/testing.md`
120
116
 
121
117
  For every testable source module, exactly one corresponding unit test MUST exist under `test/unit/`, mirroring directory structure.
122
118
 
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
3
  /**
4
- * @namespace TeqFw_Di_Container_Wrapper_Executor
4
+ * @namespace TeqFw_Di_Container_Executor
5
5
  * @description Applies wrapper pipeline to resolved values.
6
6
  */
7
7
 
@@ -11,7 +11,7 @@
11
11
  * Executes wrapper pipeline declared in `depId.wrappers` using functions
12
12
  * exported by the resolved module namespace.
13
13
  */
14
- export default class TeqFw_Di_Container_Wrapper_Executor {
14
+ export default class TeqFw_Di_Container_Executor {
15
15
 
16
16
  /**
17
17
  * Creates wrapper executor instance.
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
3
  /**
4
- * @namespace TeqFw_Di_Container_Resolve_GraphResolver
4
+ * @namespace TeqFw_Di_Container_GraphResolver
5
5
  * @description Dependency graph resolver for container preloading.
6
6
  */
7
7
 
@@ -13,23 +13,23 @@
13
13
  */
14
14
 
15
15
  /**
16
- * @typedef {object} TeqFw_Di_Container_Resolve_GraphResolver_Dependencies
16
+ * @typedef {object} TeqFw_Di_Container_GraphResolver_Dependencies
17
17
  * @property {TeqFw_Di_Parser} parser
18
18
  * @property {TeqFw_Di_Resolver} resolver
19
19
  * @property {{log(message: string): void}|null} [logger]
20
20
  */
21
21
 
22
22
  /**
23
- * @typedef {{depId: TeqFw_Di_DepId__DTO, namespace: object}} TeqFw_Di_Container_Resolve_GraphResolver_Node
23
+ * @typedef {{depId: TeqFw_Di_DepId__DTO, namespace: object}} TeqFw_Di_Container_GraphResolver_Node
24
24
  */
25
25
 
26
26
  import {buildDependencyKey} from '../Internal/DependencyKey.mjs';
27
27
  import {readDepsDecl} from '../Internal/DepsDecl.mjs';
28
28
 
29
- export default class TeqFw_Di_Container_Resolve_GraphResolver {
29
+ export default class TeqFw_Di_Container_GraphResolver {
30
30
 
31
31
  /**
32
- * @param {TeqFw_Di_Container_Resolve_GraphResolver_Dependencies} deps
32
+ * @param {TeqFw_Di_Container_GraphResolver_Dependencies} deps
33
33
  */
34
34
  constructor({parser, resolver, logger = null}) {
35
35
  /** @type {{log(message: string): void}|null} */
@@ -43,7 +43,7 @@ export default class TeqFw_Di_Container_Resolve_GraphResolver {
43
43
 
44
44
  /**
45
45
  * @param {TeqFw_Di_DepId__DTO} depId
46
- * @param {Map<string, TeqFw_Di_Container_Resolve_GraphResolver_Node>} out
46
+ * @param {Map<string, TeqFw_Di_Container_GraphResolver_Node>} out
47
47
  * @param {Set<string>} stack
48
48
  * @param {string[]} chain
49
49
  * @returns {Promise<void>}
@@ -87,10 +87,10 @@ export default class TeqFw_Di_Container_Resolve_GraphResolver {
87
87
  * Resolves full dependency graph for a root depId.
88
88
  *
89
89
  * @param {TeqFw_Di_DepId__DTO} depId
90
- * @returns {Promise<Map<string, TeqFw_Di_Container_Resolve_GraphResolver_Node>>}
90
+ * @returns {Promise<Map<string, TeqFw_Di_Container_GraphResolver_Node>>}
91
91
  */
92
92
  this.resolve = async function (depId) {
93
- /** @type {Map<string, TeqFw_Di_Container_Resolve_GraphResolver_Node>} */
93
+ /** @type {Map<string, TeqFw_Di_Container_GraphResolver_Node>} */
94
94
  const out = new Map();
95
95
  /** @type {Set<string>} */
96
96
  const stack = new Set();
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
3
  /**
4
- * @namespace TeqFw_Di_Container_Instantiate_Instantiator
4
+ * @namespace TeqFw_Di_Container_Instantiate
5
5
  * @description Instantiates selected exports using composition rules.
6
6
  */
7
7
 
@@ -25,7 +25,7 @@ import TeqFw_Di_Enum_Composition from '../Enum/Composition.mjs';
25
25
  /**
26
26
  * @typedef {CallableFactory | ConstructableFactory} Factory
27
27
  */
28
- export default class TeqFw_Di_Container_Instantiate_Instantiator {
28
+ export default class TeqFw_Di_Container_Instantiate {
29
29
 
30
30
  /**
31
31
  * Creates instantiator instance.
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
3
  /**
4
- * @namespace TeqFw_Di_Container_Lifecycle_Registry
4
+ * @namespace TeqFw_Di_Container_Lifecycle
5
5
  * @description Lifecycle policy cache for produced values.
6
6
  */
7
7
 
@@ -17,7 +17,7 @@ import {buildDependencyKey} from '../Internal/DependencyKey.mjs';
17
17
  * - transient values are never cached;
18
18
  * - as-is composition is returned as produced without lifecycle caching.
19
19
  */
20
- export default class TeqFw_Di_Container_Lifecycle_Registry {
20
+ export default class TeqFw_Di_Container_Lifecycle {
21
21
 
22
22
  /**
23
23
  * Creates lifecycle registry instance.
@@ -13,10 +13,10 @@ import {makePromiseSafe} from '../Internal/PromiseSafe.mjs';
13
13
  * @typedef {object} TeqFw_Di_Container_Pipeline_Context
14
14
  * @property {TeqFw_Di_Parser} parser
15
15
  * @property {TeqFw_Di_Resolver|undefined} resolver
16
- * @property {TeqFw_Di_Container_Resolve_GraphResolver|undefined} graphResolver
17
- * @property {TeqFw_Di_Container_Lifecycle_Registry|undefined} lifecycle
18
- * @property {TeqFw_Di_Container_Instantiate_Instantiator} instantiator
19
- * @property {TeqFw_Di_Container_Wrapper_Executor} wrapperExecutor
16
+ * @property {TeqFw_Di_Container_GraphResolver|undefined} graphResolver
17
+ * @property {TeqFw_Di_Container_Lifecycle|undefined} lifecycle
18
+ * @property {TeqFw_Di_Container_Instantiate} instantiator
19
+ * @property {TeqFw_Di_Container_Executor} wrapperExecutor
20
20
  * @property {{log(message: string): void, error(message: string, error?: unknown): void}} logger
21
21
  * @property {boolean} testMode
22
22
  * @property {Map<string, unknown>} mockRegistry
package/src/Container.mjs CHANGED
@@ -8,10 +8,10 @@
8
8
  import TeqFw_Di_Parser from './Parser.mjs';
9
9
  import {Factory as TeqFw_Di_Dto_Resolver_Config_Factory} from './Dto/Resolver/Config.mjs';
10
10
  import TeqFw_Di_Resolver from './Container/Resolver.mjs';
11
- import TeqFw_Di_Container_Resolve_GraphResolver from './Container/GraphResolver.mjs';
12
- import TeqFw_Di_Container_Instantiate_Instantiator from './Container/Instantiate.mjs';
13
- import TeqFw_Di_Container_Lifecycle_Registry from './Container/Lifecycle.mjs';
14
- import TeqFw_Di_Container_Wrapper_Executor from './Container/Executor.mjs';
11
+ import TeqFw_Di_Container_GraphResolver from './Container/GraphResolver.mjs';
12
+ import TeqFw_Di_Container_Instantiate from './Container/Instantiate.mjs';
13
+ import TeqFw_Di_Container_Lifecycle from './Container/Lifecycle.mjs';
14
+ import TeqFw_Di_Container_Executor from './Container/Executor.mjs';
15
15
  import {executeContainerPipeline} from './Container/Pipeline.mjs';
16
16
  import TeqFw_Di_Internal_Logger, {TeqFw_Di_Internal_Logger_Noop} from './Internal/Logger.mjs';
17
17
  import {buildDependencyKey} from './Internal/DependencyKey.mjs';
@@ -46,16 +46,16 @@ export default class TeqFw_Di_Container {
46
46
  const configFactory = new TeqFw_Di_Dto_Resolver_Config_Factory();
47
47
  /** @type {TeqFw_Di_Resolver|undefined} */
48
48
  let resolver;
49
- /** @type {TeqFw_Di_Container_Resolve_GraphResolver|undefined} */
49
+ /** @type {TeqFw_Di_Container_GraphResolver|undefined} */
50
50
  let graphResolver;
51
- /** @type {TeqFw_Di_Container_Lifecycle_Registry|undefined} */
51
+ /** @type {TeqFw_Di_Container_Lifecycle|undefined} */
52
52
  let lifecycle;
53
53
  /** @type {{log(message: string): void, error(message: string, error?: unknown): void}} */
54
54
  let logger = TeqFw_Di_Internal_Logger_Noop;
55
- /** @type {TeqFw_Di_Container_Instantiate_Instantiator} */
56
- const instantiator = new TeqFw_Di_Container_Instantiate_Instantiator();
57
- /** @type {TeqFw_Di_Container_Wrapper_Executor} */
58
- const wrapperExecutor = new TeqFw_Di_Container_Wrapper_Executor();
55
+ /** @type {TeqFw_Di_Container_Instantiate} */
56
+ const instantiator = new TeqFw_Di_Container_Instantiate();
57
+ /** @type {TeqFw_Di_Container_Executor} */
58
+ const wrapperExecutor = new TeqFw_Di_Container_Executor();
59
59
 
60
60
  const getKey = buildDependencyKey;
61
61
  const getMockKey = buildDependencyKey;
@@ -104,8 +104,8 @@ export default class TeqFw_Di_Container {
104
104
  const resolverConfig = configFactory.create({namespaces: namespaceRoots});
105
105
  if (typeof parser.setLogger === 'function') parser.setLogger(logger);
106
106
  resolver = new TeqFw_Di_Resolver({config: resolverConfig, logger});
107
- graphResolver = new TeqFw_Di_Container_Resolve_GraphResolver({parser, resolver, logger});
108
- lifecycle = new TeqFw_Di_Container_Lifecycle_Registry(logger);
107
+ graphResolver = new TeqFw_Di_Container_GraphResolver({parser, resolver, logger});
108
+ lifecycle = new TeqFw_Di_Container_Lifecycle(logger);
109
109
  };
110
110
 
111
111
  /**
package/src/Parser.mjs CHANGED
@@ -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,10 @@
1
1
  declare global {
2
2
  type TeqFw_Di_Config_NamespaceRegistry = import("./src/Config/NamespaceRegistry.mjs").default;
3
3
  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;
4
+ type TeqFw_Di_Container_Instantiate = import("./src/Container/Instantiate.mjs").default;
5
+ type TeqFw_Di_Container_Lifecycle = import("./src/Container/Lifecycle.mjs").default;
6
+ type TeqFw_Di_Container_GraphResolver = import("./src/Container/GraphResolver.mjs").default;
7
+ type TeqFw_Di_Container_Executor = import("./src/Container/Executor.mjs").default;
8
8
  type TeqFw_Di_Parser = import("./src/Parser.mjs").default;
9
9
  type TeqFw_Di_DepId = import("./src/Dto/DepId.mjs").default;
10
10
  type TeqFw_Di_DepId__DTO = import("./src/Dto/DepId.mjs").default;