Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Strongly 💪🏼 Typed Eventemitter Module For Nestjs Framework 🦁

License

NotificationsYou must be signed in to change notification settings

nestjsx/nest-emitter

Repository files navigation

Strongly 💪🏼 Typed Eventemitter Module ForNestjs 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 therewas 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 ofemit,on, and other common EventEmitter APIs.

and not only that, it will work with any kind ofEventEmitter that implementsNodeJS.Events.

Install

IMPORTANT: you will need typescript 3.0+

npm install nest-emitter

or

yarn add nest-emitter

Usage

As Normal ImportNestEmitterModule into your root module(akaAppModule)

TheNestEmitterModule#forRoot(emitter: NodeJS.Events) takes any event emitter that implementsNodeJS.Events.

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

// app.module.tsimport{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(newEventEmitter())],controllers:[AppController],providers:[AppService],})exportclassAppModule{}

Now it's time to define our events, let's add two eventsone callednotification and it's payload will be a string.and another one isnewRequest and it's payload will be function that has one arg of typeRequest.

// app.events.tsinterfaceAppEvents{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; theStrictEventEmitter!

// app.events.tsimport{EventEmitter}from'events';import{StrictEventEmitter}from'nest-emitter';interfaceAppEvents{notification:string;newRequest:(req:Express.Request)=>void;}exporttypeMyEventEmitter=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.tsimport{Get,Controller,Req}from'@nestjs/common';import{AppService}from'./app.service';import{InjectEventEmitter}from'nest-emitter';import{MyEventEmitter}from'app.events';@Controller()exportclassAppController{constructor(privatereadonlyappService:AppService,    @InjectEventEmitter()privatereadonlyemitter: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);returnthis.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()exportclassAppServiceimplementsOnModuleInit{constructor(@InjectEventEmitter()privatereadonlyemitter:MyEventEmitter){}onModuleInit(){this.emitter.on('notification',asyncmsg=>awaitthis.onNotification(msg));this.emitter.on('newRequest',asyncreq=>awaitthis.onRequest(req));}root():string{return'Hello World!';}privateasynconNotification(msg:string){console.log(`OnNotification:${msg}`);}privateasynconRequest(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:

interfaceAppEvents{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 justnumber.

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 socketsexporttypeServerSocket=StrictEventEmitter<SocketIO.Socket,EventsFromServer,EventsFromClient>;exporttypeClientSocket=StrictEventEmitter<SocketIOClient.Socket,EventsFromClient,EventsFromServer>;// elsewhere on serverletserverSocket:ServerSocket=newSocketIO.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 clientletclientSocket:ClientSocket=newSocketIOClient.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 aboutStrictEventEmitter see@bterlson 's library

CHANGELOG

SeeCHANGELOG 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 ofcontributors who participated in this project.

License

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

About

Strongly 💪🏼 Typed Eventemitter Module For Nestjs Framework 🦁

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp