tidy up API, enforce correct listener prototype