All Projects β†’ nestjsx β†’ Nest Emitter

nestjsx / Nest Emitter

Licence: mit
Strongly πŸ’ͺ🏼 Typed Eventemitter Module For Nestjs Framework 🦁

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Nest Emitter

To Case
Simple case detection and conversion for strings.
Stars: ✭ 111 (-16.54%)
Mutual labels:  utility
Nestjs Amqp
Amqp connections for nestjs πŸ’Œ
Stars: ✭ 123 (-7.52%)
Mutual labels:  nestjs
Interactor
A Simple Website User Interaction Tracker.
Stars: ✭ 128 (-3.76%)
Mutual labels:  utility
Base App Nestjs
Base application using nest JS focused on DDD architecture and SOLID principles
Stars: ✭ 115 (-13.53%)
Mutual labels:  nestjs
Thaw Carrots
Thaw carrots by warming up your laptop to a specific temperature
Stars: ✭ 120 (-9.77%)
Mutual labels:  utility
Nest Cnode
CNode 瀾区 Nest η‰ˆζœ¬ https://cnodejs.org/
Stars: ✭ 125 (-6.02%)
Mutual labels:  nestjs
Linuxacademy Dl
Download videos from Linux Academy (linuxacademy.com) for personal offline use
Stars: ✭ 111 (-16.54%)
Mutual labels:  utility
Nestjs Rbac
Awesome RBAC for NestJs
Stars: ✭ 129 (-3.01%)
Mutual labels:  nestjs
Nest Permissions Seed
A simple application demonstrating the basic usage of permissions with NestJS.
Stars: ✭ 121 (-9.02%)
Mutual labels:  nestjs
Elf Strings
elf-strings will programmatically read an ELF binary's string sections within a given binary. This is meant to be much like the strings UNIX utility, however is purpose built for ELF binaries.
Stars: ✭ 127 (-4.51%)
Mutual labels:  utility
Tspath
TypeScript path alias resolver
Stars: ✭ 115 (-13.53%)
Mutual labels:  utility
Ngx Context
Angular Context: Easy property binding for router outlet and nested component trees.
Stars: ✭ 118 (-11.28%)
Mutual labels:  utility
Swift Selection Search
Swift Selection Search (SSS) is a simple Firefox add-on that lets you quickly search for some text in a page using your favorite search engines.
Stars: ✭ 125 (-6.02%)
Mutual labels:  utility
Kody
.files and environment configuration manager created with node
Stars: ✭ 113 (-15.04%)
Mutual labels:  utility
Nest Event
Event handling with decorators for NestJS Framework
Stars: ✭ 128 (-3.76%)
Mutual labels:  nestjs
Endlines
Easy conversion between new-line conventions
Stars: ✭ 112 (-15.79%)
Mutual labels:  utility
Node Rate Limiter Flexible
Node.js rate limit requests by key with atomic increments in single process or distributed environment.
Stars: ✭ 1,950 (+1366.17%)
Mutual labels:  nestjs
Calypsobot
A fully customizable bot built with discord.js
Stars: ✭ 131 (-1.5%)
Mutual labels:  utility
Asciigraph
Go package to make lightweight ASCII line graph β•­β”ˆβ•― in command line apps with no other dependencies.
Stars: ✭ 1,805 (+1257.14%)
Mutual labels:  utility
Slickr
A collection of python and bash scripts to collect and analyze frame rendering performance in Android apps.
Stars: ✭ 126 (-5.26%)
Mutual labels:  utility

Nest Emitter

Strongly πŸ’ͺ🏼 Typed Eventemitter Module For Nestjs Framework 🦁

Quick Overview

Ever wondered if there is a way to have a strongly typed way to use event emitter names ?

Ever wondered why your event emitter is not working as intended and then realized that there was a typo on your events name? if so, then this ones for you πŸ˜„ .

How?

By Declaring events using a simple interface mapping event names to their payloads to get stricter versions of emit, on, and other common EventEmitter APIs.

and not only that, it will work with any kind of EventEmitter that implements NodeJS.Events.

Install

IMPORTANT: you will need typescript 3.0+

npm install nest-emitter

or

yarn add nest-emitter

Usage

As Normal Import NestEmitterModule into your root module (aka AppModule)

The NestEmitterModule#forRoot(emitter: NodeJS.Events) takes any event emitter that implements NodeJS.Events.

For simplicity I will use nodejs built-in eventemitter, but of course you can use whatever you need.

// app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { NestEmitterModule } from 'nest-emitter';
import { EventEmitter } from 'events';
@Module({
  imports: [NestEmitterModule.forRoot(new EventEmitter())],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Now it's time to define our events, let's add two events one called notification and it's payload will be a string. and another one is newRequest and it's payload will be function that has one arg of type Request.

// app.events.ts
interface AppEvents {
  notification: string;
  // as a side note: that is equivalent to
  // newRequest: Express.Request;
  newRequest: (req: Express.Request) => void;
}

After that let's bring up our secret weapon; the StrictEventEmitter!

// app.events.ts
import { EventEmitter } from 'events';
import { StrictEventEmitter } from 'nest-emitter';

interface AppEvents {
  notification: string;
  newRequest: (req: Express.Request) => void;
}

export type MyEventEmitter = StrictEventEmitter<EventEmitter, AppEvents>;

good good, now let's use it.

πŸ‘ TIP: Keep all of your events in a separate file like {prefix}.events.ts.

I will use it to send a notification when we receive a request

// app.controller.ts

import { Get, Controller, Req } from '@nestjs/common';
import { AppService } from './app.service';
import { InjectEventEmitter } from 'nest-emitter';
import { MyEventEmitter } from 'app.events';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    @InjectEventEmitter() private readonly emitter: MyEventEmitter,
  ) {}

  @Get()
  root(@Req() req: Express.Request): string {
    this.emitter.emit('notification', 'new req');
    // this will throw an error at compile-time
    // as `notification` event only accepts `string`
    // this.emitter.emit('notification', 1234);
    this.emitter.emit('newRequest', req);
    return this.appService.root();
  }
}

Did you notice @InjectEventEmitter()? you guessed it, it's a helper decorator to get the instance of the underlying eventemitter.

now on the other side

import { Injectable, OnModuleInit } from '@nestjs/common';
import { InjectEventEmitter } from 'nest-emitter';
import { MyEventEmitter } from 'app.events';

@Injectable()
export class AppService implements OnModuleInit {
  constructor(@InjectEventEmitter() private readonly emitter: MyEventEmitter) {}
  onModuleInit() {
    this.emitter.on('notification', async msg => await this.onNotification(msg));
    this.emitter.on('newRequest', async req => await this.onRequest(req));
  }
  root(): string {
    return 'Hello World!';
  }

  private async onNotification(msg: string) {
    console.log(`OnNotification: ${msg}`);
  }

  private async onRequest(req: Express.Request) {
    console.log(`OnRequest from: ${req['ip']}`);
  }
}

And that's it! Easy? now let's dive in.

In Depth

Event Records

Event records are interfaces or object types that map event names to the event's payload types. In the following example, three events are declared:

interface AppEvents {
  req: (request: Express.Request, response: Express.Response) => void;
  done: void;
  conn: Connection;
}

Each event shows one of three ways to type the event payloads:

  1. Function type: Parameters are the event payload. The return type is ignored.
  2. void: A shortcut for an event with no payload, i.e. () => void
  3. Anything else: A shortcut for an event with one payload, for example (p: number) => void can be written as just number.

StrictEventEmitter<TEmitterType, TEventRecord, TEmitRecord = TEventRecord>

The default export. A generic type that takes three type parameters:

  1. TEmitterType: Your EventEmitter type (e.g. node's EventEmitter or socket.io socket)
  2. TEventRecord: A type mapping event names to event payloads
  3. TEmitRecord: Optionally, a similar type mapping things you can emit.

The third parameter is handy when typing web sockets where client and server can listen to and emit different events. For example, if you are using socket.io:

// create types representing the server side and client
// side sockets
export type ServerSocket =
  StrictEventEmitter<SocketIO.Socket, EventsFromServer, EventsFromClient>;
export type ClientSocket =
  StrictEventEmitter<SocketIOClient.Socket, EventsFromClient, EventsFromServer>;

// elsewhere on server
let serverSocket: ServerSocket = new SocketIO.Socket();
serverSocket.on(/* only events that are sent from the client are allowed */, ...)
serverSocket.emit(/* only events that are emitted from the server are allowed */, ...)

// elsewhere on client
let clientSocket: ClientSocket = new SocketIOClient.Socket();
clientSocket.on(/* only events that are sent from the server are allowed */, ...)
clientSocket.emit(/* only events that are emitted from the client are allowed */, ...)

For more information about StrictEventEmitter see @bterlson 's library

CHANGELOG

See CHANGELOG for more information.

Contributing

You are welcome to contribute to this project, just open a PR.

Authors

  • Shady Khalifa (@shekohex) - Initial work
  • Brian Terlson (@bterlson) - strict event emitter types

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].