@adaas/a-concept 0.1.53 → 0.1.55

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaas/a-concept",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "description": "A-Concept is a framework to build new Applications within or outside the ADAAS ecosystem. This framework is designed to be modular structure regardless environment and program goal.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.cjs",
@@ -474,6 +474,66 @@ export class A_Feature<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__
474
474
  }
475
475
 
476
476
 
477
+ /**
478
+ * Allows to chain the feature to another feature.
479
+ * In this case the parent feature scope (if new not provided), stages, caller will be used.
480
+ *
481
+ * [!] Note: Chained feature will use the same caller as the parent feature.
482
+ *
483
+ * @param feature
484
+ */
485
+ chain(
486
+ /**
487
+ * A Feature to be chained
488
+ */
489
+ feature: A_Feature,
490
+ /**
491
+ * Optional scope to be used for the chained feature.
492
+ */
493
+ scope?: A_Scope
494
+ )
495
+ chain<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__FeatureAvailableComponents>(
496
+ /**
497
+ * Component whose feature should be chained
498
+ */
499
+ component: A_TYPES__FeatureAvailableComponents,
500
+ /**
501
+ * A Feature Name to be chained
502
+ */
503
+ feature: string,
504
+ /**
505
+ * Optional scope to be used for the chained feature.
506
+ */
507
+ scope?: A_Scope
508
+ )
509
+ chain<T extends A_TYPES__FeatureAvailableComponents = A_TYPES__FeatureAvailableComponents>(
510
+ param1: A_TYPES__FeatureAvailableComponents | A_Feature,
511
+ param2?: string | A_Scope,
512
+ param3?: A_Scope
513
+ ) {
514
+ let feature: A_Feature;
515
+ let scope: A_Scope | undefined;
516
+
517
+ if (param1 instanceof A_Feature) {
518
+ feature = param1;
519
+ scope = param2 instanceof A_Scope ? param2 : undefined;
520
+ } else {
521
+ feature = new A_Feature({
522
+ name: param2 as string,
523
+ component: param1 as T
524
+ });
525
+ scope = param3 instanceof A_Scope ? param3 : undefined;
526
+ }
527
+
528
+ const featureScope = scope || this.scope;
529
+
530
+ // create new caller for the chained feature
531
+ feature._caller = this._caller;
532
+
533
+ return feature.process(featureScope);
534
+ }
535
+
536
+
477
537
 
478
538
 
479
539
  toString(): string {
@@ -703,10 +703,9 @@ export class A_Scope<
703
703
 
704
704
  case A_TypeGuards.isEntityConstructor(param1): {
705
705
  // 3) Check entities
706
- this.allowedEntities.forEach(ctor => {
707
- if (A_CommonHelper.isInheritedFrom(ctor, param1)) {
708
- const instance = this.resolve<T>(ctor);
709
- if (instance) results.push(instance as T);
706
+ this.entities.forEach(entity => {
707
+ if (A_CommonHelper.isInheritedFrom(entity.constructor, param1)) {
708
+ results.push(entity as T);
710
709
  }
711
710
  });
712
711
  break;
@@ -740,13 +739,13 @@ export class A_Scope<
740
739
 
741
740
 
742
741
  const parentScope = this._parent;
743
-
742
+
744
743
  while (parentScope && parentScope.has(param1 as any)) {
745
744
  const parentResults = parentScope.resolveAll<T>(param1 as any);
746
745
  results.push(...parentResults);
747
746
  break;
748
747
  }
749
-
748
+
750
749
 
751
750
  return results;
752
751
  }
@@ -586,7 +586,7 @@ describe('A-Feature tests', () => {
586
586
  const executionResults: string[] = [];
587
587
 
588
588
  class BaseEntity extends A_Entity {
589
- async test() {
589
+ async test() {
590
590
  await this.call('myFeature');
591
591
  }
592
592
 
@@ -598,7 +598,7 @@ describe('A-Feature tests', () => {
598
598
  name: 'myFeature',
599
599
  scope: [BaseEntity]
600
600
  })
601
- testMethod() {
601
+ testMethod() {
602
602
  executionResults.push('testMethod');
603
603
  }
604
604
  }
@@ -625,4 +625,45 @@ describe('A-Feature tests', () => {
625
625
 
626
626
  expect(executionResults).toEqual(['testMethod', 'testMethod']);
627
627
  });
628
+ it('Should allow be possible to do a Feature Chaining without Caller Change', async () => {
629
+ const executionResults: string[] = [];
630
+
631
+ class Component_B extends A_Component {
632
+
633
+ @A_Feature.Extend()
634
+ featureB(
635
+ @A_Inject(A_Caller) caller: Component_A
636
+ ) {
637
+ executionResults.push('featureB');
638
+
639
+ expect(caller).toBeInstanceOf(Component_A);
640
+ }
641
+ }
642
+
643
+ class Component_A extends A_Component {
644
+
645
+ @A_Feature.Extend()
646
+ async featureA(
647
+ @A_Inject(A_Feature) feature: A_Feature,
648
+ @A_Inject(Component_B) compb: Component_B
649
+ ) {
650
+ executionResults.push('featureA');
651
+
652
+ await feature.chain(compb, 'featureB');
653
+ }
654
+ }
655
+
656
+
657
+
658
+ const scope = new A_Scope({ name: 'TestScope', components: [Component_A, Component_B] });
659
+
660
+
661
+ const compA = scope.resolve(Component_A)!;
662
+
663
+ await compA.call('featureA');
664
+
665
+ expect(executionResults).toEqual(['featureA', 'featureB']);
666
+
667
+
668
+ });
628
669
  });
@@ -433,5 +433,23 @@ describe('A-Scope tests', () => {
433
433
  // the first element should be instance of ComponentC as it is registered in child scope
434
434
  expect(resolvedComponents[0] instanceof ComponentC).toBe(true);
435
435
  });
436
+ it('Should resolve all entities registered in the scope', async () => {
436
437
 
438
+ class MyEntity extends A_Entity { }
439
+
440
+
441
+ const scope = new A_Scope({ name: 'TestScope' });
442
+
443
+ scope.register(new MyEntity());
444
+ scope.register(new MyEntity());
445
+ scope.register(new MyEntity());
446
+
447
+ const resolvedEntities = scope.resolveAll<MyEntity>(MyEntity);
448
+
449
+ expect(resolvedEntities.length).toBe(3);
450
+ resolvedEntities.forEach(entity => {
451
+ expect(entity).toBeInstanceOf(MyEntity);
452
+ });
453
+
454
+ });
437
455
  });