@noego/ioc 0.0.9 → 0.0.11

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.
Files changed (29) hide show
  1. package/dist/framework/implementation/Container.cjs +70 -8
  2. package/dist/framework/implementation/Container.cjs.map +1 -1
  3. package/dist/framework/implementation/Container.d.cts +12 -1
  4. package/dist/framework/implementation/Container.d.ts +12 -1
  5. package/dist/framework/implementation/Container.js +60 -8
  6. package/dist/framework/implementation/Container.js.map +1 -1
  7. package/dist/framework/implementation/ProxyFactory.cjs +200 -0
  8. package/dist/framework/implementation/ProxyFactory.cjs.map +1 -0
  9. package/dist/framework/implementation/ProxyFactory.d.cts +37 -0
  10. package/dist/framework/implementation/ProxyFactory.d.ts +37 -0
  11. package/dist/framework/implementation/ProxyFactory.js +169 -0
  12. package/dist/framework/implementation/ProxyFactory.js.map +1 -0
  13. package/dist/framework/implementation/TraceCleanup.cjs +83 -0
  14. package/dist/framework/implementation/TraceCleanup.cjs.map +1 -0
  15. package/dist/framework/implementation/TraceCleanup.d.cts +24 -0
  16. package/dist/framework/implementation/TraceCleanup.d.ts +24 -0
  17. package/dist/framework/implementation/TraceCleanup.js +49 -0
  18. package/dist/framework/implementation/TraceCleanup.js.map +1 -0
  19. package/dist/framework/implementation/TraceLogger.cjs +274 -0
  20. package/dist/framework/implementation/TraceLogger.cjs.map +1 -0
  21. package/dist/framework/implementation/TraceLogger.d.cts +82 -0
  22. package/dist/framework/implementation/TraceLogger.d.ts +82 -0
  23. package/dist/framework/implementation/TraceLogger.js +228 -0
  24. package/dist/framework/implementation/TraceLogger.js.map +1 -0
  25. package/dist/framework/interface/Container.cjs.map +1 -1
  26. package/dist/framework/interface/Container.d.cts +9 -1
  27. package/dist/framework/interface/Container.d.ts +9 -1
  28. package/package.json +5 -1
  29. package/readme.md +130 -3
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var Container_exports = {};
20
30
  __export(Container_exports, {
@@ -28,6 +38,9 @@ var import_LoadAs = require("./LoadAs.cjs");
28
38
  var import_Parameter = require("./Parameter.cjs");
29
39
  var import_ContainerErrors = require("../errors/ContainerErrors.cjs");
30
40
  var import_DecoratorSupport = require("./DecoratorSupport.cjs");
41
+ var import_ProxyFactory = require("./ProxyFactory.cjs");
42
+ var TraceLoggerModule = __toESM(require("./TraceLogger.cjs"), 1);
43
+ var import_TraceCleanup = require("./TraceCleanup.cjs");
31
44
  var ContainerRouting = /* @__PURE__ */ ((ContainerRouting2) => {
32
45
  ContainerRouting2["FUNCTIONAL"] = "FUNCTIONAL";
33
46
  ContainerRouting2["CLASS"] = "CLASS";
@@ -44,6 +57,9 @@ class Container {
44
57
  this._functionStorageScoped = /* @__PURE__ */ new Map();
45
58
  this._classStorageSingleton = /* @__PURE__ */ new Map();
46
59
  this._classStorageScoped = /* @__PURE__ */ new Map();
60
+ // Tracing configuration
61
+ this._enableTracing = false;
62
+ this._traceRetentionMinutes = 5;
47
63
  }
48
64
  // Registration methods
49
65
  registerClass(classDefinition, options) {
@@ -80,8 +96,42 @@ class Container {
80
96
  childContainer._classDefinition = new Map(this._classDefinition);
81
97
  childContainer._functionStorageSingleton = this._functionStorageSingleton;
82
98
  childContainer._classStorageSingleton = this._classStorageSingleton;
99
+ childContainer._enableTracing = this._enableTracing;
100
+ childContainer._traceRetentionMinutes = this._traceRetentionMinutes;
83
101
  return childContainer;
84
102
  }
103
+ // Tracing API
104
+ setTracingEnabled(enabled) {
105
+ this._enableTracing = enabled;
106
+ if (enabled && !import_TraceCleanup.TraceCleanup.isCleanupRunning()) {
107
+ (0, import_ProxyFactory.setTraceLogger)(TraceLoggerModule);
108
+ import_TraceCleanup.TraceCleanup.start(this._traceRetentionMinutes);
109
+ }
110
+ }
111
+ isTracingEnabled() {
112
+ return this._enableTracing;
113
+ }
114
+ setTraceRetentionMinutes(minutes) {
115
+ this._traceRetentionMinutes = Math.max(1, minutes);
116
+ }
117
+ getTraces(retentionMinutes) {
118
+ const retention = retentionMinutes ?? this._traceRetentionMinutes;
119
+ return TraceLoggerModule.getRecentTraces(retention);
120
+ }
121
+ getAllTraces() {
122
+ return TraceLoggerModule.getAllTraces();
123
+ }
124
+ clearTraces() {
125
+ TraceLoggerModule.clearAllTraces();
126
+ }
127
+ exportTraces(filepath) {
128
+ const data = TraceLoggerModule.exportTracesToJson();
129
+ const fs = require("fs");
130
+ fs.writeFileSync(filepath, JSON.stringify(data, null, 2));
131
+ }
132
+ getTraceStatistics() {
133
+ return TraceLoggerModule.getTraceStatistics();
134
+ }
85
135
  // Private helper methods
86
136
  clearDefinitions(label) {
87
137
  this._routing.delete(label);
@@ -171,7 +221,7 @@ class Container {
171
221
  }
172
222
  }
173
223
  // Central resolution logic
174
- async loadInstance(label, params = [], resolutionChain = []) {
224
+ async loadInstance(label, params = [], resolutionChain = [], parentProxyId) {
175
225
  const currentLabelStr = typeof label === "function" && label.name ? label.name : String(label);
176
226
  if (resolutionChain.includes(currentLabelStr)) {
177
227
  console.error(`[IOC LoadInstance] Circular dependency detected: ${[...resolutionChain, currentLabelStr].join(" -> ")}`);
@@ -186,7 +236,7 @@ class Container {
186
236
  }
187
237
  }
188
238
  if (this.isRegisteredAsClass(label)) {
189
- return this.loadClassInstance(label, params, nextResolutionChain);
239
+ return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);
190
240
  }
191
241
  if (this.isRegisteredAsFunction(label)) {
192
242
  return this.loadFunctionInstance(label, params, nextResolutionChain);
@@ -197,7 +247,7 @@ class Container {
197
247
  if (!this._routing.has(label)) {
198
248
  this._routing.set(label, "CLASS" /* CLASS */);
199
249
  }
200
- return this.loadClassInstance(label, params, nextResolutionChain);
250
+ return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);
201
251
  }
202
252
  }
203
253
  console.error(`[IOC LoadInstance] Dependency not found and cannot be resolved: ${currentLabelStr}`);
@@ -210,7 +260,7 @@ class Container {
210
260
  }
211
261
  return valueContainer.value;
212
262
  }
213
- loadClassInstance(classDefinition, params, resolutionChain) {
263
+ loadClassInstance(classDefinition, params, resolutionChain, parentProxyId) {
214
264
  const storageType = this.getStorageType(classDefinition);
215
265
  const className = classDefinition.name || "[Anonymous Class]";
216
266
  if (storageType && this.hasInstance(classDefinition)) {
@@ -224,9 +274,13 @@ class Container {
224
274
  } else {
225
275
  dependenciesToResolve = (0, import_DecoratorSupport.getResolvedDependencies)(classDefinition);
226
276
  }
277
+ let futureProxyId;
278
+ if (this._enableTracing) {
279
+ futureProxyId = (0, import_ProxyFactory.reserveProxyId)();
280
+ }
227
281
  const paramsCopy = [...params];
228
282
  const resolutionPromises = dependenciesToResolve.map(
229
- (dependencyIdentifier) => this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain)
283
+ (dependencyIdentifier) => this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain, futureProxyId)
230
284
  // Recursive call handles auto-registration
231
285
  );
232
286
  let finalInstance = Promise.all(resolutionPromises).catch((error) => {
@@ -242,8 +296,12 @@ class Container {
242
296
  instancePromise = (async () => {
243
297
  try {
244
298
  const instance = new classDefinition(...resolvedDependencies);
245
- this.setInstance(classDefinition, instance, storageType);
246
- return instance;
299
+ let wrappedInstance = instance;
300
+ if (this._enableTracing && futureProxyId !== void 0) {
301
+ wrappedInstance = (0, import_ProxyFactory.wrapWithProxy)(instance, className, parentProxyId, futureProxyId);
302
+ }
303
+ this.setInstance(classDefinition, wrappedInstance, storageType);
304
+ return wrappedInstance;
247
305
  } catch (err) {
248
306
  console.error(`[IOC LoadClass] Error during instantiation of ${className}: ${err.message}`, err.stack);
249
307
  if (storageType === "singleton") this._classStorageSingleton.delete(classDefinition);
@@ -256,7 +314,11 @@ class Container {
256
314
  instancePromise = (async () => {
257
315
  try {
258
316
  const instance = new classDefinition(...resolvedDependencies);
259
- return instance;
317
+ let wrappedInstance = instance;
318
+ if (this._enableTracing && futureProxyId !== void 0) {
319
+ wrappedInstance = (0, import_ProxyFactory.wrapWithProxy)(instance, className, parentProxyId, futureProxyId);
320
+ }
321
+ return wrappedInstance;
260
322
  } catch (err) {
261
323
  console.error(`[IOC LoadClass] Error during instantiation of transient ${className}: ${err.message}`, err.stack);
262
324
  throw err;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../framework/implementation/Container.ts"],"sourcesContent":["import 'reflect-metadata'; // Ensure polyfill is loaded conceptually\nimport type { ContainerOptions, IContainerClient, IContainerFunctionDefinition, IContainerSetup } from \"../interface/Container.cjs\";\nimport { LoadAs } from \"./LoadAs.cjs\";\nimport { Parameter } from \"./Parameter.cjs\";\nimport type { ParameterValue } from \"./Parameter.cjs\";\nimport { NotAClassDefinitionError, ParameterNotFoundError, DependencyNotFoundError, InstanceNotCreatedError, CircularDependencyError } from \"../errors/ContainerErrors.cjs\";\nimport {\n getScope,\n getComponentOptions, // Use helper\n getResolvedDependencies // Use helper\n} from './DecoratorSupport'; // Assume helpers exist or create them\n\nenum ContainerRouting {\n FUNCTIONAL = \"FUNCTIONAL\",\n CLASS = \"CLASS\"\n // No need for COMPONENT route, just check metadata if CLASS/FUNCTIONAL fails\n}\n\ntype StorageType = 'singleton' | 'scoped' | 'transient';\n\nexport class Container implements IContainerClient, IContainerSetup {\n // Routing and definition maps\n private _routing: Map<any, ContainerRouting> = new Map();\n private _functionDefinition: Map<any, IContainerFunctionDefinition> = new Map();\n private _classDefinition: Map<Function, Partial<ContainerOptions>> = new Map();\n\n // Storage maps\n private _functionStorageSingleton: Map<any, any> = new Map();\n private _functionStorageScoped: Map<any, any> = new Map();\n private _classStorageSingleton: Map<Function, any> = new Map();\n private _classStorageScoped: Map<Function, any> = new Map();\n\n // Registration methods\n registerClass<T>(classDefinition: new (...args: any[]) => T, options?: Partial<ContainerOptions>): void {\n // Basic validation\n if (typeof classDefinition !== 'function' || !classDefinition.prototype) {\n console.warn(`[IOC] Attempted to register non-class: ${String(classDefinition)}`);\n // Optional: throw error instead?\n // throw new NotAClassDefinitionError(`Attempted to register non-class: ${String(classDefinition)}`);\n return; // Don't proceed if not a class constructor\n }\n\n // Always clear previous definitions for this exact class constructor\n this.clearDefinitions(classDefinition);\n\n // Always set the routing type so 'isClassDefinition' works\n this._routing.set(classDefinition, ContainerRouting.CLASS);\n\n // Store manual options *only if they are actually provided and have content*\n if (options && Object.keys(options).length > 0) {\n this._classDefinition.set(classDefinition, options);\n // console.log(`[IOC RegClass] Manually registered ${classDefinition.name} with options:`, options);\n } else {\n // console.log(`[IOC RegClass] Manually registered ${classDefinition.name} with no specific options (will use decorators if present).`);\n // If no options are provided, we don't store anything in _classDefinition,\n // effectively clearing any previous manual config and letting decorators take over if present.\n }\n }\n\n registerFunction<T extends (...arg: any[]) => any>(label: any, func: T, options: Partial<ContainerOptions> = {} as any): void {\n this.clearDefinitions(label);\n this._routing.set(label, ContainerRouting.FUNCTIONAL);\n this._functionDefinition.set(label, { function: func, options });\n // console.log(`[IOC RegFunc] Registered function with label ${String(label)} and options:`, options);\n }\n\n // Instance resolution methods - Simplify to just call loadInstance\n instance<T, Args extends any[]>(classDefinition: new (...args: Args) => T, params: ParameterValue<any>[] = []): Promise<T> {\n // Basic check upfront\n if (typeof classDefinition !== 'function' || !classDefinition.prototype) {\n throw new NotAClassDefinitionError(`Cannot resolve instance for non-class: ${String(classDefinition)}`);\n }\n return this.loadInstance(classDefinition, params) as Promise<T>;\n }\n\n get<T>(label: any, param: ParameterValue<any>[] = []): Promise<T> | T {\n // Just delegate to loadInstance, which handles routing and auto-registration\n return this.loadInstance(label, param);\n }\n\n extend(): IContainerClient & IContainerSetup {\n const childContainer = createContainer() as Container;\n\n // Copy routing and definition maps (share the registration knowledge)\n childContainer._routing = new Map(this._routing);\n childContainer._functionDefinition = new Map(this._functionDefinition);\n childContainer._classDefinition = new Map(this._classDefinition);\n\n // Share singleton storage (singletons are shared across all containers)\n childContainer._functionStorageSingleton = this._functionStorageSingleton;\n childContainer._classStorageSingleton = this._classStorageSingleton;\n\n // Do NOT share scoped storage (new container = new scope)\n // Child gets its own empty scoped storage\n\n // console.log('[IOC Extend] Created child container.');\n return childContainer;\n }\n\n // Private helper methods\n private clearDefinitions(label: any): void {\n this._routing.delete(label);\n this._functionDefinition.delete(label);\n // Only delete from classDefinition if the label is actually a function constructor\n if (typeof label === 'function') {\n this._classDefinition.delete(label);\n }\n }\n\n // Checks if the label is *currently* registered as a class\n private isRegisteredAsClass(label: any): boolean {\n return this._routing.get(label) === ContainerRouting.CLASS;\n }\n\n // Checks if the label is *currently* registered as a function\n private isRegisteredAsFunction(label: any): boolean {\n return this._routing.get(label) === ContainerRouting.FUNCTIONAL;\n }\n\n\n private hasInstance(label: any): boolean {\n const storageType = this.getStorageType(label); // This checks decorators if needed\n\n if (!storageType) {\n // Transient instances are never stored\n return false;\n }\n\n // Determine if it's treated as a class (registered or decorated) *after* getting type\n const isClass = this.isClassType(label); // Use a helper that checks routing OR decorator\n\n if (isClass) {\n return storageType === 'singleton'\n ? this._classStorageSingleton.has(label)\n : this._classStorageScoped.has(label);\n } else { // Must be a function if not a class\n return storageType === 'singleton'\n ? this._functionStorageSingleton.has(label)\n : this._functionStorageScoped.has(label);\n }\n }\n\n // Helper to determine if something should be treated as a class (registered or decorated)\n private isClassType(label: any): boolean {\n if (this.isRegisteredAsClass(label)) {\n return true;\n }\n // If not explicitly registered as a class, check if it's a function with @Component\n if (typeof label === 'function' && label.prototype && !this.isRegisteredAsFunction(label)) {\n return getComponentOptions(label) !== null;\n }\n return false;\n }\n\n private getInstance(label: any): any {\n const storageType = this.getStorageType(label); // Checks decorators if needed\n\n if (!storageType) {\n // This should ideally not be reached if called after hasInstance check\n console.error(`[IOC GetInstance] Attempted to get instance for non-stored type: ${String(label)}`);\n throw new InstanceNotCreatedError();\n }\n\n const isClass = this.isClassType(label); // Check routing OR decorator\n\n if (isClass) {\n return storageType === 'singleton'\n ? this._classStorageSingleton.get(label)\n : this._classStorageScoped.get(label);\n } else { // Must be a function\n return storageType === 'singleton'\n ? this._functionStorageSingleton.get(label)\n : this._functionStorageScoped.get(label);\n }\n }\n\n private setInstance(label: any, instance: any, storageType?: StorageType): void { // Made storageType non-optional\n const isClass = this.isClassType(label); // Determine type based on routing OR decorator\n\n if (isClass) {\n if (storageType === 'singleton') {\n this._classStorageSingleton.set(label, instance);\n } else if (storageType == 'scoped'){ // storageType === 'scoped'\n this._classStorageScoped.set(label, instance);\n }\n } else { // Must be a function\n if (storageType === 'singleton') {\n this._functionStorageSingleton.set(label, instance);\n } else if(storageType === \"scoped\"){ // storageType === 'scoped'\n this._functionStorageScoped.set(label, instance);\n }\n }\n }\n\n private getStorageType(label: any): StorageType {\n let manualLoadAs: LoadAs | undefined;\n let decoratorScope: LoadAs | undefined;\n const isPotentialClass = typeof label === 'function' && label.prototype;\n\n // Get manual registration options if available\n if (this.isRegisteredAsClass(label)) { // Use helper\n manualLoadAs = this._classDefinition.get(label)?.loadAs;\n } else if (this.isRegisteredAsFunction(label)) { // Use helper\n manualLoadAs = this._functionDefinition.get(label)?.options?.loadAs;\n }\n\n // Get decorator scope only if it's potentially a class *and not explicitly registered as a function*\n if (isPotentialClass && !this.isRegisteredAsFunction(label)) {\n decoratorScope = getScope(label); // Uses getComponentOptions internally\n }\n\n // Determine final scope: Manual > Decorator > Default (Transient)\n const finalScope = manualLoadAs ?? decoratorScope ?? LoadAs.Transient;\n\n if (finalScope === LoadAs.Singleton) {\n return 'singleton';\n } else if (finalScope === LoadAs.Scoped) {\n return 'scoped';\n }else{\n return 'transient'; // Transient\n }\n }\n\n // Central resolution logic\n protected async loadInstance(\n label: any,\n params: ParameterValue<any>[] = [],\n resolutionChain: string[] = [] // Track resolution path\n ): Promise<any> {\n\n // --- Circular Dependency Check ---\n const currentLabelStr = (typeof label === 'function' && label.name) ? label.name : String(label);\n if (resolutionChain.includes(currentLabelStr)) {\n console.error(`[IOC LoadInstance] Circular dependency detected: ${[...resolutionChain, currentLabelStr].join(' -> ')}`);\n throw new CircularDependencyError([...resolutionChain, currentLabelStr]);\n }\n const nextResolutionChain = [...resolutionChain, currentLabelStr];\n // --- End Circular Dependency Check ---\n\n // --- Handle Parameters ---\n if (label instanceof Parameter) {\n try {\n // Pass a *copy* of params to avoid side effects in resolveParameterValue\n return Promise.resolve(this.resolveParameterValue(label, [...params]));\n } catch (e) {\n // console.error(`[IOC LoadInstance] Error resolving parameter ${param.toString()}:`, e);\n return Promise.reject(e);\n }\n }\n // --- End Handle Parameters ---\n\n\n // --- Check Explicit Registrations ---\n if (this.isRegisteredAsClass(label)) {\n // console.log(`[IOC LoadInstance] Resolving explicitly registered class: ${currentLabelStr}`);\n return this.loadClassInstance(label, params, nextResolutionChain);\n }\n if (this.isRegisteredAsFunction(label)) {\n // console.log(`[IOC LoadInstance] Resolving explicitly registered function: ${currentLabelStr}`);\n return this.loadFunctionInstance(label, params, nextResolutionChain);\n }\n // --- End Check Explicit Registrations ---\n\n\n // --- Attempt Auto-Registration/Resolution for Decorated Classes ---\n if (typeof label === 'function' && label.prototype) {\n const componentOptions = getComponentOptions(label); // Check for @Component\n if (componentOptions !== null) {\n // console.log(`[IOC LoadInstance] Auto-resolving @Component class: ${currentLabelStr}`);\n // Set routing *now* so subsequent internal checks work correctly\n if (!this._routing.has(label)) { // Only set if not already set\n this._routing.set(label, ContainerRouting.CLASS);\n // console.log(`[IOC LoadInstance] Set routing for auto-resolved class: ${currentLabelStr}`);\n }\n // Proceed to load it as a class\n return this.loadClassInstance(label, params, nextResolutionChain);\n }\n }\n // --- End Auto-Registration ---\n\n\n // --- Dependency Not Found ---\n console.error(`[IOC LoadInstance] Dependency not found and cannot be resolved: ${currentLabelStr}`);\n throw new DependencyNotFoundError(currentLabelStr);\n }\n\n\n private resolveParameterValue(param: Parameter, params: ParameterValue<any>[]): any { // No mutation\n // Find the *last* provided value for the parameter\n const valueContainer = [...params].reverse().find((p) => p.belongsTo(param));\n if (!valueContainer) {\n // console.error(`[IOC ResolveParam] Parameter not found: ${param.toString()}`);\n throw new ParameterNotFoundError(param.toString());\n }\n // console.log(`[IOC ResolveParam] Resolved parameter ${param.toString()}`);\n return valueContainer.value;\n }\n\n private loadClassInstance(\n classDefinition: any, // Should be a class constructor here\n params: ParameterValue<any>[],\n resolutionChain: string[]\n ): Promise<any> {\n const storageType = this.getStorageType(classDefinition);\n const className = classDefinition.name || '[Anonymous Class]';\n\n // Check storage first (handle stored promises)\n if (storageType && this.hasInstance(classDefinition)) {\n const instance = this.getInstance(classDefinition);\n // console.log(`[IOC LoadClass] Found existing ${storageType} instance for ${className}. IsPromise: ${isPromise(instance)}`);\n return instance\n }\n // console.log(`[IOC LoadClass] Creating new ${storageType || 'transient'} instance for ${className}`);\n\n // --- Determine Dependencies ---\n const manualOptions = this._classDefinition.get(classDefinition) as ContainerOptions | undefined;\n let dependenciesToResolve: any[];\n\n if (manualOptions?.param && Array.isArray(manualOptions.param)) {\n dependenciesToResolve = manualOptions.param;\n // console.log(`[IOC LoadClass] Using manual dependencies for ${className}`);\n } else {\n // Use decorator-derived dependencies\n dependenciesToResolve = getResolvedDependencies(classDefinition);\n // console.log(`[IOC LoadClass] Using decorator/reflected dependencies for ${className}:`, dependenciesToResolve.map(d => typeof d === 'function' ? d.name : String(d)));\n }\n // --- End Determine Dependencies ---\n\n\n // --- Resolve Dependencies ---\n // Create a *copy* of params to pass down for dependency resolution\n const paramsCopy = [...params];\n const resolutionPromises = dependenciesToResolve.map(dependencyIdentifier =>\n this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain) // Recursive call handles auto-registration\n );\n\n let finalInstance = Promise.all(resolutionPromises)\n .catch((error)=>{\n console.error(`[IOC LoadClass] Failed to resolve one or more dependencies for ${className}:`, error);\n // Clean up potential partially stored promise if this was going to be singleton/scoped\n if (storageType && this.isRegisteredAsClass(classDefinition)) { // Check if it was actually *being* stored\n if (storageType === 'singleton') this._classStorageSingleton.delete(classDefinition);\n if (storageType === 'scoped') this._classStorageScoped.delete(classDefinition);\n }\n throw error; // Re-throw dependency resolution error\n }).then(async(resolvedDependencies)=>{\n // --- Instantiate Class ---\n // Store the promise *before* starting instantiation for concurrent requests\n let instancePromise: Promise<any> | undefined;\n if (storageType && !this.hasInstance(classDefinition)) { // Check again in case of race condition?\n // Create the promise wrapper immediately\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadClass] Instantiating ${className} with ${resolvedDependencies.length} args.`);\n const instance = new classDefinition(...resolvedDependencies);\n // Overwrite the stored promise with the actual instance *after* it's created\n this.setInstance(classDefinition, instance, storageType); // Use the correct storageType\n // console.log(`[IOC LoadClass] Stored actual ${storageType} instance for ${className}`);\n return instance;\n } catch (err: any) {\n console.error(`[IOC LoadClass] Error during instantiation of ${className}: ${err.message}`, err.stack);\n // Clean up the stored promise on failure\n if (storageType === 'singleton') this._classStorageSingleton.delete(classDefinition);\n if (storageType === 'scoped') this._classStorageScoped.delete(classDefinition);\n throw err; // Re-throw instantiation error\n }\n })();\n // console.log(`[IOC LoadClass] Storing promise for concurrent requests (${storageType}) for ${className}`);\n this.setInstance(classDefinition, instancePromise, storageType);\n } else {\n // If already has instance (from storage check) or is transient, just instantiate directly\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadClass] Instantiating transient ${className} with ${resolvedDependencies.length} args.`);\n const instance = new classDefinition(...resolvedDependencies);\n // No storing for transient\n return instance;\n } catch (err: any) {\n console.error(`[IOC LoadClass] Error during instantiation of transient ${className}: ${err.message}`, err.stack);\n throw err; // Re-throw instantiation error\n }\n })();\n }\n // --- End Instantiate Class ---\n // Await and return the final instance (either newly created or from the stored promise)\n return await instancePromise;\n });\n\n if(storageType && storageType !== 'transient'){\n this.setInstance(classDefinition, finalInstance, storageType); // Store the promise\n }\n return finalInstance\n }\n\n private loadFunctionInstance(\n funcLabel: any,\n params: ParameterValue<any>[],\n resolutionChain: string[]\n ): Promise<any> { // Always return Promise<any> since this is an async function\n const functionConfig = this._functionDefinition.get(funcLabel)!; // Assumed to exist by caller\n const storageType = this.getStorageType(funcLabel); // Only uses manual options for functions\n const labelStr = String(funcLabel);\n\n // Check storage first\n if (storageType && this.hasInstance(funcLabel)) {\n const instance = this.getInstance(funcLabel);\n // console.log(`[IOC LoadFunc] Found existing ${storageType} instance for ${labelStr}. IsPromise: ${isPromise(instance)}`);\n return instance;\n }\n // console.log(`[IOC LoadFunc] Creating new ${storageType || 'transient'} instance for ${labelStr}`);\n\n const ioc_func = functionConfig.function;\n const options = functionConfig.options;\n const dependenciesToResolve: any[] = options?.param || [];\n\n // --- Resolve Dependencies ---\n const paramsCopy = [...params]; // Create a copy\n const resolutionPromises = dependenciesToResolve.map(dependencyIdentifier =>\n this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain)\n );\n\n let finalInstance = Promise.all(resolutionPromises).catch((error)=>{\n console.error(`[IOC LoadFunc] Failed to resolve dependencies for function ${labelStr}:`, error);\n // Clean up potential partial storage\n if (storageType && this.isRegisteredAsFunction(funcLabel)) {\n if (storageType === 'singleton') this._functionStorageSingleton.delete(funcLabel);\n if (storageType === 'scoped') this._functionStorageScoped.delete(funcLabel);\n }\n throw error;\n }).then(async(resolvedArgs)=>{\n let instancePromise: Promise<any> | undefined;\n if (storageType && !this.hasInstance(funcLabel)) {\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadFunc] Invoking ${labelStr} with ${resolvedArgs.length} args.`);\n const result = await ioc_func.apply(null, resolvedArgs); // Await in case function is async\n // Overwrite stored promise with actual result\n this.setInstance(funcLabel, result, storageType);\n // console.log(`[IOC LoadFunc] Stored actual ${storageType} instance for ${labelStr}`);\n return result;\n } catch (err: any) {\n console.error(`[IOC LoadFunc] Error executing function ${labelStr}: ${err.message}`, err.stack);\n // Clean up stored promise on failure\n if (storageType === 'singleton') this._functionStorageSingleton.delete(funcLabel);\n if (storageType === 'scoped') this._functionStorageScoped.delete(funcLabel);\n throw err;\n }\n })();\n // console.log(`[IOC LoadFunc] Storing promise for concurrent requests (${storageType}) for ${labelStr}`);\n this.setInstance(funcLabel, instancePromise, storageType);\n } else {\n // Transient or already resolved from storage check\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadFunc] Invoking transient ${labelStr} with ${resolvedArgs.length} args.`);\n const result = await ioc_func.apply(null, resolvedArgs); // Await in case function is async\n // No storing for transient\n return result;\n } catch (err: any) {\n console.error(`[IOC LoadFunc] Error executing transient function ${labelStr}: ${err.message}`, err.stack);\n throw err;\n }\n })();\n }\n // --- End Invoke Function ---\n\n return await instancePromise; // Return the final (awaited) result\n });\n\n if(storageType && storageType !== 'transient'){\n this.setInstance(funcLabel, finalInstance, storageType); // Store the promise\n }\n\n return finalInstance;\n }\n}\n\n// Helper functions\nexport function isPromise(obj: any): obj is Promise<any> {\n // Simplified check - more robust check might be needed depending on environment\n return !!obj && typeof obj.then === 'function';\n}\n\nexport function createContainer(): IContainerClient & IContainerSetup {\n return new Container();\n}\n"],"mappings":"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","names":["ContainerRouting"]}
1
+ {"version":3,"sources":["../../../framework/implementation/Container.ts"],"sourcesContent":["import 'reflect-metadata'; // Ensure polyfill is loaded conceptually\nimport type { ContainerOptions, IContainerClient, IContainerFunctionDefinition, IContainerSetup } from \"../interface/Container.cjs\";\nimport { LoadAs } from \"./LoadAs.cjs\";\nimport { Parameter } from \"./Parameter.cjs\";\nimport type { ParameterValue } from \"./Parameter.cjs\";\nimport { NotAClassDefinitionError, ParameterNotFoundError, DependencyNotFoundError, InstanceNotCreatedError, CircularDependencyError } from \"../errors/ContainerErrors.cjs\";\nimport {\n getScope,\n getComponentOptions, // Use helper\n getResolvedDependencies // Use helper\n} from './DecoratorSupport'; // Assume helpers exist or create them\nimport { wrapWithProxy, setTraceLogger, reserveProxyId } from \"./ProxyFactory.cjs\";\nimport * as TraceLoggerModule from \"./TraceLogger.cjs\";\nimport { TraceCleanup } from \"./TraceCleanup.cjs\";\n\nenum ContainerRouting {\n FUNCTIONAL = \"FUNCTIONAL\",\n CLASS = \"CLASS\"\n // No need for COMPONENT route, just check metadata if CLASS/FUNCTIONAL fails\n}\n\ntype StorageType = 'singleton' | 'scoped' | 'transient';\n\nexport class Container implements IContainerClient, IContainerSetup {\n // Routing and definition maps\n private _routing: Map<any, ContainerRouting> = new Map();\n private _functionDefinition: Map<any, IContainerFunctionDefinition> = new Map();\n private _classDefinition: Map<Function, Partial<ContainerOptions>> = new Map();\n\n // Storage maps\n private _functionStorageSingleton: Map<any, any> = new Map();\n private _functionStorageScoped: Map<any, any> = new Map();\n private _classStorageSingleton: Map<Function, any> = new Map();\n private _classStorageScoped: Map<Function, any> = new Map();\n\n // Tracing configuration\n private _enableTracing: boolean = false;\n private _traceRetentionMinutes: number = 5;\n\n // Registration methods\n registerClass<T>(classDefinition: new (...args: any[]) => T, options?: Partial<ContainerOptions>): void {\n // Basic validation\n if (typeof classDefinition !== 'function' || !classDefinition.prototype) {\n console.warn(`[IOC] Attempted to register non-class: ${String(classDefinition)}`);\n // Optional: throw error instead?\n // throw new NotAClassDefinitionError(`Attempted to register non-class: ${String(classDefinition)}`);\n return; // Don't proceed if not a class constructor\n }\n\n // Always clear previous definitions for this exact class constructor\n this.clearDefinitions(classDefinition);\n\n // Always set the routing type so 'isClassDefinition' works\n this._routing.set(classDefinition, ContainerRouting.CLASS);\n\n // Store manual options *only if they are actually provided and have content*\n if (options && Object.keys(options).length > 0) {\n this._classDefinition.set(classDefinition, options);\n // console.log(`[IOC RegClass] Manually registered ${classDefinition.name} with options:`, options);\n } else {\n // console.log(`[IOC RegClass] Manually registered ${classDefinition.name} with no specific options (will use decorators if present).`);\n // If no options are provided, we don't store anything in _classDefinition,\n // effectively clearing any previous manual config and letting decorators take over if present.\n }\n }\n\n registerFunction<T extends (...arg: any[]) => any>(label: any, func: T, options: Partial<ContainerOptions> = {} as any): void {\n this.clearDefinitions(label);\n this._routing.set(label, ContainerRouting.FUNCTIONAL);\n this._functionDefinition.set(label, { function: func, options });\n // console.log(`[IOC RegFunc] Registered function with label ${String(label)} and options:`, options);\n }\n\n // Instance resolution methods - Simplify to just call loadInstance\n instance<T, Args extends any[]>(classDefinition: new (...args: Args) => T, params: ParameterValue<any>[] = []): Promise<T> {\n // Basic check upfront\n if (typeof classDefinition !== 'function' || !classDefinition.prototype) {\n throw new NotAClassDefinitionError(`Cannot resolve instance for non-class: ${String(classDefinition)}`);\n }\n return this.loadInstance(classDefinition, params) as Promise<T>;\n }\n\n get<T>(label: any, param: ParameterValue<any>[] = []): Promise<T> | T {\n // Just delegate to loadInstance, which handles routing and auto-registration\n return this.loadInstance(label, param);\n }\n\n extend(): IContainerClient & IContainerSetup {\n const childContainer = createContainer() as Container;\n\n // Copy routing and definition maps (share the registration knowledge)\n childContainer._routing = new Map(this._routing);\n childContainer._functionDefinition = new Map(this._functionDefinition);\n childContainer._classDefinition = new Map(this._classDefinition);\n\n // Share singleton storage (singletons are shared across all containers)\n childContainer._functionStorageSingleton = this._functionStorageSingleton;\n childContainer._classStorageSingleton = this._classStorageSingleton;\n\n // Do NOT share scoped storage (new container = new scope)\n // Child gets its own empty scoped storage\n\n // Share tracing configuration\n childContainer._enableTracing = this._enableTracing;\n childContainer._traceRetentionMinutes = this._traceRetentionMinutes;\n\n // console.log('[IOC Extend] Created child container.');\n return childContainer;\n }\n\n // Tracing API\n setTracingEnabled(enabled: boolean): void {\n this._enableTracing = enabled;\n if (enabled && !TraceCleanup.isCleanupRunning()) {\n // Set the trace logger for the ProxyFactory\n setTraceLogger(TraceLoggerModule as any);\n // Start automatic cleanup\n TraceCleanup.start(this._traceRetentionMinutes);\n }\n }\n\n isTracingEnabled(): boolean {\n return this._enableTracing;\n }\n\n setTraceRetentionMinutes(minutes: number): void {\n this._traceRetentionMinutes = Math.max(1, minutes);\n }\n\n getTraces(retentionMinutes?: number): any[] {\n const retention = retentionMinutes ?? this._traceRetentionMinutes;\n return TraceLoggerModule.getRecentTraces(retention);\n }\n\n getAllTraces(): any[] {\n return TraceLoggerModule.getAllTraces();\n }\n\n clearTraces(): void {\n TraceLoggerModule.clearAllTraces();\n }\n\n exportTraces(filepath: string): void {\n const data = TraceLoggerModule.exportTracesToJson();\n const fs = require('fs');\n fs.writeFileSync(filepath, JSON.stringify(data, null, 2));\n }\n\n getTraceStatistics(): any {\n return TraceLoggerModule.getTraceStatistics();\n }\n\n // Private helper methods\n private clearDefinitions(label: any): void {\n this._routing.delete(label);\n this._functionDefinition.delete(label);\n // Only delete from classDefinition if the label is actually a function constructor\n if (typeof label === 'function') {\n this._classDefinition.delete(label);\n }\n }\n\n // Checks if the label is *currently* registered as a class\n private isRegisteredAsClass(label: any): boolean {\n return this._routing.get(label) === ContainerRouting.CLASS;\n }\n\n // Checks if the label is *currently* registered as a function\n private isRegisteredAsFunction(label: any): boolean {\n return this._routing.get(label) === ContainerRouting.FUNCTIONAL;\n }\n\n\n private hasInstance(label: any): boolean {\n const storageType = this.getStorageType(label); // This checks decorators if needed\n\n if (!storageType) {\n // Transient instances are never stored\n return false;\n }\n\n // Determine if it's treated as a class (registered or decorated) *after* getting type\n const isClass = this.isClassType(label); // Use a helper that checks routing OR decorator\n\n if (isClass) {\n return storageType === 'singleton'\n ? this._classStorageSingleton.has(label)\n : this._classStorageScoped.has(label);\n } else { // Must be a function if not a class\n return storageType === 'singleton'\n ? this._functionStorageSingleton.has(label)\n : this._functionStorageScoped.has(label);\n }\n }\n\n // Helper to determine if something should be treated as a class (registered or decorated)\n private isClassType(label: any): boolean {\n if (this.isRegisteredAsClass(label)) {\n return true;\n }\n // If not explicitly registered as a class, check if it's a function with @Component\n if (typeof label === 'function' && label.prototype && !this.isRegisteredAsFunction(label)) {\n return getComponentOptions(label) !== null;\n }\n return false;\n }\n\n private getInstance(label: any): any {\n const storageType = this.getStorageType(label); // Checks decorators if needed\n\n if (!storageType) {\n // This should ideally not be reached if called after hasInstance check\n console.error(`[IOC GetInstance] Attempted to get instance for non-stored type: ${String(label)}`);\n throw new InstanceNotCreatedError();\n }\n\n const isClass = this.isClassType(label); // Check routing OR decorator\n\n if (isClass) {\n return storageType === 'singleton'\n ? this._classStorageSingleton.get(label)\n : this._classStorageScoped.get(label);\n } else { // Must be a function\n return storageType === 'singleton'\n ? this._functionStorageSingleton.get(label)\n : this._functionStorageScoped.get(label);\n }\n }\n\n private setInstance(label: any, instance: any, storageType?: StorageType): void { // Made storageType non-optional\n const isClass = this.isClassType(label); // Determine type based on routing OR decorator\n\n if (isClass) {\n if (storageType === 'singleton') {\n this._classStorageSingleton.set(label, instance);\n } else if (storageType == 'scoped'){ // storageType === 'scoped'\n this._classStorageScoped.set(label, instance);\n }\n } else { // Must be a function\n if (storageType === 'singleton') {\n this._functionStorageSingleton.set(label, instance);\n } else if(storageType === \"scoped\"){ // storageType === 'scoped'\n this._functionStorageScoped.set(label, instance);\n }\n }\n }\n\n private getStorageType(label: any): StorageType {\n let manualLoadAs: LoadAs | undefined;\n let decoratorScope: LoadAs | undefined;\n const isPotentialClass = typeof label === 'function' && label.prototype;\n\n // Get manual registration options if available\n if (this.isRegisteredAsClass(label)) { // Use helper\n manualLoadAs = this._classDefinition.get(label)?.loadAs;\n } else if (this.isRegisteredAsFunction(label)) { // Use helper\n manualLoadAs = this._functionDefinition.get(label)?.options?.loadAs;\n }\n\n // Get decorator scope only if it's potentially a class *and not explicitly registered as a function*\n if (isPotentialClass && !this.isRegisteredAsFunction(label)) {\n decoratorScope = getScope(label); // Uses getComponentOptions internally\n }\n\n // Determine final scope: Manual > Decorator > Default (Transient)\n const finalScope = manualLoadAs ?? decoratorScope ?? LoadAs.Transient;\n\n if (finalScope === LoadAs.Singleton) {\n return 'singleton';\n } else if (finalScope === LoadAs.Scoped) {\n return 'scoped';\n }else{\n return 'transient'; // Transient\n }\n }\n\n // Central resolution logic\n protected async loadInstance(\n label: any,\n params: ParameterValue<any>[] = [],\n resolutionChain: string[] = [], // Track resolution path\n parentProxyId?: number // For proxy hierarchy tracking\n ): Promise<any> {\n\n // --- Circular Dependency Check ---\n const currentLabelStr = (typeof label === 'function' && label.name) ? label.name : String(label);\n if (resolutionChain.includes(currentLabelStr)) {\n console.error(`[IOC LoadInstance] Circular dependency detected: ${[...resolutionChain, currentLabelStr].join(' -> ')}`);\n throw new CircularDependencyError([...resolutionChain, currentLabelStr]);\n }\n const nextResolutionChain = [...resolutionChain, currentLabelStr];\n // --- End Circular Dependency Check ---\n\n // --- Handle Parameters ---\n if (label instanceof Parameter) {\n try {\n // Pass a *copy* of params to avoid side effects in resolveParameterValue\n return Promise.resolve(this.resolveParameterValue(label, [...params]));\n } catch (e) {\n // console.error(`[IOC LoadInstance] Error resolving parameter ${param.toString()}:`, e);\n return Promise.reject(e);\n }\n }\n // --- End Handle Parameters ---\n\n\n // --- Check Explicit Registrations ---\n if (this.isRegisteredAsClass(label)) {\n // console.log(`[IOC LoadInstance] Resolving explicitly registered class: ${currentLabelStr}`);\n return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);\n }\n if (this.isRegisteredAsFunction(label)) {\n // console.log(`[IOC LoadInstance] Resolving explicitly registered function: ${currentLabelStr}`);\n return this.loadFunctionInstance(label, params, nextResolutionChain);\n }\n // --- End Check Explicit Registrations ---\n\n\n // --- Attempt Auto-Registration/Resolution for Decorated Classes ---\n if (typeof label === 'function' && label.prototype) {\n const componentOptions = getComponentOptions(label); // Check for @Component\n if (componentOptions !== null) {\n // console.log(`[IOC LoadInstance] Auto-resolving @Component class: ${currentLabelStr}`);\n // Set routing *now* so subsequent internal checks work correctly\n if (!this._routing.has(label)) { // Only set if not already set\n this._routing.set(label, ContainerRouting.CLASS);\n // console.log(`[IOC LoadInstance] Set routing for auto-resolved class: ${currentLabelStr}`);\n }\n // Proceed to load it as a class\n return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);\n }\n }\n // --- End Auto-Registration ---\n\n\n // --- Dependency Not Found ---\n console.error(`[IOC LoadInstance] Dependency not found and cannot be resolved: ${currentLabelStr}`);\n throw new DependencyNotFoundError(currentLabelStr);\n }\n\n\n private resolveParameterValue(param: Parameter, params: ParameterValue<any>[]): any { // No mutation\n // Find the *last* provided value for the parameter\n const valueContainer = [...params].reverse().find((p) => p.belongsTo(param));\n if (!valueContainer) {\n // console.error(`[IOC ResolveParam] Parameter not found: ${param.toString()}`);\n throw new ParameterNotFoundError(param.toString());\n }\n // console.log(`[IOC ResolveParam] Resolved parameter ${param.toString()}`);\n return valueContainer.value;\n }\n\n private loadClassInstance(\n classDefinition: any, // Should be a class constructor here\n params: ParameterValue<any>[],\n resolutionChain: string[],\n parentProxyId?: number\n ): Promise<any> {\n const storageType = this.getStorageType(classDefinition);\n const className = classDefinition.name || '[Anonymous Class]';\n\n // Check storage first (handle stored promises)\n if (storageType && this.hasInstance(classDefinition)) {\n const instance = this.getInstance(classDefinition);\n // console.log(`[IOC LoadClass] Found existing ${storageType} instance for ${className}. IsPromise: ${isPromise(instance)}`);\n return instance\n }\n // console.log(`[IOC LoadClass] Creating new ${storageType || 'transient'} instance for ${className}`);\n\n // --- Determine Dependencies ---\n const manualOptions = this._classDefinition.get(classDefinition) as ContainerOptions | undefined;\n let dependenciesToResolve: any[];\n\n if (manualOptions?.param && Array.isArray(manualOptions.param)) {\n dependenciesToResolve = manualOptions.param;\n // console.log(`[IOC LoadClass] Using manual dependencies for ${className}`);\n } else {\n // Use decorator-derived dependencies\n dependenciesToResolve = getResolvedDependencies(classDefinition);\n // console.log(`[IOC LoadClass] Using decorator/reflected dependencies for ${className}:`, dependenciesToResolve.map(d => typeof d === 'function' ? d.name : String(d)));\n }\n // --- End Determine Dependencies ---\n\n // Reserve a proxy ID if tracing is enabled\n let futureProxyId: number | undefined;\n if (this._enableTracing) {\n futureProxyId = reserveProxyId();\n }\n\n // --- Resolve Dependencies ---\n // Create a *copy* of params to pass down for dependency resolution\n const paramsCopy = [...params];\n const resolutionPromises = dependenciesToResolve.map(dependencyIdentifier =>\n this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain, futureProxyId) // Recursive call handles auto-registration\n );\n\n let finalInstance = Promise.all(resolutionPromises)\n .catch((error)=>{\n console.error(`[IOC LoadClass] Failed to resolve one or more dependencies for ${className}:`, error);\n // Clean up potential partially stored promise if this was going to be singleton/scoped\n if (storageType && this.isRegisteredAsClass(classDefinition)) { // Check if it was actually *being* stored\n if (storageType === 'singleton') this._classStorageSingleton.delete(classDefinition);\n if (storageType === 'scoped') this._classStorageScoped.delete(classDefinition);\n }\n throw error; // Re-throw dependency resolution error\n }).then(async(resolvedDependencies)=>{\n // --- Instantiate Class ---\n // Store the promise *before* starting instantiation for concurrent requests\n let instancePromise: Promise<any> | undefined;\n if (storageType && !this.hasInstance(classDefinition)) { // Check again in case of race condition?\n // Create the promise wrapper immediately\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadClass] Instantiating ${className} with ${resolvedDependencies.length} args.`);\n const instance = new classDefinition(...resolvedDependencies);\n\n // Wrap with proxy if tracing is enabled\n let wrappedInstance = instance;\n if (this._enableTracing && futureProxyId !== undefined) {\n wrappedInstance = wrapWithProxy(instance, className, parentProxyId, futureProxyId);\n }\n\n // Overwrite the stored promise with the actual instance *after* it's created\n this.setInstance(classDefinition, wrappedInstance, storageType); // Use the correct storageType\n // console.log(`[IOC LoadClass] Stored actual ${storageType} instance for ${className}`);\n return wrappedInstance;\n } catch (err: any) {\n console.error(`[IOC LoadClass] Error during instantiation of ${className}: ${err.message}`, err.stack);\n // Clean up the stored promise on failure\n if (storageType === 'singleton') this._classStorageSingleton.delete(classDefinition);\n if (storageType === 'scoped') this._classStorageScoped.delete(classDefinition);\n throw err; // Re-throw instantiation error\n }\n })();\n // console.log(`[IOC LoadClass] Storing promise for concurrent requests (${storageType}) for ${className}`);\n this.setInstance(classDefinition, instancePromise, storageType);\n } else {\n // If already has instance (from storage check) or is transient, just instantiate directly\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadClass] Instantiating transient ${className} with ${resolvedDependencies.length} args.`);\n const instance = new classDefinition(...resolvedDependencies);\n\n // Wrap with proxy if tracing is enabled\n let wrappedInstance = instance;\n if (this._enableTracing && futureProxyId !== undefined) {\n wrappedInstance = wrapWithProxy(instance, className, parentProxyId, futureProxyId);\n }\n\n // No storing for transient\n return wrappedInstance;\n } catch (err: any) {\n console.error(`[IOC LoadClass] Error during instantiation of transient ${className}: ${err.message}`, err.stack);\n throw err; // Re-throw instantiation error\n }\n })();\n }\n // --- End Instantiate Class ---\n // Await and return the final instance (either newly created or from the stored promise)\n return await instancePromise;\n });\n\n if(storageType && storageType !== 'transient'){\n this.setInstance(classDefinition, finalInstance, storageType); // Store the promise\n }\n return finalInstance\n }\n\n private loadFunctionInstance(\n funcLabel: any,\n params: ParameterValue<any>[],\n resolutionChain: string[]\n ): Promise<any> { // Always return Promise<any> since this is an async function\n const functionConfig = this._functionDefinition.get(funcLabel)!; // Assumed to exist by caller\n const storageType = this.getStorageType(funcLabel); // Only uses manual options for functions\n const labelStr = String(funcLabel);\n\n // Check storage first\n if (storageType && this.hasInstance(funcLabel)) {\n const instance = this.getInstance(funcLabel);\n // console.log(`[IOC LoadFunc] Found existing ${storageType} instance for ${labelStr}. IsPromise: ${isPromise(instance)}`);\n return instance;\n }\n // console.log(`[IOC LoadFunc] Creating new ${storageType || 'transient'} instance for ${labelStr}`);\n\n const ioc_func = functionConfig.function;\n const options = functionConfig.options;\n const dependenciesToResolve: any[] = options?.param || [];\n\n // --- Resolve Dependencies ---\n const paramsCopy = [...params]; // Create a copy\n const resolutionPromises = dependenciesToResolve.map(dependencyIdentifier =>\n this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain)\n );\n\n let finalInstance = Promise.all(resolutionPromises).catch((error)=>{\n console.error(`[IOC LoadFunc] Failed to resolve dependencies for function ${labelStr}:`, error);\n // Clean up potential partial storage\n if (storageType && this.isRegisteredAsFunction(funcLabel)) {\n if (storageType === 'singleton') this._functionStorageSingleton.delete(funcLabel);\n if (storageType === 'scoped') this._functionStorageScoped.delete(funcLabel);\n }\n throw error;\n }).then(async(resolvedArgs)=>{\n let instancePromise: Promise<any> | undefined;\n if (storageType && !this.hasInstance(funcLabel)) {\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadFunc] Invoking ${labelStr} with ${resolvedArgs.length} args.`);\n const result = await ioc_func.apply(null, resolvedArgs); // Await in case function is async\n // Overwrite stored promise with actual result\n this.setInstance(funcLabel, result, storageType);\n // console.log(`[IOC LoadFunc] Stored actual ${storageType} instance for ${labelStr}`);\n return result;\n } catch (err: any) {\n console.error(`[IOC LoadFunc] Error executing function ${labelStr}: ${err.message}`, err.stack);\n // Clean up stored promise on failure\n if (storageType === 'singleton') this._functionStorageSingleton.delete(funcLabel);\n if (storageType === 'scoped') this._functionStorageScoped.delete(funcLabel);\n throw err;\n }\n })();\n // console.log(`[IOC LoadFunc] Storing promise for concurrent requests (${storageType}) for ${labelStr}`);\n this.setInstance(funcLabel, instancePromise, storageType);\n } else {\n // Transient or already resolved from storage check\n instancePromise = (async () => {\n try {\n // console.log(`[IOC LoadFunc] Invoking transient ${labelStr} with ${resolvedArgs.length} args.`);\n const result = await ioc_func.apply(null, resolvedArgs); // Await in case function is async\n // No storing for transient\n return result;\n } catch (err: any) {\n console.error(`[IOC LoadFunc] Error executing transient function ${labelStr}: ${err.message}`, err.stack);\n throw err;\n }\n })();\n }\n // --- End Invoke Function ---\n\n return await instancePromise; // Return the final (awaited) result\n });\n\n if(storageType && storageType !== 'transient'){\n this.setInstance(funcLabel, finalInstance, storageType); // Store the promise\n }\n\n return finalInstance;\n }\n}\n\n// Helper functions\nexport function isPromise(obj: any): obj is Promise<any> {\n // Simplified check - more robust check might be needed depending on environment\n return !!obj && typeof obj.then === 'function';\n}\n\nexport function createContainer(): IContainerClient & IContainerSetup {\n return new Container();\n}\n"],"mappings":"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","names":["ContainerRouting"]}
@@ -10,11 +10,21 @@ declare class Container implements IContainerClient, IContainerSetup {
10
10
  private _functionStorageScoped;
11
11
  private _classStorageSingleton;
12
12
  private _classStorageScoped;
13
+ private _enableTracing;
14
+ private _traceRetentionMinutes;
13
15
  registerClass<T>(classDefinition: new (...args: any[]) => T, options?: Partial<ContainerOptions>): void;
14
16
  registerFunction<T extends (...arg: any[]) => any>(label: any, func: T, options?: Partial<ContainerOptions>): void;
15
17
  instance<T, Args extends any[]>(classDefinition: new (...args: Args) => T, params?: ParameterValue<any>[]): Promise<T>;
16
18
  get<T>(label: any, param?: ParameterValue<any>[]): Promise<T> | T;
17
19
  extend(): IContainerClient & IContainerSetup;
20
+ setTracingEnabled(enabled: boolean): void;
21
+ isTracingEnabled(): boolean;
22
+ setTraceRetentionMinutes(minutes: number): void;
23
+ getTraces(retentionMinutes?: number): any[];
24
+ getAllTraces(): any[];
25
+ clearTraces(): void;
26
+ exportTraces(filepath: string): void;
27
+ getTraceStatistics(): any;
18
28
  private clearDefinitions;
19
29
  private isRegisteredAsClass;
20
30
  private isRegisteredAsFunction;
@@ -23,7 +33,8 @@ declare class Container implements IContainerClient, IContainerSetup {
23
33
  private getInstance;
24
34
  private setInstance;
25
35
  private getStorageType;
26
- protected loadInstance(label: any, params?: ParameterValue<any>[], resolutionChain?: string[]): Promise<any>;
36
+ protected loadInstance(label: any, params?: ParameterValue<any>[], resolutionChain?: string[], // Track resolution path
37
+ parentProxyId?: number): Promise<any>;
27
38
  private resolveParameterValue;
28
39
  private loadClassInstance;
29
40
  private loadFunctionInstance;
@@ -10,11 +10,21 @@ declare class Container implements IContainerClient, IContainerSetup {
10
10
  private _functionStorageScoped;
11
11
  private _classStorageSingleton;
12
12
  private _classStorageScoped;
13
+ private _enableTracing;
14
+ private _traceRetentionMinutes;
13
15
  registerClass<T>(classDefinition: new (...args: any[]) => T, options?: Partial<ContainerOptions>): void;
14
16
  registerFunction<T extends (...arg: any[]) => any>(label: any, func: T, options?: Partial<ContainerOptions>): void;
15
17
  instance<T, Args extends any[]>(classDefinition: new (...args: Args) => T, params?: ParameterValue<any>[]): Promise<T>;
16
18
  get<T>(label: any, param?: ParameterValue<any>[]): Promise<T> | T;
17
19
  extend(): IContainerClient & IContainerSetup;
20
+ setTracingEnabled(enabled: boolean): void;
21
+ isTracingEnabled(): boolean;
22
+ setTraceRetentionMinutes(minutes: number): void;
23
+ getTraces(retentionMinutes?: number): any[];
24
+ getAllTraces(): any[];
25
+ clearTraces(): void;
26
+ exportTraces(filepath: string): void;
27
+ getTraceStatistics(): any;
18
28
  private clearDefinitions;
19
29
  private isRegisteredAsClass;
20
30
  private isRegisteredAsFunction;
@@ -23,7 +33,8 @@ declare class Container implements IContainerClient, IContainerSetup {
23
33
  private getInstance;
24
34
  private setInstance;
25
35
  private getStorageType;
26
- protected loadInstance(label: any, params?: ParameterValue<any>[], resolutionChain?: string[]): Promise<any>;
36
+ protected loadInstance(label: any, params?: ParameterValue<any>[], resolutionChain?: string[], // Track resolution path
37
+ parentProxyId?: number): Promise<any>;
27
38
  private resolveParameterValue;
28
39
  private loadClassInstance;
29
40
  private loadFunctionInstance;
@@ -7,6 +7,9 @@ import {
7
7
  getComponentOptions,
8
8
  getResolvedDependencies
9
9
  } from "./DecoratorSupport.js";
10
+ import { wrapWithProxy, setTraceLogger, reserveProxyId } from "./ProxyFactory.js";
11
+ import * as TraceLoggerModule from "./TraceLogger.js";
12
+ import { TraceCleanup } from "./TraceCleanup.js";
10
13
  var ContainerRouting = /* @__PURE__ */ ((ContainerRouting2) => {
11
14
  ContainerRouting2["FUNCTIONAL"] = "FUNCTIONAL";
12
15
  ContainerRouting2["CLASS"] = "CLASS";
@@ -23,6 +26,9 @@ class Container {
23
26
  this._functionStorageScoped = /* @__PURE__ */ new Map();
24
27
  this._classStorageSingleton = /* @__PURE__ */ new Map();
25
28
  this._classStorageScoped = /* @__PURE__ */ new Map();
29
+ // Tracing configuration
30
+ this._enableTracing = false;
31
+ this._traceRetentionMinutes = 5;
26
32
  }
27
33
  // Registration methods
28
34
  registerClass(classDefinition, options) {
@@ -59,8 +65,42 @@ class Container {
59
65
  childContainer._classDefinition = new Map(this._classDefinition);
60
66
  childContainer._functionStorageSingleton = this._functionStorageSingleton;
61
67
  childContainer._classStorageSingleton = this._classStorageSingleton;
68
+ childContainer._enableTracing = this._enableTracing;
69
+ childContainer._traceRetentionMinutes = this._traceRetentionMinutes;
62
70
  return childContainer;
63
71
  }
72
+ // Tracing API
73
+ setTracingEnabled(enabled) {
74
+ this._enableTracing = enabled;
75
+ if (enabled && !TraceCleanup.isCleanupRunning()) {
76
+ setTraceLogger(TraceLoggerModule);
77
+ TraceCleanup.start(this._traceRetentionMinutes);
78
+ }
79
+ }
80
+ isTracingEnabled() {
81
+ return this._enableTracing;
82
+ }
83
+ setTraceRetentionMinutes(minutes) {
84
+ this._traceRetentionMinutes = Math.max(1, minutes);
85
+ }
86
+ getTraces(retentionMinutes) {
87
+ const retention = retentionMinutes ?? this._traceRetentionMinutes;
88
+ return TraceLoggerModule.getRecentTraces(retention);
89
+ }
90
+ getAllTraces() {
91
+ return TraceLoggerModule.getAllTraces();
92
+ }
93
+ clearTraces() {
94
+ TraceLoggerModule.clearAllTraces();
95
+ }
96
+ exportTraces(filepath) {
97
+ const data = TraceLoggerModule.exportTracesToJson();
98
+ const fs = require("fs");
99
+ fs.writeFileSync(filepath, JSON.stringify(data, null, 2));
100
+ }
101
+ getTraceStatistics() {
102
+ return TraceLoggerModule.getTraceStatistics();
103
+ }
64
104
  // Private helper methods
65
105
  clearDefinitions(label) {
66
106
  this._routing.delete(label);
@@ -150,7 +190,7 @@ class Container {
150
190
  }
151
191
  }
152
192
  // Central resolution logic
153
- async loadInstance(label, params = [], resolutionChain = []) {
193
+ async loadInstance(label, params = [], resolutionChain = [], parentProxyId) {
154
194
  const currentLabelStr = typeof label === "function" && label.name ? label.name : String(label);
155
195
  if (resolutionChain.includes(currentLabelStr)) {
156
196
  console.error(`[IOC LoadInstance] Circular dependency detected: ${[...resolutionChain, currentLabelStr].join(" -> ")}`);
@@ -165,7 +205,7 @@ class Container {
165
205
  }
166
206
  }
167
207
  if (this.isRegisteredAsClass(label)) {
168
- return this.loadClassInstance(label, params, nextResolutionChain);
208
+ return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);
169
209
  }
170
210
  if (this.isRegisteredAsFunction(label)) {
171
211
  return this.loadFunctionInstance(label, params, nextResolutionChain);
@@ -176,7 +216,7 @@ class Container {
176
216
  if (!this._routing.has(label)) {
177
217
  this._routing.set(label, "CLASS" /* CLASS */);
178
218
  }
179
- return this.loadClassInstance(label, params, nextResolutionChain);
219
+ return this.loadClassInstance(label, params, nextResolutionChain, parentProxyId);
180
220
  }
181
221
  }
182
222
  console.error(`[IOC LoadInstance] Dependency not found and cannot be resolved: ${currentLabelStr}`);
@@ -189,7 +229,7 @@ class Container {
189
229
  }
190
230
  return valueContainer.value;
191
231
  }
192
- loadClassInstance(classDefinition, params, resolutionChain) {
232
+ loadClassInstance(classDefinition, params, resolutionChain, parentProxyId) {
193
233
  const storageType = this.getStorageType(classDefinition);
194
234
  const className = classDefinition.name || "[Anonymous Class]";
195
235
  if (storageType && this.hasInstance(classDefinition)) {
@@ -203,9 +243,13 @@ class Container {
203
243
  } else {
204
244
  dependenciesToResolve = getResolvedDependencies(classDefinition);
205
245
  }
246
+ let futureProxyId;
247
+ if (this._enableTracing) {
248
+ futureProxyId = reserveProxyId();
249
+ }
206
250
  const paramsCopy = [...params];
207
251
  const resolutionPromises = dependenciesToResolve.map(
208
- (dependencyIdentifier) => this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain)
252
+ (dependencyIdentifier) => this.loadInstance(dependencyIdentifier, paramsCopy, resolutionChain, futureProxyId)
209
253
  // Recursive call handles auto-registration
210
254
  );
211
255
  let finalInstance = Promise.all(resolutionPromises).catch((error) => {
@@ -221,8 +265,12 @@ class Container {
221
265
  instancePromise = (async () => {
222
266
  try {
223
267
  const instance = new classDefinition(...resolvedDependencies);
224
- this.setInstance(classDefinition, instance, storageType);
225
- return instance;
268
+ let wrappedInstance = instance;
269
+ if (this._enableTracing && futureProxyId !== void 0) {
270
+ wrappedInstance = wrapWithProxy(instance, className, parentProxyId, futureProxyId);
271
+ }
272
+ this.setInstance(classDefinition, wrappedInstance, storageType);
273
+ return wrappedInstance;
226
274
  } catch (err) {
227
275
  console.error(`[IOC LoadClass] Error during instantiation of ${className}: ${err.message}`, err.stack);
228
276
  if (storageType === "singleton") this._classStorageSingleton.delete(classDefinition);
@@ -235,7 +283,11 @@ class Container {
235
283
  instancePromise = (async () => {
236
284
  try {
237
285
  const instance = new classDefinition(...resolvedDependencies);
238
- return instance;
286
+ let wrappedInstance = instance;
287
+ if (this._enableTracing && futureProxyId !== void 0) {
288
+ wrappedInstance = wrapWithProxy(instance, className, parentProxyId, futureProxyId);
289
+ }
290
+ return wrappedInstance;
239
291
  } catch (err) {
240
292
  console.error(`[IOC LoadClass] Error during instantiation of transient ${className}: ${err.message}`, err.stack);
241
293
  throw err;