JCC Express

Digging Deeper

Events

Introduction

JCC Express MVC has a container-backed event system with two modes:

  • Internal events/listeners (EventEmitter-based)
  • Broadcast events (Socket.IO) when an event defines broadcastOn()

Use the global emit(...) helper to dispatch events.


Dispatch events

TypeScript
emit(new UserRegistered(user));
emit(new LogIn());

emit resolves the framework Event service and calls dispatch.


Event + listener classes

Generate scaffolding with ArtisanNode:

Bash
bun artisanNode make:event UserRegistered
bun artisanNode make:listener SendWelcomeEmail UserRegistered

Listener shape:

TypeScript
@Inject()
export class SendWelcomeEmail {
  handle(event: UserRegistered): void {
    // send email
  }
}

Register listeners in a provider

Create/extend an event service provider and map event names to listener classes:

TypeScript
import { EventServiceProvider as ServiceProvider } from "jcc-express-mvc/Core/Provider";
import { UpdateEmail } from "app/Events/UpdateEmail";

export class EventServiceProvider extends ServiceProvider {
  protected listen: Record<any, Function[]> = {
    Register: [UpdateEmail],
  };

  register(): void {}
}

Add the provider in bootstrap/providers.ts.

The framework auto-boots listeners/subscribers for providers that extend EventServiceProvider.


Subscribers

Subscribers centralize multiple event hooks in one class:

TypeScript
@Inject()
export class UserEventsSubscriber {
  onLogin(user: User) {
    // ...
  }

  subscribe(event: EventEmitter) {
    event.listen(LogIn.name, UserEventsSubscriber, "onLogin");
  }
}

Register subscribers via provider subscribe:

TypeScript
protected subscribe: any[] = [UserEventsSubscriber];

Dispatch behavior details

For non-broadcast events:

  • Event name is event.constructor.name.
  • dispatch stores the event instance in the container singleton for that name.
  • Registered listener classes are resolved from container and their handle(...) is invoked.

For event.listen(..., ListenerClass, "methodName") subscriber style:

  • The listener class is resolved from container.
  • The named method is called through container method invocation.

Events vs Broadcasting

  • Use this events system for in-process domain hooks (emails, logs, side effects).
  • Add broadcastOn() to the event when it should also go to Socket.IO clients.
  • See Broadcasting.md for channel/payload details.

Summary

  • Dispatch with emit(new EventClass(...)).
  • Register listeners in an EventServiceProvider.
  • Use subscribers for grouped event wiring.
  • Add broadcastOn() when you want client-facing realtime broadcasting.