There's nonstandard nomenclature in "_dispose"; if the constructing function is called _create, the common pattern is to pair it with _destroy.
typedefs ending with _t are reserved for standards extensions, though these days people ignore this a lot because it feels like general practice to add _t.
There's no way to pass in a custom allocator, or logging callback, or set some debug logging flags. Maybe something to tackle later.
Both _select functions fall short in that they do not allow select'ing on channels + other file descriptors simultaneously. General library design practice is to have the library return a file descriptor that can be used in whatever event loop the application already uses. (The fd can be a dummy pipe or eventfd.)
All of these things are in the header, so they matter the most as they set ABI and API for any user. Unfortunately getting them right as early as possible is important to avoid breaks; yet very hard to do since often API aspects only become clear after a library has non-trivial users.
[edited to tone down a bit]