Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
typed-emitter
Advanced tools
The 'typed-emitter' npm package provides a strongly-typed event emitter for TypeScript. It allows developers to define and use event emitters with type safety, ensuring that the events and their associated data are correctly typed.
Basic Event Emission
This feature allows you to define and emit basic events with type safety. The event 'event1' is defined to accept a string message, and the emitter ensures that only strings are passed when emitting this event.
const { TypedEmitter } = require('typed-emitter');
interface MyEvents {
event1: (message: string) => void;
}
const emitter = new TypedEmitter<MyEvents>();
emitter.on('event1', (message) => {
console.log(message);
});
emitter.emit('event1', 'Hello, World!');
Multiple Event Listeners
This feature demonstrates how you can attach multiple listeners to a single event. Both listeners will be called when 'event1' is emitted, and they will receive the same message.
const { TypedEmitter } = require('typed-emitter');
interface MyEvents {
event1: (message: string) => void;
event2: (count: number) => void;
}
const emitter = new TypedEmitter<MyEvents>();
emitter.on('event1', (message) => {
console.log('Listener 1:', message);
});
emitter.on('event1', (message) => {
console.log('Listener 2:', message);
});
emitter.emit('event1', 'Hello, World!');
Removing Event Listeners
This feature shows how to remove an event listener. The listener is first added to 'event1', then removed using the 'off' method. The second emission of 'event1' does not trigger the listener.
const { TypedEmitter } = require('typed-emitter');
interface MyEvents {
event1: (message: string) => void;
}
const emitter = new TypedEmitter<MyEvents>();
const listener = (message: string) => {
console.log(message);
};
emitter.on('event1', listener);
emitter.emit('event1', 'Hello, World!');
emitter.off('event1', listener);
emitter.emit('event1', 'This will not be logged');
EventEmitter3 is a high-performance event emitter for Node.js and the browser. It provides a similar API to Node.js's built-in EventEmitter but with better performance and additional features. Unlike 'typed-emitter', it does not provide built-in TypeScript support, so type safety must be manually managed.
Mitt is a tiny (~200 bytes) functional event emitter. It is designed to be extremely lightweight and simple to use. While it is not as feature-rich as 'typed-emitter' and does not provide built-in TypeScript support, it is a good choice for projects where size and simplicity are critical.
Nanoevents is a tiny (around 200 bytes) event emitter library for JavaScript. It is similar to 'mitt' in its focus on minimalism and simplicity. Like 'mitt', it does not provide built-in TypeScript support, so type safety must be manually managed.
Strictly typed event emitter interface for TypeScript.
Code size: Zero bytes - Just the typings, no implementation. Use the default event emitter of the events
module in node.js or bring your favorite implementation when writing code for the browser.
$ npm install --save-dev typed-emitter
# Using yarn:
$ yarn add --dev typed-emitter
import EventEmitter from "events"
import TypedEmitter from "typed-emitter"
// Define your emitter's types like that:
// Key: Event name; Value: Listener function signature
type MessageEvents = {
error: (error: Error) => void,
message: (body: string, from: string) => void
}
const messageEmitter = new EventEmitter() as TypedEmitter<MessageEvents>
// Good 👍
messageEmitter.emit("message", "Hi there!", "no-reply@test.com")
// TypeScript will catch those mistakes ✋
messageEmitter.emit("mail", "Hi there!", "no-reply@test.com")
messageEmitter.emit("message", "Hi there!", true)
// Good 👍
messageEmitter.on("error", (error: Error) => { /* ... */ })
// TypeScript will catch those mistakes ✋
messageEmitter.on("error", (error: string) => { /* ... */ })
messageEmitter.on("failure", (error: Error) => { /* ... */ })
You might find yourself in a situation where you need to extend an event emitter, but also want to strictly type its events. Here is how to.
class MyEventEmitter extends (EventEmitter as new () => TypedEmitter<MyEvents>) {
// ...
}
As a generic class:
class MyEventEmitter<T> extends (EventEmitter as { new<T>(): TypedEmitter<T> })<T> {
// ...
}
fromEvent
types inferenceThe default fromEvent
from RxJS will return an Observable<unknown>
for our typed emitter.
This can be fixed by the following code, by replacing the fromEvent
type with our enhanced one: FromEvent
:
import { fromEvent as rxFromEvent } from "rxjs"
import { default as TypedEmitter, FromEvent } from "typed-emitter/rxjs"
// The `Observable` typing can be correctly inferenced
const fromEvent = rxFromEvent as FromEvent
Learn more from rxjs fromEvent compatibility #9
for the fromEvent
compatibility discussions.
The interface that comes with @types/node
is not type-safe at all. It does not even offer a way of specifying the events that the emitter will emit...
The eventemitter3
package is a popular event emitter implementation that comes with TypeScript types out of the box. Unfortunately there is no way to declare the event arguments that the listeners have to expect.
There were a few other examples of type-safe event emitter interfaces out there as well. They were either not published to npm, had an inconsistent interface or other limitations.
MIT
FAQs
Strictly typed event emitter interface for TypeScript 3.
We found that typed-emitter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.