@adaas/a-concept 0.1.55 → 0.1.57
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/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +183 -1
- package/dist/index.d.ts +183 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/global/A-Dependency/A-Dependency-Flat.decorator.ts +68 -0
- package/src/global/A-Dependency/A-Dependency.class.ts +11 -0
- package/src/global/A-Dependency/A-Dependency.types.ts +6 -0
- package/src/global/A-Inject/A-Inject.types.ts +1 -0
- package/src/global/A-Scope/A-Scope.class.ts +332 -102
- package/src/global/A-Stage/A-Stage.class.ts +24 -15
- package/tests/A-Scope.test.ts +224 -0
|
@@ -200,6 +200,35 @@ export class A_Scope<
|
|
|
200
200
|
initializer.call(this, param1, param2);
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Generator to iterate through all parent scopes
|
|
205
|
+
*/
|
|
206
|
+
*parents(): Generator<A_Scope> {
|
|
207
|
+
let currentParent = this._parent;
|
|
208
|
+
while (currentParent) {
|
|
209
|
+
yield currentParent;
|
|
210
|
+
currentParent = currentParent._parent;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* This method is used to retrieve a parent scope at a specific level
|
|
216
|
+
*
|
|
217
|
+
* @param level
|
|
218
|
+
* @returns
|
|
219
|
+
*/
|
|
220
|
+
parentAtLevel(level: number): A_Scope | undefined {
|
|
221
|
+
let currentParent = this._parent;
|
|
222
|
+
let currentLevel = 0;
|
|
223
|
+
while (currentParent) {
|
|
224
|
+
if (currentLevel === level) {
|
|
225
|
+
return currentParent;
|
|
226
|
+
}
|
|
227
|
+
currentParent = currentParent._parent;
|
|
228
|
+
currentLevel++;
|
|
229
|
+
}
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
203
232
|
|
|
204
233
|
|
|
205
234
|
/**
|
|
@@ -460,6 +489,63 @@ export class A_Scope<
|
|
|
460
489
|
ctor: unknown
|
|
461
490
|
): boolean {
|
|
462
491
|
|
|
492
|
+
let found = this.hasFlat(ctor as any);
|
|
493
|
+
|
|
494
|
+
if (!found && !!this._parent)
|
|
495
|
+
try {
|
|
496
|
+
return this._parent.has(ctor as any);
|
|
497
|
+
} catch (error) {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return found;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* This method is used to check if the component is available in the scope
|
|
507
|
+
*
|
|
508
|
+
* [!] Note that this method checks for the component ONLY in the current scope
|
|
509
|
+
*
|
|
510
|
+
* @param component
|
|
511
|
+
* @returns
|
|
512
|
+
*/
|
|
513
|
+
hasFlat<T extends A_Component>(
|
|
514
|
+
/**
|
|
515
|
+
* Provide a component constructor to check if it's available in the scope
|
|
516
|
+
*/
|
|
517
|
+
component: A_TYPES__Component_Constructor<T>
|
|
518
|
+
): boolean
|
|
519
|
+
hasFlat<T extends A_Entity>(
|
|
520
|
+
/**
|
|
521
|
+
* Provide an entity constructor to check if it's available in the scope
|
|
522
|
+
*
|
|
523
|
+
* [!] Note that entities are unique per aseid, so this method checks if there's at least one entity of the provided type in the scope
|
|
524
|
+
*/
|
|
525
|
+
entity: A_TYPES__Entity_Constructor<T>
|
|
526
|
+
): boolean
|
|
527
|
+
hasFlat<T extends A_Fragment>(
|
|
528
|
+
/**
|
|
529
|
+
* Provide a fragment constructor to check if it's available in the scope
|
|
530
|
+
*/
|
|
531
|
+
fragment: A_TYPES__Fragment_Constructor<T>
|
|
532
|
+
): boolean
|
|
533
|
+
hasFlat<T extends A_Error>(
|
|
534
|
+
/**
|
|
535
|
+
* Provide an error constructor to check if it's available in the scope
|
|
536
|
+
*/
|
|
537
|
+
error: A_TYPES__Error_Constructor<T>
|
|
538
|
+
): boolean
|
|
539
|
+
hasFlat(
|
|
540
|
+
/**
|
|
541
|
+
* Provide a string to check if a component, entity or fragment with the provided name is available in the scope
|
|
542
|
+
*/
|
|
543
|
+
constructor: string
|
|
544
|
+
): boolean
|
|
545
|
+
hasFlat(
|
|
546
|
+
ctor: unknown
|
|
547
|
+
): boolean {
|
|
548
|
+
|
|
463
549
|
let found = false;
|
|
464
550
|
|
|
465
551
|
switch (true) {
|
|
@@ -468,7 +554,8 @@ export class A_Scope<
|
|
|
468
554
|
return true;
|
|
469
555
|
|
|
470
556
|
// 2) Check by string name.
|
|
471
|
-
case
|
|
557
|
+
case A_TypeGuards.isString(ctor): {
|
|
558
|
+
|
|
472
559
|
// 2.1 Check if it's a component name
|
|
473
560
|
const possibleComponent = Array.from(this.allowedComponents).find(c => c.name === ctor);
|
|
474
561
|
if (possibleComponent) found = true;
|
|
@@ -485,11 +572,7 @@ export class A_Scope<
|
|
|
485
572
|
const possibleError = Array.from(this.allowedErrors).find(e => e.name === ctor);
|
|
486
573
|
if (possibleError) found = true;
|
|
487
574
|
|
|
488
|
-
|
|
489
|
-
if (!!this._parent)
|
|
490
|
-
return this._parent.has(ctor);
|
|
491
|
-
|
|
492
|
-
return false;
|
|
575
|
+
break;
|
|
493
576
|
}
|
|
494
577
|
// 3) Check if it's a Component
|
|
495
578
|
case A_TypeGuards.isComponentConstructor(ctor): {
|
|
@@ -536,15 +619,6 @@ export class A_Scope<
|
|
|
536
619
|
}
|
|
537
620
|
}
|
|
538
621
|
|
|
539
|
-
// 7) Check parent scope in case not found
|
|
540
|
-
if (!found && !!this._parent)
|
|
541
|
-
try {
|
|
542
|
-
return this._parent.has(ctor as any);
|
|
543
|
-
} catch (error) {
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
622
|
return found;
|
|
549
623
|
}
|
|
550
624
|
|
|
@@ -646,6 +720,8 @@ export class A_Scope<
|
|
|
646
720
|
* This method should resolve all instances of the components, or entities within the scope, by provided parent class
|
|
647
721
|
* So in case of providing a base class it should return all instances that extends this base class
|
|
648
722
|
*
|
|
723
|
+
* [!] Applicable for the current scope ONLY, no parent scopes are checked
|
|
724
|
+
*
|
|
649
725
|
* @param component
|
|
650
726
|
*/
|
|
651
727
|
resolveAll<T extends A_Component>(
|
|
@@ -675,6 +751,68 @@ export class A_Scope<
|
|
|
675
751
|
*/
|
|
676
752
|
param1: A_TYPES__InjectableConstructors
|
|
677
753
|
): Array<T> {
|
|
754
|
+
|
|
755
|
+
const results: Array<T> = [];
|
|
756
|
+
|
|
757
|
+
// 1) Resolve all in the current scope
|
|
758
|
+
const currentResults = this.resolveFlatAll<T>(param1 as any);
|
|
759
|
+
results.push(...currentResults);
|
|
760
|
+
|
|
761
|
+
// 2) Resolve all in the parent scope
|
|
762
|
+
|
|
763
|
+
let parentScope = this._parent;
|
|
764
|
+
|
|
765
|
+
while (parentScope && parentScope.has(param1 as any)) {
|
|
766
|
+
const parentResults = parentScope.resolveFlatAll<T>(param1 as any);
|
|
767
|
+
results.push(...parentResults);
|
|
768
|
+
|
|
769
|
+
// Move to the next parent scope
|
|
770
|
+
parentScope = parentScope._parent;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
return results;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* This method should resolve all instances of the components, or entities within the scope, by provided parent class
|
|
782
|
+
* So in case of providing a base class it should return all instances that extends this base class
|
|
783
|
+
*
|
|
784
|
+
* [!] Applicable for the current scope ONLY, no parent scopes are checked
|
|
785
|
+
*
|
|
786
|
+
* @param component
|
|
787
|
+
*/
|
|
788
|
+
resolveFlatAll<T extends A_Component>(
|
|
789
|
+
/**
|
|
790
|
+
* Provide a component constructor to resolve its instance from the scope
|
|
791
|
+
*/
|
|
792
|
+
component: A_TYPES__Component_Constructor<T>
|
|
793
|
+
): Array<T>
|
|
794
|
+
resolveFlatAll<T extends A_Fragment>(
|
|
795
|
+
/**
|
|
796
|
+
* Provide a fragment constructor to resolve its instance from the scope
|
|
797
|
+
*/
|
|
798
|
+
fragment: A_TYPES__Fragment_Constructor<T>
|
|
799
|
+
): Array<T>
|
|
800
|
+
resolveFlatAll<T extends A_Entity>(
|
|
801
|
+
/**
|
|
802
|
+
* Provide an entity constructor to resolve its instance or an array of instances from the scope
|
|
803
|
+
*/
|
|
804
|
+
entity: A_TYPES__Entity_Constructor<T>
|
|
805
|
+
): Array<T>
|
|
806
|
+
resolveFlatAll<T extends A_TYPES__ScopeResolvableComponents>(
|
|
807
|
+
constructorName: string
|
|
808
|
+
): Array<T>
|
|
809
|
+
resolveFlatAll<T extends A_TYPES__ScopeResolvableComponents>(
|
|
810
|
+
/**
|
|
811
|
+
* Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
|
|
812
|
+
*/
|
|
813
|
+
param1: A_TYPES__InjectableConstructors
|
|
814
|
+
): Array<T> {
|
|
815
|
+
|
|
678
816
|
const results: Array<T> = [];
|
|
679
817
|
|
|
680
818
|
switch (true) {
|
|
@@ -704,6 +842,7 @@ export class A_Scope<
|
|
|
704
842
|
case A_TypeGuards.isEntityConstructor(param1): {
|
|
705
843
|
// 3) Check entities
|
|
706
844
|
this.entities.forEach(entity => {
|
|
845
|
+
|
|
707
846
|
if (A_CommonHelper.isInheritedFrom(entity.constructor, param1)) {
|
|
708
847
|
results.push(entity as T);
|
|
709
848
|
}
|
|
@@ -738,19 +877,11 @@ export class A_Scope<
|
|
|
738
877
|
}
|
|
739
878
|
|
|
740
879
|
|
|
741
|
-
const parentScope = this._parent;
|
|
742
|
-
|
|
743
|
-
while (parentScope && parentScope.has(param1 as any)) {
|
|
744
|
-
const parentResults = parentScope.resolveAll<T>(param1 as any);
|
|
745
|
-
results.push(...parentResults);
|
|
746
|
-
break;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
|
|
750
880
|
return results;
|
|
751
881
|
}
|
|
752
882
|
|
|
753
883
|
|
|
884
|
+
|
|
754
885
|
/**
|
|
755
886
|
* This method allows to resolve/inject a component, fragment or entity from the scope
|
|
756
887
|
* Depending on the provided parameters it can resolve:
|
|
@@ -843,29 +974,114 @@ export class A_Scope<
|
|
|
843
974
|
param1: A_TYPES__InjectableConstructors | Array<A_TYPES__InjectableConstructors>,
|
|
844
975
|
param2?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
845
976
|
): T | Array<T> | undefined {
|
|
846
|
-
switch (true) {
|
|
847
|
-
case A_TypeGuards.isArray(param1): {
|
|
848
|
-
return param1.map(c => {
|
|
849
|
-
if (A_TypeGuards.isString(c))
|
|
850
|
-
return this.resolveByName(c);
|
|
851
|
-
else
|
|
852
|
-
return this.resolveOnce(c, param2);
|
|
853
|
-
}).filter(Boolean) as Array<T>;
|
|
854
|
-
}
|
|
855
977
|
|
|
856
|
-
case A_TypeGuards.isFunction(param1): {
|
|
857
|
-
return this.resolveOnce(param1, param2) as T;
|
|
858
|
-
}
|
|
859
978
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
979
|
+
if (A_TypeGuards.isArray(param1)) {
|
|
980
|
+
return param1.map(c => this.resolveOnce(c, param2)) as Array<T>;
|
|
981
|
+
} else {
|
|
982
|
+
return this.resolveOnce(param1, param2) as T;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
863
985
|
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* This polymorphic method allows to resolve/inject a component, fragment or entity from the scope
|
|
989
|
+
* Depending on the provided parameters it can resolve:
|
|
990
|
+
* - A single component/fragment/entity by its constructor or name
|
|
991
|
+
* - An array of components/fragments/entities by providing an array of constructors
|
|
992
|
+
* - An entity or an array of entities by providing the entity constructor and query instructions
|
|
993
|
+
*
|
|
994
|
+
* [!] Applicable for the current scope ONLY, no parent scopes are checked
|
|
995
|
+
*
|
|
996
|
+
* @param component
|
|
997
|
+
*/
|
|
998
|
+
resolveFlat<T extends A_Component>(
|
|
999
|
+
/**
|
|
1000
|
+
* Provide a component constructor to resolve its instance from the scope
|
|
1001
|
+
*/
|
|
1002
|
+
component: A_TYPES__Component_Constructor<T>
|
|
1003
|
+
): T | undefined
|
|
1004
|
+
resolveFlat<T extends A_TYPES__Component_Constructor[]>(
|
|
1005
|
+
/**
|
|
1006
|
+
* Provide an array of component constructors to resolve their instances from the scope
|
|
1007
|
+
*/
|
|
1008
|
+
components: [...T]
|
|
1009
|
+
): Array<InstanceType<T[number]>> | undefined
|
|
1010
|
+
resolveFlat<T extends A_Fragment>(
|
|
1011
|
+
/**
|
|
1012
|
+
* Provide a fragment constructor to resolve its instance from the scope
|
|
1013
|
+
*/
|
|
1014
|
+
fragment: A_TYPES__Fragment_Constructor<T>
|
|
1015
|
+
): T | undefined
|
|
1016
|
+
resolveFlat<T extends A_TYPES__Fragment_Constructor[]>(
|
|
1017
|
+
/**
|
|
1018
|
+
* Provide an array of fragment constructors to resolve their instances from the scope
|
|
1019
|
+
*/
|
|
1020
|
+
fragments: [...T]
|
|
1021
|
+
): Array<InstanceType<T[number]>> | undefined
|
|
1022
|
+
resolveFlat<T extends A_Entity>(
|
|
1023
|
+
/**
|
|
1024
|
+
* Provide an entity constructor to resolve its instance or an array of instances from the scope
|
|
1025
|
+
*/
|
|
1026
|
+
entity: A_TYPES__Entity_Constructor<T>
|
|
1027
|
+
): T | undefined
|
|
1028
|
+
|
|
1029
|
+
resolveFlat<T extends A_Entity>(
|
|
1030
|
+
/**
|
|
1031
|
+
* Provide an entity constructor to resolve its instance or an array of instances from the scope
|
|
1032
|
+
*/
|
|
1033
|
+
entity: A_TYPES__Entity_Constructor<T>,
|
|
1034
|
+
/**
|
|
1035
|
+
* Provide optional instructions to find a specific entity or a set of entities
|
|
1036
|
+
*/
|
|
1037
|
+
instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>
|
|
1038
|
+
): Array<T>
|
|
1039
|
+
resolveFlat<T extends A_Scope>(
|
|
1040
|
+
/**
|
|
1041
|
+
* Uses only in case of resolving a single entity
|
|
1042
|
+
*
|
|
1043
|
+
* Provide an entity constructor to resolve its instance from the scope
|
|
1044
|
+
*/
|
|
1045
|
+
scope: A_TYPES__Scope_Constructor<T>
|
|
1046
|
+
): T | undefined
|
|
1047
|
+
resolveFlat<T extends A_Error>(
|
|
1048
|
+
/**
|
|
1049
|
+
* Uses only in case of resolving a single entity
|
|
1050
|
+
*
|
|
1051
|
+
* Provide an entity constructor to resolve its instance from the scope
|
|
1052
|
+
*/
|
|
1053
|
+
scope: A_TYPES__Error_Constructor<T>
|
|
1054
|
+
): T | undefined
|
|
1055
|
+
resolveFlat<T extends A_TYPES__ScopeResolvableComponents>(
|
|
1056
|
+
constructorName: string
|
|
1057
|
+
): T | undefined
|
|
1058
|
+
// base definition
|
|
1059
|
+
resolveFlat<T extends A_TYPES__ScopeResolvableComponents>(
|
|
1060
|
+
/**
|
|
1061
|
+
* Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
|
|
1062
|
+
*/
|
|
1063
|
+
param1: A_TYPES__InjectableConstructors,
|
|
1064
|
+
|
|
1065
|
+
): T | Array<T> | undefined
|
|
1066
|
+
resolveFlat<T extends A_TYPES__ScopeLinkedConstructors>(
|
|
1067
|
+
/**
|
|
1068
|
+
* Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
|
|
1069
|
+
*/
|
|
1070
|
+
param1: InstanceType<T>,
|
|
1071
|
+
|
|
1072
|
+
): T | Array<T> | undefined
|
|
1073
|
+
resolveFlat<T extends A_TYPES__ScopeResolvableComponents>(
|
|
1074
|
+
/**
|
|
1075
|
+
* Provide a component, fragment or entity constructor or an array of constructors to resolve its instance(s) from the scope
|
|
1076
|
+
*/
|
|
1077
|
+
param1: A_TYPES__InjectableConstructors | Array<A_TYPES__InjectableConstructors>,
|
|
1078
|
+
param2?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
1079
|
+
): T | Array<T | undefined> | undefined {
|
|
1080
|
+
|
|
1081
|
+
if (A_TypeGuards.isArray(param1)) {
|
|
1082
|
+
return param1.map(c => this.resolveFlatOnce(c, param2)) as Array<T>;
|
|
1083
|
+
} else {
|
|
1084
|
+
return this.resolveFlatOnce(param1, param2) as T;
|
|
869
1085
|
}
|
|
870
1086
|
}
|
|
871
1087
|
|
|
@@ -883,6 +1099,7 @@ export class A_Scope<
|
|
|
883
1099
|
* This method is used internally to resolve a component, fragment or entity by its constructor name
|
|
884
1100
|
*
|
|
885
1101
|
* [!] Note that this method checks for the component, fragment or entity in the current scope and all parent scopes
|
|
1102
|
+
* [!!] Note: No parent scopes are checked
|
|
886
1103
|
*
|
|
887
1104
|
* @param name - name of the component, fragment or entity to resolve (constructor name for components and fragments, static entity property for entities, static code property for commands)
|
|
888
1105
|
* @returns
|
|
@@ -925,26 +1142,21 @@ export class A_Scope<
|
|
|
925
1142
|
);
|
|
926
1143
|
if (error) return this.resolveOnce(error) as InstanceType<_ErrorType[number]>;
|
|
927
1144
|
|
|
928
|
-
// If not found in current scope, check parent scope
|
|
929
|
-
if (!!this._parent) {
|
|
930
|
-
return this._parent.resolveByName(name) as any;
|
|
931
|
-
}
|
|
932
|
-
|
|
933
1145
|
return undefined;
|
|
934
1146
|
}
|
|
935
1147
|
|
|
936
1148
|
/**
|
|
937
|
-
*
|
|
1149
|
+
* Resolves a component, fragment or entity from the scope without checking parent scopes
|
|
938
1150
|
*
|
|
939
1151
|
* @param component
|
|
940
1152
|
* @param instructions
|
|
941
|
-
* @returns
|
|
942
1153
|
*/
|
|
943
|
-
private
|
|
1154
|
+
private resolveFlatOnce(
|
|
944
1155
|
component: any,
|
|
945
1156
|
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
946
1157
|
): A_TYPES__ScopeResolvableComponents | A_Scope | A_TYPES__ScopeLinkedComponents | Array<A_TYPES__ScopeResolvableComponents> | undefined {
|
|
947
1158
|
|
|
1159
|
+
let value: A_TYPES__ScopeResolvableComponents | A_Scope | A_TYPES__ScopeLinkedComponents | Array<A_TYPES__ScopeResolvableComponents> | undefined = undefined;
|
|
948
1160
|
|
|
949
1161
|
const componentName = A_CommonHelper.getComponentName(component);
|
|
950
1162
|
|
|
@@ -952,23 +1164,33 @@ export class A_Scope<
|
|
|
952
1164
|
return undefined;
|
|
953
1165
|
|
|
954
1166
|
switch (true) {
|
|
1167
|
+
case A_TypeGuards.isString(component): {
|
|
1168
|
+
value = this.resolveByName(component) as A_TYPES__ScopeResolvableComponents | A_Scope | A_TYPES__ScopeLinkedComponents | undefined;
|
|
1169
|
+
break;
|
|
1170
|
+
}
|
|
955
1171
|
case A_TypeGuards.isConstructorAllowedForScopeAllocation(component): {
|
|
956
|
-
|
|
1172
|
+
value = this.resolveIssuer(component);
|
|
1173
|
+
break;
|
|
957
1174
|
}
|
|
958
1175
|
case A_TypeGuards.isEntityConstructor(component): {
|
|
959
|
-
|
|
1176
|
+
value = this.resolveEntity(component, instructions);
|
|
1177
|
+
break;
|
|
960
1178
|
}
|
|
961
1179
|
case A_TypeGuards.isFragmentConstructor(component): {
|
|
962
|
-
|
|
1180
|
+
value = this.resolveFragment(component);
|
|
1181
|
+
break;
|
|
963
1182
|
}
|
|
964
1183
|
case A_TypeGuards.isScopeConstructor(component): {
|
|
965
|
-
|
|
1184
|
+
value = this.resolveScope(component);
|
|
1185
|
+
break;
|
|
966
1186
|
}
|
|
967
1187
|
case A_TypeGuards.isComponentConstructor(component): {
|
|
968
|
-
|
|
1188
|
+
value = this.resolveComponent(component);
|
|
1189
|
+
break;
|
|
969
1190
|
}
|
|
970
1191
|
case A_TypeGuards.isErrorConstructor(component): {
|
|
971
|
-
|
|
1192
|
+
value = this.resolveError(component);
|
|
1193
|
+
break;
|
|
972
1194
|
}
|
|
973
1195
|
default:
|
|
974
1196
|
throw new A_ScopeError(
|
|
@@ -976,8 +1198,44 @@ export class A_Scope<
|
|
|
976
1198
|
`Injected Component ${componentName} not found in the scope`
|
|
977
1199
|
);
|
|
978
1200
|
}
|
|
1201
|
+
|
|
1202
|
+
return value;
|
|
979
1203
|
}
|
|
980
1204
|
|
|
1205
|
+
/**
|
|
1206
|
+
* This method is used internally to resolve a single component, fragment or entity from the scope
|
|
1207
|
+
*
|
|
1208
|
+
* @param component
|
|
1209
|
+
* @param instructions
|
|
1210
|
+
* @returns
|
|
1211
|
+
*/
|
|
1212
|
+
private resolveOnce(
|
|
1213
|
+
component: any,
|
|
1214
|
+
instructions?: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions>
|
|
1215
|
+
): A_TYPES__ScopeResolvableComponents | A_Scope | A_TYPES__ScopeLinkedComponents | Array<A_TYPES__ScopeResolvableComponents> | undefined {
|
|
1216
|
+
|
|
1217
|
+
const values = this.resolveFlatOnce(component, instructions);
|
|
1218
|
+
|
|
1219
|
+
// The idea here that in case when Scope has no exact component we have to resolve it from the _parent
|
|
1220
|
+
// That means that we should ensure that there's no components that are children of the required component
|
|
1221
|
+
if (!values && !!this.parent) {
|
|
1222
|
+
return this.parent.resolveOnce(component, instructions);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
return values;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
/**
|
|
1230
|
+
* Resolves the issuer of the scope by provided constructor
|
|
1231
|
+
*
|
|
1232
|
+
* [!] Note that this method checks ONLY for the direct issuer of the scope
|
|
1233
|
+
* [!!] No parent scopes are checked
|
|
1234
|
+
*
|
|
1235
|
+
*
|
|
1236
|
+
* @param ctor
|
|
1237
|
+
* @returns
|
|
1238
|
+
*/
|
|
981
1239
|
private resolveIssuer(
|
|
982
1240
|
ctor: A_TYPES__ScopeLinkedConstructors
|
|
983
1241
|
): A_TYPES__ScopeLinkedComponents | undefined {
|
|
@@ -991,9 +1249,7 @@ export class A_Scope<
|
|
|
991
1249
|
)) {
|
|
992
1250
|
return issuer!;
|
|
993
1251
|
}
|
|
994
|
-
|
|
995
|
-
return this._parent.resolveIssuer(ctor);
|
|
996
|
-
}
|
|
1252
|
+
|
|
997
1253
|
|
|
998
1254
|
return undefined;
|
|
999
1255
|
}
|
|
@@ -1002,6 +1258,7 @@ export class A_Scope<
|
|
|
1002
1258
|
* This method is used internally to resolve a single entity from the scope based on the provided instructions
|
|
1003
1259
|
*
|
|
1004
1260
|
* [!] Note that this method can return either a single entity or an array of entities depending on the instructions provided
|
|
1261
|
+
* [!!] Note: No parent scopes are checked
|
|
1005
1262
|
*
|
|
1006
1263
|
* @param entity
|
|
1007
1264
|
* @param instructions
|
|
@@ -1023,18 +1280,7 @@ export class A_Scope<
|
|
|
1023
1280
|
* [!!] In case when no entity found in the current scope, it tries to resolve it from the parent scope (if exists)
|
|
1024
1281
|
*/
|
|
1025
1282
|
case !instructions: {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
switch (true) {
|
|
1029
|
-
case !!found:
|
|
1030
|
-
return found as T;
|
|
1031
|
-
|
|
1032
|
-
case !found && !!this._parent:
|
|
1033
|
-
return this._parent.resolveEntity(entity, instructions);
|
|
1034
|
-
|
|
1035
|
-
default:
|
|
1036
|
-
return undefined;
|
|
1037
|
-
}
|
|
1283
|
+
return this.entities.find(e => e instanceof entity) as T | undefined;
|
|
1038
1284
|
}
|
|
1039
1285
|
/**
|
|
1040
1286
|
* 2) In case when aseid is provided in the query, we can directly get the entity from the map
|
|
@@ -1091,8 +1337,8 @@ export class A_Scope<
|
|
|
1091
1337
|
});
|
|
1092
1338
|
});
|
|
1093
1339
|
|
|
1094
|
-
if (found.length === 0
|
|
1095
|
-
return
|
|
1340
|
+
if (found.length === 0)
|
|
1341
|
+
return undefined;
|
|
1096
1342
|
|
|
1097
1343
|
if (count === 1)
|
|
1098
1344
|
return found[0] as T;
|
|
@@ -1104,27 +1350,21 @@ export class A_Scope<
|
|
|
1104
1350
|
/**
|
|
1105
1351
|
* This method is used internally to resolve a single error from the scope
|
|
1106
1352
|
*
|
|
1353
|
+
* [!] Note that errors are singleton instances within the scope
|
|
1354
|
+
* [!!] No parent scopes are checked
|
|
1355
|
+
*
|
|
1107
1356
|
* @param error
|
|
1108
1357
|
* @returns
|
|
1109
1358
|
*/
|
|
1110
1359
|
private resolveError<T extends A_Error>(error: A_TYPES__Error_Constructor<T>): T | undefined {
|
|
1111
1360
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
switch (true) {
|
|
1115
|
-
case !!found:
|
|
1116
|
-
return found as T;
|
|
1117
|
-
|
|
1118
|
-
case !found && !!this._parent:
|
|
1119
|
-
return this._parent.resolveError(error);
|
|
1120
|
-
|
|
1121
|
-
default:
|
|
1122
|
-
return undefined;
|
|
1123
|
-
}
|
|
1361
|
+
return this.errors.find(e => e instanceof error) as T | undefined;
|
|
1124
1362
|
}
|
|
1125
1363
|
/**
|
|
1126
1364
|
* This method is used internally to resolve a single fragment from the scope
|
|
1127
1365
|
*
|
|
1366
|
+
* [!] Note that this method checks for the fragment in the current scope and all parent scopes
|
|
1367
|
+
*
|
|
1128
1368
|
* @param fragment
|
|
1129
1369
|
* @returns
|
|
1130
1370
|
*/
|
|
@@ -1142,9 +1382,6 @@ export class A_Scope<
|
|
|
1142
1382
|
return this.resolveFragment(found);
|
|
1143
1383
|
}
|
|
1144
1384
|
|
|
1145
|
-
case !fragmentInstancePresented && !!this._parent:
|
|
1146
|
-
return this._parent.resolveFragment(fragment);
|
|
1147
|
-
|
|
1148
1385
|
default:
|
|
1149
1386
|
return undefined;
|
|
1150
1387
|
}
|
|
@@ -1158,17 +1395,18 @@ export class A_Scope<
|
|
|
1158
1395
|
private resolveScope(scope: A_TYPES__Scope_Constructor): A_Scope {
|
|
1159
1396
|
return this;
|
|
1160
1397
|
}
|
|
1398
|
+
|
|
1161
1399
|
/**
|
|
1162
1400
|
* This method is used internally to resolve a single component from the scope
|
|
1163
1401
|
*
|
|
1402
|
+
* [!!] Note: No parent scopes are checked
|
|
1403
|
+
*
|
|
1164
1404
|
* @param component
|
|
1165
1405
|
* @returns
|
|
1166
1406
|
*/
|
|
1167
1407
|
private resolveComponent<T extends A_Component>(component: A_TYPES__Component_Constructor<T>): InstanceType<_ComponentType[number]> | undefined {
|
|
1168
1408
|
|
|
1169
|
-
|
|
1170
|
-
// BUT: if it's not presented in _parent we have to check for inheritance
|
|
1171
|
-
// That means that we should ensure that there's no components that are children of the required component
|
|
1409
|
+
|
|
1172
1410
|
switch (true) {
|
|
1173
1411
|
// 1) In case when the component is available and exists in the scope
|
|
1174
1412
|
case this.allowedComponents.has(component) && this._components.has(component): {
|
|
@@ -1233,16 +1471,8 @@ export class A_Scope<
|
|
|
1233
1471
|
return this.resolveComponent(found);
|
|
1234
1472
|
}
|
|
1235
1473
|
|
|
1236
|
-
// 4) In case when the component is not available in the scope but the _parent is available
|
|
1237
|
-
case !!this._parent: {
|
|
1238
|
-
return this._parent.resolveComponent(component) as InstanceType<_ComponentType[number]>;
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
1474
|
default:
|
|
1242
|
-
|
|
1243
|
-
A_ScopeError.ResolutionError,
|
|
1244
|
-
`Component ${component.name} not found in the scope ${this.name}`
|
|
1245
|
-
);
|
|
1475
|
+
return undefined;
|
|
1246
1476
|
}
|
|
1247
1477
|
}
|
|
1248
1478
|
|
|
@@ -140,29 +140,38 @@ export class A_Stage {
|
|
|
140
140
|
return this._feature;
|
|
141
141
|
|
|
142
142
|
default: {
|
|
143
|
-
const { target, require, create, defaultArgs, parent } = arg;
|
|
143
|
+
const { target, require, create, defaultArgs, parent, flat } = arg;
|
|
144
144
|
|
|
145
145
|
|
|
146
146
|
let dependency;
|
|
147
147
|
let targetScope = scope;
|
|
148
148
|
|
|
149
|
-
if (parent && typeof parent.layerOffset === 'number') {
|
|
150
|
-
let parentScope = scope.parent;
|
|
151
149
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
150
|
+
switch (true) {
|
|
151
|
+
// 1) Flat resolution
|
|
152
|
+
case flat: {
|
|
153
|
+
dependency = targetScope.resolveFlat(target);
|
|
154
|
+
break;
|
|
157
155
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
// 2) Parent resolution
|
|
157
|
+
case parent && typeof parent.layerOffset === 'number': {
|
|
158
|
+
const targetParent = targetScope.parentAtLevel(parent.layerOffset);
|
|
159
|
+
if (!targetParent) {
|
|
160
|
+
throw new A_StageError(
|
|
161
|
+
A_StageError.ArgumentsResolutionError,
|
|
162
|
+
`Unable to resolve parent scope at layer offset ${parent.layerOffset} for argument ${A_CommonHelper.getComponentName(arg.target)} for stage ${this.name} in scope ${scope.name}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
dependency = targetParent.resolve(target);
|
|
166
|
+
targetScope = targetParent;
|
|
167
|
+
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
// 3) Normal resolution
|
|
171
|
+
default: {
|
|
172
|
+
dependency = targetScope.resolve(target);
|
|
173
|
+
break;
|
|
162
174
|
}
|
|
163
|
-
|
|
164
|
-
} else {
|
|
165
|
-
dependency = targetScope.resolve(target);
|
|
166
175
|
}
|
|
167
176
|
|
|
168
177
|
if (create && !dependency && A_TypeGuards.isAllowedForDependencyDefaultCreation(target)) {
|