# @sprs/emitter

> Simple event emitter

Latest version **0.0.2** (published 2023-12-13) · MIT license · 0 weekly downloads

## Install

```sh
npm install @sprs/emitter
pnpm add @sprs/emitter
yarn add @sprs/emitter
bun add @sprs/emitter
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.2 |
| Published | 2023-12-13 |
| First published | 2023-12-12 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 19.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Brett Mitchell |
| Maintainers | brett-mitchell |
| Keywords | event, emitter |

## Links

- npm: https://www.npmjs.com/package/@sprs/emitter
- npm.io page: https://npm.io/package/@sprs/emitter

## Alternatives

- [async-exit-hook](https://npm.io/package/async-exit-hook.md) — 3.7M weekly downloads
- [evnty](https://npm.io/package/evnty.md) — 7.2K weekly downloads
- [eleventy-plugin-asciidoc](https://npm.io/package/eleventy-plugin-asciidoc.md) — 3.5K weekly downloads
- [@jswork/next-get2get](https://npm.io/package/@jswork/next-get2get.md) — 945 weekly downloads
- [@dashersw/axon](https://npm.io/package/@dashersw/axon.md) — 934 weekly downloads

## Recent versions

- 0.0.2 (latest) — 2023-12-13
- 0.0.1 — 2023-12-12

## README

# `Emitter`

This package provides a simple, slightly opinionated event emitter with a reduced inferface resembling Node.js's `EventEmitter`.

Listener registration is idempotent. Multiple registrations of the same function will not result in multiple invocations of that function.

Use `.on`/`.off`/`.emit` to register/remove listeners and emit events.

Use `.xform` to produce a `XForm` instance for a single event (see the next section for details on `XForm`).

Use the optional `events` parameter to `Emitter`s constructor to specify known events. The emitter is still allowed to emit any event (no error will be thrown if you emit an event which is not declared in `events`). Specifying `events` pre-allocates containers for listeners, attaches known property names to an `events` property on the `Emitter` instance, and provides type annotations for known event names in instance methods.

The `emitter` factory wraps the `Emitter` class's constructor, and provides a way of creating an `Emitter` which does not require the `new` keyword.

## Example 1: The basics

```js

import { Emitter } from '@sprs/emitter';

const e = new Emitter(['a', 'b', 'c']);

const logIt = value => console.log('a emitted ', value);
e.on('a', logIt);

e.emit('a', 123);
// -> Message logged: 'a emitted 123'

e.off('a', logIt);
e.emit('a', 456);
// -> No message logged

```

## Example 2: Emitter subclass

```js

import { Emitter } from '@sprs/emitter';

class RequestEmitter extends Emitter {
  constructor(url, options) {
    super(['init', 'response', 'error'])
    this.url = url;
    this.options = options;
  }

  init() {
    this.emit('init', {
      url: this.url,
      options: this.options,
    });

    fetch(this.url, this.options)
      .then(response => {
        this.emit('response', response);
      })
      .catch(error => {
        this.emit('error', error);
      });
  }
}

const google = new RequestEmitter('https://www.google.com', { method: 'GET' });

google.on('init', (startValues) => console.log('Request started: ', startValues));
google.on('response', (response) => console.log('Request succeeded: ', response));
google.on('error', (error) => console.log('Request failed: ', error));

google.init();

```

## Example 3: Transforming events

Following is a more complicated example using the fluent `xform` API to transform event payloads asynchronously. Most use cases shouldn't require this; if you can, just stick to plain old `Emitter`s.

```js

import { Emitter } from '@sprs/emitter';

class RequestEmitter extends Emitter {
  ...
}

const ddg = new RequestEmitter('https://www.duckduckgo.com', { method: 'GET' });
ddg
  .xform({ response: data => data.text() })
  .xform({ response: text => text.slice(0, 100) })
  .on('response', sliced => console.log('First 100 characters of the Duck Duck Go home page HTML...', sliced))

ddg.init();

```

# `XForm`

The `XForm` class serves as an event transformer. It is constructed from an existing `Emitter` and a set of functions to transform event payloads with, and it has the same `on`/`off` methods as an `Emitter`, but it has no `emit` method.

`XForm` can be used to transform both `Emitter`s from this package, and `EventTarget`s from the standard browser API.

If a transformer function returns a `Promise`, `XForm` will wait for that `Promise` to resolve, and then will emit the resolved value, rather than immediately emitting the `Promise` itself.

The third (optional) parameter to the `XForm` constructor provides options. The `multiReturn` option requires a transformer function to return an array of values. This allows an `XForm` to transform event payloads from `Emitter`s which emit multiple values to their events.

The `xform` factory function wraps the `XForm` class's constructor, and provides a method of creating an `XForm` that does not require the `new` keyword.

```js

import { Emitter, XForm } from '@sprs/emitter';

const e1 = new Emitter();
const x1 = new XForm(e1, { myEvent: payload => payload.myProperty * 5 });
x1.on('myEvent', console.log);
e1.emit('myEvent', { myProperty: 6 });
// -> '30'

const e2 = new EventTarget();
const x2 = new XForm(e2, { myEvent: event => event.detail.myProperty * 5 });
x2.on('myEvent', console.log);
e2.dispatchEvent(new CustomEvent('myEvent', { detail: { myProperty: 6 } }));
// -> '30'

const emitsMultiple = new Emitter();
const x3 = new XForm(
  emitsMultiple,
  { myEvent: (a, b, c) => [a, b * 2, c * 3] },
  { multiReturn: true },
);
x3.on('myEvent', console.log);
emitsMultiple.emit('myEvent', 2, 4, 6);
// -> 2, 8, 18
//    Note that this is NOT [2, 8, 18]

```

---
_Source: https://npm.io/package/@sprs/emitter · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
