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

node-mediator

v2.0.2

Published

A Node.js event based mediator design pattern written in typescript with eventemitter2. It Allows building seperate, decoupled, more testable modules in a breeze.

Downloads

3

Readme

node-mediator

node-mediator implements the mediator design pattern with events. It supports creating decoupled components(called colleagues) which all interact through one component(called mediator) through events. If you have large projects with a lot of dependencies between components, this is the library for you.

Why should you use this library?

  • When you have many components communicating with one another, using a mediator with events will make your development times quicker and building new fetures easier and faster as everything is decoupled.
  • Easier to follow the S.O.L.I.D principles as you have fewer intercomponent dependencies and a better view of the hierarchy of your components.
  • Simpler to test your components.
  • Ensures strictness between inter-component communication.
  • Uses eventemitter2 library by default(it is overridable if you implement the Emitter interface and pass it as a 2nd argument to the mediator initialization)

Installation

npm install node-mediator -S
or
yarn add node-mediator

Examples

you can find an example of usage in the examples folder found here

relations.ts

used by the mediator to restrict inter-component commumnication

import { RelationsMap } from 'node-mediator'
// tester, uploader and logger are our class that extended the Colleague abstract class
// each colleague implementation has on and emit objects which accept strings of events names as keys and booleans as values.
// in our case it means that tester is allowed to fire a test event and receive a test event, etc.
const relations: RelationsMap = {
  tester: {
    on: { test: true },
    emit: { test: true }
  },
  uploader: {
    on: { upload: true },
    emit: { upload: true }
  },
  logger: {
    on: { log: true },
    emit: { upload: true }
  }
}

export default relations

Logger.ts

import { Colleague } from 'node-mediator'
// our logger extends Colleague, therefore has .on, .emit, .emitAsync and .register on its prototype.
// we define our methods here and we will register them later. If you want to emit an event to some other component you simply use the this.emit or this.emitAsync if you need to await the answer.
class Logger extends Colleague {
  log(...args) {
    // our emit will only happen if it allowed in our relations map!
    this.emit('upload', { someArumentToUpload: true })
    console.log('logger: ', ...args)
  }
}
export default Logger

Main.ts

import { NodeMediator } from 'node-mediator'
import relations from './relations'
import Tester from './Tester'
import Logger from './Logger'
import Uploader from './Uploader'

class Main {
  async run() {
    // our mediator is a singleton, first time we call .getInstance with our relations map to initialize the mediator
    const mediator = NodeMediator.getInstance(relations)
    /*
      subsequent calls to getInstance will ignore any params and return our mediator singleton
      NodeMediator.getInstance() -> mediator
    */

    // we call our extended Colleagues with their name and we pass the mediator singleton to them
    const tester = new Tester('tester', mediator)
    const logger = new Logger('logger', mediator)
    const uploader = new Uploader('uploader', mediator)

    // register the extended Colleagues.
    tester.register()
    logger.register()
    uploader.register()

    // define events. Only events defined in relationsMap will be allowed!
    logger.on('log', logger.log)
    tester.on('test', tester.test)
    uploader.on('upload', uploader.upload)

    // example emit
    tester.emit('test')
    /*
      we can also call .emitAsync. If you have a lot of async operations 
      but you still want them decoupled, you can use .emitAsync, 
      .emitAsync uses promise.all to resolve all listeners promises and return all values.
     */

    // we defined our tester and uplaoder to allow firing upload
    const uploaded = await uploader.emitAsync('upload', 'some data for upload...')
    console.log(uploaded)
  }
}
new Main().run()

License

MIT