You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.4 KiB

3 years ago
  1. package nova.monadic_sfx.util.reactive.store
  2. import monix.bio.Task
  3. import monix.eval.Coeval
  4. import monix.reactive.OverflowStrategy
  5. import monix.reactive.subjects.ConcurrentSubject
  6. object Store {
  7. def createL[A, M](
  8. initialAction: A,
  9. initialState: M,
  10. reducer: Reducer[A, M],
  11. middlewares: Seq[Middleware[A, M]] = Seq.empty,
  12. overflowStrategy: OverflowStrategy.Synchronous[A] =
  13. OverflowStrategy.DropOld(50)
  14. ): Task[Store[A, M]] =
  15. Task.deferAction { implicit s =>
  16. Task {
  17. val subject = ConcurrentSubject.publish[A](overflowStrategy)
  18. val fold: ((A, M), A) => Coeval[(A, M)] = {
  19. case ((_, state), action) =>
  20. Coeval {
  21. val (newState, effects) = reducer(state, action)
  22. effects.subscribe(subject.onNext _)
  23. action -> newState
  24. }
  25. }
  26. val obs = subject
  27. .scanEval0F[Coeval, (A, M)](
  28. Coeval.pure(initialAction -> initialState)
  29. )(fold)
  30. val res = middlewares
  31. .foldLeft(obs) {
  32. case (obs, middleware) => middleware(obs)
  33. }
  34. .doOnNextF(i => Coeval(println(s"Emitted item 1: $i")))
  35. .behavior(initialAction -> initialState)
  36. .refCount
  37. // .doOnNextF(i => Coeval(println(s"Emitted item 2: $i")))
  38. MonixProSubject.from(
  39. subject,
  40. res
  41. )
  42. }
  43. }
  44. }