#6: Fix up error handling

- Errors are now written to *both* the read channel and the channel-delivery channel (in the latter case, wrapped in a unidirectional, single-purpose channel which delivers that error and has no other use).
- Do not assume that on-error will return an event with a `data` attribute. This attribute is not guaranteed to exist by the W3 spec for WebSockets. Instead, defer error delivery until `onclose()` is called, which is guaranteed by spec to have `reason` and `code` attributes.
- Do not assume that put! will act synchronously.