Skip to content

Instantly share code, notes, and snippets.

@Tagakov
Last active December 11, 2017 16:44
Show Gist options
  • Save Tagakov/b4ed51702a549e6db364eb74f875fd0c to your computer and use it in GitHub Desktop.
Save Tagakov/b4ed51702a549e6db364eb74f875fd0c to your computer and use it in GitHub Desktop.
redux?
typealias Epic<State> = (actions: Observable<Action>, currentState: CurrentState<State>) -> Observable<Action>
typealias CurrentState<State> = () -> State
class EpicMiddleware<State: Any> constructor(): Middleware<State> {
private val epics = PublishSubject.create<Epic<State>>()
override fun invoke(store: Store<State>, nextDispatcher: Dispatcher) : Dispatcher {
val actions = PublishSubject.create<Action>()
epics
.flatMap { it(actions, { store.currentState }) }
.subscribe { store.dispatch(it) }
return { action ->
nextDispatcher(action)
actions.onNext(action)
}
}
fun registerEpic(epic: Epic<State>) = PublishSubject.create<Action>()
.run {
val cancellableEpic: Epic<State> = { actions, store -> epic(actions, store).takeUntil(this) }
epics.onNext(cancellableEpic)
Disposables.fromAction { onComplete() }
}
}
interface Action
typealias Reducer<State> = (state: State, action: Action) -> State
typealias Dispatcher = (action: Action) -> Unit
typealias Middleware<State> = (store: Store<State>, nextDispatcher: Dispatcher) -> Dispatcher
val INIT_ACTION: Action = object: Action {}
class Store<State: Any> (
reducer: Reducer<State>,
initialState: State,
reduceScheduler: Scheduler = Schedulers.io(),
vararg middlewares: Middleware<State> = emptyArray()
) {
val dispatch: Dispatcher
val states: Observable<State>
@Volatile var currentState: State = reducer(initialState, INIT_ACTION)
private set
init {
val subject = PublishSubject.create<Action>()
dispatch = middlewares.foldRight(subject::onNext as Dispatcher) { middleware, nextDispatcher ->
middleware(this, nextDispatcher)
}
states = subject
.observeOn(reduceScheduler, false, 8)
.scan(currentState, reducer)
.replay(1)
.refCount()
.also { it.subscribe { state -> currentState = state } }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment