Rewrite event API to use a tagged union