Package-level declarations
Types
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.
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.
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.
What to do when an effect in a batch fails.
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.
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.
Stores per-chat FSM state.
Properties
The dispatcher telek runs blocking-capable work on — synchronous EffectHandlers (see EffectExecutorImpl) and, in :persistence, file I/O.
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.