{"id":13661020,"url":"https://github.com/nestjsx/nest-emitter","last_synced_at":"2025-04-05T07:06:23.587Z","repository":{"id":40748801,"uuid":"144772384","full_name":"nestjsx/nest-emitter","owner":"nestjsx","description":"Strongly 💪🏼 Typed Eventemitter Module For Nestjs Framework 🦁","archived":false,"fork":false,"pushed_at":"2023-01-04T11:38:53.000Z","size":2219,"stargazers_count":182,"open_issues_count":28,"forks_count":26,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-10-29T22:37:19.415Z","etag":null,"topics":["eventemitter","nestjs","typescript","utility"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nestjsx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-14T21:09:41.000Z","updated_at":"2024-10-12T16:45:58.000Z","dependencies_parsed_at":"2023-02-02T10:47:05.045Z","dependency_job_id":null,"html_url":"https://github.com/nestjsx/nest-emitter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnest-emitter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnest-emitter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnest-emitter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nestjsx%2Fnest-emitter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nestjsx","download_url":"https://codeload.github.com/nestjsx/nest-emitter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246591768,"owners_count":20801986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eventemitter","nestjs","typescript","utility"],"created_at":"2024-08-02T05:01:28.674Z","updated_at":"2025-04-05T07:06:23.559Z","avatar_url":"https://github.com/nestjsx.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Nest Emitter\n\nStrongly 💪🏼 Typed Eventemitter Module For [Nestjs](https://github.com/nestjs/nest) Framework 🦁\n\n## Quick Overview\n\nEver wondered if there is a way to have a strongly typed way to use event emitter names ?\n\nEver wondered why your event emitter is not working as intended and then realized that there\nwas a typo on your events name? if so, then this ones for you :smile: .\n\n## How?\n\nBy Declaring events using a simple interface mapping event names to their payloads to get stricter versions of `emit`, `on`, and other common EventEmitter APIs.\n\nand not only that, it will work with any kind of `EventEmitter` that implements [`NodeJS.Events`](https://nodejs.org/api/events.html).\n\n## Install\n\n#### IMPORTANT: you will need typescript 3.0+\n\n```bash\nnpm install nest-emitter\n```\nor \n\n```bash\nyarn add nest-emitter\n```\n\n## Usage\n\nAs Normal Import `NestEmitterModule` into your root module _(aka `AppModule`)_\n\nThe `NestEmitterModule#forRoot(emitter: NodeJS.Events)` takes any event emitter that implements `NodeJS.Events`.\n\nFor simplicity I will use nodejs built-in eventemitter, but of course you can use whatever you need.\n\n```ts\n// app.module.ts\n\nimport { Module } from '@nestjs/common';\nimport { AppController } from './app.controller';\nimport { AppService } from './app.service';\nimport { NestEmitterModule } from 'nest-emitter';\nimport { EventEmitter } from 'events';\n@Module({\n  imports: [NestEmitterModule.forRoot(new EventEmitter())],\n  controllers: [AppController],\n  providers: [AppService],\n})\nexport class AppModule {}\n```\n\nNow it's time to define our events, let's add two events\none called `notification` and it's payload will be a string.\nand another one is `newRequest` and it's payload will be function that has one arg of type `Request`.\n\n```ts\n// app.events.ts\ninterface AppEvents {\n  notification: string;\n  // as a side note: that is equivalent to\n  // newRequest: Express.Request;\n  newRequest: (req: Express.Request) =\u003e void;\n}\n```\n\nAfter that let's bring up our secret weapon; the `StrictEventEmitter`!\n\n```ts\n// app.events.ts\nimport { EventEmitter } from 'events';\nimport { StrictEventEmitter } from 'nest-emitter';\n\ninterface AppEvents {\n  notification: string;\n  newRequest: (req: Express.Request) =\u003e void;\n}\n\nexport type MyEventEmitter = StrictEventEmitter\u003cEventEmitter, AppEvents\u003e;\n```\n\ngood good, now let's use it.\n\n\u003e :+1: TIP: Keep all of your events in a separate file like `{prefix}.events.ts`.\n\nI will use it to send a notification when we receive a request\n\n```ts\n// app.controller.ts\n\nimport { Get, Controller, Req } from '@nestjs/common';\nimport { AppService } from './app.service';\nimport { InjectEventEmitter } from 'nest-emitter';\nimport { MyEventEmitter } from 'app.events';\n\n@Controller()\nexport class AppController {\n  constructor(\n    private readonly appService: AppService,\n    @InjectEventEmitter() private readonly emitter: MyEventEmitter,\n  ) {}\n\n  @Get()\n  root(@Req() req: Express.Request): string {\n    this.emitter.emit('notification', 'new req');\n    // this will throw an error at compile-time\n    // as `notification` event only accepts `string`\n    // this.emitter.emit('notification', 1234);\n    this.emitter.emit('newRequest', req);\n    return this.appService.root();\n  }\n}\n```\n\nDid you notice `@InjectEventEmitter()`? you guessed it, it's a helper decorator to get the instance of the underlying eventemitter.\n\nnow on the other side\n\n```ts\nimport { Injectable, OnModuleInit } from '@nestjs/common';\nimport { InjectEventEmitter } from 'nest-emitter';\nimport { MyEventEmitter } from 'app.events';\n\n@Injectable()\nexport class AppService implements OnModuleInit {\n  constructor(@InjectEventEmitter() private readonly emitter: MyEventEmitter) {}\n  onModuleInit() {\n    this.emitter.on('notification', async msg =\u003e await this.onNotification(msg));\n    this.emitter.on('newRequest', async req =\u003e await this.onRequest(req));\n  }\n  root(): string {\n    return 'Hello World!';\n  }\n\n  private async onNotification(msg: string) {\n    console.log(`OnNotification: ${msg}`);\n  }\n\n  private async onRequest(req: Express.Request) {\n    console.log(`OnRequest from: ${req['ip']}`);\n  }\n}\n```\n\nAnd that's it! Easy? now let's dive in.\n\n## In Depth\n\n#### Event Records\n\nEvent records are interfaces or object types that map event names to the event's payload types. In the following example, three events are declared:\n\n```ts\ninterface AppEvents {\n  req: (request: Express.Request, response: Express.Response) =\u003e void;\n  done: void;\n  conn: Connection;\n}\n```\n\nEach event shows one of three ways to type the event payloads:\n\n1.  **Function type:** Parameters are the event payload. The return type is ignored.\n1.  **`void`:** A shortcut for an event with no payload, i.e. `() =\u003e void`\n1.  **Anything else:** A shortcut for an event with one payload, for example `(p: number) =\u003e void` can be written as just `number`.\n\n#### StrictEventEmitter\u003cTEmitterType, TEventRecord, TEmitRecord = TEventRecord\u003e\n\nThe default export. A generic type that takes three type parameters:\n\n1.  _TEmitterType_: Your EventEmitter type (e.g. node's EventEmitter or socket.io socket)\n2.  _TEventRecord_: A type mapping event names to event payloads\n3.  _TEmitRecord_: Optionally, a similar type mapping things you can emit.\n\nThe 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:\n\n```ts\n// create types representing the server side and client\n// side sockets\nexport type ServerSocket =\n  StrictEventEmitter\u003cSocketIO.Socket, EventsFromServer, EventsFromClient\u003e;\nexport type ClientSocket =\n  StrictEventEmitter\u003cSocketIOClient.Socket, EventsFromClient, EventsFromServer\u003e;\n\n// elsewhere on server\nlet serverSocket: ServerSocket = new SocketIO.Socket();\nserverSocket.on(/* only events that are sent from the client are allowed */, ...)\nserverSocket.emit(/* only events that are emitted from the server are allowed */, ...)\n\n// elsewhere on client\nlet clientSocket: ClientSocket = new SocketIOClient.Socket();\nclientSocket.on(/* only events that are sent from the server are allowed */, ...)\nclientSocket.emit(/* only events that are emitted from the client are allowed */, ...)\n```\n\nFor more information about `StrictEventEmitter` see [@bterlson 's library](https://github.com/bterlson/strict-event-emitter-types)\n\n\n## CHANGELOG\n\nSee [CHANGELOG](CHANGELOG.md) for more information.\n\n## Contributing\n\nYou are welcome to contribute to this project, just open a PR.\n\n## Authors\n\n- **Shady Khalifa** ([@shekohex](https://github.com/shekohex)) - _Initial work_\n- **Brian Terlson** ([@bterlson](https://github.com/bterlson)) - _strict event emitter types_\n\nSee also the list of [contributors](https://github.com/nestjsx/nest-router/contributors) who participated in this project.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjsx%2Fnest-emitter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnestjsx%2Fnest-emitter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnestjsx%2Fnest-emitter/lists"}