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
StoreProtocol
forStore
- 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.ModelProtocol
allows 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.binding
has 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
.default
QoS. We have reduced the QoS from.userInteractive
to 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.