slck-mediator

A production-ready Mediator pattern framework for TypeScript, Go, and Python, providing a unified, observable dispatch layer for command/query separation, async streaming, and event-driven architectures.

Request dispatch · async streaming · notification fan-out · 11-behaviour middleware pipeline · transactional outbox · idempotent inbox · saga orchestration · integration event bus

Get Started View on GitHub


Overview

slck-mediator is an event-driven platform kernel built around the Mediator pattern. It decouples message producers from their handlers through a central dispatch layer, adding a configurable middleware pipeline, structured observability, and durable infrastructure primitives without coupling application code to any specific transport or persistence technology.

Inspired by martinothamar/Mediator, the .NET source-generator mediator.

Language Package Install
TypeScript @slck/mediator npm install @slck/mediator
Python slck-mediator pip install slck-mediator
Go github.com/chandru415/slck-mediator/go/mediator go get ...@latest

Feature Matrix

Core Dispatch

Feature TypeScript Go Python
send — command/query (1:1)
stream — async streaming (1:1)
publish — notifications (1:N)
Build-time direct-dispatch generator
Dispatch filters (pre/post hooks)

Middleware

Feature TypeScript Go Python
11-behaviour middleware pipeline
Sequential and parallel publishers

Durable Infrastructure

Feature TypeScript Go Python
Transactional outbox + dead-letter queue
Idempotent inbox consumer
Saga orchestration with LIFO compensation
Integration event bus (5 transports)

Observability and Persistence

Feature TypeScript Go Python
Structured logging / metrics / tracing
OpenTelemetry adapters
SQL adapters (PostgreSQL, MSSQL)
MongoDB adapters
DI container
Lifecycle host and background workers

Dispatch Modes

Three dispatch modes cover all messaging patterns:

flowchart TD
    subgraph "Dispatch Modes"
        direction LR
        S([send]) -->|"1 : 1"| RH["RequestHandler"]
        RH --> TResponse(["TResponse"])
        ST([stream]) -->|"1 : 1"| SH["StreamHandler"]
        SH --> Items(["AsyncIterable<TItem>"])
        P([publish]) -->|"1 : N"| NH1["Handler A"]
        P --> NH2["Handler B"]
        P --> NH3["Handler C"]
    end

Request Lifecycle

Every send() call passes through dispatch filters and the middleware pipeline before reaching the handler:

sequenceDiagram
    participant C as Caller
    participant M as Mediator
    participant F as DispatchFilter
    participant P as Middleware Pipeline
    participant H as Handler

    C->>M: send(request)
    M->>F: onBeforeDispatch(request)
    M->>P: enter pipeline
    P->>H: handle(request, ctx)
    H-->>P: response
    P-->>M: exit pipeline
    M->>F: onAfterDispatch(response)
    M-->>C: response

Middleware Pipeline

Eleven built-in behaviours wrap every handler in Russian Doll order (outermost to innermost):

flowchart LR
    Req([Request]) --> L["1 Logging"]
    L --> V["2 Validation"]
    V --> A["3 Authorization"]
    A --> Me["4 Metrics"]
    Me --> RL["5 Rate Limit"]
    RL --> Bu["6 Bulkhead"]
    Bu --> Ca["7 Caching"]
    Ca --> Re["8 Retry"]
    Re --> Ti["9 Timeout"]
    Ti --> CB["10 Circuit Breaker"]
    CB --> Tx["11 Transaction"]
    Tx --> H([Handler])
    style Req fill:#4a90d9,color:#fff
    style H fill:#27ae60,color:#fff

Durable Infrastructure

flowchart LR
    H[Handler] -->|enqueue| OW[OutboxWriter]
    OW --> OS[(OutboxStore)]
    WK[OutboxWorker] -->|poll and publish| OS
    WK --> EB[[Event Bus]]

    EB -->|consume| IC[InboxConsumer]
    IC -->|idempotency check| IS[(InboxStore)]
    IS --> YH[Your Handler]

    subgraph "Saga Orchestration"
        SE[Start] --> SM[SagaManager]
        SM --> Step1[Step 1]
        Step1 --> Step2[Step 2]
        Step2 -->|on failure| Comp["Compensate (LIFO)"]
    end

Two mediator variants are provided:

  • RuntimeMediator — registry-based handler resolution via Map/dict lookups. Suitable for all use cases.
  • GeneratedMediator — build-time generated direct-dispatch with no runtime reflection. Eliminates lookup overhead for latency-sensitive paths.