strict-event-emitter
Advanced tools
Comparing version 0.3.1 to 0.3.2
@@ -0,2 +1,4 @@ | ||
export * from './Emitter'; | ||
export * from './MemoryLeakError'; | ||
export * from './StrictEventEmitter'; | ||
export * from './StrictEventTarget'; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
@@ -13,3 +17,5 @@ if (k2 === undefined) k2 = k; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./Emitter"), exports); | ||
__exportStar(require("./MemoryLeakError"), exports); | ||
__exportStar(require("./StrictEventEmitter"), exports); | ||
__exportStar(require("./StrictEventTarget"), exports); |
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
import { EventEmitter } from 'events'; | ||
@@ -2,0 +3,0 @@ export declare type EventMapType = Record<string | symbol | number, any>; |
@@ -25,2 +25,3 @@ "use strict"; | ||
class StrictMessageEvent extends MessageEvent { | ||
type; | ||
constructor(type, eventInitDict) { | ||
@@ -27,0 +28,0 @@ super(type, eventInitDict); |
{ | ||
"name": "strict-event-emitter", | ||
"version": "0.3.1", | ||
"description": "Type-safe \"EventEmitter\" for everyday use", | ||
"version": "0.3.2", | ||
"description": "Type-safe implementation of EventEmitter for browser and Node.js", | ||
"main": "lib/index.js", | ||
"typings": "lib/index.js", | ||
"typings": "lib/index.d.ts", | ||
"repository": "git@github.com:open-draft/strict-event-emitter.git", | ||
@@ -19,3 +19,2 @@ "author": "Artem Zakharchenko <kettanaito@gmail.com>", | ||
"files": [ | ||
"README.md", | ||
"lib" | ||
@@ -26,8 +25,9 @@ ], | ||
"@types/events": "^3.0.0", | ||
"@types/jest": "^26.0.19", | ||
"jest": "^26.6.3", | ||
"@types/jest": "^29.2.4", | ||
"jest": "^29.3.1", | ||
"jest-extended": "^3.2.0", | ||
"rimraf": "^3.0.2", | ||
"ts-jest": "^26.4.4", | ||
"ts-jest": "^29.0.3", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.1.3" | ||
"typescript": "4.8" | ||
}, | ||
@@ -34,0 +34,0 @@ "dependencies": { |
# Strict Event Emitter | ||
`EventEmitter` mirror that restricts emitting/handling events other than specified in an interface. | ||
A type-safe implementation of `EventEmitter` for browser and Node.js. | ||
## Features | ||
- Restricts emitting of the unknown event types. | ||
- Infers emitted data types from the listener's call signature. | ||
## Motivation | ||
The native `EventEmitter` class uses a generic `string` to describe what type of events can be emitted. In most cases you design a strict set of events that you expect your emitter to emit/listen to. This package helps you to type-annotate an emitter instance to produce type violations if an unknown event is emitted/listened to. | ||
Despite event emitters potentially accepting any runtime value, defining a strict event contract is crucial when developing complex event-driven architectures. Unfortunately, the native type definitions for Node's `EventEmitter` annotate event names as `string`, which forbids any stricter type validation. | ||
```js | ||
// index.js | ||
const emitter = new EventEmitter() | ||
emitter.addListener('ping', (n: number) => {}) | ||
// Let's say our application expects a "ping" | ||
// event with the number payload. | ||
emitter.on('ping', (n: number) => {}) | ||
// The "pong" event is not expected, but will be emitted anyway. | ||
// The data passed to the event is incompatible with the expected type. | ||
emitter.emit('pong', 'not a number') | ||
// We can, however, emit a different event by mistake. | ||
emitter.emit('poing', 1) | ||
// Or even the correct event with the wrong data. | ||
emitter.emit('ping', 'wait, not a number') | ||
``` | ||
The purpose of this library is to provide an `EventEmitter` instance that can accept a generic describing the expected events contract. | ||
```ts | ||
import { StrictEventEmitter } from 'strict-event-emitter' | ||
import { Emitter } from 'strict-event-emitter' | ||
interface EventsMap { | ||
ping: (n: number) => void | ||
// Define a strict events contract where keys | ||
// represent event names and values represent | ||
// the list of arguments expected in ".emit()". | ||
type Events = { | ||
ping: [number] | ||
} | ||
const emitter = new StrictEventEmitter<EventsMap>() | ||
const emitter = new Emitter<Events>() | ||
emitter.addListener('ping', (n) => { | ||
@@ -37,7 +42,7 @@ // "n" argument type is inferred as "number'. | ||
emitter.emit('ping', 10) // OK | ||
emitter.emit('ping', 'wait, not a number') // TypeError | ||
emitter.emit('unknown', 10) // TypeError | ||
emitter.emit('unknown', 10) // TypeError (invalid event name) | ||
emitter.emit('ping', 'wait, not a number') // TypeError (invalid data) | ||
``` | ||
This library is a superset class of the native `EventEmitter` with only the type definition logic attached. There's no additional functionality present. | ||
This library is also a custom `EventEmitter` implementation, which makes it compatible with other environments, like browsers or React Native. | ||
@@ -55,14 +60,14 @@ ## Getting started | ||
```ts | ||
import { StrictEventEmitter } from 'strict-event-emitter' | ||
import { Emitter } from 'strict-event-emitter' | ||
// 1. Define an interface that describes your events. | ||
// Set event names as the keys, and their listner functions as the values. | ||
interface EventsMap { | ||
connect: (id: string) => void | ||
disconnect: (id: string) => void | ||
// Set event names as the keys, and their expected payloads as values. | ||
interface Events { | ||
connect: [id: string] | ||
disconnect: [id: string] | ||
} | ||
// 2. Create a strict emitter and pass the previously defined "EventsMap" | ||
// 2. Create a strict emitter and pass the previously defined "Events" | ||
// as its first generic argument. | ||
const emitter = new StrictEventEmitter<EventsMap>() | ||
const emitter = new Emitter<Events>() | ||
@@ -69,0 +74,0 @@ // 3. Use the "emitter" the same way you'd use the regular "EventEmitter" instance. |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
19274
12
401
80
9
1