Package-level declarations

Types

Link copied to clipboard

Handles an Effect that shouldn't block the transition that produced it — typically network calls. Unlike EffectHandler, this doesn't run as part of the current transition and doesn't produce an EffectResult: it runs independently (cancelled if the chat goes idle, see ChatWorkers in telek's implementation), and whatever Event it returns re-enters the FSM as its own, later transition — handled by StateDispatcher's transition(state, event) overload.

Link copied to clipboard
data class Callback(val chatId: Long, val messageId: Long, val data: String) : Input
Link copied to clipboard
interface Debounced

Opt-in marker for an Effect whose async dispatch should cancel any previous in-flight async effect for the same chat with an equal debounceKey, instead of letting them run concurrently — e.g. a user clicking through categories quickly, where only the latest fetch's result should matter.

Link copied to clipboard
interface Dispatcher
Link copied to clipboard
interface Effect
Link copied to clipboard
interface EffectExecutor
Link copied to clipboard
class EffectExecutorImpl(effectRegistry: EffectRegistry, context: suspend () -> ExecutionContext, failurePolicy: EffectFailurePolicy = EffectFailurePolicy.CONTINUE, logger: TelekLogger = TelekLogger.NoOp) : EffectExecutor

Looks up a handler per effect in effectRegistry and runs it. context is resolved once per execute call — transport-specific executors (e.g. telegramEffectExecutor()) use this to supply an ExecutionContext that may only become available after telek itself is constructed (e.g. once a bot instance exists), without Telek needing to own or track that lifecycle.

Link copied to clipboard
class EffectFailed(val error: Throwable) : EffectResult
Link copied to clipboard

What to do when an effect in a batch fails.

Link copied to clipboard
interface EffectHandler<E : Effect>
Link copied to clipboard
Link copied to clipboard
interface EffectResult
Link copied to clipboard
Link copied to clipboard
data object EmptyState : State
Link copied to clipboard
interface Event

Something that happened asynchronously and needs to re-enter the FSM for a chat — the result of an AsyncEffectHandler, not something a user sent. Unlike Input, an Event can never start a flow: it's routed purely by the chat's current state (see StateDispatcher.transition overload that takes an Event), never by command or callback data.

Link copied to clipboard
Link copied to clipboard
interface FinalState
Link copied to clipboard
Link copied to clipboard
fun interface InitialStateProvider
Link copied to clipboard
interface Input
Link copied to clipboard
data class Message(val chatId: Long, val text: String) : Input
Link copied to clipboard
interface State
Link copied to clipboard
Link copied to clipboard
interface StateMachine<S : State, I : Input>
Link copied to clipboard
interface StateStorage<S : State>
Link copied to clipboard
class Telek(scope: CoroutineScope = CoroutineScope(Dispatchers.Default), userStateStore: UserStateStore = DefaultUserStateStore(), dispatchers: List<StateDispatcher<out State>>, initialStateProvider: InitialStateProvider = InitialStateProvider { EmptyState }, interceptors: List<TelekInterceptor> = emptyList(), effectExecutor: EffectExecutor, findDispatcherStrategy: FindDispatcherStrategy = DefaultFindDispatcherStrategy(dispatchers), chatWorkerIdleTimeout: Duration = 15.minutes, chatInboxCapacity: Int = 64, logger: TelekLogger = TelekLogger.NoOp)
Link copied to clipboard
Link copied to clipboard
interface TelekLogger

telek's own logging seam: println/java.util.logging are not acceptable in a library, since the consumer can neither redirect nor silence them. Pass an implementation that forwards to whatever the consumer already uses (slf4j, kotlin-logging, ...) — telek has no opinion on the concrete backend and does not depend on one.

Link copied to clipboard
Link copied to clipboard
class TelekTransitionGate<S : State>(telek: Telek, kClass: KClass<S>) : TransitionGate<S>
Link copied to clipboard
Link copied to clipboard
interface TransitionGate<S : State>
Link copied to clipboard
data class TransitionResult<S : State>(val newState: S, val effects: List<Effect> = emptyList())
Link copied to clipboard
data class UpdateResult(val oldState: State?, val newState: State, val effects: List<Effect>, val dispatcher: StateDispatcher<out State>?)
Link copied to clipboard
interface UserStateStore

Stores per-chat FSM state.

Link copied to clipboard
annotation class WizardDsl

Properties

Link copied to clipboard
expect val telekIoDispatcher: CoroutineDispatcher

The dispatcher telek runs blocking-capable work on — synchronous EffectHandlers (see EffectExecutorImpl) and, in :persistence, file I/O.

actual val telekIoDispatcher: CoroutineDispatcher
actual val telekIoDispatcher: CoroutineDispatcher

Dispatchers.IO is unreachable from a Kotlin/Native source set: kotlinx-coroutines declares the public one as an expect extension in its concurrent source set, but Dispatchers on Native also has an internal val IO member, and a member always shadows an extension — so the reference resolves to the internal one and fails to compile outside kotlinx-coroutines itself.

Functions

Link copied to clipboard
Link copied to clipboard
inline fun <S : State> transition(block: TransitionBuilder<S>.() -> Unit): TransitionResult<S>