Git Product home page Git Product logo

pubsub.js's Introduction

pubsub.js

Dependency free JavaScript pubsub implementation with wildcards, inheritance and multisubscriptions.

Working smoothly both on frontend and backend side.

Read documentation, check tests file, be inspired and feel free to use it and/or contribute.

Build Status Dependency Status License

Web page

NPM pubsub.js link

Features

  • Currently it is the most advanced dependency-free pub/sub library on npm
  • Very fast
  • Easy to understand
  • Dependency free = using native JavaScript code
  • Configurable link
  • Works on server and browser side smoothly link
  • Event inheritance link
  • Wildcards publish wildcard subscribe wildcard
  • subscribeOnce method link
  • Multiple subscriptions link
  • Possibility to make new instances of pubsub with private namespaces scope link
  • Possibility to publish async events link
  • Possibility to define context for all callbacks by providing pubsub|newInstance "context" param link
  • Possibility to define context for each callback link
  • Controll under event bubbling depth
  • Works with require.js library
  • Written with TDD
  • Compiled + gzipped weighs only 1kB, less than 320 lines of code
  • Works also on IE 6+

Installation

  • download from Github
  • npm: npm install pubsub.js
  • bower: bower install pubsub-advanced

Default pubsub.js configuration:

	separator : '/' // defined namespace separator
	context         // has dynamic value - when not defined it will be always reference to used callback in subscribe method
	recurrent : false // defines inheritance of publish event
	async 	  : false // if true - publish events will be asynchronous
	log       : false // set to true will log unsubscribed namespaces to which You publish event

Using pubsub inside node.js

	var pubsub = require('pubsub.js');

	pubsub.subscribe('hello/world', function(text) {
		console.log(text);
	});
	pubsub.publish('hello/world', ['my text']);

Examples

Basic example

	//subscribe to 'hello/world' namespace
	pubsub.subscribe('hello/world', function() {
		console.log('hello world!');
	});
	//publish event on 'hello/world' namespace
	pubsub.publish('hello/world');
	//prints "hello world" inside console

Publish with param

	//subscribe to 'hello/world' namespace
	pubsub.subscribe('hello/world', function(data) {
		console.log(data);
	});
	//publish event on 'hello/world' namespace
	pubsub.publish('hello/world', ['hello!']); // second parameter is an array of arguments
	//prints "hello!" inside console

Unsubscribe

	//subscribe to 'hello/world' namespace
	var subscription = pubsub.subscribe('hello/world', function() {
		console.log('hello world!');
	});
	//publish event on 'hello/world' namespace
	pubsub.publish('hello/world');
	//prints "hello world" inside console

	//unsubscribe
	pubsub.unsubscribe(subscription);
	//publish event on 'hello/world' namespace
	pubsub.publish('hello/world');
	//nothing happen - we've previously unsubscribed that subscription

Changing default configuration

Browser

Before pubsub script loader - make global variable named "pubsub" with your default configuration

	pubsub = {
		separator : '.'
		context : referenceToContext
	}

After pubsub load - use it with your configuration, pubsub.js will replace that previous "pubsub" global variable with its own instance

	//subscribe to 'hello.world' namespace
	var subscription = pubsub.subscribe('hello.world', function() {
		console.log('hello world!');
	});
	//publish event on 'hello.world' namespace
	pubsub.publish('hello.world');
	//prints "hello world" inside console

	//unsubscribe
	pubsub.unsubscribe(subscription);
	//publish event on 'hello.world' namespace
	pubsub.publish('hello.world');
	//nothing happen - we've previously unsubscribed that subscription

Node.js

Before pubsub require execution - set global.pubsubConfig variable

	global.pubsubConfig = {
		separator : '.'
	}

After pubsub load, it'll have your configuration as in browser example

Event inheritance

	//subscribe to 'hello' namespace
	var subscription = pubsub.subscribe('hello', function() {
		console.log('hello world!');
	});
	//publish event on 'hello/world' namespace
	pubsub.publish('hello/world', [], {
		recurrent : true
	});
	//prints "hello world" inside console
	//first event goes to "hello" namespace
	//then it tries to execute on "hello/world" but nothing is listening on it

Method: subscribeOnce

	var iterator = 0;
	var data = null;

	pubsub.subscribeOnce('hello/world', function(param) {
		data = param;
		iterator++;
	});
	pubsub.publish('hello/world', ['hello']);
	pubsub.publish('hello/world', ['world']);
	console.log(iterator); //1
	console.log(data); //'hello'

Publish wildcard "*"

	var number = 0;

	//subscribe to "hello/world" namespace
	pubsub.subscribe('hello/world', function() {
		number++;
	});
	//subscribe to "hello/earth" namespace
	pubsub.subscribe('hello/earth', function() {
		number++;
	});
	//subscribe to "hello/galaxy" namespace
	pubsub.subscribe('hello/galaxy', function() {
		number++;
	});
	//subscribe to "hello/world/inner" namespace
	pubsub.subscribe('hello/world/inner', function() {
		number++;
	});

	pubsub.publish('hello/*');
	//hello/* executes:
	//	hello/world, hello/earth, hello/galaxy
	//	namespace, hello/world/inner is not executed
	//
	//	"*" goes only one namespace deeper
	console.log(number); //3

Subscribe wildcard "*"

	var number = 0;

	var subscription = pubsub.subscribe('hello/*/world', function() {
		number += 1;
	});

	pubsub.publish('hello'); // won't handle
	pubsub.publish('hello/my'); // won't handle
	pubsub.publish('hello/great/galaxy'); // won't handle

	pubsub.publish('hello/my/world'); // handles
	pubsub.publish('hello/huge/world'); // handles
	pubsub.publish('hello/great/world'); // handles

	console.log(number); // 3

Multiple subscriptions

many namespaces, one callback

	var number = 0;

	var subscription = pubsub.subscribe(['hello/world', 'goodbye/world'], function() {
		number++;
	});

	pubsub.publish('hello/world');
	console.log(number); //1
	pubsub.publish('goodbye/world');
	console.log(number); //2
	pubsub.unsubscribe(subscription);

	pubsub.publish('hello/world');
	console.log(number); //2
	pubsub.publish('goodbye/world');
	console.log(number); //2

one namespace, many callbacks

	var number1 = 0;
	var number2 = 0;

	var subscription = pubsub.subscribe('hello/world', [function() {
		number1++;
	}, function() {
		number2 += 2;
	}]);

	pubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //1,2
	pubsub.unsubscribe(subscription);

	pubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //2,4

many namespaces, many callbacks

	var number1 = 0;
	var number2 = 0;

	var subscription = pubsub.subscribe(['hello/world', 'goodbye/world'], [function() {
		number1++;
	}, function() {
		number2 += 2;
	}]);

	pubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //1,2
	pubsub.publish('goodbye/world');
	console.log(number1 + ',' + number2); //2,4
	pubsub.unsubscribe(subscription);

	pubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //2,4
	pubsub.publish('goodbye/world');
	console.log(number1 + ',' + number2); //2,4

making new instances with own namespaces scope

	var number1 = 0;
	var number2 = 0;

	var privatePubsub = pubsub.newInstance();

	pubsub.subscribe('hello/world', function() {
		number1++;
	});

	privatePubsub.subscribe('hello/world', function() {
		number2++;
	});

	pubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //1,0

	privatePubsub.publish('hello/world');
	console.log(number1 + ',' + number2); //1,1

making new instances with own context

	var contextArgument = ["object"];
	var privatePubsub = pubsub.newInstance({
		context : contextArgument
	});

	privatePubsub.subscribe('hello/context', function() {
		var that = this;

		console.log(that === contextArgument); //true
	});
	privatePubsub.publish('hello/context');

Using pubsub asynchronously

	var number1 = 0;

	var asyncPubsub = pubsub.newInstance({
		async : true
	});

	asyncPubsub.subscribeOnce('hello/world', function() {
		number1++;
		console.log(number1); //2
	});

	asyncPubsub.publish('hello/world'); // asynchronous call to 'hello/world'

	number1++;
	console.log(number1); //1

Using context param in subscribe method

	var contextArgument = ["object"];
	var privatePubsub = pubsub.newInstance();

	function callbackFirst() {
		var that = this;

		console.log(that === callbackFirst); // true
	}
	function callbackSecond() {
		var that = this;

		console.log(that === contextArgument); // true
	}

	var privateSubscribtion1 = privatePubsub.subscribe('hello/context', callbackFirst);
	var privateSubscribtion2 = privatePubsub.subscribe('hello/that', callbackSecond, {
		context : contextArgument
	});

Changelog

  • v1.5.2
    • Fixed IE11 cross frames communication (isArray)
  • v1.5.1
    • Fix "context" option for subscribeOnce
    • .eslintrc style guide added + code stylistic fixes
  • v1.5.0
    • Fix issue #8 - "context" option, new test cases
  • v1.4.3
    • Fix issue #7 - "recurrent" option, new test cases
  • v1.4.2
    • Documentation changes
  • v1.4.1
    • Travis integration
  • v1.4.0
    • Added subscription wildcard "*"
  • v1.3.1
    • Fixed problem with "window reference error" in node.js environment
  • v1.3.0
    • Changed the way of using context parameter in subscribe method - API changes to subscribe method!
  • v1.2.0
    • Changed the way of using event inheritance - API changes to publish method!
    • Added possibility to use "publish" asynchronously
  • v1.1.0
    • reworked core
    • changed the way of setting own config
    • implemented "newInstance" method
  • v1.0.6
    • Fixed bug with unsubscription - subscription during publish of the same namespace (test case 3)
  • v1.0.5
    • Added multisubscription possibilities
  • v1.0.4
    • Added subscribeOnce method
  • v1.0.3
    • Changed scope binding in pubsub
  • v1.0.2
    • Publish wildcard "*" added
  • v1.0.1
    • Improved performance - about 350% on chrome, 20% on firefox
  • v1.0.0
    • Every basic test passing

License

MIT

pubsub.js's People

Contributors

sahadar avatar bryant1410 avatar tomas2387 avatar hashchange avatar

Stargazers

 avatar daniel o avatar  avatar liudonghua avatar cheng avatar  avatar Paul Marlow avatar  avatar ANZART avatar Jiny avatar CLAY avatar Thanakij Pechprasarn avatar Anton Rusinov avatar  avatar  avatar Paul Russo avatar Arthur Endlein avatar ALISON RODRIGUES avatar  avatar  avatar Jason Todd avatar Mohammad Rajabloo avatar André Wisén avatar Guilherme Prezzi avatar Tomas Tamagnone avatar Greg Murray avatar Jimin Park avatar limichange avatar Daniil Grishkin avatar SEHI L'YI avatar Katrina Kaciczak avatar Daniel Blendea avatar Elisa Nicole avatar  avatar Chris Coetzee avatar  avatar John Dave Manuel avatar Anton St. avatar Cat  avatar Boris Raicheff avatar Chris Matthieu avatar Sebastian P. avatar Pedro H. B. de Morais avatar Rio Purnomo avatar Oliver Liu avatar Milad Kawas avatar  avatar Matheus Seabra avatar  avatar Matt Lenz avatar Martin Wecke avatar Haroldo de Oliveira Pinheiro avatar Tegar Jagat Geni Arya Perkasa avatar Johannes Ekman avatar Noah Halstead avatar Xabier Vázquez Gallardo avatar Kevin Chang avatar 乌鸦 avatar Justin Ma avatar Ariadine Gomes avatar  avatar Michelange Baudoux avatar Mark Miretsky avatar Per Ghosh avatar Andrey Yakovlev avatar Harlley Oliveira avatar Alessandro avatar EM avatar  avatar Anderlu avatar  avatar James Yang avatar jun kowura avatar ERWIN JOHN T. CARPIO, MD, FPCR avatar Guilherme Soster avatar Lu Nelson avatar Jimmy Utterström avatar Luis Gonzalez avatar George Endrulat avatar  avatar  avatar NIC avatar wen avatar  avatar Xander Lewis avatar Vesa Kauppinen avatar Wenxuan avatar Michael Tomko avatar Michael Puckett avatar Michael Galloway avatar Sarhan avatar Shangbin Yang avatar Mateusz Kocz avatar Tomasz Konojacki avatar  avatar Jan Bieroń avatar Wojciech Rydel avatar Bartłomiej Sobczuk avatar Piotr Kowalski avatar Ionuț Colceriu avatar

Watchers

 avatar  avatar James Cloos avatar  avatar itbaby avatar Licínio Sousa avatar Michelange Baudoux avatar Deepak Bhola avatar

pubsub.js's Issues

Tag missing for v1.5.1

Version 1.5.1 doesn't get fetched with Bower because the release isn't tagged.

Can you please add the tag? Thanks!

(I was just about to report a broken context option in subscribeOnce and then realised that you've already fixed it but Bower had fetched the previous version.)

Callback with Parameters

Hi,

it is possible to have parameters for callback?

As I need own context (such as clientId and others) for individual subscribers.

Thanks

New instance of pubsub on window/scope overwrites the old instance

Hi,
If a pubsub is already loaded and an instance is created on window, and incase if we load pubsub again the new instance overwrites the old pubsub instance.

if(typeof window === 'object') { window.pubsub = pubsubInstance; if(window !== scope) { scope.pubsub = pubsubInstance; } }

Isn't this should be other way around?

We should check if there's any instance already available, if not available only then start constructing.

Please add pubsub.js to BOWER

It's always nice to have a consistent way of getting all the project dependecies from one place. This implementation of Pub/Sub is very good and registering it as a BOWER package will probably boost its popularity.

Reference Error: Window

When using this as a nodejs module on the server I get the following erro in ./pubsub.js/pubsub.js on line 256 there is a reference error stating window is not defined.

Since I am not using this in the browser and only on the node server I just removed the two if statements starting on 256.

Array detection fails in IE11 when called from iframe

In IE11, when communicating across window boundaries (calling subscribe() from an embedded iframe), the array detection does not work. Passing a namespace array to subscribe() results in an error:

nsString.split is not a function 
    at Object.subscribe (... pubsub.js:134)
    at Object.subscribe (... pubsub.js:251)
    etc

That is easy to fix by replacing the current array detection

typeof nsString === 'object' && nsString instanceof Array

with more a robust version from an established libary. The the approach taken by Underscore, for instance, works well:

function isArray (obj) { 
    return Array.isArray ? Array.isArray(obj) : Object.prototype.toString.call(obj) === '[object Array]';
}

A PR is coming your way :)

event published twice

The following code will publish the event twice:

'use strict';

var pubsub = require('pubsub.js').newInstance({
   recurrent: true
});

var subscription = pubsub.subscribe('hello', function() {
   console.log('hello world!');
});

pubsub.publish('hello', []);

Output:

hello world!
hello world!

I would expect only one event.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.