Type-Safe Event Definition
Define events with compile-time versioning guarantees. No runtime surprises.
-- Event definition
instance Event "user_registered"
-- Event payload
data UserInfo = UserInfo
{ userId :: Text
, email :: Text
} deriving (Generic, FromJSON, ToJSON)
-- Version declaration
type instance MaxVersion UserRegistered = 0
type instance Versions UserRegistered =
'[UserInfo]
-- Migration (automatic for single version)
instance MigrateVersion 0 UserRegistered
Backend-Agnostic Subscriptions
Subscribe to events with handlers that work across all backends.
{-# LANGUAGE RequiredTypeArguments #-}
-- Subscribe to events (works with any backend)
subscribeToUsers :: BackendHandle backend -> IO (SubscriptionHandle backend)
subscribeToUsers store =
subscribe store
( match "user_registered" handleUser :?
MatchEnd )
(EventSelector AllStreams FromBeginning)
where
-- Handler runs for each event
handleUser envelope = do
let user = envelope.payload
putStrLn $ "New user: " <> user.email
return Continue
SQL Projection Handlers
Transform events into queryable read models with ACID guarantees.
{-# LANGUAGE RequiredTypeArguments #-}
-- Projection handler (PostgreSQL transactions)
userProjection :: ProjectionHandler "user_registered" backend
userProjection envelope = do
let user = envelope.payload
-- Execute SQL in transaction
statement () $ Statement sql encoder decoder True
where
sql = "INSERT INTO users (id, email) VALUES ($1, $2)"
encoder = contrazip2
(param (nonNullable text))
(param (nonNullable text))
Flexible Backend Choice
Start simple, scale when ready. Same API, different backends.
-- File system store
fsStore :: IO (BackendHandle FilesystemStore)
sqlStore =
newFilesystemStore "./events"
-- PostgreSQL store
sqlStore :: IO (BackendHandle PostgreSQLStore)
sqlStore = do
pool <- createPool postgresSettings
newPostgreSQLStore pool
-- Same operations, different backends
insertEvents devStore Nothing batch
insertEvents sqlStore Nothing batch
.png)
![I made a (useless) quantum computer at home (2023) [video]](https://www.youtube.com/img/desktop/supported_browsers/edgium.png)
