Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aleclarson/ee-ts
Type-safe, isomorphic event emitters
https://github.com/aleclarson/ee-ts
event-emitter events typescript
Last synced: 10 days ago
JSON representation
Type-safe, isomorphic event emitters
- Host: GitHub
- URL: https://github.com/aleclarson/ee-ts
- Owner: aleclarson
- License: mit
- Created: 2018-09-11T02:09:31.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-08-19T17:35:47.000Z (about 2 years ago)
- Last Synced: 2024-05-01T22:24:23.229Z (6 months ago)
- Topics: event-emitter, events, typescript
- Language: TypeScript
- Homepage:
- Size: 177 KB
- Stars: 125
- Watchers: 4
- Forks: 2
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ee-ts
[![npm](https://img.shields.io/npm/v/ee-ts.svg)](https://www.npmjs.com/package/ee-ts)
[![Build status](https://travis-ci.org/aleclarson/ee-ts.svg?branch=master)](https://travis-ci.org/aleclarson/ee-ts)
[![codecov](https://codecov.io/gh/aleclarson/ee-ts/branch/master/graph/badge.svg)](https://codecov.io/gh/aleclarson/ee-ts)
[![Bundle size](https://badgen.net/bundlephobia/min/ee-ts)](https://bundlephobia.com/result?p=ee-ts)
[![Install size](https://packagephobia.now.sh/badge?p=ee-ts)](https://packagephobia.now.sh/result?p=ee-ts)
[![Code style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/alecdotbiz)Type-safe event emitters (for TypeScript)
### Features
- strict event names
- type-checking for emitted data
- flexible `listeners()` generator method
- add/remove listeners during emit
- great for sub-classing
- one-time listeners
- default handlers
### Example
```ts
import { EventEmitter as EE } from 'ee-ts'type User = { name: string }
// All possible events must be explicitly defined as methods here.
// The return type can be non-void because the `emit` method returns the last non-void value.
// The return type can never be required, because `void` is implicitly added to every event.
interface Events {
login(user: User): void
logout(): string
}// Make your subclass generic to let users add their own events.
class App extends EE {
// You _cannot_ emit user-added events from here, though.
someMethod(this: App) {
this.emit('logout')
}
}type UserEvents = { test(): void }
let app = new App()// Emit your custom event.
app.emit('test')// The type of `user` is inferred.
app.on('login', user => {
console.log(user.name) // user.name is string
})// Invalid argument types are caught.
app.one('login', (invalid: boolean) => {}) // [ts] Type 'User' is not assignable to type 'boolean'.// Invalid return values are caught.
app.one('logout', () => true) // [ts] Type 'boolean' is not assignable to type 'string | void'.// Unknown event names are caught.
app.emit('invalid') // [ts] Argument of type '"invalid"' is not assignable to parameter of type '"login" | "logout"'.
```
### Subclassing
This library was designed with subclassing in mind.
- The internal cache is non-enumerable
- Few public methods: `on`, `one`, `off`, `emit`, `listeners`
- Override `_onEventHandled(key: string)` to know when an event has at least one listener
- Override `_onEventUnhandled(key: string)` to know when an event has no listeners
### Disposables
When you pass an array as the last argument of `on`, `one`, or `EE.unhandle`,
an object is pushed onto it. This object has a `dispose(): void` method, which
you should call to remove the associated listener from its event.This is a useful way of grouping listeners together.
```ts
import { EventEmitter, Disposable } from 'ee-ts'const ee = new EventEmitter<{ foo(): void }>()
const disposables: Disposable[] = []
let count = 0
const fn = ee.on('foo', () => count++, disposables)assert(disposables.length == 1)
disposables[0].dispose()
ee.emit('foo')assert(count == 0)
```
## API Reference
The type signatures below are _not_ 100% accurate. They're here to give you a general idea of the API. Find the real type signatures in [the source code](./src/ee.ts) or [VS Code](https://code.visualstudio.com/docs/editor/intellisense).
#### `on(key: string, fn: Function, disposables?: Disposable[]): Function`
Add a listener to the given event key.
Use the `one` method to add a one-time listener.
_Returns:_ the `fn` argument
#### `on(map: { [key: string]: Function }, disposables?: Disposable[]): this`
Add every listener value to its associated event key.
Use the `one` method to add one-time listeners.
#### `off(key: string, fn?: Function): this`
Remove a listener for the given event key.
Omit the `fn` argument to remove all listeners for the given event key.
Call `off('*')` to remove all listeners for every event key.
#### `emit(key: string, ...args: any[]): any`
Emit an event to listeners associated with the given event key.
You can safely add/remove listeners from inside a listener.
_Returns:_ last non-void value returned by a listener
#### `listeners(key: string): IterableIterator`
Create a generator of the listeners for the given event key.
Use this with `for..of` or spread it into an array. Read more about generators [here](https://medium.com/javascript-scene/the-hidden-power-of-es6-generators-observable-async-flow-control-cfa4c7f31435).
## Static methods
#### `unhandle(ee: EventEmitter, key: string, fn: Function, disposables?: Disposable[]): Function`
Set the default handler for an event key.
The default handler is called when no other listeners exist for the same event key.
#### `keys(ee: EventEmitter): string[]`
Get an array of event keys that have listeners.
#### `count(ee: EventEmitter, key: string): number`
Get the number of listeners an event has.
#### `has(ee: EventEmitter, key: string): boolean`
Check if an event has listeners.
_Returns:_ true when the given event key has `>= 1` listener.