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.

57 lines
1.5 KiB

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