Skip to main content

Notifications

Hosanna provides a lightweight publish/subscribe system for app-wide notifications. You can listen using the @onNotification decorator (auto-managed lifecycle) or manually subscribe/unsubscribe for full control. Notifications are generically typed for strongly-typed payloads.

API overview

export interface INotification<T = undefined> { name: string; data: T }
export type onNotification<T = undefined> = (notification: INotification<T>) => void;
export function onNotification(notificationName: string) { /* decorator registering handlers */ }
export interface INotificationCenter {
dispatch(notification: INotification<any>): void;
subscribe(name: string, handler: onNotification<any>): IIdentifiable;
unsubscribe(name: string, handler: onNotification<any> | IIdentifiable): void;
}
export class HsNotification<T = undefined> implements INotification<T> {
constructor(name: string, data?: T) { /* ... */ }
dispatch() { AppUtils.resolve<INotificationCenter>('notificationCenter').dispatch(this); }
}

Decorator subscriptions are automatically toggled when a view enters/leaves the view hierarchy via internal hooks:

export function toggleNotificationSubscription(target: INotificationClient, active: boolean) {
if (!target.notificationHandlers) return;
const notificationCenter = AppUtils.resolve<INotificationCenter>('notificationCenter');
for (const { name, handler } of target.notificationHandlers) {
if (active) notificationCenter.subscribe(name, handler.bind(target));
else notificationCenter.unsubscribe(name, handler);
}
}

Sending notifications

enum SampleNotificationType { First = 'first', Second = 'second' }

new HsNotification<JsonData>(SampleNotificationType.First).dispatch();
new HsNotification<JsonData>(SampleNotificationType.Second).dispatch();

Receiving notifications (decorators)

@onNotification(SampleNotificationType.First)
onFirstNotification(notification: HsNotification<JsonData>) {
this.numberOfFirstNotificationsReceived++;
}

@onNotification(SampleNotificationType.Second)
onSecondNotification(notification: HsNotification<JsonData>) {
this.numberOfSecondNotificationsReceived++;
}

Notes:

  • Decorator-based handlers are auto-subscribed when the view is mounted and auto-unsubscribed when it is removed from the view hierarchy.
  • This is ideal for view-scoped listeners.

Receiving notifications (manual subscribe/unsubscribe)

Manual control lets you subscribe anywhere (services, long-lived views) and decide when to unsubscribe.

const nc = AppUtils.resolve<INotificationCenter>('notificationCenter');
const handler: onNotification<MyPayload> = (n) => { /* handle n.data */ };
const token = nc.subscribe('my-event', handler);
// later
nc.unsubscribe('my-event', handler); // or pass token

Best practices

  • Prefer decorators for view-local subscriptions that should follow view mount/unmount.
  • Use manual subscribe/unsubscribe for app-wide or service-level listeners.
  • Define string constants/enums for notification names.
  • Use generic payloads for type safety: HsNotification<MyType>(name, data).