bulletproof-nodejs icon indicating copy to clipboard operation
bulletproof-nodejs copied to clipboard

Event dispatch, npm repository, has been archived. Is there a maintained alternative?

Open jlison opened this issue 5 years ago • 5 comments

Hi,

First of all thank you for sharing this node-js project skeleton, and writing a blog post about it :)

I was wondering if you are aware that event dispatch has been archived:

https://github.com/pleerock/event-dispatch#readme

Do you know by any chance if there is a maintained alternative?

Best!

jlison avatar Apr 24 '19 01:04 jlison

Oh well, that's sad I liked that package :(

I will try to find an alternative, or write a service that does the same

santiq avatar Apr 24 '19 17:04 santiq

I just found about that package as well, and it looks awesome. Hopefully there are some similar alternatives out there. If you decide to create a similar service, and if you accept PRs, I will be happy to collaborate :)

jlison avatar Apr 24 '19 21:04 jlison

You might want to check out https://github.com/KeesCBakker/Strongly-Typed-Events-for-TypeScript

I'm in the process of replacing event-dispatch with it for the project I'm currently working on.

jblyberg avatar Jul 13 '19 19:07 jblyberg

I just found this package which I am going to use in my project as an alternative.

https://github.com/j/type-events

I particularly like how events are dispatched as class instances so you can depend on the arguments that are passed to the subscribers.

twrayden avatar Sep 08 '20 06:09 twrayden

I ended up doing a custom implementation with eventemitter2 because I needed wildcard support. I thought I'd share in-case it helps somebody.

You could probably improve it with decorators, like remove the need for the abstract attach method but I didn't want to spend that much time on it and this meets my needs fine.

Here is the pub/sub classes:

import { EventEmitter2 } from "eventemitter2";

export interface IEventPublisherArgs {
  subscribers: EventSubscriber[];
}

export class EventPublisher {
  private emitter: EventEmitter2;

  constructor(args: IEventPublisherArgs) {
    this.emitter = new EventEmitter2({ wildcard: true, delimiter: "." });

    const bus: IEventBus = {
      subscribe: (id, cb) => {
        this.emitter.on(id, cb);
      }
    };

    for (const subscriber of args.subscribers) {
      subscriber.attach(bus);
    }
  }

  publish(event: PublishEvent) {
    this.emitter.emit(event.id, event);
  }
}

export class PublishEvent {
  constructor(public id: string) {}
}

export type SubscribeListenerFunction = (event: PublishEvent) => void;

export type SubscribeFunction = (
  id: string,
  cb: SubscribeListenerFunction
) => void;

export interface IEventBus {
  subscribe: SubscribeFunction;
}

export abstract class EventSubscriber {
  abstract attach(bus: IEventBus): void;
}

Here is a basic example on how it is used (w/ dependency injection):

import { Container } from "typedi";

export class IntegrationConnectedEvent extends PublishEvent {
  constructor(public payload: any) {
    super("integration.connected");
  }
}

export class IntegrationSubscriber extends EventSubscriber {
  attach(bus: IEventBus) {
    bus.subscribe(
      "integration.connected",
      this.onIntegrationConnectedEvent
    );
  }

  async onIntegrationConnectedEvent(event: PublishEvent) {
    if (event instanceof IntegrationConnectedEvent) {
      console.log(event.payload);
    }
  }
}

Container.set("publisher", new EventPublisher({ subscribers: [new IntegrationSubscriber()] }));

const publisher = Container.get("publisher");

publisher.publish(new IntegrationConnectedEvent("Hello World!"));

// Console output: Hello World!

twrayden avatar Sep 16 '20 11:09 twrayden