@mizdra/strictly-typed-event-target
Version:
This is a strictly-typed version of `EventTarget`
114 lines (87 loc) • 4.88 kB
Markdown
# @mizdra/strictly-typed-event-target
>) >)
This is a strictly-typed version of [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/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`](https://github.com/primus/eventemitter3). However, recently, Node.js has implemented [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/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`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent), so it's very small in size.
## Feature
- Based on [`EventTarget`](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) and [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent)
- Strictly-typed API
- Restrict the types of events to be dispatched with `EventMap`
- Universal
- Work in the browser/Node.js in the future (**NOTE: not supported in some environments yet**)
- Standardized API
- `EventTarget` and `CustomEvent` are standardized by WHATWG (ref: [spec](https://dom.spec.whatwg.org/#interface-eventtarget))
- VERY VERY small size
- **_ES Module version size is 1XX B._** (ref: [source](https://unpkg.com/@mizdra/strictly-typed-event-target/dist/esm/index.js))
## Install
```console
$ npm install -S @mizdra/strictly-typed-event-target
$ yarn add @mizdra/strictly-typed-event-target
```
## Usage
<!-- prettier-ignore-start -->
```typescript
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);
```
<!-- prettier-ignore-end -->
## APIs
ref: [src/index.ts](https://github.com/mizdra/strictly-typed-event-target/blob/master/src/index.ts)
## Compatibility
Apart from the type definition, [they are identical to `EventTarget` `CustomEvent`](https://github.com/mizdra/strictly-typed-event-target/blob/master/src/index.ts), so the compatibility with them is the same. See MDN or Node.js API Documents for details.
- Browser
- `EventTarget`: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget#Browser_compatibility
- `CustomEvent`: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Browser_compatibility
- 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)
```console
$ # Wait for passing CI...
$ git switch master
$ git pull
$ yarn version
$ npm run build
$ npm publish
$ git push --follow-tags
```