-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scala.js support #54
Comments
Thanks. Yes, can see the excellent modularity. I'd like to
In
Please see https://tech.zilverline.com/2011/02/10/towards-an-immutable-domain-model-monads-part-5 for details. This pattern is like a "journal" but decoupled from the actual persistence mechanism. A code example for an idea. Note The pattern works in reverse:
Showing all of this to make the case that this is not so much about I wonder if you would agree to review this Is there a way to achieve this same effect of events detached from journal with |
Yes, there is almost everything you need. sealed abstract class CustomerEvent
final case class CollateralRegistered(collateral: Collateral) extends CustomerEvent
sealed abstract class CustomerRejection
object CustomerNotFound extends CustomerRejection
def update(state: Option[CustomerState], e: CustomerEvent): Folded[Option[CustomerState]] = ???
@autoFunctorK(false)
trait Customer[F[_]] {
def registerCollateral(collateral: Collateral): F[Unit]
}
final class CustomerActions[F[_]](
implicit
F: MonadActionReject[F, Option[CustomerState], CustomerEvent, CustomerRejection]
) extends Customer[F] {
import F._
def registerCollateral(collateral: Collateral): F[Unit] =
read.flatMap {
case Some(customer) =>
append(CollateralRegistered(collateral))
case None =>
reject(CustomerNotFound)
}
}
type In[A] = ActionT[EitherT[IO, CustomerRejection, ?], Option[CustomerState], CustomerEvent, ?]
type Out[A] = IO[Either[CustomerRejection, (Chain[CustomerEvent], A))
val customerActions = new CustomerActions[In]
val customers: CustomerId => Customer[Out] = {
customerId =>
customerActions.mapK(new (In ~> Out) {
def apply[A](action: In[A]): Out[A] =
CustomerRepository.findCustomerById(customerId)
.flatMap { customerState =>
action.run(customerState, _.update(_)).value.flatMap {
case Right(Next(a @ (events, _))) => CustomerRepository.appendEvents(customerId, events).as(Right(a))
case Left(rejection) => IO(Left(rejection))
case Right(Impossible) => IO.raiseError(new IllegalStateException)
}
}
} I don't know what |
@SemanticBeeng I can only see slight problems with So I would first move Clock to schedule module, and then core would surely cross-compile. |
Excellent example Denis. Reviewed this thoroughly and looks very good.
In this previous project I reused this little pattern from the article above
Wip on fitting this in with your example but can see things to try. So by the example above you mean that such kind of code should cross-build? |
@SemanticBeeng I think it’s better to move our discussion from the closed PR #50.
I’m very into adding Scala.js support. You don’t need Akka for single-machine environment (assuming we run entities in browser). The runtime is very easy to implement. All components are already here.
We need to decide how the event journal should be implemented, in-mem or using browser local storage. It’s up to you to decide, I’ll help you to implement it, but I don’t have experience with browser specific API
The text was updated successfully, but these errors were encountered: