struct Post {
let id: String
var text: String
var likeState: Bool
}
protocol State {}
struct RootState : State {
var userId: String? = nil
var posts: [String:Post] = [:]
}
protocol Renderable {
func render(_ state: State)
}
struct PostsImpression: Event {}
struct LikeRequested: Event {
let postId: String
let likeState: Bool
}
class Reducer : Subscriber {
let store: Store
let controller: Renderable
var state: RootState
init(store: Store, controller: Renderable, state: RootState){
self.store = store
self.controller = controller
self.state = state
}
func onEvent(event: Event){
switch event {
case _ as PostsImpression:
store.get("posts/\(state.userId!)")
store.get("likes/\(state.userId!)")
case let event as LikeRequested:
store.set("likes/\(state.userId!)/\(event.postId)", event.likeState)
case let event as Value where event.key.hasPrefix("likes"):
let postId = event.key.components(separatedBy: "/").last!
let likeState = event.val as! Bool
state.posts[postId]?.likeState = likeState
controller.render(state)
case let event as Value where event.key.hasPrefix("posts"):
let post = Post(
id: event.key.components(separatedBy: "/").last!,
text: event.val as! String,
likeState: false)
state.posts[post.id] = post
controller.render(state)
default:
break
}
}
}
Context
Redux’s reducer inspired me to think about this. Kleppmann’s blog post on turning the database inside out inspired me to think about stream processing in general.
Problem
Consolidate event processing from UI and data streams.