Skip to content

[Feature] Topic<T> wrapper for type-safe pub-sub (vs as never casts) #273

Description

@pathosDev

Size / Priority

  • Size: S (~50 lines)
  • Category: C.3 Type-Safety.
  • Risk: medium — pub-sub API surface change.

Affected files

  • src/cluster/pubsub/DistributedPubSubMediator.ts — Subscribe/Publish messages typed ActorRef without payload type.
  • src/cluster/pubsub/Messages.ts — message classes.

Background

DistributedPubSubMediator's Subscribe(topic, ref) accepts ActorRef<unknown> (or ActorRef<any>). The published payload is untyped — anything could land in the subscriber's mailbox under the topic.

Typed pubsub: associate a payload type with a topic. Subscribers receive correctly-typed messages.

Target

Phantom-typed topic wrapper:

// src/cluster/pubsub/Topic.ts (new)

/** Typed topic — payload type associated. */
export class Topic<T> {
  constructor(public readonly name: string) {}
  /** Phantom marker — never read at runtime. */
  declare readonly _payloadType: T;
}

// Usage:
const UserEventsTopic = new Topic<UserEvent>('user-events');

mediator.tell(new Subscribe(UserEventsTopic, subscriberRef));   // subscriberRef typed ActorRef<UserEvent>
mediator.tell(new Publish(UserEventsTopic, { kind: 'created', userId: '42' }));   // payload narrowed

Subscribe and Publish become generic:

export class Subscribe<T> {
  constructor(public readonly topic: Topic<T>, public readonly ref: ActorRef<T>) {}
}
export class Publish<T> {
  constructor(public readonly topic: Topic<T>, public readonly message: T) {}
}

Integration / risk

  • API changeSubscribe(string, ref) no longer compiles; must use Topic.
  • Cross-language compat unaffected — wire format unchanged.
  • Migration path: provide a backward-compat untyped variant + deprecation warning.

Test plan

  1. Per-site type-check — subscribers receive typed messages.
  2. Wire-format: published messages unchanged on the wire.
  3. Compile-time: mismatched payload types caught.

Acceptance criteria

  • Topic<T> exported.
  • Subscribe + Publish generic on T.
  • Migration documented.
  • Tests pass.
  • CHANGELOG entry under "DistributedPubSub: typed topics".

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowNice-to-have / niche / demand-driven

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions