ServerlessIRCd Docs

Docs home

ADR-001: Pure reducers and the effect system

Date: 2025-01-15 (Phase 1) Status: Accepted Supersedes: — Superseded by: —

Context

Every IRC daemon must decide where side effects happen. A traditional ircd threads mutable state and IO through command handlers — the handler reads a channel roster, sends messages, mutates a user record, and returns. That makes handlers hard to unit-test (they require a live socket, a real timer, a populated data store) and hard to reason about (the handler's observable behaviour is inseparable from its IO).

ServerlessIRCd targets two cloud adapters (Cloudflare Workers, AWS Lambda) that share one protocol core. If the core performed IO directly, each adapter would need its own mock surface for every core test — or worse, the core would grow adapter-specific code paths.

Decision

Every command handler is a pure function with the signature:

type Reducer<S> = (state: S, msg: IrcMessage, ctx: Ctx) => { state: S; effects: Effect[] };

Consequences

Positive:

Negative:

References