two-sided event emitter with support for middleware