Files
pubsub/docs/architecture/event-targets/redis.md
glm-5.1 371dabc20d Add per-adapter architecture docs in event-targets/ directory
- Create docs/architecture/event-targets/ with individual specs:
  in-process, redis, websocket-client, websocket-server,
  worker, iroh-spoke, iroh-hub
- Update event-targets.md to serve as index with topology model
  (symmetric vs fan-out) and adapter status table
- Update architecture.md index to reference new directory
2026-05-07 14:49:50 +00:00

2.6 KiB

status, last_updated
status last_updated
draft 2026-05-07

Redis Event Target

Import: @alkdev/pubsub/event-target-redis Peer dep: ioredis@^5.0.0 (optional) Status: Implemented. Needs tests.

Adapted from @graphql-yoga/redis-event-target (MIT).

createRedisEventTarget

function createRedisEventTarget<TEvent extends TypedEvent>(
  args: CreateRedisEventTargetArgs,
): TypedEventTarget<TEvent>;

CreateRedisEventTargetArgs

Field Type Required Description
publishClient Redis | Cluster Yes ioredis client for publishing. Can share a connection.
subscribeClient Redis | Cluster Yes ioredis client for subscribing. Must be dedicated — Redis requires subscriber connections to only receive messages.
serializer { stringify, parse } No Custom serializer. Defaults to JSON.

How It Works

  • dispatchEventpublishClient.publish(event.type, serializer.stringify(event.detail))
  • addEventListenersubscribeClient.subscribe(topic), track callbacks per topic
  • removeEventListener → remove callback; if no callbacks remain for topic, subscribeClient.unsubscribe(topic)
  • On message: deserializes with serializer.parse, reconstructs CustomEvent(channel, { detail: envelope })

The detail of the CustomEvent dispatched to local listeners is the full EventEnvelope object ({ type, id, payload }).

Channel Naming

Currently uses the topic string directly as the Redis channel name (e.g., call.responded:uuid-123). Should support a configurable prefix: createRedisEventTarget({ ..., prefix: "alk:events:" }).

Limitations (Current)

  • No error handling — connection failures, reconnection, and message parse errors are not handled
  • No channel prefix — raw event types as channel names risk collision in shared Redis instances
  • No unsubscribe cleanup on client disconnect — if the subscribe client disconnects, registered callbacks remain in the map but will never fire

Test Coverage

No tests yet. Need:

  1. Publish path — dispatchEvent sends to Redis with correct channel and serialized envelope
  2. Subscribe path — addEventListener subscribes to Redis, onMessage dispatches to local listeners
  3. Unsubscribe — removeEventListener unsubscribes from Redis when no listeners remain for a topic
  4. Topic scoping — type:id topics are correctly formed
  5. Envelope serialization — full { type, id, payload } round-trips through JSON
  6. Multiple listeners — multiple listeners on same topic, single Redis subscribe
  7. Error propagation — what happens on connection failure