moonevent

    A MoonBit event bus and message abstraction layer for application decoupling.

    event
    event-bus
    pubsub
    message
    moonbit
    Download zip
    Author
    Version
    0.2.0
    License
    MIT
    Last updated
    2 months ago
    Downloads
    31

    No dependencies

    #MoonEvent

    MoonEvent is a MoonBit event bus and message abstraction layer for application decoupling.

    #Quick Start

    let bus = EventBus::new(name="app")
    .use_middleware("audit-tag", (event, _) => {
    MiddlewareContinue({ ..event, tags: append_tag(event.tags, "audit") })
    })
    .subscribe("audit-log", (event, _) => {
    if event.payload == "" {
    OutcomeFailed("empty payload")
    } else {
    OutcomeHandled("stored")
    }
    }, topic="user", tag="audit")

    let event = Event::new("user.created", topic="user", payload="alice")
    let (_, report) = bus.publish(event)

    #Features

    • Event, subscription, handler report, and dispatch report models
    • Real EventBus.publish execution for user-provided handler callbacks
    • Middleware pipeline that can rewrite or halt events before dispatch
    • Validated topic patterns with exact, *, and # matching
    • Handler priority plus pause, resume, unsubscribe, and correct one-shot lifecycle
    • Typed event wrapper with explicit payload encoding
    • Logical tick scheduler for delayed events
    • In-memory event queues with drain, peek, take, topic filter, and tag filter helpers
    • Queryable event store with retention, sequence cursors, and replay
    • Composable routing rules for forwarding, fan-out, tagging, renaming, promotion, and drop
    • Executable retry and dead-letter delivery flow with attempt reports
    • Idempotency cache for duplicate WebHook and task delivery protection
    • Resumable batch dispatch with event limits and failure stop policies
    • Dispatch metrics grouped by handler and topic
    • Event validation middleware with configurable policies
    • Human-readable debug traces and event summaries
    • 83 regression tests and a runnable CLI example

    #Core Workflow

    EventRouter.route transforms or fans out an input event. DedupCache removes duplicate deliveries, EventBus.publish executes middleware and matching handlers, and BusMetrics summarizes the resulting reports. EventStore.replay can later send selected stored events through the same pipeline.

    #Repository

    This project is developed for the 2026 MoonBit ecosystem hackathon.

    #Examples

    Run the CLI example:

    moon run cmd/main

    Run the full test suite:

    moon test

    Check package buildability:

    moon check

    #Development

    moon check moon test moon run cmd/main moon fmt --check moon info

    #License

    MIT

    HandlerFn

    type HandlerFn = (Event, EventContext) -> HandlerOutcome

    MiddlewareFn

    type MiddlewareFn = (Event, EventContext) -> MiddlewareOutcome

    BatchFailureMode

    pub(all) enum BatchFailureMode {
    BatchContinue
    BatchStopOnFailure
    BatchStopOnUndelivered
    BatchStopOnStopped
    } derive(Eq,
    Debug
    )

    BatchHaltReason

    pub(all) enum BatchHaltReason {
    BatchNotHalted
    BatchLimitReached
    BatchDispatchFailed(Int)
    BatchUndelivered(Int)
    BatchDispatchStopped(Int)
    } derive(Eq,
    Debug
    )

    BatchOptions

    pub(all) struct BatchOptions {
    max_events : Int
    failure_mode : BatchFailureMode
    } derive(Eq,
    Debug
    )

    BatchOptions::new

    fn BatchOptions::new(max_events? : Int, failure_mode? : BatchFailureMode) -> BatchOptions

    BatchReport

    pub(all) struct BatchReport {
    input_count : Int
    reports : Array[DispatchReport]
    remaining : EventQueue
    halt_reason : BatchHaltReason
    } derive(Eq,
    Debug
    )

    BatchReport::completed

    fn BatchReport::completed(self : BatchReport) -> Bool

    BatchReport::continue_with

    fn BatchReport::continue_with(self : BatchReport, bus : EventBus, options? : BatchOptions) -> (EventBus, BatchReport)

    BatchReport::failed

    fn BatchReport::failed(self : BatchReport) -> Int

    BatchReport::metrics

    fn BatchReport::metrics(self : BatchReport) -> BusMetrics

    BatchReport::processed

    fn BatchReport::processed(self : BatchReport) -> Int

    BatchReport::remaining_count

    fn BatchReport::remaining_count(self : BatchReport) -> Int

    BatchReport::undelivered

    fn BatchReport::undelivered(self : BatchReport) -> Int

    BusMetrics

    pub(all) struct BusMetrics {
    published : Int
    successful_events : Int
    failed_events : Int
    stopped_events : Int
    handler_deliveries : Int
    handler_ignored : Int
    handler_failures : Int
    handlers : Array[HandlerMetrics]
    topics : Array[TopicMetrics]
    } derive(Eq,
    Debug
    )

    Immutable metrics snapshot built from dispatch reports.

    BusMetrics::delivery_percent

    fn BusMetrics::delivery_percent(self : BusMetrics) -> Int

    BusMetrics::failing_handlers

    fn BusMetrics::failing_handlers(self : BusMetrics) -> Array[HandlerMetrics]

    BusMetrics::handler

    fn BusMetrics::handler(self : BusMetrics, name : String) -> HandlerMetrics?

    BusMetrics::merge

    fn BusMetrics::merge(self : BusMetrics, other : BusMetrics) -> BusMetrics

    BusMetrics::new

    fn BusMetrics::new() -> BusMetrics

    BusMetrics::record

    fn BusMetrics::record(self : BusMetrics, report : DispatchReport) -> BusMetrics

    BusMetrics::record_many

    fn BusMetrics::record_many(self : BusMetrics, reports : Array[DispatchReport]) -> BusMetrics

    BusMetrics::success_percent

    fn BusMetrics::success_percent(self : BusMetrics) -> Int

    BusMetrics::summary

    fn BusMetrics::summary(self : BusMetrics) -> String

    BusMetrics::topic

    fn BusMetrics::topic(self : BusMetrics, name : String) -> TopicMetrics?

    DedupBatch

    pub(all) struct DedupBatch {
    accepted : Array[Event]
    duplicates : Array[Event]
    unkeyed : Array[Event]
    } derive(Eq,
    Debug
    )

    DedupBatch::total

    fn DedupBatch::total(self : DedupBatch) -> Int

    DedupCache

    pub(all) struct DedupCache {
    strategy : DedupStrategy
    capacity : Int
    seen : Array[SeenEvent]
    next_sequence : Int
    } derive(Eq,
    Debug
    )

    DedupCache::check

    fn DedupCache::check(self : DedupCache, event : Event) -> DedupDecision

    DedupCache::clear

    fn DedupCache::clear(self : DedupCache) -> DedupCache

    DedupCache::filter

    fn DedupCache::filter(self : DedupCache, events : Array[Event], accept_unkeyed? : Bool) -> (DedupCache, DedupBatch)

    DedupCache::find

    fn DedupCache::find(self : DedupCache, key : String) -> SeenEvent?

    DedupCache::forget

    fn DedupCache::forget(self : DedupCache, key : String) -> DedupCache

    DedupCache::length

    fn DedupCache::length(self : DedupCache) -> Int

    DedupCache::new

    fn DedupCache::new(strategy? : DedupStrategy, capacity? : Int) -> DedupCache

    DedupCache::publish_unique

    fn DedupCache::publish_unique(self : DedupCache, bus : EventBus, events : Array[Event], accept_unkeyed? : Bool) -> (DedupCache, EventBus, UniquePublishResult)

    DedupCache::remember

    fn DedupCache::remember(self : DedupCache, event : Event) -> DedupCache

    DedupDecision

    pub(all) enum DedupDecision {
    DedupAccept(String)
    DedupDuplicate(String, Int)
    DedupUnkeyed
    } derive(Eq,
    Debug
    )

    DedupStrategy

    pub(all) enum DedupStrategy {
    DedupCorrelation
    DedupNameAndCorrelation
    DedupTopicAndPayload
    DedupNameTopicAndPayload
    } derive(Eq,
    Debug
    )

    DeliveryAttempt

    pub(all) struct DeliveryAttempt {
    number : Int
    event : Event
    report : DispatchReport
    } derive(Eq,
    Debug
    )

    DeliveryBatch

    pub(all) struct DeliveryBatch {
    runs : Array[DeliveryRun]
    succeeded : Int
    dead_lettered : Int
    dropped : Int
    total_attempts : Int
    } derive(Eq,
    Debug
    )

    DeliveryBatch::failed_runs

    fn DeliveryBatch::failed_runs(self : DeliveryBatch) -> Array[DeliveryRun]

    DeliveryBatch::is_ok

    fn DeliveryBatch::is_ok(self : DeliveryBatch) -> Bool

    DeliveryBatch::metrics

    fn DeliveryBatch::metrics(self : DeliveryBatch) -> BusMetrics

    DeliveryBatch::reports

    DeliveryRun

    pub(all) struct DeliveryRun {
    original : Event
    attempts : Array[DeliveryAttempt]
    state : DeliveryState
    dead_letter : Event?
    dead_letter_report : DispatchReport?
    } derive(Eq,
    Debug
    )

    DeliveryRun::attempt_count

    fn DeliveryRun::attempt_count(self : DeliveryRun) -> Int

    DeliveryRun::failure_reasons

    fn DeliveryRun::failure_reasons(self : DeliveryRun) -> Array[String]

    DeliveryRun::last_report

    fn DeliveryRun::last_report(self : DeliveryRun) -> DispatchReport?

    DeliveryRun::succeeded

    fn DeliveryRun::succeeded(self : DeliveryRun) -> Bool

    DeliveryRun::was_retried

    fn DeliveryRun::was_retried(self : DeliveryRun) -> Bool

    DeliveryState

    pub(all) enum DeliveryState {
    DeliverySucceeded
    DeliveryDeadLettered
    DeliveryDropped(String)
    } derive(Eq,
    Debug
    )

    DispatchControl

    pub(all) enum DispatchControl {
    Continue
    Stop
    } derive(Eq,
    Debug
    )

    MoonEvent is a small event bus and message abstraction layer.

    DispatchReport

    pub(all) struct DispatchReport {
    event : Event
    delivered : Int
    ignored : Int
    failed : Int
    stopped : Bool
    reports : Array[HandlerReport]
    } derive(Eq,
    Debug
    )

    DispatchReport::from_reports

    fn DispatchReport::from_reports(event : Event, reports : Array[HandlerReport], stopped? : Bool) -> DispatchReport

    DispatchReport::is_ok

    fn DispatchReport::is_ok(self : DispatchReport) -> Bool

    Event

    pub(all) struct Event {
    name : String
    topic : String
    payload : String
    tags : Array[String]
    priority : Int
    correlation_id : String
    } derive(Eq,
    Debug
    )

    Event::has_tag

    fn Event::has_tag(self : Event, tag : String) -> Bool

    Event::matches_topic

    fn Event::matches_topic(self : Event, topic : String) -> Bool

    Event::new

    fn Event::new(name : String, topic? : String, payload? : String, tags? : Array[String], priority? : Int, correlation_id? : String) -> Event

    Event::summary

    fn Event::summary(self : Event) -> String

    EventBatch

    pub(all) struct EventBatch {
    index : Int
    events : Array[Event]
    } derive(Eq,
    Debug
    )

    EventBatch::length

    fn EventBatch::length(self : EventBatch) -> Int

    EventBatch::publish

    fn EventBatch::publish(self : EventBatch, bus : EventBus, options? : BatchOptions) -> (EventBus, BatchReport)

    EventBus

    pub(all) struct EventBus {
    name : String
    handlers : Array[Handler]
    middlewares : Array[Middleware]
    scheduled : Array[ScheduledEvent]
    trace : Array[TraceEntry]
    publish_count : Int
    next_id : Int
    }

    EventBus::active_handler_count

    fn EventBus::active_handler_count(self : EventBus) -> Int

    EventBus::handler_count

    fn EventBus::handler_count(self : EventBus) -> Int

    EventBus::has_handler

    fn EventBus::has_handler(self : EventBus, id : Int) -> Bool

    EventBus::middleware_count

    fn EventBus::middleware_count(self : EventBus) -> Int

    EventBus::new

    fn EventBus::new(name? : String) -> EventBus

    EventBus::pause

    fn EventBus::pause(self : EventBus, id : Int) -> EventBus

    EventBus::publish

    fn EventBus::publish(self : EventBus, event : Event) -> (EventBus, DispatchReport)

    EventBus::publish_batch

    fn EventBus::publish_batch(self : EventBus, events : Array[Event], options? : BatchOptions) -> (EventBus, BatchReport)

    EventBus::publish_many

    fn EventBus::publish_many(self : EventBus, events : Array[Event]) -> (EventBus, Array[DispatchReport])

    EventBus::publish_many_with_retry

    fn EventBus::publish_many_with_retry(self : EventBus, events : Array[Event], policy : RetryPolicy) -> (EventBus, DeliveryBatch)

    EventBus::publish_with_retry

    fn EventBus::publish_with_retry(self : EventBus, event : Event, policy : RetryPolicy) -> (EventBus, DeliveryRun)

    Publishes an event and executes RetryPolicy decisions until the event succeeds, is converted to a dead-letter event, or is dropped.

    EventBus::resume_handler

    fn EventBus::resume_handler(self : EventBus, id : Int) -> EventBus

    EventBus::schedule_in

    fn EventBus::schedule_in(self : EventBus, event : Event, delay_ticks : Int) -> EventBus

    EventBus::scheduled_count

    fn EventBus::scheduled_count(self : EventBus) -> Int

    EventBus::subscribe

    fn EventBus::subscribe(self : EventBus, name : String, topic? : String, tag? : String, min_priority? : Int, once? : Bool, callback : (Event, EventContext) -> HandlerOutcome, handler_priority? : Int) -> EventBus

    EventBus::tick

    EventBus::tick_many

    fn EventBus::tick_many(self : EventBus, count : Int) -> (EventBus, Array[DispatchReport])

    EventBus::trace_entries

    fn EventBus::trace_entries(self : EventBus) -> Array[TraceEntry]

    EventBus::unsubscribe

    fn EventBus::unsubscribe(self : EventBus, id : Int) -> EventBus

    EventBus::use_middleware

    fn EventBus::use_middleware(self : EventBus, name : String, callback : (Event, EventContext) -> MiddlewareOutcome) -> EventBus

    EventBus::with_handler

    fn EventBus::with_handler(self : EventBus, handler : Handler) -> EventBus

    EventContext

    pub(all) struct EventContext {
    bus_name : String
    publish_index : Int
    handler_index : Int
    } derive(Eq,
    Debug
    )

    Context passed to handlers and middleware.

    EventQuery

    pub(all) struct EventQuery {
    name : String
    topic_pattern : String
    tag : String
    correlation_id : String
    min_priority : Int
    after_sequence : Int
    limit : Int
    } derive(Eq,
    Debug
    )

    Query criteria. Empty strings disable the corresponding filter.

    EventQuery::after

    fn EventQuery::after(self : EventQuery, after_sequence : Int) -> EventQuery

    EventQuery::all

    fn EventQuery::all() -> EventQuery

    EventQuery::matches

    fn EventQuery::matches(self : EventQuery, record : StoredEvent) -> Bool

    EventQuery::take

    fn EventQuery::take(self : EventQuery, limit : Int) -> EventQuery

    EventQuery::with_correlation

    fn EventQuery::with_correlation(self : EventQuery, correlation_id : String) -> EventQuery

    EventQuery::with_min_priority

    fn EventQuery::with_min_priority(self : EventQuery, min_priority : Int) -> EventQuery

    EventQuery::with_name

    fn EventQuery::with_name(self : EventQuery, name : String) -> EventQuery

    EventQuery::with_tag

    fn EventQuery::with_tag(self : EventQuery, tag : String) -> EventQuery

    EventQuery::with_topic

    fn EventQuery::with_topic(self : EventQuery, topic_pattern : String) -> EventQuery

    EventQueue

    pub(all) struct EventQueue {
    events : Array[Event]
    } derive(Eq,
    Debug
    )

    EventQueue::drain

    fn EventQueue::drain(self : EventQueue, subscriptions : Array[Subscription]) -> Array[DispatchReport]

    EventQueue::drain_bus

    fn EventQueue::drain_bus(self : EventQueue, bus : EventBus) -> (EventBus, Array[DispatchReport])

    EventQueue::filter_tag

    fn EventQueue::filter_tag(self : EventQueue, tag : String) -> EventQueue

    EventQueue::filter_topic

    fn EventQueue::filter_topic(self : EventQueue, topic : String) -> EventQueue

    EventQueue::from

    fn EventQueue::from(events : Array[Event]) -> EventQueue

    EventQueue::highest_priority

    fn EventQueue::highest_priority(self : EventQueue) -> Event?

    EventQueue::is_empty

    fn EventQueue::is_empty(self : EventQueue) -> Bool

    EventQueue::length

    fn EventQueue::length(self : EventQueue) -> Int

    EventQueue::new

    fn EventQueue::new() -> EventQueue

    EventQueue::peek

    fn EventQueue::peek(self : EventQueue) -> Event?

    EventQueue::push

    fn EventQueue::push(self : EventQueue, event : Event) -> EventQueue

    EventQueue::push_many

    fn EventQueue::push_many(self : EventQueue, events : Array[Event]) -> EventQueue

    EventQueue::take

    fn EventQueue::take(self : EventQueue) -> (QueueTake, EventQueue)

    EventRouter

    pub(all) struct EventRouter {
    rules : Array[RouteRule]
    } derive(Eq,
    Debug
    )

    EventRouter::active_rule_count

    fn EventRouter::active_rule_count(self : EventRouter) -> Int

    EventRouter::add_rule

    fn EventRouter::add_rule(self : EventRouter, rule : RouteRule) -> EventRouter

    EventRouter::disable

    fn EventRouter::disable(self : EventRouter, name : String) -> EventRouter

    EventRouter::enable

    fn EventRouter::enable(self : EventRouter, name : String) -> EventRouter

    EventRouter::invalid_rules

    fn EventRouter::invalid_rules(self : EventRouter) -> Array[RouteRule]

    EventRouter::new

    EventRouter::remove_rule

    fn EventRouter::remove_rule(self : EventRouter, name : String) -> EventRouter

    EventRouter::route

    fn EventRouter::route(self : EventRouter, event : Event) -> RoutingResult

    EventRouter::route_many

    fn EventRouter::route_many(self : EventRouter, events : Array[Event]) -> Array[RoutingResult]

    EventRouter::rule_count

    fn EventRouter::rule_count(self : EventRouter) -> Int

    EventStore

    pub(all) struct EventStore {
    records : Array[StoredEvent]
    next_sequence : Int
    max_entries : Int
    } derive(Eq,
    Debug
    )

    EventStore::append

    fn EventStore::append(self : EventStore, event : Event, source? : String, stored_tick? : Int) -> (EventStore, StoredEvent)

    EventStore::append_many

    fn EventStore::append_many(self : EventStore, events : Array[Event], source? : String, stored_tick? : Int) -> (EventStore, Array[StoredEvent])

    EventStore::clear

    fn EventStore::clear(self : EventStore) -> EventStore

    EventStore::correlation_count

    fn EventStore::correlation_count(self : EventStore, correlation_id : String) -> Int

    EventStore::events

    fn EventStore::events(self : EventStore) -> Array[Event]

    EventStore::get

    fn EventStore::get(self : EventStore, sequence : Int) -> StoredEvent?

    EventStore::is_empty

    fn EventStore::is_empty(self : EventStore) -> Bool

    EventStore::latest

    fn EventStore::latest(self : EventStore) -> StoredEvent?

    EventStore::length

    fn EventStore::length(self : EventStore) -> Int

    EventStore::new

    fn EventStore::new(max_entries? : Int) -> EventStore

    EventStore::query

    fn EventStore::query(self : EventStore, query : EventQuery) -> Array[StoredEvent]

    EventStore::remove_before

    fn EventStore::remove_before(self : EventStore, sequence : Int) -> EventStore

    EventStore::replay

    fn EventStore::replay(self : EventStore, bus : EventBus, query? : EventQuery) -> (EventBus, Array[DispatchReport])

    EventStore::stats

    fn EventStore::stats(self : EventStore) -> StoreStats

    EventStore::topic_count

    fn EventStore::topic_count(self : EventStore, topic_pattern : String) -> Int

    EventValidation

    pub(all) struct EventValidation {
    event : Event
    issues : Array[ValidationIssue]
    } derive(Eq,
    Debug
    )

    EventValidation::error_count

    fn EventValidation::error_count(self : EventValidation) -> Int

    EventValidation::is_valid

    fn EventValidation::is_valid(self : EventValidation) -> Bool

    EventValidation::warning_count

    fn EventValidation::warning_count(self : EventValidation) -> Int

    EventValidationPolicy

    pub(all) struct EventValidationPolicy {
    require_topic : Bool
    require_correlation_id : Bool
    allow_empty_tags : Bool
    min_priority : Int
    max_priority : Int
    max_payload_length : Int
    } derive(Eq,
    Debug
    )

    EventValidationPolicy::default

    Handler

    pub(all) struct Handler {
    id : Int
    name : String
    subscription : Subscription
    priority : Int
    callback : (Event, EventContext) -> HandlerOutcome
    }

    Handler::new

    fn Handler::new(id : Int, name : String, subscription : Subscription, priority : Int, callback : (Event, EventContext) -> HandlerOutcome) -> Handler

    HandlerMetrics

    pub(all) struct HandlerMetrics {
    handler : String
    handled : Int
    ignored : Int
    failed : Int
    } derive(Eq,
    Debug
    )

    HandlerOutcome

    pub(all) enum HandlerOutcome {
    OutcomeHandled(String)
    OutcomeIgnored(String)
    OutcomeFailed(String)
    OutcomeStopped(String)
    } derive(Eq,
    Debug
    )

    HandlerReport

    pub(all) struct HandlerReport {
    handler : String
    status : HandlerStatus
    note : String
    } derive(Eq,
    Debug
    )

    HandlerReport::failed

    fn HandlerReport::failed(handler : String, reason : String) -> HandlerReport

    HandlerReport::ignored

    fn HandlerReport::ignored(handler : String, note? : String) -> HandlerReport

    HandlerReport::ok

    fn HandlerReport::ok(handler : String, note? : String) -> HandlerReport

    HandlerStatus

    pub(all) enum HandlerStatus {
    Handled
    Ignored
    Failed(String)
    } derive(Eq,
    Debug
    )

    Middleware

    pub(all) struct Middleware {
    name : String
    callback : (Event, EventContext) -> MiddlewareOutcome
    }

    Middleware::new

    fn Middleware::new(name : String, callback : (Event, EventContext) -> MiddlewareOutcome) -> Middleware

    MiddlewareOutcome

    pub(all) enum MiddlewareOutcome {
    MiddlewareContinue(Event)
    MiddlewareHalt(String)
    } derive(
    Debug
    )

    QueueTake

    pub(all) enum QueueTake {
    Empty
    Item(Event)
    } derive(Eq,
    Debug
    )

    A tiny in-memory queue abstraction used by examples and simple applications.

    RetryDecision

    pub(all) enum RetryDecision {
    Retry(Event)
    DeadLetter(Event)
    Drop(String)
    } derive(Eq,
    Debug
    )

    Retry and dead-letter helpers for failed dispatch flows.

    RetryPolicy

    pub(all) struct RetryPolicy {
    max_attempts : Int
    dead_letter_topic : String
    retry_tag : String
    } derive(Eq,
    Debug
    )

    RetryPolicy::decide

    fn RetryPolicy::decide(self : RetryPolicy, event : Event, attempt : Int, reason : String) -> RetryDecision

    RetryPolicy::new

    fn RetryPolicy::new(max_attempts? : Int, dead_letter_topic? : String, retry_tag? : String) -> RetryPolicy

    RouteAction

    pub(all) enum RouteAction {
    RouteForward(String)
    RouteFanOut(Array[String])
    RouteRename(String)
    RouteAddTag(String)
    RouteRaisePriority(Int)
    RouteDrop(String)
    } derive(Eq,
    Debug
    )

    Transformation performed by a routing rule.

    RouteNote

    pub(all) struct RouteNote {
    rule : String
    input_topic : String
    output_count : Int
    message : String
    } derive(Eq,
    Debug
    )

    RouteRule

    pub(all) struct RouteRule {
    name : String
    topic_pattern : String
    required_tag : String
    min_priority : Int
    rule_priority : Int
    terminal : Bool
    active : Bool
    action : RouteAction
    } derive(Eq,
    Debug
    )

    RouteRule::is_valid

    fn RouteRule::is_valid(self : RouteRule) -> Bool

    RouteRule::matches

    fn RouteRule::matches(self : RouteRule, event : Event) -> Bool

    RouteRule::new

    fn RouteRule::new(name : String, topic_pattern : String, action : RouteAction, required_tag? : String, min_priority? : Int, rule_priority? : Int, terminal? : Bool) -> RouteRule

    RoutingResult

    pub(all) struct RoutingResult {
    input : Event
    events : Array[Event]
    matched_rules : Int
    dropped : Bool
    notes : Array[RouteNote]
    } derive(Eq,
    Debug
    )

    RoutingResult::first

    fn RoutingResult::first(self : RoutingResult) -> Event?

    RoutingResult::output_count

    fn RoutingResult::output_count(self : RoutingResult) -> Int

    RoutingResult::publish

    ScheduledEvent

    pub(all) struct ScheduledEvent {
    id : Int
    event : Event
    remaining_ticks : Int
    } derive(Eq,
    Debug
    )

    A delayed event with a countdown measured in logical ticks.

    ScheduledEvent::new

    fn ScheduledEvent::new(id : Int, event : Event, delay_ticks : Int) -> ScheduledEvent

    SeenEvent

    pub(all) struct SeenEvent {
    key : String
    sequence : Int
    event_name : String
    } derive(Eq,
    Debug
    )

    StoreStats

    pub(all) struct StoreStats {
    entries : Int
    first_sequence : Int
    last_sequence : Int
    next_sequence : Int
    } derive(Eq,
    Debug
    )

    StoredEvent

    pub(all) struct StoredEvent {
    sequence : Int
    event : Event
    source : String
    stored_tick : Int
    } derive(Eq,
    Debug
    )

    Event persisted by the in-memory store.

    Subscription

    pub(all) struct Subscription {
    id : Int
    name : String
    topic : String
    tag : String
    min_priority : Int
    once : Bool
    active : Bool
    } derive(Eq,
    Debug
    )

    Subscription::matches

    fn Subscription::matches(self : Subscription, event : Event) -> Bool

    Subscription::new

    fn Subscription::new(id : Int, name : String, topic? : String, tag? : String, min_priority? : Int, once? : Bool) -> Subscription

    TopicMetrics

    pub(all) struct TopicMetrics {
    topic : String
    published : Int
    delivered : Int
    failed : Int
    } derive(Eq,
    Debug
    )

    TopicPattern

    pub(all) struct TopicPattern {
    raw : String
    segments : Array[String]
    status : TopicPatternStatus
    } derive(Eq,
    Debug
    )

    Compiled dot-separated topic pattern.

    * consumes exactly one segment and # consumes remaining segments. An empty pattern matches every topic for backwards compatibility.

    TopicPattern::compile

    fn TopicPattern::compile(raw : String) -> TopicPattern

    TopicPattern::is_catch_all

    fn TopicPattern::is_catch_all(self : TopicPattern) -> Bool

    TopicPattern::is_valid

    fn TopicPattern::is_valid(self : TopicPattern) -> Bool

    TopicPattern::matches

    fn TopicPattern::matches(self : TopicPattern, topic : String) -> Bool

    TopicPattern::specificity

    fn TopicPattern::specificity(self : TopicPattern) -> Int

    Higher specificity means fewer wildcard segments.

    TopicPatternStatus

    pub(all) enum TopicPatternStatus {
    PatternValid
    PatternEmptySegment(Int)
    PatternHashNotLast(Int)
    PatternInvalidWildcard(Int, String)
    } derive(Eq,
    Debug
    )

    Result returned while validating a topic pattern.

    TraceEntry

    pub(all) struct TraceEntry {
    index : Int
    kind : TraceKind
    event_name : String
    actor : String
    message : String
    } derive(Eq,
    Debug
    )

    TraceEntry::new

    fn TraceEntry::new(index : Int, kind : TraceKind, event_name : String, actor : String, message : String) -> TraceEntry

    TraceKind

    pub(all) enum TraceKind {
    TracePublish
    TraceMiddleware
    TraceHandler
    TraceSchedule
    TraceError
    } derive(Eq,
    Debug
    )

    Debug trace item recorded by EventBus while publishing events.

    TypedEvent

    pub(all) struct TypedEvent[A] {
    name : String
    topic : String
    value : A
    tags : Array[String]
    priority : Int
    correlation_id : String
    encode : (A) -> String
    }

    A typed event wrapper. The encoder is explicit so MoonEvent can stay small and avoid forcing a JSON dependency on users.

    TypedEvent::new

    fn[A] TypedEvent::new(name : String, value : A, encode : (A) -> String, topic? : String, tags? : Array[String], priority? : Int, correlation_id? : String) -> TypedEvent[A]

    TypedEvent::to_event

    fn[A] TypedEvent::to_event(self : TypedEvent[A]) -> Event

    UniquePublishResult

    pub(all) struct UniquePublishResult {
    reports : Array[DispatchReport]
    accepted : Int
    duplicates : Int
    unkeyed : Int
    } derive(Eq,
    Debug
    )

    ValidationBatch

    pub(all) struct ValidationBatch {
    results : Array[EventValidation]
    valid : Int
    invalid : Int
    warnings : Int
    errors : Int
    } derive(Eq,
    Debug
    )

    ValidationIssue

    pub(all) struct ValidationIssue {
    code : String
    message : String
    severity : ValidationSeverity
    } derive(Eq,
    Debug
    )

    ValidationSeverity

    pub(all) enum ValidationSeverity {
    ValidationWarning
    ValidationError
    } derive(Eq,
    Debug
    )

    active_count

    fn active_count(subscriptions : Array[Subscription]) -> Int

    append_tag

    fn append_tag(tags : Array[String], tag : String) -> Array[String]

    chunk_events

    fn chunk_events(events : Array[Event], size : Int) -> Array[EventBatch]

    collect_failures

    fn collect_failures(report : DispatchReport) -> Array[String]

    dead_letter_queue

    fn dead_letter_queue(reports : Array[DispatchReport], policy : RetryPolicy) -> EventQueue

    dedup_key

    fn dedup_key(strategy : DedupStrategy, event : Event) -> String

    dispatch

    fn dispatch(event : Event, subscriptions : Array[Subscription]) -> DispatchReport

    filter_by_topic

    fn filter_by_topic(subscriptions : Array[Subscription], topic : String) -> Array[Subscription]

    flatten_batches

    fn flatten_batches(batches : Array[EventBatch]) -> Array[Event]

    metrics_from_reports

    fn metrics_from_reports(reports : Array[DispatchReport]) -> BusMetrics

    publish_name

    fn publish_name(name : String, subscriptions : Array[Subscription]) -> DispatchReport

    report_needs_retry

    fn report_needs_retry(report : DispatchReport) -> Bool

    topic_matches

    fn topic_matches(pattern : String, topic : String) -> Bool

    trace_summary

    fn trace_summary(entries : Array[TraceEntry]) -> Array[String]

    validate_event

    fn validate_event(event : Event, policy? : EventValidationPolicy) -> EventValidation

    validate_events

    fn validate_events(events : Array[Event], policy? : EventValidationPolicy) -> ValidationBatch

    validate_topic_pattern

    fn validate_topic_pattern(pattern : String) -> TopicPatternStatus

    validation_middleware

    fn validation_middleware(policy : EventValidationPolicy) -> ((Event, EventContext) -> MiddlewareOutcome)