Skip to content

0.2.0

Compare
Choose a tag to compare
@gordonbrander gordonbrander released this 16 Sep 18:14
· 16 commits to main since this release
5ea1c8b

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 implements StoreProtocol
  • Implement StoreProtocol for Store
  • 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 an update(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 implements ModelProtocol. 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
  • 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> to Update<Model: ModelProtocol>.
    • Store type signature changes from Store<State, Action, Environment> to Store<Model: ModelProtocol>
    • Store initializer changes from Store.init(update:state:environment:) to Store.init(state:environment:). Now that state conforms to ModelProtocol, you don't have to explicitly pass in the update function as a closure. We can just call the protocol implementation.
  • store.binding has been removed in favor of Binding(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.