s2.spring.automate.data.persister.SpringDataAutomateReactivePersister.kt Maven / Gradle / Ivy
package s2.spring.automate.data.persister
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.zip
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.reactive.awaitFirstOrNull
import kotlinx.coroutines.reactive.awaitSingle
import kotlinx.coroutines.reactor.asFlux
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import reactor.core.publisher.Flux
import s2.automate.core.context.AutomateContext
import s2.automate.core.context.InitTransitionAppliedContext
import s2.automate.core.context.TransitionAppliedContext
import s2.automate.core.persist.AutomatePersister
import s2.dsl.automate.Evt
import s2.dsl.automate.S2Automate
import s2.dsl.automate.S2State
import s2.dsl.automate.model.WithS2Id
import s2.dsl.automate.model.WithS2State
class SpringDataAutomateReactivePersister(
private val repository: ReactiveCrudRepository,
) : AutomatePersister where
EVENT : Evt,
STATE : S2State,
ENTITY : WithS2State,
ENTITY : WithS2Id {
override suspend fun persist(
transitionContext: TransitionAppliedContext,
): ENTITY {
return repository.save(transitionContext.entity).awaitSingle()
}
override suspend fun load(automateContext: AutomateContext, id: ID & Any): ENTITY? {
return repository.findById(id).awaitFirstOrNull()
}
override suspend fun persist(
transitionContext: InitTransitionAppliedContext
): ENTITY {
return repository.save(transitionContext.entity).awaitSingle()
}
override suspend fun persistInitFlow(
transitionContexts: Flow>
): Flow = flow {
val entities = mutableListOf()
val events = mutableListOf()
transitionContexts.collect { context ->
entities.add(context.entity)
events.add(context.event)
}
repository.saveAll(entities)
events.forEach { event ->
emit(event)
}
}
override suspend fun persistFlow(
transitionContext: Flow>
): Flow = flow {
val entities = mutableListOf()
val events = mutableListOf()
// Collect entities and events from the transition context
transitionContext.collect { context ->
entities.add(context.entity)
events.add(context.event)
}
// Persist the entities using the repository
repository.saveAll(entities)
// Emit the events
events.forEach { event ->
emit(event)
}
}
}