Emit on change, deep copy objects

* Only emit on change
* Deep copy all objects on input and output
* Add keypath access
* Fix nested `.wait()`

This also, somewhat controversially, switches ObjectState to use a more "functional" style internally. This successfully hides the internal state object from any outside mutation, and does not present any notable performance hits.
might rephrase to indicate that it only emits on change.