convert hooks into soft hooks

This implements soft hooks in a very aggressive destructive way.

cc @Matt-Esch 
it's worth noting that this is also a soft-unset hook. Anything stateful allocated by a hook will remain. (So if you were thinking of using this to unhook events and count listeners for example, it wouldn't work). Perhaps we should recursively unhook when destroying parent nodes?