Repository navigation
0.2.0
Version 0.2.0 is an important update to ObservableStore. It introduces the ability to create scoped stores for sub-components, called ViewStores. ViewStores are conceptually like bindings to stores, except that they expose the store API, instead of a binding API. This approach is inspired by the component mapping pattern from Elm.
Changes
- Introduce
StoreProtocol, a protocol that describes a kind of store. - Introduce
ViewStore<Model: ModelProtocol>, which implementsStoreProtocol - Implement
StoreProtocolforStore - Introduce
CursorProtocol, which describes how to map from one domain to another, and provides a convenience function for updating child components. - Introduce
ModelProtocol, which implements anupdate(state:action:environment)static function.ModelProtocolallows us to treat action and environment as associatedtypes, which simplifies many of our other type signatures.
- Synthesize
update(state:actions:environment)method for any type that implementsModelProtocol. This allows you to dispatch multiple actions immediately in sequence, effectively composing multiple actions.- This helper replaces
pipe - Useful when dispatching actions down to multiple child sub-components
- This helper replaces
- Add new tests
Breaking changes
- Store requires that state implement
ModelProtocol. This allows us to simplify the signatures of many other APIs- Update type signature changes from
Update<State, Action>toUpdate<Model: ModelProtocol>. - Store type signature changes from
Store<State, Action, Environment>toStore<Model: ModelProtocol> - Store initializer changes from
Store.init(update:state:environment:)toStore.init(state:environment:). Now that state conforms toModelProtocol, you don't have to explicitly pass in the update function as a closure. We can just call the protocol implementation.
- Update type signature changes from
store.bindinghas been removed in favor ofBinding(store:get:send:)- Remove Update.pipe. Redundant now. Was never happy with it anyway. It was an inelegant way to accomplish the same thing as
update(state:actions:environment:). - Join fx on main with a
.defaultQoS. We have reduced the QoS from.userInteractiveto avoid spamming that QoS with actions. This should not affect ordinary use of ObservableStore. fx are async/never block user interaction anyway, so a default QoS should be fine.