@mizdra/strictly-typed-event-target
This is a strictly-typed 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 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 that unexpected events of type is dispatched , may cause runtime errors.
Therefore, @mizdra/strictly-typed-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 small in size.
Feature
- Based on
EventTarget
andCustomEvent
- Strictly-typed API
- Restrict the types of events to be dispatched with
EventMap
- Restrict the types of events to be dispatched with
- Universal
- Work in the browser/Node.js in the future (NOTE: not supported in some environments yet)
- Standardized API
-
EventTarget
andCustomEvent
are standardized by WHATWG (ref: spec)
-
- VERY VERY small size
- ES Module version size is 1XX B. (ref: source)
Install
$ npm install -S @mizdra/strictly-typed-event-target
$ yarn add @mizdra/strictly-typed-event-target
Usage
import { createSTEventTarget } from '@mizdra/strictly-typed-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;
}
// `createSTEventTarget` is a utility for creating
// strictly-typed `CustomEvent` and `EventTarget`.
const [FooCustomEvent, FooEventTarget] = createSTEventTarget<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: STEventListenerOrEventListenerObject<
FooEventMap,
'onmessage',
> = () => {};
fooEventTarget.addEventListener('onmessage', listener);
fooEventTarget.removeEventListener('onmessage', listener);
APIs
ref: src/index.ts
Compatibility
Apart from the type definition, they are identical to EventTarget
CustomEvent
, so the compatibility with them is the same. See MDN or Node.js API Documents for details.
- Browser
- Node.js
-
EventTarget
: https://nodejs.org/api/events.html#events_eventtarget_and_event_api -
CustomEvent
: not implemented yet
-
How to develop (for Contributor)
-
yarn run start
: Run for production -
yarn run build
: Build for production -
yarn run dev
: Run for development -
yarn 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