Skip to content

robinpokorny/dead-simple

This branch is 1 commit ahead of, 2 commits behind master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

322318d Β· Dec 21, 2020

History

54 Commits
Dec 30, 2019
Jan 18, 2017
Jan 18, 2017
Dec 6, 2020
Dec 6, 2020
Dec 6, 2020
Jul 7, 2019
Dec 6, 2020
Dec 6, 2020
Jul 7, 2019
Dec 6, 2020
Dec 6, 2020
Dec 6, 2020
Dec 6, 2020
Dec 21, 2020

Repository files navigation

πŸ’€πŸ’‘ Dead simple PubSub and EventEmitter

Small, readable, almost-tweetable modules utilising classic patterns in modern language.

GitHub Workflow Status license git3moji code style: prettier Managed by Yarn

Features

  • Small: PubSub: 127 bytes, EventEmitter: 138 bytes, together: 191 bytes (all gzipped)
  • Best practices: Subscribe returns unsubscribe. So you can use anonymous functions.
  • Readable: There is nothing magical in the code; except the simplicity.
  • Modern: Uses new, yet well-supported features.
  • Efficient: No memory leaks, no duplicate calls, no extra looping.
  • Clean API: sub and pub (or on and emit), need no more, can't go less.
  • Modular: Use only what you need.
  • Typed TypeScript definitions are bundled

Install

Install using yarn or npm:

yarn add dead-simple
# or via npm
npm install --save dead-simple

Usage

import pubsub from "dead-simple/pubsub";
import eventEmitter from "dead-simple/eventEmitter";
// Alternatively:
// import { pubsub, eventEmitter } from 'dead-simple'

// === PubSub ======
const clicks = pubsub();

const unSub = clicks.sub((target) => console.log(`Clicked on ${target}!`));

clicks.pub("button");
// -> Clicked on button!

unSub();

clicks.pub("link");
// nothing

// === eventEmitter ===
// eventEmitter = named PubSub
const events = eventEmitter();

events.on("click", (target) => console.log(`Clicked on ${target}!`));

const unSubChange = events.on("change", (newValue) =>
  console.log(`Value is now ${newValue}!`)
);

events.emit("change", 1968);
// -> Value is now 1968!

unSubChange();

events.emit("change", 1968);
// nothing

events.emit("click", "button");
// -> Clicked on button!

Browser compatibility

Used ES6: const, arrow functions, Map, Set, object shorthand

Chrome* Edge FF IE Opera Safari iOS Node
38 12 13 -* 25 7.1 8 4

Notes:

  • Chrome includes mobile Chrome (Android 4+).
  • IE 11 does not support only syntax feature, arrow functions and object shorthand.
  • The module needs to be bundled, of course.

Super small versions

This project started a pair of gists which included a hand minified version, too.

We were able to get down to 91B for PubSub:

export default (s = new Set()) => ({
  pub: (d) => s.forEach((f) => f(d)),
  sub: (f) => s.add(f).delete.bind(s, f),
});

And 139B for EventEmitter (p is PubSub):

export default (e) => (
  (e = new Map()),
  Object.freeze({
    on: (n, f) => (e.has(name) || e.set(n, p()), e.get(n).sub(f)),
    emit: (n, d) => e.has(n) && e.get(n).pub(d),
  })
);

These versions are for fun, more like a proof of concept and may not work in some browsers.