Split the public interface into submodules

The purpose of this change is to avoid polluting the namespace with too
many exports. I also moved the private interface into its own submodule
so that I can import and access its functionality from the other
submodules.