There's a flaw in the default retry behavior on line 59: whenever an error occurs, a new call stack is created and we immediately return.
Instead of returning, we should await this._onEventsError here and ensure that onEventsError is a promise.
Currently waiting for amplitude.flush causes the node.js event loop to never clear in the case of a rate limit error.
Here's an example integration test without a rate limit using jest:

And here's one with a rate limit, notice how jest never exits:
