package nova.monadic_sfx.util.reactive 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 // object Middleware { // def apply[A,M,T](ob: Observable[(A,M)], cb: (A,M) => T): Observable[(A,M)] = ob // } @JsonCodec final case class StoreInfo[A]( name: String, action: A, time: LocalDateTime = LocalDateTime.now() ) 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 encoder: Encoder[LoggerMessage] = // Encoder.forProduct1("message")(m => m.message.value) val format = create(ThrowableFormat.Default, PositionFormat.Full) def create( throwableFormat: ThrowableFormat, positionFormat: PositionFormat ): io.odin.formatter.Formatter = { // val encoder: Encoder[LoggerMessage] = // Encoder.forProduct1("message")(m => m.message.value) (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, _) => logger.debug(StoreInfo(name, a)) } ) ) }