Skip to content

Repository files navigation

npm Build Status Coverage Status install size

event-emitter

Simple event emitter.

Install

npm i @for-fun/event-emitter

Usage

import * as React from 'react';
import {create, on, emit} from '@for-fun/event-emitter';

const emitter = create();

export default function() {
  const [message, setMessage] = React.useState('');
  React.useEffect(() => on(emitter, 'message', setMessage));

  return <div>
    <p>{message}</p>
    <button onClick={() => emit(emitter, 'message', 'hello')}>Click Me</button>
  </div>;
}

Compatibility Note

This lib support these browsers or devices with these methods or APIs pollyfilled.

Design Note

Wildcard subscriptions (e.g. on(ee, '*', handler)) are not supported by design. Path-level or hierarchical subscriptions are a consumer-side concern — for example, react-f0rm builds them on top of this emitter via onPathEvent.

API

Unsubscribing

on/once return an OffFunction that removes that exact subscription:

const off = on(ee, 'message', handler);
off(); // removes this exact subscription

Additionally, off and removeAllListeners remove listeners in bulk:

off(ee, 'message', handler); // removes one exact subscription
off(ee, 'message'); // removes every 'message' listener
off(ee); // removes every listener of every key
removeAllListeners(ee, 'message'); // same as off(ee, 'message')
removeAllListeners(ee); // same as off(ee)

Both are no-ops for keys or handlers that were never subscribed.

Error isolation in emit

Handlers of one emit are independent: if a handler throws, the remaining handlers of that same emit still run. The collected errors are reported one by one to the errorEvent channel (onError/onceError subscribers). If no error handler is subscribed either, emit rethrows the first collected error, so failures are never silently swallowed:

onError(ee, err => report(err)); // receives every collected error
emit(ee, 'a'); // throws the first error only when no error handler exists

maxListeners (DEV-only warning)

When more than 10 listeners accumulate on one key — a common symptom of a missing unsubscribe — a console.warn fires once per key, in development only:

setMaxListeners(ee, 20); // raise the limit for this emitter
setMaxListeners(ee, 0); // disable the warning for this emitter

The gate is process.env.NODE_ENV !== 'production' (also silent when process is unavailable, e.g. the UMD build loaded directly in a browser). Production builds skip the whole check; on only pays a single boolean test.

Listener changes during emit

emit iterates the key's handler set with Set semantics:

  • a listener added while an emit is running is invoked by that same emit (Set iteration visits entries appended mid-iteration);
  • a listener removed before the iteration reaches it is skipped;
  • removing a whole key (off(ee, key) / removeAllListeners(ee, key)) does not stop an emit that is already running.

Workflow

# develop
npm start

# build
npm run build

# test
npm test

# commit changes
npm run commit

# publish
npm publish

About

Simple event emitter.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages