@mizdra/type-safe-event-target v0.1.0
@mizdra/type-safe-event-target
This is a type-safe version of EventTarget
.
Motivation
Traditionally, there was no universal native event emitter for browsers and Node.js. Therefore, if you wanted a universal event emitter that worked in both environments, you had to use a 3rd-party library like eventemitter3
. However, recently, Node.js has implemented EventTarget
(An experimental feature not yet available to the public as of 2020/09), EventTarget
is establishing itself as a universal event emitter.
Because EventTarget
is a native API, it's faster and smaller than a 3rd party library like eventemitter3
(rather than needing an extra bundle!). However, EventTarget
cannot restrict the types of events it dispatches like eventemitter3
. This has the problem of dispatching events of an unexpected type, which can cause runtime errors.
Therefore, @mizdra/type-safe-event-target
provides EventTarget
, which can restrict the types of events to be dispatched. It's based on EventTarget
and CustomEvent
, so it's very fast and very small in size.
Feature
- Based on
EventTarget
andCustomEvent
- Type-safe API
- Restrict the types of events to dispatch with
EventMap
.
- Restrict the types of events to dispatch with
- Universal
- Works on browsers (and Node.js in the near future...).
- Standardized API
EventTarget
andCustomEvent
are standardized by WHATWG (ref: spec)
- High performance
EventTarget
andCustomEvent
are optimized for each platform.
- VERY VERY small size
- ES Module version size is 1XX B. (ref: source)
Install
$ npm install -S @mizdra/type-safe-event-target
$ yarn add @mizdra/type-safe-event-target
Usage
import { createTypeSafeEventTarget } from '@mizdra/type-safe-event-target';
// First, you should define event for `EventTarget`.
interface FooEventMap {
// `onmessage` is event name, and `string` is type of `CustomEvent#detail`.
onmessage: string;
onerror: Error;
oninstall: undefined;
}
// `createTypeSafeEventTarget` is a utility for creating
// type-safe `CustomEvent` and `EventTarget`.
const [FooCustomEvent, FooEventTarget] = createTypeSafeEventTarget<FooEventMap>();
const fooEventTarget = new FooEventTarget();
// `addEventListener`
fooEventTarget.addEventListener('onmessage', (event) => {
// `event.detail` is infered `string` type.
});
fooEventTarget.addEventListener('onerror', (event) => {
// `event.detail` is infered `Error` type.
});
// `dispatchEvent`
fooEventTarget.dispatchEvent(
new FooCustomEvent('onmessage', { detail: 'hello' })
);
// compile error
fooEventTarget.dispatchEvent(
new FooCustomEvent('onmessage', { detail: new Error() }),
);
fooEventTarget.dispatchEvent(new FooCustomEvent('oninstall'));
// `removeEventListener`
const listener: TypeSafeEventListenerOrEventListenerObject<
FooEventMap,
'onmessage',
> = () => {};
fooEventTarget.addEventListener('onmessage', listener);
fooEventTarget.removeEventListener('onmessage', listener);
APIs
ref: src/index.ts
How to develop (for Contributor)
yarn run start
: Run for productionyarn run build
: Build for productionyarn run dev
: Run for developmentyarn run check
: Try static-checking
How to release (for Contributor)
$ # Wait for passing CI...
$ git switch master
$ git pull
$ yarn version
$ npm run build
$ npm publish
$ git push --follow-tags