npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@thenja/event-emitter

v2.1.1

Published

Simple class to emit and subscribe to events

Downloads

177

Readme

Test Coverage-shield-badge-1

EventEmitter

Simple service used to emit and subscribe to events.

How to use

npm install @thenja/event-emitter --save

Installation

Typescript

import { EventEmitter } from '@thenja/event-emitter';
let eventEmitter = new EventEmitter();

Javascript (browser)

<script src="dist/event-emitter.min.js" type="text/javascript"></script>
var eventEmitter = new EventEmitter();

Methods

|Method|Description| |------|-----------| |emit(eventName: string, data: any)|Emit the event to any subscribers| |subscribe(eventName: string, fn: Function, options?: iSubscribeOptions)|Subscribe to an event, the function will be called once the event is emitted| |unsubscribe(eventName: string, fn: Function)|Unsubscribe from an event|

Use cases & examples

Use as a service

This will be handy if you need a publish and subscribe service for an entire application, you will probably create the EventEmitter class as a singleton for this.

import { EventEmitter } from '@thenja/event-emitter';

let eventEmitter = new EventEmitter();
let fnOne = (data) => {
  console.log('custom-event fired with value: ' + data.val);
};
eventEmitter.subscribe('custom-event', fnOne);
eventEmitter.emit('custom-event', { val: 10 });
eventEmitter.unsubscribe('custom-event', fnOne);

Extending EventEmitter

import { EventEmitter } from '@thenja/event-emitter';

class AppEvents extends EventEmitter {}
const appEvents = new AppEvents();

class Home {
  listen() {
    // you can set the scope to this object
    appEvents.subscribe('event-1', this.listener, { scope: this });
  }

  private listener(data) {
    const val = this.sayHi();
    expect(val).toEqual('Hi');
  }

  private sayHi() { return 'Hi'; }
}
const home = new Home();
home.listen();
appEvents.emit('event-1', { val: 10 });

Use abstract class

A class that extends the EventEmitterAbstract class will basically have a property (this.event) exposed which is just an instance of the EventEmitter class. Useful if you want to emit and listen to events inside of a class.

import { EventEmitterAbstract } from '@thenja/event-emitter';

class MyClass extends EventEmitterAbstract {
  public val: number = 0;

  constructor() {
    super();
    this.event.subscribe('custom-event', this.listenForCustomEvent);
  }

  private listenForCustomEvent() {
    this.val = 10;
  }

  doSomething() {
    this.event.emit('custom-event', {});
  }
}

let myClass = new MyClass();
myClass.doSomething();
// Now myClass.val should equal 10

Emittable events abstract class

This is useful if you have a service (normally a singleton) that is used throughout your application and you want to be able to emit events from the service.

Basic usage:

import { EmittableEvents } from '@thenja/event-emitter';

class UserService extends EmittableEvents {
  addUser(username: string) {
    // perform some functionality to add a user
    // ...
    // now emit an event
    this.emit('user-added', { username: username });
  }
}

// normally a service is a singleton used throughout an application
let userSrv = new UserService();
let userAdded = (data) => {
  // event is fired when a user is added
};
userSrv.on('user-added', userAdded);
userSrv.addUser('nathan');
userSrv.off('user-added', userAdded);

Setting the "this" scope

// this will be our singleton service class
class ScopeTest extends EmittableEvents {
  public fireEvent() {
    this.emit('test-event', { val: 100 });
  }
}

class ListenTest {
  private scopeTest: ScopeTest;
  val: any = null;

  constructor(scopeTest: ScopeTest) {
    this.scopeTest = scopeTest;
    // when you listen to the event, set the scope to "this" so that the 
    // this keyword refers to the listenTest instance
    this.scopeTest.on('test-event', this.listenToEvent, { scope: this });
  }

  listenToEvent(data) {
    this.val = data.val;
  }
}

let scopeTest = new ScopeTest();
let listenTest = new ListenTest(scopeTest);
scopeTest.fireEvent();
expect(listenTest.val).toEqual(100);

Only one listener per event

Sometimes you may only want to have one listener function per event, we can accomplish this by using a unqiue id

let fired = 0;
let myClass = new MyClass();
let listener = (data) => {
  fired++;
};
let listenerTwo = (data) => {
  fired++;
};
// even know we attach two listeners, only the last listener will be used 
// because we have set a uniqueId
myClass.on('testing', listener, { uniqueId: "myUniqueId" });
myClass.on('testing', listenerTwo, { uniqueId: "myUniqueId" });
myClass.fireEvent('testing');
expect(fired).toEqual(1);

Development

npm run init - Setup the app for development (run once after cloning)

npm run dev - Run this command when you want to work on this app. It will compile typescript, run tests and watch for file changes.

Distribution

npm run build -- -v <version> - Create a distribution build of the app.

-v (version) - [Optional] Either "patch", "minor" or "major". Increase the version number in the package.json file.

The build command creates a /compiled directory which has all the javascript compiled code and typescript definitions. As well, a /dist directory is created that contains a minified javascript file.

Testing

Tests are automatically ran when you do a build.

npm run test - Run the tests. The tests will be ran in a nodejs environment. You can run the tests in a browser environment by opening the file /spec/in-browser/SpecRunner.html.

License

MIT © Nathan Anderson