# eventsource-api This project provides what we think be a lean eventsourcing API. The goal is to set a common ground for eventsourcing-based application, yet doesn't force you to be trapped under a restrictive framework. This library main abstraction is the `Store` typeclass. ```haskell -- | Main event store abstraction. It exposes essential features expected from -- an event store. class Store store where -- | Appends a batch of events at the end of a stream. appendEvents :: (EncodeEvent a, MonadBase IO m) => store -> StreamName -> ExpectedVersion -> [a] -> m (Async EventNumber) -- | Reads a stream in a stream-processing fashion. readStream :: MonadBase IO m => store -> StreamName -> Batch -> Stream (Of SavedEvent) (ExceptT ReadFailure m) () -- | Subscribes to given stream. subscribe :: MonadBase IO m => store -> StreamName -> m Subscription ``` The idea is to use any backend of your liking as long as it's able to derive that typeclass with its related implicit constraints. 1. `appendEvents` MUST add events at the end of a stream without doing any other alteration on the stream. The order of the event's array MUST be respected within the store. Most important, the implementation MUST comply to the given `ExpectedVersion` passed by the user. 2. `readStream` SHOULD retrieve a set of event given a starting position and a batch size (represented by the `Batch` parameter). The returned array MUST have its events ordered by their `EventNumber` property. 3. `subscribe` SHOULD register a subscription to the given stream. An implementation MUST allow to subscribe to a stream that doesn't exist yet. A subscription allows the user to be notified of any event added to the stream. There is no mandatory timing to meet regarding how fast the subscription is notified by a change. We only suggest to dispatch new events as soon as possible. #### `ExpectedVersion` A word on `ExpectedVersion`. It's a mean to preserve data consistency in a concurrent setting. ```haskell -- | The purpose of 'ExpectedVersion' is to make sure a certain stream state is -- at an expected point in order to carry out a write. data ExpectedVersion = AnyVersion -- Stream is a any given state. | NoStream -- Stream shouldn't exist. | StreamExists -- Stream should exist. | ExactVersion EventNumber -- Stream should be at givent event number. ``` On a write, if the `ExpectedVersion` condition given by the user is not met within the store, the implementation should raise an exception. At the moment, the API doesn't capture this situation in the type system.