Postboy Help

PostboyAbstractRegistrator

PostboyAbstractRegistrator is a base class for grouping message registrations and subscriptions into a single lifecycle‑managed unit.
It provides up() and down() methods, several record* helpers, and automatic cleanup of every subscription created within the registrator.

1. Core lifecycle: up() and down()

Subclasses implement _up() to declare which message types they need.
All subscriptions become active after up() is called, and are torn down entirely by down().

import {PostboyAbstractRegistrator} from '@artstesh/postboy'; import {PostboyService} from '@artstesh/postboy'; class AnalyticsRegistrator extends PostboyAbstractRegistrator { constructor(postboy: PostboyService) { super(postboy); } protected _up(): void { this.recordSubject(OrderPlacedEvent); } } // usage const analytics = new AnalyticsRegistrator(postboy); analytics.up(); // subscriptions active // ... analytics.down(); // all cleaned up
  • up() activates the registrator, runs _up(), and starts listening.

  • down() destroys every subscription created via this registrator.

  • Subscriptions work only between up() and down().

2. Recording messages

The registrator offers a few methods for registering message types.

2.1 recordSubject()

Basic fire‑and‑forget pattern. Uses an underlying Subject.

this.recordSubject(UserClickedEvent);

Best for: instant events, stateless notifications.

2.2 recordReplay()

Remembers the last N events and replays them to new subscribers. Uses ReplaySubject.

// remembers up to 3 search queries this.recordReplay(SearchQueryEvent, 3);

Best for: state recovery, audit logs.

2.3 recordBehavior()

Requires an initial value and emits the current value to new subscribers immediately. Uses BehaviorSubject.

this.recordBehavior(CartStateEvent, new CartStateEvent(new CartState([])));

Best for: default settings, cache initialization.

2.4 recordWithPipe()

Accepts a pre‑configured Subject and an optional pipe for advanced processing.

const subject = new Subject<MouseMoveEvent>(); this.recordWithPipe( MouseMoveEvent, subject, (stream) => stream.pipe(throttleTime(100)) );

Best for: filtering, throttling, custom transformations.

2.5 recordHandler()

Requires predefined Executor and Handler.

this.recordHandler(FormatDateExecutor, new FormatDateHander());

Best for: Synchronous domain logic, mapping, and formatting

2.5 recordExecutor()

Requires predefined Executor.

this.recordExecutor(FormatDateExecutor,(executor) => { return dateService.format(executor.date); });

Best for: Synchronous domain logic, mapping, and formatting

3. Registering dependent services

A registrator can manage services that implement IPostboyDependingService.
Call registerServices([...]) in the constructor to activate their up() logic when the registrator starts. This ensures that services do not attempt to subscribe or fire on message types before they are registered. The registrator calls each service’s up() only after its own _up() has finished, guaranteeing a safe initialization order.

class AuthService implements IPostboyDependingService { constructor(private postboy: PostboyService) { } up(): void { this.postboy.sub(UserLoginEvent).subscribe(/* ... */); } } class AppRegistrator extends PostboyAbstractRegistrator { constructor(postboy: PostboyService, auth: AuthService) { super(postboy); this.registerServices([auth]); } protected _up(): void { this.recordSubject(UserLoginEvent); } }

When AppRegistrator.down() is called, all subscriptions created by AuthService.up() are also cleaned up.

4. Global vs local registrators

Scope

Typical use

Lifetime

Global

App‑wide events (auth, locale, network)

Created once, lives forever

Local

Feature‑specific logic (profile page, wizard)

Created per feature, destroyed on leave

// global registrator class AppRegistrator extends PostboyAbstractRegistrator { _up() { this.recordSubject(LocaleChangedEvent); this.recordReplay(NetworkStatusEvent); } } // local registrator class UserProfileRegistrator extends PostboyAbstractRegistrator { _up() { this.recordBehavior(UserPreferencesEvent, defaultPrefs); this.recordSubject(ProfileScrollEvent); } }

5. Key points

  • PostboyAbstractRegistrator provides centralised lifecycle for a group of messages.

  • up()/down() is explicit and predictable; no hidden state.

  • Choose the recording method that matches your messaging needs.

  • Use registerServices() to delegate subscription logic to separate services while still maintaining a single cleanup point.

  • Always call down() when the registrator’s scope is destroyed.

24 апреля 2026