package outwatchapp.util.reactive.store import java.time.LocalDateTime import io.circe.Encoder import io.circe.Printer import io.circe.generic.JsonCodec import io.circe.syntax._ import io.odin.Logger import io.odin.LoggerMessage import io.odin.formatter.options.PositionFormat import io.odin.formatter.options.ThrowableFormat import io.odin.meta.Render import monix.bio.Task import monix.reactive.Observable @JsonCodec final case class StoreInfo[A]( name: String, action: A, time: LocalDateTime ) object StoreInfo { val printer = Printer.noSpaces implicit def render[T: Encoder]: Render[StoreInfo[T]] = new Render[StoreInfo[T]] { override def render(m: StoreInfo[T]): String = printer.print(m.asJson) } } object Middlewares { val format = create(ThrowableFormat.Default, PositionFormat.Full) def create( throwableFormat: ThrowableFormat, positionFormat: PositionFormat ): io.odin.formatter.Formatter = (msg: LoggerMessage) => msg.message.value def actionStateLoggerMiddleware[A, M]( logger: Logger[Task] ): Task[Middleware[A, M]] = Task.deferAction(implicit s => Task((obs: Observable[(A, M)]) => obs.doOnNextF { case (a, m) => logger.debug(s"Received action $a with state $m") } ) ) def actionLoggerMiddleware[A: Encoder, M]( logger: Logger[Task], name: String ): Task[Middleware[A, M]] = Task.deferAction(implicit s => Task((obs: Observable[(A, M)]) => obs.doOnNextF { case (a, _) => Task(LocalDateTime.now()) .flatMap(curTime => logger.debug(StoreInfo(name, a, curTime))) } ) ) }