refactor core into a class with better async flow