@adaas/a-concept 0.1.11 → 0.1.13
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/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js +2 -2
- package/dist/src/global/A-Abstraction/A-Abstraction-Extend.decorator.js.map +1 -1
- package/dist/src/helpers/A_StepsManager.class.js +13 -7
- package/dist/src/helpers/A_StepsManager.class.js.map +1 -1
- package/package.json +2 -2
- package/src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts +2 -3
- package/src/helpers/A_StepsManager.class.ts +15 -8
- package/tests/A-Abstraction.test.ts +106 -2
- package/tests/A-Feature.test.ts +89 -0
|
@@ -46,11 +46,11 @@ config = {}) {
|
|
|
46
46
|
metaKey = A_Component_constants_1.A_TYPES__ComponentMetaKey.ABSTRACTIONS;
|
|
47
47
|
break;
|
|
48
48
|
}
|
|
49
|
+
const setName = `CONCEPT_ABSTRACTION::${name}`;
|
|
49
50
|
// Get the existed metadata or create a new one
|
|
50
51
|
const existedMeta = meta.get(metaKey) || new A_Meta_class_1.A_Meta();
|
|
51
52
|
// Set the metadata of the method to define a custom Stage with name
|
|
52
|
-
const existedMetaValue = existedMeta.get(
|
|
53
|
-
const setName = `CONCEPT_ABSTRACTION::${name}`;
|
|
53
|
+
const existedMetaValue = existedMeta.get(setName) || [];
|
|
54
54
|
// Add the new method to the metadata
|
|
55
55
|
existedMetaValue.push({
|
|
56
56
|
name: setName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A-Abstraction-Extend.decorator.js","sourceRoot":"","sources":["../../../../src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts"],"names":[],"mappings":";;AA2BA,
|
|
1
|
+
{"version":3,"file":"A-Abstraction-Extend.decorator.js","sourceRoot":"","sources":["../../../../src/global/A-Abstraction/A-Abstraction-Extend.decorator.ts"],"names":[],"mappings":";;AA2BA,oDA2EC;AAjGD,uFAA8E;AAI9E,8EAAqE;AAErE,qGAAsG;AACtG,qGAAsG;AAEtG,+DAA2D;AAC3D,sFAA4E;AAG5E;;;;;;;;GAQG;AACH,SAAgB,oBAAoB;AAChC;;GAEG;AACH,IAAkC;AAClC;;;GAGG;AACH,SAAuD,EAAE;IAEzD,OAAO,UACH,MAAiC,EACjC,WAAmB,EACnB,UAAmD;;QAEnD,qBAAqB;QACrB,MAAM,aAAa,GAAG,CAAA,MAAC,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,WAAW,0CAAE,IAAI,KAAI,MAAM,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC;QAEjG,IAAI,CAAC,IAAI;YACL,MAAM,IAAI,wCAAkB,CACxB,wCAAkB,CAAC,yBAAyB,EAC5C,gEAAgE,aAAa,IAAI,CACpF,CAAC;QAEN,kEAAkE;QAClE,IAAI,CAAC,kCAAY,CAAC,oCAAoC,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,wCAAkB,CACxB,wCAAkB,CAAC,yBAAyB,EAC5C,iCAAiC,IAAI,UAAU,aAAa,gEAAgE,CAC/H,CAAC;QACN,CAAC;QAED,IAAI,OAAO,CAAC;QACZ,MAAM,IAAI,GAAsC,2BAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEvE,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,kCAAY,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,kCAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC;gBACxF,OAAO,GAAG,iDAAyB,CAAC,YAAY,CAAA;gBAChD,MAAM;YACV,KAAK,kCAAY,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,kCAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC;gBACxF,OAAO,GAAG,iDAAyB,CAAC,YAAY,CAAA;gBAChD,MAAM;QACd,CAAC;QACD,MAAM,OAAO,GAAG,wBAAwB,IAAI,EAAE,CAAC;QAE/C,+CAA+C;QAC/C,MAAM,WAAW,GAEZ,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,qBAAM,EAAE,CAAC;QAEvC,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAExD,qCAAqC;QACrC,gBAAgB,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;YAC3B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;SACtC,CAAC,CAAC;QAEH,sEAAsE;QACtE,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAG3C,sEAAsE;QACtE,2BAAS;aACJ,IAAI,CAAC,MAAM,CAAC;aACZ,GAAG,CACA,OAAO,EACP,WAAW,CACd,CAAC;IACV,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.A_TmpStage = exports.A_StepsManager = void 0;
|
|
4
|
+
const A_Error_class_1 = require("../global/A-Error/A_Error.class");
|
|
4
5
|
const A_Stage_class_1 = require("../global/A-Stage/A-Stage.class");
|
|
5
6
|
class A_StepsManager {
|
|
6
7
|
constructor(entities) {
|
|
@@ -23,23 +24,28 @@ class A_StepsManager {
|
|
|
23
24
|
this.entities.forEach(entity => this.graph.set(this.ID(entity), new Set()));
|
|
24
25
|
// Add directed edges based on 'before' and 'after'
|
|
25
26
|
this.entities.forEach(entity => {
|
|
26
|
-
const
|
|
27
|
+
const entityId = this.ID(entity);
|
|
28
|
+
const { before = [], after = [] } = entity;
|
|
27
29
|
// Add edges for 'before' dependencies
|
|
30
|
+
// If entity should execute before targets, then targets depend on entity
|
|
31
|
+
// So we add edges: target -> entity (target depends on entity)
|
|
28
32
|
before.forEach(dep => {
|
|
29
33
|
const targets = this.matchEntities(dep);
|
|
30
34
|
targets.forEach(target => {
|
|
31
35
|
if (!this.graph.has(target))
|
|
32
36
|
this.graph.set(target, new Set());
|
|
33
|
-
this.graph.get(target).add(
|
|
37
|
+
this.graph.get(target).add(entityId); // target depends on entity
|
|
34
38
|
});
|
|
35
39
|
});
|
|
36
|
-
// Add edges for 'after' dependencies
|
|
40
|
+
// Add edges for 'after' dependencies
|
|
41
|
+
// If entity should execute after sources, then entity depends on sources
|
|
42
|
+
// So we add edges: entity -> source (entity depends on source)
|
|
37
43
|
after.forEach(dep => {
|
|
38
44
|
const sources = this.matchEntities(dep);
|
|
39
45
|
sources.forEach(source => {
|
|
40
|
-
if (!this.graph.has(
|
|
41
|
-
this.graph.set(
|
|
42
|
-
this.graph.get(
|
|
46
|
+
if (!this.graph.has(entityId))
|
|
47
|
+
this.graph.set(entityId, new Set());
|
|
48
|
+
this.graph.get(entityId).add(source); // entity depends on source
|
|
43
49
|
});
|
|
44
50
|
});
|
|
45
51
|
});
|
|
@@ -54,7 +60,7 @@ class A_StepsManager {
|
|
|
54
60
|
// Topological sort with cycle detection
|
|
55
61
|
visit(node) {
|
|
56
62
|
if (this.tempMark.has(node))
|
|
57
|
-
throw new
|
|
63
|
+
throw new A_Error_class_1.A_Error("Circular dependency detected");
|
|
58
64
|
if (!this.visited.has(node)) {
|
|
59
65
|
this.tempMark.add(node);
|
|
60
66
|
(this.graph.get(node) || []).forEach(neighbor => this.visit(neighbor));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"A_StepsManager.class.js","sourceRoot":"","sources":["../../../src/helpers/A_StepsManager.class.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"A_StepsManager.class.js","sourceRoot":"","sources":["../../../src/helpers/A_StepsManager.class.ts"],"names":[],"mappings":";;;AAAA,mEAA0D;AAG1D,mEAA0D;AAG1D,MAAa,cAAc;IASvB,YAAY,QAA4D;QACpE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE5C,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;IAE7B,CAAC;IAEO,YAAY,CAChB,QAA4D;QAE5D,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACvB,uCACO,IAAI,KAEP,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,MAAM,EACjC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EACzB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,IACzB;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,EAAE,CAAC,IAA0B;QACjC,OAAO,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1G,CAAC;IAEO,UAAU;QACd,yBAAyB;QACzB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;QAE5E,mDAAmD;QACnD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC;YAE3C,sCAAsC;YACtC,yEAAyE;YACzE,+DAA+D;YAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACjB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBACxC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBACrB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;wBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;oBAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,2BAA2B;gBACtE,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;YAEH,uCAAuC;YACvC,yEAAyE;YACzE,+DAA+D;YAC/D,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAChB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gBAExC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;oBACrB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;wBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;oBACnE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,2BAA2B;gBACtE,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,kCAAkC;IAC1B,aAAa,CAAC,OAAe;QACjC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,QAAQ;aACf,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;aAC7C,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,wCAAwC;IAChC,KAAK,CAAC,IAAY;QACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,uBAAO,CAAC,8BAA8B,CAAC,CAAC;QAE/E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAED,0CAA0C;IAC1C,QAAQ,CAAC,OAAkB;QACvB,IAAI,CAAC,UAAU,EAAE,CAAC;QAElB,yBAAyB;QACzB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAiB,EAAE,CAAC;QAEhC,0CAA0C;QAC1C,IAAI,CAAC,cAAc;aACd,GAAG,CAAC,EAAE,CAAC,EAAE;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAE,CAAC;YAEnE,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;gBAC5B,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;uBACtD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;YAGH,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YAED,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEP,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,uBAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC;CACJ;AA5HD,wCA4HC;AAMD,MAAa,UAAU;IAMnB,YACI,SAAiC,EAAE;QAL9B,SAAI,GAAW,YAAY,CAAC;QAOjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAGD,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACtC,GAAG,GAAG;YACN,GAAG,IAAI,CAAC,MAAM;SACjB,CAAC,EAAE,EAAc,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACtC,GAAG,GAAG;YACN,GAAG,IAAI,CAAC,KAAK;SAChB,CAAC,EAAE,EAAc,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAGD,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;IAChE,CAAC;IAGD;;;;;OAKG;IACH,GAAG,CACC,IAA0B;QAE1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvB,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ;AAtDD,gCAsDC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaas/a-concept",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"ext": "ts, js"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
-
"test": "jest
|
|
23
|
+
"test": "jest",
|
|
24
24
|
"start": "nodemon ./tests/log.ts",
|
|
25
25
|
"example:simple": "nodemon ./examples/simple/concept.ts",
|
|
26
26
|
"example:simple:trace": "node -r tsconfig-paths/register -r ts-node/register -r ./trace-require.js ./examples/simple/concept.ts",
|
|
@@ -69,6 +69,7 @@ export function A_Abstraction_Extend(
|
|
|
69
69
|
metaKey = A_TYPES__ComponentMetaKey.ABSTRACTIONS
|
|
70
70
|
break;
|
|
71
71
|
}
|
|
72
|
+
const setName = `CONCEPT_ABSTRACTION::${name}`;
|
|
72
73
|
|
|
73
74
|
// Get the existed metadata or create a new one
|
|
74
75
|
const existedMeta: A_Meta<{
|
|
@@ -76,9 +77,7 @@ export function A_Abstraction_Extend(
|
|
|
76
77
|
}> = meta.get(metaKey) || new A_Meta();
|
|
77
78
|
|
|
78
79
|
// Set the metadata of the method to define a custom Stage with name
|
|
79
|
-
const existedMetaValue = existedMeta.get(
|
|
80
|
-
|
|
81
|
-
const setName = `CONCEPT_ABSTRACTION::${name}`;
|
|
80
|
+
const existedMetaValue = existedMeta.get(setName) || [];
|
|
82
81
|
|
|
83
82
|
// Add the new method to the metadata
|
|
84
83
|
existedMetaValue.push({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { A_Error } from "../global/A-Error/A_Error.class";
|
|
1
2
|
import { A_Feature } from "../global/A-Feature/A-Feature.class";
|
|
2
3
|
import { A_TYPES__FeatureDefineDecoratorTemplateItem } from "../global/A-Feature/A-Feature.types";
|
|
3
4
|
import { A_Stage } from "../global/A-Stage/A-Stage.class";
|
|
@@ -46,30 +47,36 @@ export class A_StepsManager {
|
|
|
46
47
|
|
|
47
48
|
// Add directed edges based on 'before' and 'after'
|
|
48
49
|
this.entities.forEach(entity => {
|
|
49
|
-
const
|
|
50
|
+
const entityId = this.ID(entity);
|
|
51
|
+
const { before = [], after = [] } = entity;
|
|
50
52
|
|
|
51
53
|
// Add edges for 'before' dependencies
|
|
54
|
+
// If entity should execute before targets, then targets depend on entity
|
|
55
|
+
// So we add edges: target -> entity (target depends on entity)
|
|
52
56
|
before.forEach(dep => {
|
|
53
57
|
const targets = this.matchEntities(dep);
|
|
54
58
|
targets.forEach(target => {
|
|
55
59
|
if (!this.graph.has(target)) this.graph.set(target, new Set());
|
|
56
|
-
this.graph.get(target)!.add(
|
|
60
|
+
this.graph.get(target)!.add(entityId); // target depends on entity
|
|
57
61
|
});
|
|
58
62
|
});
|
|
59
63
|
|
|
60
|
-
// Add edges for 'after' dependencies
|
|
64
|
+
// Add edges for 'after' dependencies
|
|
65
|
+
// If entity should execute after sources, then entity depends on sources
|
|
66
|
+
// So we add edges: entity -> source (entity depends on source)
|
|
61
67
|
after.forEach(dep => {
|
|
62
68
|
const sources = this.matchEntities(dep);
|
|
69
|
+
|
|
63
70
|
sources.forEach(source => {
|
|
64
|
-
if (!this.graph.has(
|
|
65
|
-
this.graph.get(
|
|
71
|
+
if (!this.graph.has(entityId)) this.graph.set(entityId, new Set());
|
|
72
|
+
this.graph.get(entityId)!.add(source); // entity depends on source
|
|
66
73
|
});
|
|
67
74
|
});
|
|
68
75
|
});
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
// Match entities by name or regex
|
|
72
|
-
private matchEntities(pattern) {
|
|
79
|
+
private matchEntities(pattern: string): string[] {
|
|
73
80
|
const regex = new RegExp(`^${pattern}$`);
|
|
74
81
|
return this.entities
|
|
75
82
|
.filter(entity => regex.test(this.ID(entity)))
|
|
@@ -77,8 +84,8 @@ export class A_StepsManager {
|
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
// Topological sort with cycle detection
|
|
80
|
-
private visit(node) {
|
|
81
|
-
if (this.tempMark.has(node)) throw new
|
|
87
|
+
private visit(node: string): void {
|
|
88
|
+
if (this.tempMark.has(node)) throw new A_Error("Circular dependency detected");
|
|
82
89
|
|
|
83
90
|
if (!this.visited.has(node)) {
|
|
84
91
|
this.tempMark.add(node);
|
|
@@ -3,7 +3,6 @@ import './test.setup'
|
|
|
3
3
|
import { A_Concept } from '@adaas/a-concept/global/A-Concept/A-Concept.class';
|
|
4
4
|
import { A_Container } from '@adaas/a-concept/global/A-Container/A-Container.class';
|
|
5
5
|
import { A_Context } from '@adaas/a-concept/global/A-Context/A-Context.class';
|
|
6
|
-
import { A_ScopeError } from '@adaas/a-concept/global/A-Scope/A-Scope.error';
|
|
7
6
|
|
|
8
7
|
jest.retryTimes(0);
|
|
9
8
|
|
|
@@ -150,5 +149,110 @@ describe('A-Abstraction Tests', () => {
|
|
|
150
149
|
expect(containerA._test).toBe(5);
|
|
151
150
|
expect(containerB._test).toBe(1);
|
|
152
151
|
})
|
|
153
|
-
|
|
152
|
+
it('Should execute abstraction in a proper order', async () => {
|
|
153
|
+
A_Context.reset();
|
|
154
|
+
|
|
155
|
+
const order: string[] = [];
|
|
156
|
+
|
|
157
|
+
class MyContainerA extends A_Container {
|
|
158
|
+
|
|
159
|
+
@A_Concept.Load()
|
|
160
|
+
async step1() {
|
|
161
|
+
order.push('step1');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@A_Concept.Load()
|
|
165
|
+
async step2() {
|
|
166
|
+
order.push('step2');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
class MyContainerB extends A_Container {
|
|
170
|
+
|
|
171
|
+
@A_Concept.Load()
|
|
172
|
+
async step3() {
|
|
173
|
+
order.push('step3');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@A_Concept.Load()
|
|
177
|
+
async step4() {
|
|
178
|
+
order.push('step4');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
const containerA = new MyContainerA({ name: 'ContainerA' });
|
|
184
|
+
const containerB = new MyContainerB({ name: 'ContainerB' });
|
|
185
|
+
|
|
186
|
+
const concept = new A_Concept({
|
|
187
|
+
name: 'TestConcept',
|
|
188
|
+
containers: [
|
|
189
|
+
containerA,
|
|
190
|
+
containerB
|
|
191
|
+
]
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
await concept.load();
|
|
195
|
+
|
|
196
|
+
expect(order).toEqual(['step1', 'step2', 'step3', 'step4']);
|
|
197
|
+
})
|
|
198
|
+
it('Should execute abstraction in order with dependencies', async () => {
|
|
199
|
+
A_Context.reset();
|
|
200
|
+
|
|
201
|
+
const order: string[] = [];
|
|
202
|
+
|
|
203
|
+
class MyContainerA extends A_Container {
|
|
204
|
+
|
|
205
|
+
@A_Concept.Load()
|
|
206
|
+
async step1() {
|
|
207
|
+
order.push('step1');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@A_Concept.Load({
|
|
211
|
+
after: ['MyComponentA.step3']
|
|
212
|
+
})
|
|
213
|
+
async step2() {
|
|
214
|
+
order.push('step2');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
class MyComponentA extends A_Component {
|
|
219
|
+
|
|
220
|
+
@A_Concept.Load()
|
|
221
|
+
async step3() {
|
|
222
|
+
order.push('step3');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class MyContainerB extends A_Container {
|
|
228
|
+
|
|
229
|
+
@A_Concept.Load()
|
|
230
|
+
async step4() {
|
|
231
|
+
order.push('step4');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
@A_Concept.Load({
|
|
235
|
+
before: ['MyContainerB.step4']
|
|
236
|
+
})
|
|
237
|
+
async step5() {
|
|
238
|
+
order.push('step5');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
const containerA = new MyContainerA({ name: 'ContainerA', components: [MyComponentA] });
|
|
244
|
+
const containerB = new MyContainerB({ name: 'ContainerB' });
|
|
245
|
+
|
|
246
|
+
const concept = new A_Concept({
|
|
247
|
+
name: 'TestConcept',
|
|
248
|
+
containers: [
|
|
249
|
+
containerA,
|
|
250
|
+
containerB
|
|
251
|
+
]
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await concept.load();
|
|
255
|
+
|
|
256
|
+
expect(order).toEqual(['step1', 'step3', 'step2', 'step5', 'step4']);
|
|
257
|
+
})
|
|
154
258
|
});
|
package/tests/A-Feature.test.ts
CHANGED
|
@@ -139,4 +139,93 @@ describe('A-Feature tests', () => {
|
|
|
139
139
|
expect(myComponent.sum).toBe(2);
|
|
140
140
|
|
|
141
141
|
});
|
|
142
|
+
it('Should execute feature steps in base order', async () => {
|
|
143
|
+
const executionOrder: string[] = [];
|
|
144
|
+
|
|
145
|
+
// 1) create a base component with some feature
|
|
146
|
+
class My_Component extends A_Component {
|
|
147
|
+
async methodA() {
|
|
148
|
+
await this.call('myFeature')
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@A_Feature.Extend({
|
|
152
|
+
name: 'myFeature',
|
|
153
|
+
})
|
|
154
|
+
async stepOne(
|
|
155
|
+
) {
|
|
156
|
+
executionOrder.push('stepOne');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@A_Feature.Extend({
|
|
160
|
+
name: 'myFeature',
|
|
161
|
+
})
|
|
162
|
+
async stepTwo(
|
|
163
|
+
) {
|
|
164
|
+
executionOrder.push('stepTwo');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@A_Feature.Extend({
|
|
168
|
+
name: 'myFeature',
|
|
169
|
+
})
|
|
170
|
+
async stepThree(
|
|
171
|
+
) {
|
|
172
|
+
executionOrder.push('stepThree');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// 2) create a running scope
|
|
178
|
+
const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
179
|
+
|
|
180
|
+
// 3) create an instance of the component from the scope
|
|
181
|
+
const myComponent = scope.resolve(My_Component);
|
|
182
|
+
expect(myComponent).toBeInstanceOf(My_Component);
|
|
183
|
+
|
|
184
|
+
// 4) call the feature caller to execute the feature
|
|
185
|
+
await myComponent.methodA();
|
|
186
|
+
|
|
187
|
+
// 5) check the results
|
|
188
|
+
expect(executionOrder).toEqual(['stepOne', 'stepTwo', 'stepThree']);
|
|
189
|
+
});
|
|
190
|
+
it('Should execute feature steps in proper order', async () => {
|
|
191
|
+
const executionOrder: string[] = [];
|
|
192
|
+
|
|
193
|
+
// 1) create a base component with some feature
|
|
194
|
+
class My_Component extends A_Component {
|
|
195
|
+
async methodA() {
|
|
196
|
+
await this.call('myFeature')
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@A_Feature.Extend({
|
|
200
|
+
name: 'myFeature',
|
|
201
|
+
after: ['My_Component.stepTwo'],
|
|
202
|
+
})
|
|
203
|
+
async stepOne(
|
|
204
|
+
) {
|
|
205
|
+
executionOrder.push('stepOne');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
@A_Feature.Extend({
|
|
209
|
+
name: 'myFeature',
|
|
210
|
+
})
|
|
211
|
+
async stepTwo(
|
|
212
|
+
) {
|
|
213
|
+
executionOrder.push('stepTwo');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
// 2) create a running scope
|
|
219
|
+
const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
220
|
+
|
|
221
|
+
// 3) create an instance of the component from the scope
|
|
222
|
+
const myComponent = scope.resolve(My_Component);
|
|
223
|
+
expect(myComponent).toBeInstanceOf(My_Component);
|
|
224
|
+
|
|
225
|
+
// 4) call the feature caller to execute the feature
|
|
226
|
+
await myComponent.methodA();
|
|
227
|
+
|
|
228
|
+
// 5) check the results
|
|
229
|
+
expect(executionOrder).toEqual(['stepTwo', 'stepOne']);
|
|
230
|
+
});
|
|
142
231
|
});
|