@teqfw/di 2.0.4 → 2.1.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 +14 -0
- package/dist/esm.js +1 -1
- package/dist/umd.js +1 -1
- package/package.json +2 -3
- package/src/AGENTS.md +5 -5
- package/src/Container/Instantiate/Instantiator.mjs +2 -25
- package/src/Container/Wrapper/Executor.mjs +2 -17
- package/src/Container.mjs +45 -9
- package/src/Def/Parser.mjs +7 -7
- package/src/Dto/DepId.mjs +8 -13
- package/src/Dto/Resolver/Config/Namespace.mjs +13 -18
- package/src/Dto/Resolver/Config.mjs +14 -20
- package/src/Enum/Composition.mjs +1 -1
- package/src/Enum/Life.mjs +1 -1
- package/src/Enum/Platform.mjs +1 -1
- package/types.d.ts +8 -5
- package/jsconfig.json +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.0 - 2026-03-16 - Protected proxy lifecycle handling
|
|
4
|
+
|
|
5
|
+
- Fixed container lifecycle handling for protected proxy components that reject `.then` probing or freezing.
|
|
6
|
+
- Clarified and documented the sync-only composition contract for factories and wrappers.
|
|
7
|
+
- Simplified Promise contract checks and aligned related tests with the updated runtime behavior.
|
|
8
|
+
- Updated package version metadata to `2.1.0`.
|
|
9
|
+
|
|
10
|
+
## 2.0.5 - 2026-03-13 - Convention alignment release
|
|
11
|
+
|
|
12
|
+
- Fixed the `Container.get` JSDoc return typing.
|
|
13
|
+
- Removed `jsconfig.json` from the published package metadata.
|
|
14
|
+
- Aligned DTO and Enum modules with the updated TeqFW convention documents.
|
|
15
|
+
- Updated package version metadata to `2.0.5`.
|
|
16
|
+
|
|
3
17
|
## 2.0.4 - 2026-03-10 - LLM-first project positioning
|
|
4
18
|
|
|
5
19
|
- Reframed `README.md` around TeqFW architecture, runtime linking, and LLM-agent-oriented development.
|
package/dist/esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e={AS_IS:"A",FACTORY:"F"},t={SINGLETON:"S",TRANSIENT:"T"},o={TEQ:"teq",NODE:"node",NPM:"npm"},r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e,t){const o=e&&"object"==typeof e?e:{},c=new l;c.moduleName="string"==typeof o.moduleName?o.moduleName:"";const p="string"==typeof o.platform?o.platform:void 0;c.platform=p&&i.has(p)?p:r;let f=null;null===o.exportName?f=null:"string"==typeof o.exportName&&(f=o.exportName),c.exportName=f;const u="string"==typeof o.composition?o.composition:void 0;c.composition=u&&s.has(u)?u:n;const m="string"==typeof o.life?o.life:void 0;return c.life=m&&a.has(m)?m:null,c.wrappers=Array.isArray(o.wrappers)?o.wrappers.filter(e=>"string"==typeof e):[],c.origin="string"==typeof o.origin?o.origin:"",!0===t?.immutable&&(Object.freeze(c.wrappers),Object.freeze(c)),c}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const m=u.indexOf("__"),d=u.lastIndexOf("__");if(-1!==m&&m!==d)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==m){if(g=u.slice(0,m),w=u.slice(m+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s},{immutable:!0});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e,t){const o=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{},n=new f;return n.prefix="string"==typeof o.prefix?o.prefix:void 0,n.target="string"==typeof o.target?o.target:void 0,n.defaultExt="string"==typeof o.defaultExt?o.defaultExt:void 0,!0===r.immutable&&Object.freeze(n),n}};class m{namespaces;nodeModulesRoot}class d{constructor(){const e=new u;this.create=function(t,o){const r=t&&"object"==typeof t?t:{},n=o&&"object"==typeof o?o:{},i=new m,s=Array.isArray(r.namespaces)?r.namespaces:[];return i.namespaces=s.map(t=>e.create(t,n)),i.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,!0===n.immutable&&(Object.freeze(i.namespaces),Object.freeze(i)),i}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(function(e){if(null==e)return!1;const t=typeof e;return("object"===t||"function"===t)&&"function"==typeof e.then}(t))throw new Error("Factory composition must return synchronously (non-thenable).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){if(null==e)return!1;const t=typeof e;if("object"!==t&&"function"!==t)return!1;return"function"==typeof e.then},t=function(e){return"function"==typeof e};this.execute=function(o,r,n){let i=r;const s=o.wrappers;for(const o of s){if(!(o in n))throw new Error(`Wrapper '${o}' is not found in module namespace.`);const r=n[o];if(!t(r))throw new Error(`Wrapper '${o}' must be callable.`);if(i=r(i),e(i))throw new Error(`Wrapper '${o}' must return synchronously (non-thenable).`)}return i}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});class x{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map;let i=!1,s=!1,a=new p;const l=new d;let c,f,u,m=E;const x=new h,C=new y,b=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},v=function(e){if(null==e)return e;const t=typeof e;return"object"!==t&&"function"!==t||"[object Module]"===Object.prototype.toString.call(e)||Object.isFrozen(e)||Object.freeze(e),e},I=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},j=function(e){s&&m.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){I(),j("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){I(),j("addPostprocess()."),o.push(e)},this.setParser=function(e){I(),a=e,"function"==typeof a.setLogger&&a.setLogger(s?m:null),j("setParser().")},this.addNamespaceRoot=function(e,t,o){I(),j(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){I(),j("enableTestMode()."),i=!0},this.enableLogging=function(){I(),s||(s=!0,m=new N,"function"==typeof a.setLogger&&a.setLogger(m),m.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(I(),j(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const o=a.parse(e);n.set(_(o),t)},this.get=async function(s){if("failed"===e)throw m.error(`Container.get: rejected in failed state cdc='${s}'.`),new Error("Container is in failed state.");let p="start";try{m.log(`Container.get: cdc='${s}'.`),function(){if("notConfigured"!==e)return;m.log("Container.transition: notConfigured -> operational."),e="operational";const t=l.create({namespaces:r},{immutable:!0});"function"==typeof a.setLogger&&a.setLogger(m),c=new g({config:t,logger:m}),f=new w({parser:a,resolver:c,logger:m}),u=new $(m)}(),m.log(`Container.state: '${e}'.`),p="parse",m.log("Container.pipeline: parse:entry.");const d=a.parse(s);m.log(`Container.pipeline: parse:exit '${d.platform}::${d.moduleName}'.`),p="preprocess",m.log("Container.pipeline: preprocess:entry.");const h=function(e){let o=e;for(const e of t)o=e(o);return o}(d);if(m.log(`Container.pipeline: preprocess:exit '${h.platform}::${h.moduleName}'.`),!0===i){p="mock",m.log("Container.pipeline: mock-lookup:entry.");const e=_(h);if(n.has(e)){m.log(`Container.pipeline: mock-lookup:hit '${e}'.`),p="freeze",m.log("Container.pipeline: freeze:entry.");const t=v(n.get(e));return m.log("Container.pipeline: freeze:exit."),m.log("Container.pipeline: return:success."),t}m.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else m.log("Container.pipeline: mock-lookup:disabled.");p="resolve",m.log("Container.pipeline: resolve:entry.");const y=await f.resolve(h);m.log(`Container.pipeline: resolve:exit nodes=${y.size}.`);const N=new Map,E=function(e){if(N.has(e))return N.get(e);if(!y.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=y.get(e);p="lifecycle",m.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=u.apply(t.depId,function(){p="instantiate",m.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=a.parse(r);e[t]=E(b(n))}const n=x.instantiate(t.depId,t.namespace,e);m.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p="postprocess",m.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);m.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=C.execute(t.depId,i,t.namespace);p="freeze",m.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const l=v(s);return m.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),l});return m.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),N.set(e,r),r},I=E(b(h));return m.log("Container.pipeline: return:success."),I}catch(t){throw m.error(`Container.pipeline: failed at stage='${p}'.`,t),m.log("Container.transition: operational -> failed."),e="failed",t}}}}export{x as default};
|
|
1
|
+
var e=Object.freeze({AS_IS:"A",FACTORY:"F"});var t=Object.freeze({SINGLETON:"S",TRANSIENT:"T"});var o=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e){const t=e&&"object"==typeof e?e:{},o=new l;o.moduleName="string"==typeof t.moduleName?t.moduleName:"";const c="string"==typeof t.platform?t.platform:void 0;o.platform=c&&i.has(c)?c:r;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),o.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;o.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return o.life=u&&a.has(u)?u:null,o.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],o.origin="string"==typeof t.origin?t.origin:"",Object.freeze(o.wrappers),Object.freeze(o)}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const d=u.indexOf("__"),m=u.lastIndexOf("__");if(-1!==d&&d!==m)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==d){if(g=u.slice(0,d),w=u.slice(d+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},o=new f;return o.prefix="string"==typeof t.prefix?t.prefix:void 0,o.target="string"==typeof t.target?t.target:void 0,o.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(o)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const o=t&&"object"==typeof t?t:{},r=new d,n=Array.isArray(o.namespaces)?o.namespaces:[];return r.namespaces=n.map(t=>e.create(t)),r.nodeModulesRoot="string"==typeof o.nodeModulesRoot?o.nodeModulesRoot:void 0,Object.freeze(r.namespaces),Object.freeze(r)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(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 ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,o,r){let n=o;const i=t.wrappers;for(const t of i){if(!(t in r))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const o=r[t];if(!e(o))throw new Error(`Wrapper '${t}' must be callable.`);if(n=o(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});class x{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map,i=new WeakMap;let s=!1,a=!1,l=new p;const c=new m;let f,u,d,x=E;const C=new h,v=new y,b=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},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){x.log(`Container.freeze: skipped (${String(e)}).`)}return e},R=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const o=e;if(i.has(o))return i.get(o);try{return Reflect.get(o,"then"),e}catch{const e=new Proxy(o,{get(e,t,o){if("then"!==t)return Reflect.get(e,t,o)}});return i.set(o,e),e}},j=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},A=function(e){a&&x.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){j(),A("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){j(),A("addPostprocess()."),o.push(e)},this.setParser=function(e){j(),l=e,"function"==typeof l.setLogger&&l.setLogger(a?x:null),A("setParser().")},this.addNamespaceRoot=function(e,t,o){j(),A(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){j(),A("enableTestMode()."),s=!0},this.enableLogging=function(){j(),a||(a=!0,x=new N,"function"==typeof l.setLogger&&l.setLogger(x),x.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(j(),A(`register('${e}').`),!0!==s)throw new Error("Container test mode is disabled.");const o=l.parse(e);n.set(_(o),t)},this.get=async function(i){if("failed"===e)throw x.error(`Container.get: rejected in failed state cdc='${i}'.`),new Error("Container is in failed state.");let a="start";try{x.log(`Container.get: cdc='${i}'.`),function(){if("notConfigured"!==e)return;x.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:r});"function"==typeof l.setLogger&&l.setLogger(x),f=new g({config:t,logger:x}),u=new w({parser:l,resolver:f,logger:x}),d=new $(x)}(),x.log(`Container.state: '${e}'.`),a="parse",x.log("Container.pipeline: parse:entry.");const p=l.parse(i);x.log(`Container.pipeline: parse:exit '${p.platform}::${p.moduleName}'.`),a="preprocess",x.log("Container.pipeline: preprocess:entry.");const m=function(e){let o=e;for(const e of t)o=e(o);return o}(p);if(x.log(`Container.pipeline: preprocess:exit '${m.platform}::${m.moduleName}'.`),!0===s){a="mock",x.log("Container.pipeline: mock-lookup:entry.");const e=_(m);if(n.has(e)){x.log(`Container.pipeline: mock-lookup:hit '${e}'.`),a="freeze",x.log("Container.pipeline: freeze:entry.");const t=I(n.get(e));return x.log("Container.pipeline: freeze:exit."),x.log("Container.pipeline: return:success."),R(t)}x.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else x.log("Container.pipeline: mock-lookup:disabled.");a="resolve",x.log("Container.pipeline: resolve:entry.");const h=await u.resolve(m);x.log(`Container.pipeline: resolve:exit nodes=${h.size}.`);const y=new Map,N=function(e){if(y.has(e))return y.get(e);if(!h.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=h.get(e);a="lifecycle",x.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=d.apply(t.depId,function(){a="instantiate",x.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=l.parse(r);e[t]=N(b(n))}const n=C.instantiate(t.depId,t.namespace,e);x.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),a="postprocess",x.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);x.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=v.execute(t.depId,i,t.namespace);a="freeze",x.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const c=I(s);return x.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),c});return x.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y.set(e,r),r},E=N(b(m));return x.log("Container.pipeline: return:success."),R(E)}catch(t){throw x.error(`Container.pipeline: failed at stage='${a}'.`,t),x.log("Container.transition: operational -> failed."),e="failed",t}}}}export{x as default};
|
package/dist/umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TeqFw_Di_Container=t()}(this,function(){"use strict";const e={AS_IS:"A",FACTORY:"F"},t={SINGLETON:"S",TRANSIENT:"T"},o={TEQ:"teq",NODE:"node",NPM:"npm"},r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e,t){const o=e&&"object"==typeof e?e:{},c=new l;c.moduleName="string"==typeof o.moduleName?o.moduleName:"";const p="string"==typeof o.platform?o.platform:void 0;c.platform=p&&i.has(p)?p:r;let f=null;null===o.exportName?f=null:"string"==typeof o.exportName&&(f=o.exportName),c.exportName=f;const u="string"==typeof o.composition?o.composition:void 0;c.composition=u&&s.has(u)?u:n;const m="string"==typeof o.life?o.life:void 0;return c.life=m&&a.has(m)?m:null,c.wrappers=Array.isArray(o.wrappers)?o.wrappers.filter(e=>"string"==typeof e):[],c.origin="string"==typeof o.origin?o.origin:"",!0===t?.immutable&&(Object.freeze(c.wrappers),Object.freeze(c)),c}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const m=u.indexOf("__"),d=u.lastIndexOf("__");if(-1!==m&&m!==d)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==m){if(g=u.slice(0,m),w=u.slice(m+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s},{immutable:!0});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e,t){const o=e&&"object"==typeof e?e:{},r=t&&"object"==typeof t?t:{},n=new f;return n.prefix="string"==typeof o.prefix?o.prefix:void 0,n.target="string"==typeof o.target?o.target:void 0,n.defaultExt="string"==typeof o.defaultExt?o.defaultExt:void 0,!0===r.immutable&&Object.freeze(n),n}};class m{namespaces;nodeModulesRoot}class d{constructor(){const e=new u;this.create=function(t,o){const r=t&&"object"==typeof t?t:{},n=o&&"object"==typeof o?o:{},i=new m,s=Array.isArray(r.namespaces)?r.namespaces:[];return i.namespaces=s.map(t=>e.create(t,n)),i.nodeModulesRoot="string"==typeof r.nodeModulesRoot?r.nodeModulesRoot:void 0,!0===n.immutable&&(Object.freeze(i.namespaces),Object.freeze(i)),i}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(function(e){if(null==e)return!1;const t=typeof e;return("object"===t||"function"===t)&&"function"==typeof e.then}(t))throw new Error("Factory composition must return synchronously (non-thenable).");return t}throw new Error(`Unsupported composition mode: ${String(t.composition)}.`)}}}class ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){if(null==e)return!1;const t=typeof e;if("object"!==t&&"function"!==t)return!1;return"function"==typeof e.then},t=function(e){return"function"==typeof e};this.execute=function(o,r,n){let i=r;const s=o.wrappers;for(const o of s){if(!(o in n))throw new Error(`Wrapper '${o}' is not found in module namespace.`);const r=n[o];if(!t(r))throw new Error(`Wrapper '${o}' must be callable.`);if(i=r(i),e(i))throw new Error(`Wrapper '${o}' must return synchronously (non-thenable).`)}return i}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});return class{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map;let i=!1,s=!1,a=new p;const l=new d;let c,f,u,m=E;const x=new h,b=new y,C=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},v=function(e){if(null==e)return e;const t=typeof e;return"object"!==t&&"function"!==t||"[object Module]"===Object.prototype.toString.call(e)||Object.isFrozen(e)||Object.freeze(e),e},I=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},j=function(e){s&&m.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){I(),j("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){I(),j("addPostprocess()."),o.push(e)},this.setParser=function(e){I(),a=e,"function"==typeof a.setLogger&&a.setLogger(s?m:null),j("setParser().")},this.addNamespaceRoot=function(e,t,o){I(),j(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){I(),j("enableTestMode()."),i=!0},this.enableLogging=function(){I(),s||(s=!0,m=new N,"function"==typeof a.setLogger&&a.setLogger(m),m.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(I(),j(`register('${e}').`),!0!==i)throw new Error("Container test mode is disabled.");const o=a.parse(e);n.set(_(o),t)},this.get=async function(s){if("failed"===e)throw m.error(`Container.get: rejected in failed state cdc='${s}'.`),new Error("Container is in failed state.");let p="start";try{m.log(`Container.get: cdc='${s}'.`),function(){if("notConfigured"!==e)return;m.log("Container.transition: notConfigured -> operational."),e="operational";const t=l.create({namespaces:r},{immutable:!0});"function"==typeof a.setLogger&&a.setLogger(m),c=new g({config:t,logger:m}),f=new w({parser:a,resolver:c,logger:m}),u=new $(m)}(),m.log(`Container.state: '${e}'.`),p="parse",m.log("Container.pipeline: parse:entry.");const d=a.parse(s);m.log(`Container.pipeline: parse:exit '${d.platform}::${d.moduleName}'.`),p="preprocess",m.log("Container.pipeline: preprocess:entry.");const h=function(e){let o=e;for(const e of t)o=e(o);return o}(d);if(m.log(`Container.pipeline: preprocess:exit '${h.platform}::${h.moduleName}'.`),!0===i){p="mock",m.log("Container.pipeline: mock-lookup:entry.");const e=_(h);if(n.has(e)){m.log(`Container.pipeline: mock-lookup:hit '${e}'.`),p="freeze",m.log("Container.pipeline: freeze:entry.");const t=v(n.get(e));return m.log("Container.pipeline: freeze:exit."),m.log("Container.pipeline: return:success."),t}m.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else m.log("Container.pipeline: mock-lookup:disabled.");p="resolve",m.log("Container.pipeline: resolve:entry.");const y=await f.resolve(h);m.log(`Container.pipeline: resolve:exit nodes=${y.size}.`);const N=new Map,E=function(e){if(N.has(e))return N.get(e);if(!y.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=y.get(e);p="lifecycle",m.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=u.apply(t.depId,function(){p="instantiate",m.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=a.parse(r);e[t]=E(C(n))}const n=x.instantiate(t.depId,t.namespace,e);m.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),p="postprocess",m.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);m.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=b.execute(t.depId,i,t.namespace);p="freeze",m.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const l=v(s);return m.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),l});return m.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),N.set(e,r),r},I=E(C(h));return m.log("Container.pipeline: return:success."),I}catch(t){throw m.error(`Container.pipeline: failed at stage='${p}'.`,t),m.log("Container.transition: operational -> failed."),e="failed",t}}}}});
|
|
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 o=Object.freeze({TEQ:"teq",NODE:"node",NPM:"npm"});const r=o.TEQ,n=e.AS_IS,i=new Set(Object.values(o)),s=new Set(Object.values(e)),a=new Set(Object.values(t));let l=class{moduleName;platform;exportName;composition;life;wrappers;origin},c=class{create(e){const t=e&&"object"==typeof e?e:{},o=new l;o.moduleName="string"==typeof t.moduleName?t.moduleName:"";const c="string"==typeof t.platform?t.platform:void 0;o.platform=c&&i.has(c)?c:r;let p=null;null===t.exportName?p=null:"string"==typeof t.exportName&&(p=t.exportName),o.exportName=p;const f="string"==typeof t.composition?t.composition:void 0;o.composition=f&&s.has(f)?f:n;const u="string"==typeof t.life?t.life:void 0;return o.life=u&&a.has(u)?u:null,o.wrappers=Array.isArray(t.wrappers)?t.wrappers.filter(e=>"string"==typeof e):[],o.origin="string"==typeof t.origin?t.origin:"",Object.freeze(o.wrappers),Object.freeze(o)}};class p{constructor(){const r=new c;let n=null;this.parse=function(i){if(n&&n.log(`Parser.parse: input='${i}'.`),"string"!=typeof i)throw new Error("CDC must be a string.");if(0===i.length)throw new Error("CDC must be non-empty.");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(i))throw new Error("CDC must satisfy AsciiCdcIdentifier.");const s=i;let a=i,l=o.TEQ;if(a.startsWith("node_"))l=o.NODE,a=a.slice(5);else if(a.startsWith("npm_"))l=o.NPM,a=a.slice(4);else if(a.startsWith("teq_"))throw new Error("Explicit teq_ prefix is forbidden.");if(0===a.length)throw new Error("moduleName must be non-empty.");const c=a.match(/(\${1,3})(?:_([A-Za-z0-9]+(?:_[A-Za-z0-9]+)*))?$/);let p=null,f=[],u=a;if(c){const e=c[1],o=c[2];if("$"===e)p=t.SINGLETON;else{if("$$"!==e&&"$$$"!==e)throw new Error("Lifecycle marker overflow.");p=t.TRANSIENT}if(u=a.slice(0,c.index),o){f=o.split("_");for(const e of f){if(!e)throw new Error("Wrapper must be non-empty.");if(e.includes("$"))throw new Error("Wrapper must not contain $.");if(e.includes("_"))throw new Error("Wrapper must not contain _.")}}}else{if(a.includes("$"))throw new Error("Invalid lifecycle marker.");if(a.match(/(?:^|[^_])_([a-z][A-Za-z0-9]*)$/))throw new Error("Wrapper without lifecycle is forbidden.")}if(u.includes("$$$$"))throw new Error("Lifecycle marker overflow.");const d=u.indexOf("__"),m=u.lastIndexOf("__");if(-1!==d&&d!==m)throw new Error("Export delimiter must appear at most once.");if(u.startsWith("__")||u.endsWith("__"))throw new Error("Malformed export segment.");let g=u,w=null;if(-1!==d){if(g=u.slice(0,d),w=u.slice(d+2),!w)throw new Error("Export must be non-empty.");if(w.includes("_"))throw new Error("Export must not contain _.");if(w.includes("$"))throw new Error("Export must not contain $.")}if(!g)throw new Error("moduleName must be non-empty.");if(g.startsWith("_")||g.startsWith("$"))throw new Error("moduleName must not start with _ or $.");if(g.includes("__"))throw new Error("moduleName must not contain __.");if(g.includes("$"))throw new Error("moduleName must not contain $.");let h=e.AS_IS;null!==w?h=e.FACTORY:p===t.SINGLETON?(w="default",h=e.FACTORY):p===t.TRANSIENT&&(h=e.FACTORY,null===w&&(w="default"));const $=r.create({moduleName:g,platform:l,exportName:w,composition:h,life:p,wrappers:f,origin:s});return n&&n.log(`Parser.parse: produced='${$.platform}::${$.moduleName}'.`),$},this.setLogger=function(e){n=e}}}let f=class{prefix;target;defaultExt},u=class{create(e){const t=e&&"object"==typeof e?e:{},o=new f;return o.prefix="string"==typeof t.prefix?t.prefix:void 0,o.target="string"==typeof t.target?t.target:void 0,o.defaultExt="string"==typeof t.defaultExt?t.defaultExt:void 0,Object.freeze(o)}};class d{namespaces;nodeModulesRoot}class m{constructor(){const e=new u;this.create=function(t){const o=t&&"object"==typeof t?t:{},r=new d,n=Array.isArray(o.namespaces)?o.namespaces:[];return r.namespaces=n.map(t=>e.create(t)),r.nodeModulesRoot="string"==typeof o.nodeModulesRoot?o.nodeModulesRoot:void 0,Object.freeze(r.namespaces),Object.freeze(r)}}}class g{constructor({config:e,importFn:t=e=>import(e),logger:o=null}){const r=new Map,n=e;let i;const s=t,a=o,l=function(e,t){if("node"===e){const e=`node:${t}`;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("npm"===e){const e=t;return a&&a.log(`Resolver.specifier: module='${t}' -> '${e}'.`),e}if("teq"!==e)throw new Error(`Unsupported platform: ${e}`);const o=function(e){let t=null,o=-1;const r=i.namespaces;for(const n of r){const r=e.startsWith(n.prefix);a&&a.log(`Resolver.namespace: prefix='${n.prefix}' match=${String(r)} module='${e}'.`),r&&n.prefix.length>o&&(t=n,o=n.prefix.length)}if(!t)throw new Error(`Namespace rule is not found for '${e}'.`);return t}(t),r=t.slice(o.prefix.length).split("_").join("/"),n=(s=r,(l=o.defaultExt)?s.endsWith(l)?s:`${s}${l}`:s);var s,l;const c=function(e,t){return e?e.endsWith("/")?`${e}${t}`:`${e}/${t}`:t}(o.target,n);return a&&a.log(`Resolver.specifier: module='${t}' -> '${c}'.`),c};this.resolve=async function(e){var t;await Promise.resolve(),i||(i={nodeModulesRoot:(t=n).nodeModulesRoot,namespaces:t.namespaces.map(e=>({prefix:e.prefix,target:e.target,defaultExt:e.defaultExt}))});const o=e.platform,c=e.moduleName,p=`${o}::${c}`;if(r.has(p))return a&&a.log(`Resolver.cache: hit key='${p}'.`),r.get(p);a&&a.log(`Resolver.cache: miss key='${p}'.`);const f=(async()=>{const e=l(o,c);return a&&a.log(`Resolver.import: '${e}'.`),s(e)})();r.set(p,f);try{return await f}catch(e){throw r.delete(p),a&&a.error(`Resolver.cache: evict key='${p}' after failure.`,e),e}}}}class w{constructor({parser:e,resolver:t,logger:o=null}){const r=o,n=async function(o,i,s,a){const l=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(s.has(l)){const e=[...a,l].join(" -> ");throw new Error(`Cyclic dependency detected: ${e}`)}const c=function(e){return`${e.platform}::${e.moduleName}`}(o);if(!i.has(c)){s.add(l),a.push(l);try{const l=await t.resolve(o);r&&r.log(`GraphResolver.walk: resolved '${c}'.`),i.set(c,{depId:o,namespace:l});const p=Reflect.get(l,"__deps__");if(void 0===p)return;const f=p;for(const[,t]of Object.entries(f)){const o=t,l=e.parse(o);r&&r.log(`GraphResolver.walk: edge '${c}' -> '${l.platform}::${l.moduleName}'.`),await n(l,i,s,a)}}finally{a.pop(),s.delete(l)}}};this.resolve=async function(e){const t=new Map,o=new Set;return await n(e,t,o,[]),t}}}class h{constructor(){this.instantiate=function(t,o,r){const n=function(e,t){if(null===e.exportName)return t;if(!(e.exportName in t))throw new Error(`Export '${e.exportName}' is not found in module namespace.`);return t[e.exportName]}(t,o);if(t.composition===e.AS_IS)return n;if(t.composition===e.FACTORY){if("function"!=typeof n)throw new Error("Factory composition requires a callable export.");const e=n;let t;if(function(e){try{return Reflect.construct(String,[],e),!0}catch{return!1}}(e)){t=new e(r)}else{t=e(r)}if(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 ${constructor(o=null){const r=new Map,n=o;this.apply=function(o,i){if(o.composition!==e.FACTORY)return n&&n.log(`Lifecycle.apply: composition='${o.composition}' cache=skip.`),i();if(o.life===t.TRANSIENT)return n&&n.log("Lifecycle.apply: transient cache=skip."),i();if(o.life===t.SINGLETON){const e=function(e){const t=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,null===e.exportName?"":e.exportName,e.composition,null===e.life?"":e.life,t].join("::")}(o);if(r.has(e))return n&&n.log(`Lifecycle.cache: hit key='${e}'.`),r.get(e);n&&n.log(`Lifecycle.cache: miss key='${e}', create.`);const t=i();return r.set(e,t),n&&n.log(`Lifecycle.cache: stored key='${e}'.`),t}return n&&n.log("Lifecycle.apply: no lifecycle marker cache=skip."),i()}}}class y{constructor(){const e=function(e){return"function"==typeof e};this.execute=function(t,o,r){let n=o;const i=t.wrappers;for(const t of i){if(!(t in r))throw new Error(`Wrapper '${t}' is not found in module namespace.`);const o=r[t];if(!e(o))throw new Error(`Wrapper '${t}' must be callable.`);if(n=o(n),n instanceof Promise)throw new Error(`Wrapper '${t}' must return synchronously (non-Promise).`)}return n}}}class N{constructor(e="teqfw/di"){const t=`[${e}]`;this.log=function(e){console.debug(`${t} ${e}`)},this.error=function(e,o){console.error(`${t} ${e}`),o instanceof Error?console.error(o.stack??o.message):void 0!==o&&console.error(o)}}}const E=Object.freeze({log(){},error(){}});return class{constructor(){let e="notConfigured";const t=[],o=[],r=[],n=new Map,i=new WeakMap;let s=!1,a=!1,l=new p;const c=new m;let f,u,d,x=E;const C=new h,b=new y,v=function(e){return`${e.platform}::${e.moduleName}`},_=function(e){const t=null===e.exportName?"":e.exportName,o=null===e.life?"":e.life,r=Array.isArray(e.wrappers)?e.wrappers.join("|"):"";return[e.platform,e.moduleName,t,e.composition,o,r].join("::")},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){x.log(`Container.freeze: skipped (${String(e)}).`)}return e},R=function(e){if(null==e)return e;const t=typeof e;if("object"!==t&&"function"!==t)return e;const o=e;if(i.has(o))return i.get(o);try{return Reflect.get(o,"then"),e}catch{const e=new Proxy(o,{get(e,t,o){if("then"!==t)return Reflect.get(e,t,o)}});return i.set(o,e),e}},j=function(){if("notConfigured"!==e)throw new Error("Container configuration is locked.")},A=function(e){a&&x.log(`Container.builder: ${e}`)};this.addPreprocess=function(e){j(),A("addPreprocess()."),t.push(e)},this.addPostprocess=function(e){j(),A("addPostprocess()."),o.push(e)},this.setParser=function(e){j(),l=e,"function"==typeof l.setLogger&&l.setLogger(a?x:null),A("setParser().")},this.addNamespaceRoot=function(e,t,o){j(),A(`addNamespaceRoot('${e}').`),r.push({prefix:e,target:t,defaultExt:o})},this.enableTestMode=function(){j(),A("enableTestMode()."),s=!0},this.enableLogging=function(){j(),a||(a=!0,x=new N,"function"==typeof l.setLogger&&l.setLogger(x),x.log("Container.builder: enableLogging()."))},this.register=function(e,t){if(j(),A(`register('${e}').`),!0!==s)throw new Error("Container test mode is disabled.");const o=l.parse(e);n.set(_(o),t)},this.get=async function(i){if("failed"===e)throw x.error(`Container.get: rejected in failed state cdc='${i}'.`),new Error("Container is in failed state.");let a="start";try{x.log(`Container.get: cdc='${i}'.`),function(){if("notConfigured"!==e)return;x.log("Container.transition: notConfigured -> operational."),e="operational";const t=c.create({namespaces:r});"function"==typeof l.setLogger&&l.setLogger(x),f=new g({config:t,logger:x}),u=new w({parser:l,resolver:f,logger:x}),d=new $(x)}(),x.log(`Container.state: '${e}'.`),a="parse",x.log("Container.pipeline: parse:entry.");const p=l.parse(i);x.log(`Container.pipeline: parse:exit '${p.platform}::${p.moduleName}'.`),a="preprocess",x.log("Container.pipeline: preprocess:entry.");const m=function(e){let o=e;for(const e of t)o=e(o);return o}(p);if(x.log(`Container.pipeline: preprocess:exit '${m.platform}::${m.moduleName}'.`),!0===s){a="mock",x.log("Container.pipeline: mock-lookup:entry.");const e=_(m);if(n.has(e)){x.log(`Container.pipeline: mock-lookup:hit '${e}'.`),a="freeze",x.log("Container.pipeline: freeze:entry.");const t=I(n.get(e));return x.log("Container.pipeline: freeze:exit."),x.log("Container.pipeline: return:success."),R(t)}x.log(`Container.pipeline: mock-lookup:miss '${e}'.`)}else x.log("Container.pipeline: mock-lookup:disabled.");a="resolve",x.log("Container.pipeline: resolve:entry.");const h=await u.resolve(m);x.log(`Container.pipeline: resolve:exit nodes=${h.size}.`);const y=new Map,N=function(e){if(y.has(e))return y.get(e);if(!h.has(e))throw new Error(`Resolved graph node is missing for '${e}'.`);const t=h.get(e);a="lifecycle",x.log(`Container.pipeline: lifecycle:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const r=d.apply(t.depId,function(){a="instantiate",x.log(`Container.pipeline: instantiate:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const e={},r=function(e){const t=Reflect.get(e,"__deps__");return void 0===t?{}:t}(t.namespace);for(const[t,o]of Object.entries(r)){const r=o,n=l.parse(r);e[t]=N(v(n))}const n=C.instantiate(t.depId,t.namespace,e);x.log(`Container.pipeline: instantiate:exit '${t.depId.platform}::${t.depId.moduleName}'.`),a="postprocess",x.log(`Container.pipeline: postprocess:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const i=function(e){let t=e;for(const e of o)t=e(t);return t}(n);x.log(`Container.pipeline: postprocess:exit '${t.depId.platform}::${t.depId.moduleName}'.`);const s=b.execute(t.depId,i,t.namespace);a="freeze",x.log(`Container.pipeline: freeze:entry '${t.depId.platform}::${t.depId.moduleName}'.`);const c=I(s);return x.log(`Container.pipeline: freeze:exit '${t.depId.platform}::${t.depId.moduleName}'.`),c});return x.log(`Container.pipeline: lifecycle:exit '${t.depId.platform}::${t.depId.moduleName}'.`),y.set(e,r),r},E=N(v(m));return x.log("Container.pipeline: return:success."),R(E)}catch(t){throw x.error(`Container.pipeline: failed at stage='${a}'.`,t),x.log("Container.transition: operational -> failed."),e="failed",t}}}}});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teqfw/di",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.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",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"dist/",
|
|
26
26
|
"src/",
|
|
27
27
|
"CHANGELOG.md",
|
|
28
|
-
"jsconfig.json",
|
|
29
28
|
"LICENSE",
|
|
30
29
|
"README.md",
|
|
31
30
|
"types.d.ts"
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
"devDependencies": {
|
|
60
59
|
"@eslint/js": "^10.0.1",
|
|
61
60
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
62
|
-
"@rollup/plugin-terser": "^0.
|
|
61
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
63
62
|
"eslint": "^10.0.2",
|
|
64
63
|
"rollup": "^4.59.0"
|
|
65
64
|
},
|
package/src/AGENTS.md
CHANGED
|
@@ -21,9 +21,9 @@ The following documents are mandatory:
|
|
|
21
21
|
- `ctx/docs/code/depid.md`
|
|
22
22
|
- `ctx/docs/code/testing.md`
|
|
23
23
|
- `ctx/docs/code/jsdoc-spec.md`
|
|
24
|
-
- `ctx/docs/code/
|
|
25
|
-
- `ctx/docs/code/
|
|
26
|
-
- `ctx/docs/code/
|
|
24
|
+
- `ctx/docs/code/convention/es6-modules.md`
|
|
25
|
+
- `ctx/docs/code/convention/teqfw/dto.md`
|
|
26
|
+
- `ctx/docs/code/convention/teqfw/enum.md`
|
|
27
27
|
|
|
28
28
|
Agent MUST read and follow them before generating or modifying code.
|
|
29
29
|
|
|
@@ -72,8 +72,8 @@ Absence of required JSDoc constitutes non-compliance.
|
|
|
72
72
|
|
|
73
73
|
All DTO and Enum implementations MUST strictly follow:
|
|
74
74
|
|
|
75
|
-
- `ctx/docs/code/
|
|
76
|
-
- `ctx/docs/code/
|
|
75
|
+
- `ctx/docs/code/convention/teqfw/dto.md`
|
|
76
|
+
- `ctx/docs/code/convention/teqfw/enum.md`
|
|
77
77
|
|
|
78
78
|
In particular:
|
|
79
79
|
|
|
@@ -63,29 +63,6 @@ export default class TeqFw_Di_Container_Instantiate_Instantiator {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
/**
|
|
67
|
-
* Detects Promise-like asynchronous return values.
|
|
68
|
-
*
|
|
69
|
-
* @param {unknown} value
|
|
70
|
-
* @returns {boolean}
|
|
71
|
-
*/
|
|
72
|
-
const isThenable = function (value) {
|
|
73
|
-
if ((value === null) || (value === undefined)) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const type = typeof value;
|
|
78
|
-
|
|
79
|
-
if ((type !== 'object') && (type !== 'function')) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** @type {{ then?: unknown }} */
|
|
84
|
-
const maybeThenable = value;
|
|
85
|
-
|
|
86
|
-
return (typeof maybeThenable.then === 'function');
|
|
87
|
-
};
|
|
88
|
-
|
|
89
66
|
/**
|
|
90
67
|
* Produces a value from a resolved module namespace and dependency map.
|
|
91
68
|
*
|
|
@@ -126,9 +103,9 @@ export default class TeqFw_Di_Container_Instantiate_Instantiator {
|
|
|
126
103
|
result = Fn(resolvedDeps);
|
|
127
104
|
}
|
|
128
105
|
|
|
129
|
-
if (
|
|
106
|
+
if (result instanceof Promise) {
|
|
130
107
|
throw new Error(
|
|
131
|
-
'Factory composition must return synchronously (non-
|
|
108
|
+
'Factory composition must return synchronously (non-Promise).'
|
|
132
109
|
);
|
|
133
110
|
}
|
|
134
111
|
|
|
@@ -12,21 +12,6 @@ export default class TeqFw_Di_Container_Wrapper_Executor {
|
|
|
12
12
|
* Creates wrapper executor instance.
|
|
13
13
|
*/
|
|
14
14
|
constructor() {
|
|
15
|
-
/**
|
|
16
|
-
* Detects Promise-like asynchronous return values.
|
|
17
|
-
*
|
|
18
|
-
* @param {unknown} value
|
|
19
|
-
* @returns {boolean}
|
|
20
|
-
*/
|
|
21
|
-
const isThenable = function (value) {
|
|
22
|
-
if ((value === null) || (value === undefined)) return false;
|
|
23
|
-
const type = typeof value;
|
|
24
|
-
if ((type !== 'object') && (type !== 'function')) return false;
|
|
25
|
-
/** @type {{ then?: unknown }} */
|
|
26
|
-
const maybeThenable = value;
|
|
27
|
-
return (typeof maybeThenable.then === 'function');
|
|
28
|
-
};
|
|
29
|
-
|
|
30
15
|
/**
|
|
31
16
|
* Narrows unknown export to unary wrapper callable.
|
|
32
17
|
*
|
|
@@ -60,8 +45,8 @@ export default class TeqFw_Di_Container_Wrapper_Executor {
|
|
|
60
45
|
throw new Error(`Wrapper '${name}' must be callable.`);
|
|
61
46
|
}
|
|
62
47
|
current = candidate(current);
|
|
63
|
-
if (
|
|
64
|
-
throw new Error(`Wrapper '${name}' must return synchronously (non-
|
|
48
|
+
if (current instanceof Promise) {
|
|
49
|
+
throw new Error(`Wrapper '${name}' must return synchronously (non-Promise).`);
|
|
65
50
|
}
|
|
66
51
|
}
|
|
67
52
|
|
package/src/Container.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import TeqFw_Di_Def_Parser from './Def/Parser.mjs';
|
|
4
|
-
import
|
|
4
|
+
import {Factory as TeqFw_Di_Dto_Resolver_Config_Factory} from './Dto/Resolver/Config.mjs';
|
|
5
5
|
import TeqFw_Di_Resolver from './Container/Resolver.mjs';
|
|
6
6
|
import TeqFw_Di_Container_Resolve_GraphResolver from './Container/Resolve/GraphResolver.mjs';
|
|
7
7
|
import TeqFw_Di_Container_Instantiate_Instantiator from './Container/Instantiate/Instantiator.mjs';
|
|
@@ -19,6 +19,9 @@ import TeqFw_Di_Internal_Logger, {TeqFw_Di_Internal_Logger_Noop} from './Interna
|
|
|
19
19
|
* Executes immutable linking pipeline:
|
|
20
20
|
* parse -> preprocess -> resolve graph -> instantiate -> postprocess ->
|
|
21
21
|
* lifecycle -> freeze -> return.
|
|
22
|
+
*
|
|
23
|
+
* @LLM-DOC
|
|
24
|
+
* Spec: ./ctx/docs/code/components/container.md
|
|
22
25
|
*/
|
|
23
26
|
export default class TeqFw_Di_Container {
|
|
24
27
|
/**
|
|
@@ -31,17 +34,19 @@ export default class TeqFw_Di_Container {
|
|
|
31
34
|
const preprocess = [];
|
|
32
35
|
/** @type {((value: unknown) => unknown)[]} */
|
|
33
36
|
const postprocess = [];
|
|
34
|
-
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO
|
|
37
|
+
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO[]} */
|
|
35
38
|
const namespaceRoots = [];
|
|
36
39
|
/** @type {Map<string, unknown>} */
|
|
37
40
|
const mockRegistry = new Map();
|
|
41
|
+
/** @type {WeakMap<object, object>} */
|
|
42
|
+
const promiseSafeCache = new WeakMap();
|
|
38
43
|
let testMode = false;
|
|
39
44
|
let loggingEnabled = false;
|
|
40
45
|
|
|
41
46
|
/** @type {TeqFw_Di_Def_Parser} */
|
|
42
47
|
let parser = new TeqFw_Di_Def_Parser();
|
|
43
|
-
/** @type {TeqFw_Di_Dto_Resolver_Config} */
|
|
44
|
-
const configFactory = new
|
|
48
|
+
/** @type {TeqFw_Di_Dto_Resolver_Config$Factory} */
|
|
49
|
+
const configFactory = new TeqFw_Di_Dto_Resolver_Config_Factory();
|
|
45
50
|
/** @type {TeqFw_Di_Resolver|undefined} */
|
|
46
51
|
let resolver;
|
|
47
52
|
/** @type {TeqFw_Di_Container_Resolve_GraphResolver|undefined} */
|
|
@@ -95,10 +100,41 @@ export default class TeqFw_Di_Container {
|
|
|
95
100
|
if ((type !== 'object') && (type !== 'function')) return value;
|
|
96
101
|
if (Object.prototype.toString.call(value) === '[object Module]') return value;
|
|
97
102
|
if (Object.isFrozen(value)) return value;
|
|
98
|
-
|
|
103
|
+
try {
|
|
104
|
+
Object.freeze(value);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
logger.log(`Container.freeze: skipped (${String(error)}).`);
|
|
107
|
+
}
|
|
99
108
|
return value;
|
|
100
109
|
};
|
|
101
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Ensures async `get()` can resolve objects whose proxy `get('then')` throws.
|
|
113
|
+
*
|
|
114
|
+
* @param {unknown} value
|
|
115
|
+
* @returns {unknown}
|
|
116
|
+
*/
|
|
117
|
+
const asPromiseSafe = function (value) {
|
|
118
|
+
if ((value === null) || (value === undefined)) return value;
|
|
119
|
+
const type = typeof value;
|
|
120
|
+
if ((type !== 'object') && (type !== 'function')) return value;
|
|
121
|
+
const obj = /** @type {object} */ (value);
|
|
122
|
+
if (promiseSafeCache.has(obj)) return promiseSafeCache.get(obj);
|
|
123
|
+
try {
|
|
124
|
+
void Reflect.get(obj, 'then');
|
|
125
|
+
return value;
|
|
126
|
+
} catch {
|
|
127
|
+
const wrapped = new Proxy(obj, {
|
|
128
|
+
get(target, property, receiver) {
|
|
129
|
+
if (property === 'then') return undefined;
|
|
130
|
+
return Reflect.get(target, property, receiver);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
promiseSafeCache.set(obj, wrapped);
|
|
134
|
+
return wrapped;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
102
138
|
/**
|
|
103
139
|
* Applies ordered preprocess pipeline.
|
|
104
140
|
*
|
|
@@ -169,7 +205,7 @@ export default class TeqFw_Di_Container {
|
|
|
169
205
|
state = 'operational';
|
|
170
206
|
const resolverConfig = configFactory.create({
|
|
171
207
|
namespaces: namespaceRoots,
|
|
172
|
-
}
|
|
208
|
+
});
|
|
173
209
|
if (typeof parser.setLogger === 'function') parser.setLogger(logger);
|
|
174
210
|
resolver = new TeqFw_Di_Resolver({config: resolverConfig, logger});
|
|
175
211
|
graphResolver = new TeqFw_Di_Container_Resolve_GraphResolver({parser, resolver, logger});
|
|
@@ -271,7 +307,7 @@ export default class TeqFw_Di_Container {
|
|
|
271
307
|
* Resolves dependency by CDC and returns frozen linked value.
|
|
272
308
|
*
|
|
273
309
|
* @param {string} cdc
|
|
274
|
-
* @returns {Promise<
|
|
310
|
+
* @returns {Promise<any>}
|
|
275
311
|
*/
|
|
276
312
|
this.get = async function (cdc) {
|
|
277
313
|
if (state === 'failed') {
|
|
@@ -306,7 +342,7 @@ export default class TeqFw_Di_Container {
|
|
|
306
342
|
const frozenMock = freeze(mockRegistry.get(key));
|
|
307
343
|
logger.log('Container.pipeline: freeze:exit.');
|
|
308
344
|
logger.log('Container.pipeline: return:success.');
|
|
309
|
-
return frozenMock;
|
|
345
|
+
return asPromiseSafe(frozenMock);
|
|
310
346
|
}
|
|
311
347
|
logger.log(`Container.pipeline: mock-lookup:miss '${key}'.`);
|
|
312
348
|
} else {
|
|
@@ -368,7 +404,7 @@ export default class TeqFw_Di_Container {
|
|
|
368
404
|
|
|
369
405
|
const result = build(getKey(root));
|
|
370
406
|
logger.log('Container.pipeline: return:success.');
|
|
371
|
-
return result;
|
|
407
|
+
return asPromiseSafe(result);
|
|
372
408
|
} catch (error) {
|
|
373
409
|
logger.error(`Container.pipeline: failed at stage='${stage}'.`, error);
|
|
374
410
|
logger.log('Container.transition: operational -> failed.');
|
package/src/Def/Parser.mjs
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
import TeqFw_Di_Enum_Composition from '../Enum/Composition.mjs';
|
|
4
4
|
import TeqFw_Di_Enum_Life from '../Enum/Life.mjs';
|
|
5
5
|
import TeqFw_Di_Enum_Platform from '../Enum/Platform.mjs';
|
|
6
|
-
import
|
|
6
|
+
import {Factory as TeqFw_Di_Dto_DepId_Factory} from '../Dto/DepId.mjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Parser for CDC identifiers into
|
|
10
|
-
|
|
9
|
+
* Parser for CDC identifiers into frozen dependency identity DTO.
|
|
10
|
+
*/
|
|
11
11
|
export default class TeqFw_Di_Def_Parser {
|
|
12
12
|
/**
|
|
13
13
|
* Creates parser instance.
|
|
14
14
|
*/
|
|
15
15
|
constructor() {
|
|
16
|
-
/** @type {
|
|
17
|
-
const depIdFactory = new
|
|
16
|
+
/** @type {TeqFw_Di_Dto_DepId$Factory} Factory used to construct dependency identity DTO. */
|
|
17
|
+
const depIdFactory = new TeqFw_Di_Dto_DepId_Factory();
|
|
18
18
|
/** @type {{log(message: string): void}|null} */
|
|
19
19
|
let logger = null;
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Parses one CDC identifier and returns normalized
|
|
22
|
+
* Parses one CDC identifier and returns normalized frozen dependency DTO.
|
|
23
23
|
*
|
|
24
24
|
* @param {string} cdc CDC identifier string.
|
|
25
25
|
* @returns {TeqFw_Di_DepId$DTO}
|
|
@@ -128,7 +128,7 @@ export default class TeqFw_Di_Def_Parser {
|
|
|
128
128
|
life,
|
|
129
129
|
wrappers,
|
|
130
130
|
origin,
|
|
131
|
-
}
|
|
131
|
+
});
|
|
132
132
|
if (logger) logger.log(`Parser.parse: produced='${depId.platform}::${depId.moduleName}'.`);
|
|
133
133
|
return depId;
|
|
134
134
|
};
|
package/src/Dto/DepId.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import TeqFw_Di_Enum_Life from '../Enum/Life.mjs';
|
|
|
5
5
|
import TeqFw_Di_Enum_Platform from '../Enum/Platform.mjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* DTO
|
|
8
|
+
* DTO for dependency identity records and its factory.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/** @type {typeof TeqFw_Di_Enum_Platform[keyof typeof TeqFw_Di_Enum_Platform]} */
|
|
@@ -23,7 +23,7 @@ const LIFE_VALUES = new Set(Object.values(TeqFw_Di_Enum_Life));
|
|
|
23
23
|
/**
|
|
24
24
|
* Runtime DTO for parsed dependency identity.
|
|
25
25
|
*/
|
|
26
|
-
export class DTO {
|
|
26
|
+
export default class DTO {
|
|
27
27
|
/** @type {string} Resolved module namespace. */
|
|
28
28
|
moduleName;
|
|
29
29
|
|
|
@@ -47,17 +47,16 @@ export class DTO {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
* Factory for dependency identity DTO
|
|
50
|
+
* Factory for immutable dependency identity DTO.
|
|
51
51
|
*/
|
|
52
|
-
export
|
|
52
|
+
export class Factory {
|
|
53
53
|
/**
|
|
54
|
-
* Creates normalized dependency identity DTO.
|
|
54
|
+
* Creates normalized frozen dependency identity DTO.
|
|
55
55
|
*
|
|
56
56
|
* @param {unknown} [input]
|
|
57
|
-
* @param {{immutable?: boolean}} [options]
|
|
58
57
|
* @returns {TeqFw_Di_DepId$DTO}
|
|
59
58
|
*/
|
|
60
|
-
create(input
|
|
59
|
+
create(input) {
|
|
61
60
|
/** @type {Record<string, unknown>} */
|
|
62
61
|
const source = (input && typeof input === 'object')
|
|
63
62
|
? /** @type {Record<string, unknown>} */ (input)
|
|
@@ -121,11 +120,7 @@ export default class Factory {
|
|
|
121
120
|
? source.origin
|
|
122
121
|
: '';
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Object.freeze(dto);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return dto;
|
|
123
|
+
Object.freeze(dto.wrappers);
|
|
124
|
+
return Object.freeze(dto);
|
|
130
125
|
}
|
|
131
126
|
}
|
|
@@ -1,48 +1,43 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* DTO
|
|
4
|
+
* DTO for resolver namespace rule records and its factory.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Runtime DTO for one namespace resolution rule.
|
|
9
9
|
*/
|
|
10
|
-
export class DTO {
|
|
10
|
+
export default class DTO {
|
|
11
11
|
/** @type {string|undefined} Namespace prefix in depId module name. */
|
|
12
12
|
prefix;
|
|
13
|
+
|
|
13
14
|
/** @type {string|undefined} Import target base for matched namespace. */
|
|
14
15
|
target;
|
|
16
|
+
|
|
15
17
|
/** @type {string|undefined} Default extension appended to matched module path. */
|
|
16
18
|
defaultExt;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
|
-
* Factory for resolver namespace DTO
|
|
22
|
+
* Factory for immutable resolver namespace DTO.
|
|
21
23
|
*/
|
|
22
|
-
export
|
|
24
|
+
export class Factory {
|
|
23
25
|
/**
|
|
24
|
-
* Creates normalized resolver namespace DTO.
|
|
26
|
+
* Creates normalized frozen resolver namespace DTO.
|
|
25
27
|
*
|
|
26
|
-
* @param {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace$DTO
|
|
27
|
-
* @
|
|
28
|
-
* @returns {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO$}
|
|
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}
|
|
29
30
|
*/
|
|
30
|
-
create(input
|
|
31
|
-
/** @type {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace$DTO
|
|
31
|
+
create(input) {
|
|
32
|
+
/** @type {Partial<TeqFw_Di_Dto_Resolver_Config_Namespace$DTO>|Record<string, unknown>} */
|
|
32
33
|
const source = (input && (typeof input === 'object')) ? input : {};
|
|
33
|
-
/** @type {{immutable?: boolean}|Record<string, unknown>} */
|
|
34
|
-
const mode = (options && (typeof options === 'object')) ? options : {};
|
|
35
34
|
|
|
36
|
-
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO
|
|
35
|
+
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO} */
|
|
37
36
|
const dto = new DTO();
|
|
38
37
|
dto.prefix = (typeof source.prefix === 'string') ? source.prefix : undefined;
|
|
39
38
|
dto.target = (typeof source.target === 'string') ? source.target : undefined;
|
|
40
39
|
dto.defaultExt = (typeof source.defaultExt === 'string') ? source.defaultExt : undefined;
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
Object.freeze(dto);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return dto;
|
|
41
|
+
return Object.freeze(dto);
|
|
47
42
|
}
|
|
48
43
|
}
|
|
@@ -1,58 +1,52 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import {Factory as TeqFw_Di_Dto_Resolver_Config_Namespace_Factory} from './Config/Namespace.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* DTO
|
|
6
|
+
* DTO for resolver configuration records and its factory.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Runtime DTO for resolver configuration.
|
|
11
11
|
*/
|
|
12
|
-
export class DTO {
|
|
13
|
-
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO
|
|
12
|
+
export default class DTO {
|
|
13
|
+
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace$DTO[]} Namespace resolution rules. */
|
|
14
14
|
namespaces;
|
|
15
|
+
|
|
15
16
|
/** @type {string|undefined} Optional node_modules root prefix for npm modules. */
|
|
16
17
|
nodeModulesRoot;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
|
-
* Factory for resolver configuration DTO
|
|
21
|
+
* Factory for immutable resolver configuration DTO.
|
|
21
22
|
*/
|
|
22
|
-
export
|
|
23
|
+
export class Factory {
|
|
23
24
|
/**
|
|
24
25
|
* Creates factory instance.
|
|
25
26
|
*/
|
|
26
27
|
constructor() {
|
|
27
|
-
/** @type {
|
|
28
|
-
const nsFactory = new
|
|
28
|
+
/** @type {TeqFw_Di_Dto_Resolver_Config_Namespace_Factory} */
|
|
29
|
+
const nsFactory = new TeqFw_Di_Dto_Resolver_Config_Namespace_Factory();
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
|
-
* Creates normalized resolver configuration DTO.
|
|
32
|
+
* Creates normalized frozen resolver configuration DTO.
|
|
32
33
|
*
|
|
33
34
|
* @param {Partial<TeqFw_Di_Dto_Resolver_Config$DTO>|Record<string, unknown>} [input] Source values.
|
|
34
|
-
* @param {{immutable?: boolean}|Record<string, unknown>} [options] Factory options.
|
|
35
35
|
* @returns {TeqFw_Di_Dto_Resolver_Config$DTO}
|
|
36
36
|
*/
|
|
37
|
-
this.create = function (input
|
|
37
|
+
this.create = function (input) {
|
|
38
38
|
/** @type {Partial<TeqFw_Di_Dto_Resolver_Config$DTO>|Record<string, unknown>} */
|
|
39
39
|
const source = (input && (typeof input === 'object')) ? input : {};
|
|
40
|
-
/** @type {{immutable?: boolean}|Record<string, unknown>} */
|
|
41
|
-
const mode = (options && (typeof options === 'object')) ? options : {};
|
|
42
40
|
|
|
43
41
|
/** @type {TeqFw_Di_Dto_Resolver_Config$DTO} */
|
|
44
42
|
const dto = new DTO();
|
|
45
43
|
/** @type {unknown[]} */
|
|
46
44
|
const items = Array.isArray(source.namespaces) ? source.namespaces : [];
|
|
47
|
-
dto.namespaces = items.map((item) => nsFactory.create(item
|
|
45
|
+
dto.namespaces = items.map((item) => nsFactory.create(item));
|
|
48
46
|
dto.nodeModulesRoot = (typeof source.nodeModulesRoot === 'string') ? source.nodeModulesRoot : undefined;
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Object.freeze(dto);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return dto;
|
|
48
|
+
Object.freeze(dto.namespaces);
|
|
49
|
+
return Object.freeze(dto);
|
|
56
50
|
};
|
|
57
51
|
}
|
|
58
52
|
}
|
package/src/Enum/Composition.mjs
CHANGED
package/src/Enum/Life.mjs
CHANGED
package/src/Enum/Platform.mjs
CHANGED
package/types.d.ts
CHANGED
|
@@ -8,14 +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").
|
|
11
|
+
type TeqFw_Di_DepId$DTO = import("./src/Dto/DepId.mjs").default;
|
|
12
|
+
type TeqFw_Di_DepId$Factory = InstanceType<typeof import("./src/Dto/DepId.mjs").Factory>;
|
|
12
13
|
type TeqFw_Di_Dto_DepId = import("./src/Dto/DepId.mjs").default;
|
|
13
|
-
type TeqFw_Di_Dto_DepId$DTO = import("./src/Dto/DepId.mjs").
|
|
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>;
|
|
14
16
|
type TeqFw_Di_Dto_Resolver_Config = import("./src/Dto/Resolver/Config.mjs").default;
|
|
15
|
-
type TeqFw_Di_Dto_Resolver_Config$DTO = import("./src/Dto/Resolver/Config.mjs").
|
|
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>;
|
|
16
19
|
type TeqFw_Di_Dto_Resolver_Config_Namespace = import("./src/Dto/Resolver/Config/Namespace.mjs").default;
|
|
17
|
-
type TeqFw_Di_Dto_Resolver_Config_Namespace$DTO = import("./src/Dto/Resolver/Config/Namespace.mjs").
|
|
18
|
-
type TeqFw_Di_Dto_Resolver_Config_Namespace$
|
|
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>;
|
|
19
22
|
type TeqFw_Di_Enum_Composition = typeof import("./src/Enum/Composition.mjs").default;
|
|
20
23
|
type TeqFw_Di_Enum_Life = typeof import("./src/Enum/Life.mjs").default;
|
|
21
24
|
type TeqFw_Di_Enum_Platform = typeof import("./src/Enum/Platform.mjs").default;
|
package/jsconfig.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"baseUrl": ".",
|
|
4
|
-
"checkJs": true,
|
|
5
|
-
"forceConsistentCasingInFileNames": true,
|
|
6
|
-
"module": "nodenext",
|
|
7
|
-
"moduleResolution": "nodenext",
|
|
8
|
-
"noEmit": true,
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"target": "ESNext"
|
|
11
|
-
},
|
|
12
|
-
"include": ["src", "test", "types.d.ts"]
|
|
13
|
-
}
|