@navios/di 0.3.1 → 0.4.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/README.md +67 -6
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +2659 -0
- package/coverage/coverage-final.json +46 -0
- package/coverage/docs/examples/basic-usage.mts.html +376 -0
- package/coverage/docs/examples/factory-pattern.mts.html +1039 -0
- package/coverage/docs/examples/index.html +176 -0
- package/coverage/docs/examples/injection-tokens.mts.html +760 -0
- package/coverage/docs/examples/request-scope-example.mts.html +847 -0
- package/coverage/docs/examples/service-lifecycle.mts.html +1162 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +236 -0
- package/coverage/lib/_tsup-dts-rollup.d.mts.html +2806 -0
- package/coverage/lib/index.d.mts.html +310 -0
- package/coverage/lib/index.html +131 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/src/container.mts.html +586 -0
- package/coverage/src/decorators/factory.decorator.mts.html +322 -0
- package/coverage/src/decorators/index.html +146 -0
- package/coverage/src/decorators/index.mts.html +91 -0
- package/coverage/src/decorators/injectable.decorator.mts.html +394 -0
- package/coverage/src/enums/index.html +146 -0
- package/coverage/src/enums/index.mts.html +91 -0
- package/coverage/src/enums/injectable-scope.enum.mts.html +127 -0
- package/coverage/src/enums/injectable-type.enum.mts.html +97 -0
- package/coverage/src/errors/errors.enum.mts.html +109 -0
- package/coverage/src/errors/factory-not-found.mts.html +109 -0
- package/coverage/src/errors/factory-token-not-resolved.mts.html +115 -0
- package/coverage/src/errors/index.html +221 -0
- package/coverage/src/errors/index.mts.html +106 -0
- package/coverage/src/errors/instance-destroying.mts.html +109 -0
- package/coverage/src/errors/instance-expired.mts.html +109 -0
- package/coverage/src/errors/instance-not-found.mts.html +109 -0
- package/coverage/src/errors/unknown-error.mts.html +130 -0
- package/coverage/src/event-emitter.mts.html +400 -0
- package/coverage/src/factory-context.mts.html +109 -0
- package/coverage/src/index.html +296 -0
- package/coverage/src/index.mts.html +139 -0
- package/coverage/src/injection-token.mts.html +571 -0
- package/coverage/src/injector.mts.html +133 -0
- package/coverage/src/interfaces/factory.interface.mts.html +121 -0
- package/coverage/src/interfaces/index.html +161 -0
- package/coverage/src/interfaces/index.mts.html +94 -0
- package/coverage/src/interfaces/on-service-destroy.interface.mts.html +94 -0
- package/coverage/src/interfaces/on-service-init.interface.mts.html +94 -0
- package/coverage/src/registry.mts.html +247 -0
- package/coverage/src/request-context-holder.mts.html +607 -0
- package/coverage/src/service-instantiator.mts.html +559 -0
- package/coverage/src/service-locator-event-bus.mts.html +289 -0
- package/coverage/src/service-locator-instance-holder.mts.html +307 -0
- package/coverage/src/service-locator-manager.mts.html +604 -0
- package/coverage/src/service-locator.mts.html +2911 -0
- package/coverage/src/symbols/index.html +131 -0
- package/coverage/src/symbols/index.mts.html +88 -0
- package/coverage/src/symbols/injectable-token.mts.html +88 -0
- package/coverage/src/utils/defer.mts.html +304 -0
- package/coverage/src/utils/get-injectable-token.mts.html +142 -0
- package/coverage/src/utils/get-injectors.mts.html +691 -0
- package/coverage/src/utils/index.html +176 -0
- package/coverage/src/utils/index.mts.html +97 -0
- package/coverage/src/utils/types.mts.html +241 -0
- package/docs/README.md +5 -2
- package/docs/api-reference.md +38 -0
- package/docs/container.md +75 -0
- package/docs/getting-started.md +4 -3
- package/docs/injectable.md +4 -3
- package/docs/migration.md +177 -0
- package/docs/request-contexts.md +364 -0
- package/lib/_tsup-dts-rollup.d.mts +177 -36
- package/lib/_tsup-dts-rollup.d.ts +177 -36
- package/lib/index.d.mts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +480 -294
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +480 -295
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/defer.spec.mts +166 -0
- package/src/__tests__/errors.spec.mts +61 -0
- package/src/__tests__/event-emitter.spec.mts +163 -0
- package/src/__tests__/get-injectors.spec.mts +70 -0
- package/src/__tests__/registry.spec.mts +335 -0
- package/src/__tests__/request-scope.spec.mts +34 -35
- package/src/__tests__/service-instantiator.spec.mts +408 -0
- package/src/__tests__/service-locator-event-bus.spec.mts +242 -0
- package/src/__tests__/service-locator-manager.spec.mts +370 -0
- package/src/__tests__/unified-api.spec.mts +130 -0
- package/src/base-instance-holder-manager.mts +175 -0
- package/src/index.mts +1 -0
- package/src/request-context-holder.mts +73 -44
- package/src/service-locator-manager.mts +12 -70
- package/src/service-locator.mts +421 -226
package/lib/index.js
CHANGED
|
@@ -33,18 +33,18 @@ var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
// src/enums/injectable-scope.enum.mts
|
|
36
|
-
var InjectableScope = /* @__PURE__ */ ((
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return
|
|
36
|
+
var InjectableScope = /* @__PURE__ */ ((InjectableScope5) => {
|
|
37
|
+
InjectableScope5["Singleton"] = "Singleton";
|
|
38
|
+
InjectableScope5["Transient"] = "Transient";
|
|
39
|
+
InjectableScope5["Request"] = "Request";
|
|
40
|
+
return InjectableScope5;
|
|
41
41
|
})(InjectableScope || {});
|
|
42
42
|
|
|
43
43
|
// src/enums/injectable-type.enum.mts
|
|
44
|
-
var InjectableType = /* @__PURE__ */ ((
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return
|
|
44
|
+
var InjectableType = /* @__PURE__ */ ((InjectableType5) => {
|
|
45
|
+
InjectableType5["Class"] = "Class";
|
|
46
|
+
InjectableType5["Factory"] = "Factory";
|
|
47
|
+
return InjectableType5;
|
|
48
48
|
})(InjectableType || {});
|
|
49
49
|
|
|
50
50
|
// src/injection-token.mts
|
|
@@ -439,6 +439,132 @@ function createDeferred() {
|
|
|
439
439
|
return new Deferred();
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
+
// src/service-locator-instance-holder.mts
|
|
443
|
+
var ServiceLocatorInstanceHolderStatus = /* @__PURE__ */ ((ServiceLocatorInstanceHolderStatus3) => {
|
|
444
|
+
ServiceLocatorInstanceHolderStatus3["Created"] = "created";
|
|
445
|
+
ServiceLocatorInstanceHolderStatus3["Creating"] = "creating";
|
|
446
|
+
ServiceLocatorInstanceHolderStatus3["Destroying"] = "destroying";
|
|
447
|
+
ServiceLocatorInstanceHolderStatus3["Error"] = "error";
|
|
448
|
+
return ServiceLocatorInstanceHolderStatus3;
|
|
449
|
+
})(ServiceLocatorInstanceHolderStatus || {});
|
|
450
|
+
|
|
451
|
+
// src/base-instance-holder-manager.mts
|
|
452
|
+
var BaseInstanceHolderManager = class {
|
|
453
|
+
constructor(logger = null) {
|
|
454
|
+
this.logger = logger;
|
|
455
|
+
this._holders = /* @__PURE__ */ new Map();
|
|
456
|
+
}
|
|
457
|
+
_holders;
|
|
458
|
+
/**
|
|
459
|
+
* Protected getter for accessing the holders map from subclasses.
|
|
460
|
+
*/
|
|
461
|
+
get holders() {
|
|
462
|
+
return this._holders;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Deletes a holder by name.
|
|
466
|
+
* @param name The name of the holder to delete
|
|
467
|
+
* @returns true if the holder was deleted, false if it didn't exist
|
|
468
|
+
*/
|
|
469
|
+
delete(name) {
|
|
470
|
+
return this._holders.delete(name);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Filters holders based on a predicate function.
|
|
474
|
+
* @param predicate Function to test each holder
|
|
475
|
+
* @returns A new Map containing only the holders that match the predicate
|
|
476
|
+
*/
|
|
477
|
+
filter(predicate) {
|
|
478
|
+
return new Map(
|
|
479
|
+
[...this._holders].filter(([key, value]) => predicate(value, key))
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Clears all holders from this manager.
|
|
484
|
+
*/
|
|
485
|
+
clear() {
|
|
486
|
+
this._holders.clear();
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Gets the number of holders currently managed.
|
|
490
|
+
*/
|
|
491
|
+
size() {
|
|
492
|
+
return this._holders.size;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Creates a new holder with Creating status and a deferred creation promise.
|
|
496
|
+
* This is useful for creating placeholder holders that can be fulfilled later.
|
|
497
|
+
* @param name The name of the instance
|
|
498
|
+
* @param type The injectable type
|
|
499
|
+
* @param scope The injectable scope
|
|
500
|
+
* @param deps Optional set of dependencies
|
|
501
|
+
* @param ttl Optional time-to-live in milliseconds (defaults to Infinity)
|
|
502
|
+
* @returns A tuple containing the deferred promise and the holder
|
|
503
|
+
*/
|
|
504
|
+
createCreatingHolder(name, type, scope, deps = /* @__PURE__ */ new Set(), ttl = Infinity) {
|
|
505
|
+
const deferred = createDeferred();
|
|
506
|
+
const holder = {
|
|
507
|
+
status: "creating" /* Creating */,
|
|
508
|
+
name,
|
|
509
|
+
instance: null,
|
|
510
|
+
creationPromise: deferred.promise,
|
|
511
|
+
destroyPromise: null,
|
|
512
|
+
type,
|
|
513
|
+
scope,
|
|
514
|
+
deps,
|
|
515
|
+
destroyListeners: [],
|
|
516
|
+
createdAt: Date.now(),
|
|
517
|
+
ttl
|
|
518
|
+
};
|
|
519
|
+
return [deferred, holder];
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Creates a new holder with Created status and an actual instance.
|
|
523
|
+
* This is useful for creating holders that already have their instance ready.
|
|
524
|
+
* @param name The name of the instance
|
|
525
|
+
* @param instance The actual instance to store
|
|
526
|
+
* @param type The injectable type
|
|
527
|
+
* @param scope The injectable scope
|
|
528
|
+
* @param deps Optional set of dependencies
|
|
529
|
+
* @param ttl Optional time-to-live in milliseconds (defaults to Infinity)
|
|
530
|
+
* @returns The created holder
|
|
531
|
+
*/
|
|
532
|
+
createCreatedHolder(name, instance, type, scope, deps = /* @__PURE__ */ new Set(), ttl = Infinity) {
|
|
533
|
+
const holder = {
|
|
534
|
+
status: "created" /* Created */,
|
|
535
|
+
name,
|
|
536
|
+
instance,
|
|
537
|
+
creationPromise: null,
|
|
538
|
+
destroyPromise: null,
|
|
539
|
+
type,
|
|
540
|
+
scope,
|
|
541
|
+
deps,
|
|
542
|
+
destroyListeners: [],
|
|
543
|
+
createdAt: Date.now(),
|
|
544
|
+
ttl
|
|
545
|
+
};
|
|
546
|
+
return holder;
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Gets all holder names currently managed.
|
|
550
|
+
*/
|
|
551
|
+
getAllNames() {
|
|
552
|
+
return Array.from(this._holders.keys());
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Gets all holders currently managed.
|
|
556
|
+
*/
|
|
557
|
+
getAllHolders() {
|
|
558
|
+
return Array.from(this._holders.values());
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Checks if this manager has any holders.
|
|
562
|
+
*/
|
|
563
|
+
isEmpty() {
|
|
564
|
+
return this._holders.size === 0;
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
|
|
442
568
|
// src/event-emitter.mts
|
|
443
569
|
var _EventEmitter_decorators, _init;
|
|
444
570
|
_EventEmitter_decorators = [Injectable({ scope: "Transient" /* Transient */ })];
|
|
@@ -619,18 +745,10 @@ var ServiceInstantiator = class {
|
|
|
619
745
|
}
|
|
620
746
|
};
|
|
621
747
|
|
|
622
|
-
// src/service-locator-instance-holder.mts
|
|
623
|
-
var ServiceLocatorInstanceHolderStatus = /* @__PURE__ */ ((ServiceLocatorInstanceHolderStatus2) => {
|
|
624
|
-
ServiceLocatorInstanceHolderStatus2["Created"] = "created";
|
|
625
|
-
ServiceLocatorInstanceHolderStatus2["Creating"] = "creating";
|
|
626
|
-
ServiceLocatorInstanceHolderStatus2["Destroying"] = "destroying";
|
|
627
|
-
ServiceLocatorInstanceHolderStatus2["Error"] = "error";
|
|
628
|
-
return ServiceLocatorInstanceHolderStatus2;
|
|
629
|
-
})(ServiceLocatorInstanceHolderStatus || {});
|
|
630
|
-
|
|
631
748
|
// src/request-context-holder.mts
|
|
632
|
-
var DefaultRequestContextHolder = class {
|
|
749
|
+
var DefaultRequestContextHolder = class extends BaseInstanceHolderManager {
|
|
633
750
|
constructor(requestId, priority = 100, initialMetadata) {
|
|
751
|
+
super(null);
|
|
634
752
|
this.requestId = requestId;
|
|
635
753
|
this.priority = priority;
|
|
636
754
|
if (initialMetadata) {
|
|
@@ -639,46 +757,53 @@ var DefaultRequestContextHolder = class {
|
|
|
639
757
|
});
|
|
640
758
|
}
|
|
641
759
|
}
|
|
642
|
-
instances = /* @__PURE__ */ new Map();
|
|
643
|
-
holders = /* @__PURE__ */ new Map();
|
|
644
760
|
metadata = /* @__PURE__ */ new Map();
|
|
645
761
|
createdAt = Date.now();
|
|
762
|
+
/**
|
|
763
|
+
* Public getter for holders to maintain interface compatibility.
|
|
764
|
+
*/
|
|
765
|
+
get holders() {
|
|
766
|
+
return this._holders;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Gets a holder by name. For RequestContextHolder, this is a simple lookup.
|
|
770
|
+
*/
|
|
771
|
+
get(name) {
|
|
772
|
+
return this._holders.get(name);
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Sets a holder by name.
|
|
776
|
+
*/
|
|
777
|
+
set(name, holder) {
|
|
778
|
+
this._holders.set(name, holder);
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Checks if a holder exists by name.
|
|
782
|
+
*/
|
|
783
|
+
has(name) {
|
|
784
|
+
return this._holders.has(name);
|
|
785
|
+
}
|
|
646
786
|
addInstance(instanceName, instance, holder) {
|
|
647
787
|
if (instanceName instanceof InjectionToken) {
|
|
648
|
-
|
|
649
|
-
this.
|
|
788
|
+
const name = instanceName.toString();
|
|
789
|
+
const createdHolder = this.createCreatedHolder(
|
|
790
|
+
name,
|
|
650
791
|
instance,
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
type: "Class" /* Class */,
|
|
658
|
-
scope: "Singleton" /* Singleton */,
|
|
659
|
-
createdAt: Date.now(),
|
|
660
|
-
ttl: Infinity
|
|
661
|
-
});
|
|
792
|
+
"Class" /* Class */,
|
|
793
|
+
"Singleton" /* Singleton */,
|
|
794
|
+
/* @__PURE__ */ new Set(),
|
|
795
|
+
Infinity
|
|
796
|
+
);
|
|
797
|
+
this._holders.set(name, createdHolder);
|
|
662
798
|
} else {
|
|
663
799
|
if (!holder) {
|
|
664
800
|
throw new Error("Holder is required when adding an instance by name");
|
|
665
801
|
}
|
|
666
|
-
this.
|
|
667
|
-
this.holders.set(instanceName, holder);
|
|
802
|
+
this._holders.set(instanceName, holder);
|
|
668
803
|
}
|
|
669
804
|
}
|
|
670
|
-
getInstance(instanceName) {
|
|
671
|
-
return this.instances.get(instanceName);
|
|
672
|
-
}
|
|
673
|
-
getHolder(instanceName) {
|
|
674
|
-
return this.holders.get(instanceName);
|
|
675
|
-
}
|
|
676
|
-
hasInstance(instanceName) {
|
|
677
|
-
return this.instances.has(instanceName);
|
|
678
|
-
}
|
|
679
805
|
clear() {
|
|
680
|
-
|
|
681
|
-
this.holders.clear();
|
|
806
|
+
super.clear();
|
|
682
807
|
this.metadata.clear();
|
|
683
808
|
}
|
|
684
809
|
getMetadata(key) {
|
|
@@ -744,13 +869,12 @@ var ServiceLocatorEventBus = class {
|
|
|
744
869
|
};
|
|
745
870
|
|
|
746
871
|
// src/service-locator-manager.mts
|
|
747
|
-
var ServiceLocatorManager = class {
|
|
872
|
+
var ServiceLocatorManager = class extends BaseInstanceHolderManager {
|
|
748
873
|
constructor(logger = null) {
|
|
749
|
-
|
|
874
|
+
super(logger);
|
|
750
875
|
}
|
|
751
|
-
instancesHolders = /* @__PURE__ */ new Map();
|
|
752
876
|
get(name) {
|
|
753
|
-
const holder = this.
|
|
877
|
+
const holder = this._holders.get(name);
|
|
754
878
|
if (holder) {
|
|
755
879
|
if (holder.ttl !== Infinity) {
|
|
756
880
|
const now = Date.now();
|
|
@@ -780,7 +904,7 @@ var ServiceLocatorManager = class {
|
|
|
780
904
|
}
|
|
781
905
|
}
|
|
782
906
|
set(name, holder) {
|
|
783
|
-
this.
|
|
907
|
+
this._holders.set(name, holder);
|
|
784
908
|
}
|
|
785
909
|
has(name) {
|
|
786
910
|
const [error, holder] = this.get(name);
|
|
@@ -794,43 +918,8 @@ var ServiceLocatorManager = class {
|
|
|
794
918
|
}
|
|
795
919
|
return [void 0, !!holder];
|
|
796
920
|
}
|
|
797
|
-
delete
|
|
798
|
-
|
|
799
|
-
}
|
|
800
|
-
filter(predicate) {
|
|
801
|
-
return new Map(
|
|
802
|
-
[...this.instancesHolders].filter(
|
|
803
|
-
([key, value]) => predicate(value, key)
|
|
804
|
-
)
|
|
805
|
-
);
|
|
806
|
-
}
|
|
807
|
-
/**
|
|
808
|
-
* Creates a new holder with Creating status and a deferred creation promise.
|
|
809
|
-
* This is useful for creating placeholder holders that can be fulfilled later.
|
|
810
|
-
* @param name The name of the instance
|
|
811
|
-
* @param type The injectable type
|
|
812
|
-
* @param scope The injectable scope
|
|
813
|
-
* @param deps Optional set of dependencies
|
|
814
|
-
* @param ttl Optional time-to-live in milliseconds (defaults to Infinity)
|
|
815
|
-
* @returns A tuple containing the deferred promise and the holder
|
|
816
|
-
*/
|
|
817
|
-
createCreatingHolder(name, type, scope, deps = /* @__PURE__ */ new Set(), ttl = Infinity) {
|
|
818
|
-
const deferred = createDeferred();
|
|
819
|
-
const holder = {
|
|
820
|
-
status: "creating" /* Creating */,
|
|
821
|
-
name,
|
|
822
|
-
instance: null,
|
|
823
|
-
creationPromise: deferred.promise,
|
|
824
|
-
destroyPromise: null,
|
|
825
|
-
type,
|
|
826
|
-
scope,
|
|
827
|
-
deps,
|
|
828
|
-
destroyListeners: [],
|
|
829
|
-
createdAt: Date.now(),
|
|
830
|
-
ttl
|
|
831
|
-
};
|
|
832
|
-
return [deferred, holder];
|
|
833
|
-
}
|
|
921
|
+
// delete and filter methods are inherited from BaseInstanceHolderManager
|
|
922
|
+
// createCreatingHolder method is inherited from BaseInstanceHolderManager
|
|
834
923
|
/**
|
|
835
924
|
* Creates a new holder with Created status and an actual instance.
|
|
836
925
|
* This is useful for creating holders that already have their instance ready.
|
|
@@ -843,20 +932,15 @@ var ServiceLocatorManager = class {
|
|
|
843
932
|
* @returns The created holder
|
|
844
933
|
*/
|
|
845
934
|
storeCreatedHolder(name, instance, type, scope, deps = /* @__PURE__ */ new Set(), ttl = Infinity) {
|
|
846
|
-
const holder =
|
|
847
|
-
status: "created" /* Created */,
|
|
935
|
+
const holder = this.createCreatedHolder(
|
|
848
936
|
name,
|
|
849
937
|
instance,
|
|
850
|
-
creationPromise: null,
|
|
851
|
-
destroyPromise: null,
|
|
852
938
|
type,
|
|
853
939
|
scope,
|
|
854
940
|
deps,
|
|
855
|
-
destroyListeners: [],
|
|
856
|
-
createdAt: Date.now(),
|
|
857
941
|
ttl
|
|
858
|
-
|
|
859
|
-
this.
|
|
942
|
+
);
|
|
943
|
+
this._holders.set(name, holder);
|
|
860
944
|
return holder;
|
|
861
945
|
}
|
|
862
946
|
};
|
|
@@ -901,9 +985,7 @@ var ServiceLocator = class {
|
|
|
901
985
|
return [err];
|
|
902
986
|
}
|
|
903
987
|
const { instanceName, validatedArgs, actualToken, realToken } = data;
|
|
904
|
-
|
|
905
|
-
onPrepare({ instanceName, actualToken, validatedArgs });
|
|
906
|
-
}
|
|
988
|
+
onPrepare?.({ instanceName, actualToken, validatedArgs });
|
|
907
989
|
const [error, holder] = await this.retrieveOrCreateInstanceByInstanceName(
|
|
908
990
|
instanceName,
|
|
909
991
|
realToken,
|
|
@@ -928,7 +1010,7 @@ var ServiceLocator = class {
|
|
|
928
1010
|
}
|
|
929
1011
|
const instanceName = this.generateInstanceName(actualToken, validatedArgs);
|
|
930
1012
|
if (this.currentRequestContext) {
|
|
931
|
-
const requestHolder = this.currentRequestContext.
|
|
1013
|
+
const requestHolder = this.currentRequestContext.get(instanceName);
|
|
932
1014
|
if (requestHolder) {
|
|
933
1015
|
return requestHolder.instance;
|
|
934
1016
|
}
|
|
@@ -941,63 +1023,80 @@ var ServiceLocator = class {
|
|
|
941
1023
|
}
|
|
942
1024
|
invalidate(service, round = 1) {
|
|
943
1025
|
this.logger?.log(
|
|
944
|
-
`[ServiceLocator]
|
|
1026
|
+
`[ServiceLocator] Starting invalidation process for ${service}`
|
|
945
1027
|
);
|
|
946
1028
|
const toInvalidate = this.manager.filter(
|
|
947
1029
|
(holder) => holder.name === service || holder.deps.has(service)
|
|
948
1030
|
);
|
|
949
1031
|
const promises = [];
|
|
950
1032
|
for (const [key, holder] of toInvalidate.entries()) {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1033
|
+
promises.push(this.invalidateHolder(key, holder, round));
|
|
1034
|
+
}
|
|
1035
|
+
return Promise.all(promises);
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Invalidates a single holder based on its current status.
|
|
1039
|
+
*/
|
|
1040
|
+
async invalidateHolder(key, holder, round) {
|
|
1041
|
+
switch (holder.status) {
|
|
1042
|
+
case "destroying" /* Destroying */:
|
|
1043
|
+
this.logger?.trace(`[ServiceLocator] ${key} is already being destroyed`);
|
|
1044
|
+
await holder.destroyPromise;
|
|
1045
|
+
break;
|
|
1046
|
+
case "creating" /* Creating */:
|
|
959
1047
|
this.logger?.trace(
|
|
960
|
-
`[ServiceLocator]
|
|
961
|
-
);
|
|
962
|
-
promises.push(
|
|
963
|
-
holder.creationPromise?.then(() => {
|
|
964
|
-
if (round > 3) {
|
|
965
|
-
this.logger?.error(
|
|
966
|
-
`[ServiceLocator]#invalidate(): ${key} creation is triggering a new invalidation round, but it is still not created`
|
|
967
|
-
);
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
return this.invalidate(key, round + 1);
|
|
971
|
-
})
|
|
1048
|
+
`[ServiceLocator] ${key} is being created, waiting...`
|
|
972
1049
|
);
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
await this.
|
|
984
|
-
|
|
985
|
-
promises.push(holder.destroyPromise);
|
|
1050
|
+
await holder.creationPromise;
|
|
1051
|
+
if (round > 3) {
|
|
1052
|
+
this.logger?.error(
|
|
1053
|
+
`[ServiceLocator] ${key} creation triggered too many invalidation rounds`
|
|
1054
|
+
);
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
await this.invalidate(key, round + 1);
|
|
1058
|
+
break;
|
|
1059
|
+
default:
|
|
1060
|
+
await this.destroyHolder(key, holder);
|
|
1061
|
+
break;
|
|
986
1062
|
}
|
|
987
|
-
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Destroys a holder and cleans up its resources.
|
|
1066
|
+
*/
|
|
1067
|
+
async destroyHolder(key, holder) {
|
|
1068
|
+
holder.status = "destroying" /* Destroying */;
|
|
1069
|
+
this.logger?.log(
|
|
1070
|
+
`[ServiceLocator] Invalidating ${key} and notifying listeners`
|
|
1071
|
+
);
|
|
1072
|
+
holder.destroyPromise = Promise.all(
|
|
1073
|
+
holder.destroyListeners.map((listener) => listener())
|
|
1074
|
+
).then(async () => {
|
|
1075
|
+
this.manager.delete(key);
|
|
1076
|
+
await this.emitInstanceEvent(key, "destroy");
|
|
1077
|
+
});
|
|
1078
|
+
await holder.destroyPromise;
|
|
988
1079
|
}
|
|
989
1080
|
async ready() {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1081
|
+
const holders = Array.from(this.manager.filter(() => true)).map(
|
|
1082
|
+
([, holder]) => holder
|
|
1083
|
+
);
|
|
1084
|
+
await Promise.all(
|
|
1085
|
+
holders.map((holder) => this.waitForHolderToSettle(holder))
|
|
1086
|
+
);
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Waits for a holder to settle (either created, destroyed, or error state).
|
|
1090
|
+
*/
|
|
1091
|
+
async waitForHolderToSettle(holder) {
|
|
1092
|
+
switch (holder.status) {
|
|
1093
|
+
case "creating" /* Creating */:
|
|
1094
|
+
await holder.creationPromise;
|
|
1095
|
+
break;
|
|
1096
|
+
case "destroying" /* Destroying */:
|
|
1097
|
+
await holder.destroyPromise;
|
|
1098
|
+
break;
|
|
1099
|
+
}
|
|
1001
1100
|
}
|
|
1002
1101
|
// ============================================================================
|
|
1003
1102
|
// REQUEST CONTEXT MANAGEMENT
|
|
@@ -1129,86 +1228,106 @@ var ServiceLocator = class {
|
|
|
1129
1228
|
* Gets an instance by its instance name, handling all the logic after instance name creation.
|
|
1130
1229
|
*/
|
|
1131
1230
|
async retrieveOrCreateInstanceByInstanceName(instanceName, realToken, realArgs) {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
);
|
|
1139
|
-
return [new UnknownError("InstanceNotFound" /* InstanceNotFound */)];
|
|
1140
|
-
}
|
|
1141
|
-
const requestHolder = this.currentRequestContext.getHolder(instanceName);
|
|
1142
|
-
if (requestHolder) {
|
|
1143
|
-
if (requestHolder.status === "creating" /* Creating */) {
|
|
1144
|
-
await requestHolder.creationPromise;
|
|
1145
|
-
return this.retrieveOrCreateInstanceByInstanceName(
|
|
1146
|
-
instanceName,
|
|
1147
|
-
realToken,
|
|
1148
|
-
realArgs
|
|
1149
|
-
);
|
|
1150
|
-
} else if (requestHolder.status === "destroying" /* Destroying */) {
|
|
1151
|
-
return [new UnknownError("InstanceDestroying" /* InstanceDestroying */)];
|
|
1152
|
-
}
|
|
1153
|
-
return [void 0, requestHolder];
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1231
|
+
const existingHolder = await this.tryGetExistingInstance(
|
|
1232
|
+
instanceName,
|
|
1233
|
+
realToken
|
|
1234
|
+
);
|
|
1235
|
+
if (existingHolder) {
|
|
1236
|
+
return existingHolder;
|
|
1156
1237
|
}
|
|
1238
|
+
const result = await this.createNewInstance(
|
|
1239
|
+
instanceName,
|
|
1240
|
+
realToken,
|
|
1241
|
+
realArgs
|
|
1242
|
+
);
|
|
1243
|
+
if (result[0]) {
|
|
1244
|
+
return [result[0]];
|
|
1245
|
+
}
|
|
1246
|
+
const [, holder] = result;
|
|
1247
|
+
return this.waitForInstanceReady(holder);
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Attempts to retrieve an existing instance, handling request-scoped and singleton instances.
|
|
1251
|
+
* Returns null if no instance exists and a new one should be created.
|
|
1252
|
+
*/
|
|
1253
|
+
async tryGetExistingInstance(instanceName, realToken) {
|
|
1254
|
+
const requestResult = await this.tryGetRequestScopedInstance(
|
|
1255
|
+
instanceName,
|
|
1256
|
+
realToken
|
|
1257
|
+
);
|
|
1258
|
+
if (requestResult) {
|
|
1259
|
+
return requestResult;
|
|
1260
|
+
}
|
|
1261
|
+
return this.tryGetSingletonInstance(instanceName);
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Attempts to get a request-scoped instance if applicable.
|
|
1265
|
+
*/
|
|
1266
|
+
async tryGetRequestScopedInstance(instanceName, realToken) {
|
|
1267
|
+
if (!this.registry.has(realToken)) {
|
|
1268
|
+
return null;
|
|
1269
|
+
}
|
|
1270
|
+
const record = this.registry.get(realToken);
|
|
1271
|
+
if (record.scope !== "Request" /* Request */) {
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
if (!this.currentRequestContext) {
|
|
1275
|
+
this.logger?.log(
|
|
1276
|
+
`[ServiceLocator] No current request context available for request-scoped service ${instanceName}`
|
|
1277
|
+
);
|
|
1278
|
+
return [new UnknownError("InstanceNotFound" /* InstanceNotFound */)];
|
|
1279
|
+
}
|
|
1280
|
+
const requestHolder = this.currentRequestContext.get(instanceName);
|
|
1281
|
+
if (!requestHolder) {
|
|
1282
|
+
return null;
|
|
1283
|
+
}
|
|
1284
|
+
return this.waitForInstanceReady(requestHolder);
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Attempts to get a singleton instance from the manager.
|
|
1288
|
+
*/
|
|
1289
|
+
async tryGetSingletonInstance(instanceName) {
|
|
1157
1290
|
const [error, holder] = this.manager.get(instanceName);
|
|
1158
1291
|
if (!error) {
|
|
1159
|
-
|
|
1160
|
-
await holder.creationPromise;
|
|
1161
|
-
return this.retrieveOrCreateInstanceByInstanceName(
|
|
1162
|
-
instanceName,
|
|
1163
|
-
realToken,
|
|
1164
|
-
realArgs
|
|
1165
|
-
);
|
|
1166
|
-
} else if (holder.status === "destroying" /* Destroying */) {
|
|
1167
|
-
return [new UnknownError("InstanceDestroying" /* InstanceDestroying */)];
|
|
1168
|
-
}
|
|
1169
|
-
return [void 0, holder];
|
|
1292
|
+
return this.waitForInstanceReady(holder);
|
|
1170
1293
|
}
|
|
1171
1294
|
switch (error.code) {
|
|
1172
1295
|
case "InstanceDestroying" /* InstanceDestroying */:
|
|
1173
1296
|
this.logger?.log(
|
|
1174
|
-
`[ServiceLocator]
|
|
1297
|
+
`[ServiceLocator] Instance ${instanceName} is being destroyed, waiting...`
|
|
1175
1298
|
);
|
|
1176
1299
|
await holder?.destroyPromise;
|
|
1177
|
-
return this.
|
|
1178
|
-
instanceName,
|
|
1179
|
-
realToken,
|
|
1180
|
-
realArgs
|
|
1181
|
-
);
|
|
1300
|
+
return this.tryGetSingletonInstance(instanceName);
|
|
1182
1301
|
case "InstanceExpired" /* InstanceExpired */:
|
|
1183
1302
|
this.logger?.log(
|
|
1184
|
-
`[ServiceLocator]
|
|
1303
|
+
`[ServiceLocator] Instance ${instanceName} expired, invalidating...`
|
|
1185
1304
|
);
|
|
1186
1305
|
await this.invalidate(instanceName);
|
|
1187
|
-
return this.
|
|
1188
|
-
instanceName,
|
|
1189
|
-
realToken,
|
|
1190
|
-
realArgs
|
|
1191
|
-
);
|
|
1306
|
+
return this.tryGetSingletonInstance(instanceName);
|
|
1192
1307
|
case "InstanceNotFound" /* InstanceNotFound */:
|
|
1193
|
-
|
|
1308
|
+
return null;
|
|
1309
|
+
// Instance doesn't exist, should create new one
|
|
1194
1310
|
default:
|
|
1195
1311
|
return [error];
|
|
1196
1312
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Waits for an instance holder to be ready and returns the appropriate result.
|
|
1316
|
+
*/
|
|
1317
|
+
async waitForInstanceReady(holder) {
|
|
1318
|
+
switch (holder.status) {
|
|
1319
|
+
case "creating" /* Creating */:
|
|
1320
|
+
await holder.creationPromise;
|
|
1321
|
+
return this.waitForInstanceReady(holder);
|
|
1322
|
+
case "destroying" /* Destroying */:
|
|
1323
|
+
return [new UnknownError("InstanceDestroying" /* InstanceDestroying */)];
|
|
1324
|
+
case "error" /* Error */:
|
|
1325
|
+
return [holder.instance];
|
|
1326
|
+
case "created" /* Created */:
|
|
1327
|
+
return [void 0, holder];
|
|
1328
|
+
default:
|
|
1329
|
+
return [new UnknownError("InstanceNotFound" /* InstanceNotFound */)];
|
|
1210
1330
|
}
|
|
1211
|
-
return [void 0, result[1]];
|
|
1212
1331
|
}
|
|
1213
1332
|
/**
|
|
1214
1333
|
* Emits events to listeners for instance lifecycle events.
|
|
@@ -1256,65 +1375,137 @@ var ServiceLocator = class {
|
|
|
1256
1375
|
Infinity
|
|
1257
1376
|
);
|
|
1258
1377
|
this.serviceInstantiator.instantiateService(ctx, record, args).then(async ([error, instance]) => {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
holder.status = "created" /* Created */;
|
|
1275
|
-
if (ctx.deps.size > 0) {
|
|
1276
|
-
ctx.deps.forEach((dependency) => {
|
|
1277
|
-
holder.destroyListeners.push(
|
|
1278
|
-
this.eventBus.on(
|
|
1279
|
-
dependency,
|
|
1280
|
-
"destroy",
|
|
1281
|
-
() => this.invalidate(instanceName)
|
|
1282
|
-
)
|
|
1283
|
-
);
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1286
|
-
await this.emitInstanceEvent(instanceName);
|
|
1287
|
-
deferred.resolve([void 0, instance]);
|
|
1288
|
-
}
|
|
1289
|
-
}).catch((error) => {
|
|
1290
|
-
this.logger?.error(
|
|
1291
|
-
`[ServiceLocator]#instantiateServiceFromRegistry(): Unexpected error creating instance for ${instanceName}`,
|
|
1378
|
+
await this.handleInstantiationResult(
|
|
1379
|
+
instanceName,
|
|
1380
|
+
holder,
|
|
1381
|
+
ctx,
|
|
1382
|
+
deferred,
|
|
1383
|
+
scope,
|
|
1384
|
+
error,
|
|
1385
|
+
instance
|
|
1386
|
+
);
|
|
1387
|
+
}).catch(async (error) => {
|
|
1388
|
+
await this.handleInstantiationError(
|
|
1389
|
+
instanceName,
|
|
1390
|
+
holder,
|
|
1391
|
+
deferred,
|
|
1392
|
+
scope,
|
|
1292
1393
|
error
|
|
1293
1394
|
);
|
|
1294
|
-
holder.status = "error" /* Error */;
|
|
1295
|
-
holder.instance = error;
|
|
1296
|
-
holder.creationPromise = null;
|
|
1297
|
-
if (scope === "Singleton" /* Singleton */) {
|
|
1298
|
-
setTimeout(() => this.invalidate(instanceName), 10);
|
|
1299
|
-
}
|
|
1300
|
-
deferred.reject(error);
|
|
1301
1395
|
});
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1396
|
+
this.storeInstanceByScope(scope, instanceName, holder);
|
|
1397
|
+
return [void 0, holder];
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Handles the result of service instantiation.
|
|
1401
|
+
*/
|
|
1402
|
+
async handleInstantiationResult(instanceName, holder, ctx, deferred, scope, error, instance) {
|
|
1403
|
+
holder.destroyListeners = ctx.getDestroyListeners();
|
|
1404
|
+
holder.creationPromise = null;
|
|
1405
|
+
if (error) {
|
|
1406
|
+
await this.handleInstantiationError(
|
|
1407
|
+
instanceName,
|
|
1408
|
+
holder,
|
|
1409
|
+
deferred,
|
|
1410
|
+
scope,
|
|
1411
|
+
error
|
|
1310
1412
|
);
|
|
1311
|
-
|
|
1413
|
+
} else {
|
|
1414
|
+
await this.handleInstantiationSuccess(
|
|
1312
1415
|
instanceName,
|
|
1313
|
-
holder
|
|
1314
|
-
|
|
1416
|
+
holder,
|
|
1417
|
+
ctx,
|
|
1418
|
+
deferred,
|
|
1419
|
+
instance
|
|
1315
1420
|
);
|
|
1316
1421
|
}
|
|
1317
|
-
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Handles successful service instantiation.
|
|
1425
|
+
*/
|
|
1426
|
+
async handleInstantiationSuccess(instanceName, holder, ctx, deferred, instance) {
|
|
1427
|
+
holder.instance = instance;
|
|
1428
|
+
holder.status = "created" /* Created */;
|
|
1429
|
+
if (ctx.deps.size > 0) {
|
|
1430
|
+
ctx.deps.forEach((dependency) => {
|
|
1431
|
+
holder.destroyListeners.push(
|
|
1432
|
+
this.eventBus.on(
|
|
1433
|
+
dependency,
|
|
1434
|
+
"destroy",
|
|
1435
|
+
() => this.invalidate(instanceName)
|
|
1436
|
+
)
|
|
1437
|
+
);
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
await this.emitInstanceEvent(instanceName);
|
|
1441
|
+
deferred.resolve([void 0, instance]);
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Handles service instantiation errors.
|
|
1445
|
+
*/
|
|
1446
|
+
async handleInstantiationError(instanceName, holder, deferred, scope, error) {
|
|
1447
|
+
this.logger?.error(
|
|
1448
|
+
`[ServiceLocator] Error creating instance for ${instanceName}`,
|
|
1449
|
+
error
|
|
1450
|
+
);
|
|
1451
|
+
holder.status = "error" /* Error */;
|
|
1452
|
+
holder.instance = error;
|
|
1453
|
+
holder.creationPromise = null;
|
|
1454
|
+
if (scope === "Singleton" /* Singleton */) {
|
|
1455
|
+
setTimeout(() => this.invalidate(instanceName), 10);
|
|
1456
|
+
}
|
|
1457
|
+
deferred.reject(error);
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Stores an instance holder based on its scope.
|
|
1461
|
+
*/
|
|
1462
|
+
storeInstanceByScope(scope, instanceName, holder) {
|
|
1463
|
+
switch (scope) {
|
|
1464
|
+
case "Singleton" /* Singleton */:
|
|
1465
|
+
this.logger?.debug(
|
|
1466
|
+
`[ServiceLocator] Setting singleton instance for ${instanceName}`
|
|
1467
|
+
);
|
|
1468
|
+
this.manager.set(instanceName, holder);
|
|
1469
|
+
break;
|
|
1470
|
+
case "Request" /* Request */:
|
|
1471
|
+
if (this.currentRequestContext) {
|
|
1472
|
+
this.logger?.debug(
|
|
1473
|
+
`[ServiceLocator] Setting request-scoped instance for ${instanceName}`
|
|
1474
|
+
);
|
|
1475
|
+
this.currentRequestContext.addInstance(
|
|
1476
|
+
instanceName,
|
|
1477
|
+
holder.instance,
|
|
1478
|
+
holder
|
|
1479
|
+
);
|
|
1480
|
+
}
|
|
1481
|
+
break;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Tries to get a pre-prepared instance from request contexts.
|
|
1486
|
+
*/
|
|
1487
|
+
tryGetPrePreparedInstance(instanceName, contextHolder, deps) {
|
|
1488
|
+
if (contextHolder && contextHolder.priority > 0) {
|
|
1489
|
+
const prePreparedInstance = contextHolder.get(instanceName)?.instance;
|
|
1490
|
+
if (prePreparedInstance !== void 0) {
|
|
1491
|
+
this.logger?.debug(
|
|
1492
|
+
`[ServiceLocator] Using pre-prepared instance ${instanceName} from request context ${contextHolder.requestId}`
|
|
1493
|
+
);
|
|
1494
|
+
deps.add(instanceName);
|
|
1495
|
+
return prePreparedInstance;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
if (this.currentRequestContext && this.currentRequestContext !== contextHolder) {
|
|
1499
|
+
const prePreparedInstance = this.currentRequestContext.get(instanceName)?.instance;
|
|
1500
|
+
if (prePreparedInstance !== void 0) {
|
|
1501
|
+
this.logger?.debug(
|
|
1502
|
+
`[ServiceLocator] Using pre-prepared instance ${instanceName} from current request context ${this.currentRequestContext.requestId}`
|
|
1503
|
+
);
|
|
1504
|
+
deps.add(instanceName);
|
|
1505
|
+
return prePreparedInstance;
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
return void 0;
|
|
1318
1509
|
}
|
|
1319
1510
|
/**
|
|
1320
1511
|
* Creates a factory context for dependency injection during service instantiation.
|
|
@@ -1333,33 +1524,20 @@ var ServiceLocator = class {
|
|
|
1333
1524
|
return {
|
|
1334
1525
|
// @ts-expect-error This is correct type
|
|
1335
1526
|
async inject(token, args) {
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
return prePreparedInstance;
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
if (self.currentRequestContext && self.currentRequestContext !== contextHolder) {
|
|
1348
|
-
const instanceName = self.generateInstanceName(token, args);
|
|
1349
|
-
const prePreparedInstance = self.currentRequestContext.getInstance(instanceName);
|
|
1350
|
-
if (prePreparedInstance !== void 0) {
|
|
1351
|
-
self.logger?.debug(
|
|
1352
|
-
`[ServiceLocator] Using pre-prepared instance ${instanceName} from current request context ${self.currentRequestContext.requestId}`
|
|
1353
|
-
);
|
|
1354
|
-
deps.add(instanceName);
|
|
1355
|
-
return prePreparedInstance;
|
|
1356
|
-
}
|
|
1527
|
+
const instanceName = self.generateInstanceName(token, args);
|
|
1528
|
+
const prePreparedInstance = self.tryGetPrePreparedInstance(
|
|
1529
|
+
instanceName,
|
|
1530
|
+
contextHolder,
|
|
1531
|
+
deps
|
|
1532
|
+
);
|
|
1533
|
+
if (prePreparedInstance !== void 0) {
|
|
1534
|
+
return prePreparedInstance;
|
|
1357
1535
|
}
|
|
1358
1536
|
const [error, instance] = await self.getInstance(
|
|
1359
1537
|
token,
|
|
1360
1538
|
args,
|
|
1361
|
-
({ instanceName }) => {
|
|
1362
|
-
deps.add(
|
|
1539
|
+
({ instanceName: instanceName2 }) => {
|
|
1540
|
+
deps.add(instanceName2);
|
|
1363
1541
|
}
|
|
1364
1542
|
);
|
|
1365
1543
|
if (error) {
|
|
@@ -1377,16 +1555,23 @@ var ServiceLocator = class {
|
|
|
1377
1555
|
* Generates a unique instance name based on token and arguments.
|
|
1378
1556
|
*/
|
|
1379
1557
|
generateInstanceName(token, args) {
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1558
|
+
if (!args) {
|
|
1559
|
+
return token.toString();
|
|
1560
|
+
}
|
|
1561
|
+
const formattedArgs = Object.entries(args).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)).map(([key, value]) => `${key}=${this.formatArgValue(value)}`).join(",");
|
|
1562
|
+
return `${token.toString()}:${formattedArgs.replaceAll(/"/g, "").replaceAll(/:/g, "=")}`;
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Formats a single argument value for instance name generation.
|
|
1566
|
+
*/
|
|
1567
|
+
formatArgValue(value) {
|
|
1568
|
+
if (typeof value === "function") {
|
|
1569
|
+
return `fn_${value.name}(${value.length})`;
|
|
1570
|
+
}
|
|
1571
|
+
if (typeof value === "symbol") {
|
|
1572
|
+
return value.toString();
|
|
1573
|
+
}
|
|
1574
|
+
return JSON.stringify(value).slice(0, 40);
|
|
1390
1575
|
}
|
|
1391
1576
|
};
|
|
1392
1577
|
|
|
@@ -1477,6 +1662,7 @@ _Container = __decorateElement(_init2, 0, "Container", _Container_decorators, _C
|
|
|
1477
1662
|
__runInitializers(_init2, 1, _Container);
|
|
1478
1663
|
var Container = _Container;
|
|
1479
1664
|
|
|
1665
|
+
exports.BaseInstanceHolderManager = BaseInstanceHolderManager;
|
|
1480
1666
|
exports.BoundInjectionToken = BoundInjectionToken;
|
|
1481
1667
|
exports.Container = Container;
|
|
1482
1668
|
exports.DefaultRequestContextHolder = DefaultRequestContextHolder;
|