Skip to content

Commit

Permalink
Merge pull request #5 from georapbox/issue-#4
Browse files Browse the repository at this point in the history
immediateExceptions as option; fix #4
  • Loading branch information
georapbox authored Jan 31, 2019
2 parents a05660d + 9c9aee9 commit 5208044
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 21 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/*
dist/**
examples/**
demo/
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@
"no-whitespace-before-property": 1,

// enforce consistent spacing inside braces
"object-curly-spacing": [1, "never"],
"object-curly-spacing": 0,

// enforce the consistent use of either backticks, double, or single quotes
"quotes": [1, "single", {"avoidEscape": true, "allowTemplateLiterals": true}],
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## v3.6.0
- Fix issue #4
- Add `immediateExceptions` option when creating instance


## v3.5.0
- Update `devDependencies`
- Use `mocha` and `chai` for testing instead of `karma` and `jasmine`
Expand Down
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ $ npm install PubSub
## API

* [PubSub](#PubSub)
* [new PubSub()](#new_PubSub_new)
* [new PubSub([options])](#new_PubSub_new)
* _instance_
* [.subscribe(topic, callback, [once])](#PubSub+subscribe) ⇒ <code>number</code>
* [.subscribeOnce(topic, callback)](#PubSub+subscribeOnce) ⇒ <code>number</code>
Expand All @@ -45,14 +45,22 @@ $ npm install PubSub

<a name="new_PubSub_new"></a>

### new PubSub()
### new PubSub([options])
Creates a PubSub instance.

## Instance Methods
#### Available options

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| immediateExceptions<sup>1</sup> | <code>boolean</code> | <code>false</code> | Force immediate exceptions (instead of delayed exceptions). |

<sup>1</sup> *Before version 3.6.0 PubSub would fail to deliver your topics to all subscribers if one or more failed (see issue [#4](https://github.com/georapbox/PubSub/issues/4)). As of version 3.6.0 PubSub handles this by delaying thrown exceptions by default. You can set `immediateExceptions` to `true` in order to maintain the stack trace for development reasons but this is not recommended for production.*

## Public Methods

<a name="PubSub+subscribe"></a>

### pubSub.subscribe(topic, callback, [once]) ⇒ <code>number</code>
### subscribe(topic, callback, [once]) ⇒ <code>number</code>
Subscribe to events of interest with a specific topic name and a
callback function, to be executed when the topic/event is observed.

Expand All @@ -76,7 +84,7 @@ var onUserAdd = pubsub.subscribe('user_add', function (data, topic) {
```
<a name="PubSub+subscribeOnce"></a>

### pubSub.subscribeOnce(topic, callback) ⇒ <code>number</code>
### subscribeOnce(topic, callback) ⇒ <code>number</code>
Subscribe to events of interest setting a flag
indicating the event will be published only one time.

Expand All @@ -90,14 +98,16 @@ indicating the event will be published only one time.

**Example**
```js
var pubsub = new PubSub();

var onUserAdd = pubsub.subscribeOnce('user_add', function (data, topic) {
console.log('User added');
console.log('user data:', data);
});
```
<a name="PubSub+publish"></a>

### pubSub.publish(topic, [data]) ⇒ <code>boolean</code>
### publish(topic, [data]) ⇒ <code>boolean</code>
Publishes a topic **asynchronously**, passing the data to its subscribers.
Asynchronous publication helps in that the originator of the topics will not be blocked while consumers process them.
For synchronous topic publication check `publishSync`.
Expand All @@ -112,6 +122,8 @@ For synchronous topic publication check `publishSync`.

**Example**
```js
var pubsub = new PubSub();

pubsub.publish('user_add', {
firstName: 'John',
lastName: 'Doe',
Expand All @@ -120,7 +132,7 @@ pubsub.publish('user_add', {
```
<a name="PubSub+publishSync"></a>

### pubSub.publishSync(topic, [data]) ⇒ <code>boolean</code>
### publishSync(topic, [data]) ⇒ <code>boolean</code>
Publishes a topic **synchronously**, passing the data to its subscribers.

**Kind**: instance method of <code>[PubSub](#PubSub)</code>
Expand All @@ -133,6 +145,8 @@ Publishes a topic **synchronously**, passing the data to its subscribers.

**Example**
```js
var pubsub = new PubSub();

pubsub.publishSync('user_add', {
firstName: 'John',
lastName: 'Doe',
Expand All @@ -141,7 +155,7 @@ pubsub.publishSync('user_add', {
```
<a name="PubSub+unsubscribe"></a>

### pubSub.unsubscribe(topic) ⇒ <code>boolean</code> \| <code>string</code>
### unsubscribe(topic) ⇒ <code>boolean</code> \| <code>string</code>
Unsubscribes from a specific topic, based on the topic name,
or based on a tokenized reference to the subscription.

Expand All @@ -154,6 +168,8 @@ or based on a tokenized reference to the subscription.

**Example**
```js
var pubsub = new PubSub();

// Unsubscribe using the topic's name.
pubsub.unsubscribe('user_add');

Expand All @@ -162,14 +178,15 @@ pubsub.unsubscribe(onUserAdd);
```
<a name="PubSub+unsubscribeAll"></a>

### pubSub.unsubscribeAll() ⇒ <code>[PubSub](#PubSub)</code>
### unsubscribeAll() ⇒ <code>[PubSub](#PubSub)</code>
Clears all subscriptions whatsoever.

**Kind**: instance method of <code>[PubSub](#PubSub)</code>
**Returns**: <code>[PubSub](#PubSub)</code> - The PubSub instance.
**Example**
```js
var pubsub = new PubSub();

pubsub.subscribe('message1', function () {});
pubsub.subscribe('message2', function () {});
pubsub.subscribe('message3', function () {});
Expand All @@ -178,7 +195,7 @@ pubsub.hasSubscribers(); // -> false
```
<a name="PubSub+hasSubscribers"></a>

### pubSub.hasSubscribers([topic]) ⇒ <code>boolean</code>
### hasSubscribers([topic]) ⇒ <code>boolean</code>
Checks if there are subscribers for a specific topic.
If `topic` is not provided, checks if there is at least one subscriber.

Expand All @@ -192,6 +209,7 @@ If `topic` is not provided, checks if there is at least one subscriber.
**Example**
```js
var pubsub = new PubSub();

pubsub.on('message', function (data) {
console.log(data);
});
Expand All @@ -201,7 +219,7 @@ pubsub.hasSubscribers('message');
```
<a name="PubSub+subscribers"></a>

### pubSub.subscribers() ⇒ <code>object</code>
### subscribers() ⇒ <code>object</code>
Gets all the subscribers as a set of key value pairs that
represent the topic's name and the event listener(s) bound.

Expand All @@ -221,7 +239,7 @@ pubsub.subscribers();
```
<a name="PubSub+subscribersByTopic"></a>

### pubSub.subscribersByTopic(topic) ⇒ <code>array</code>
### subscribersByTopic(topic) ⇒ <code>array</code>
Gets subscribers for a specific topic.

**Kind**: instance method of <code>[PubSub](#PubSub)</code>
Expand Down Expand Up @@ -251,7 +269,7 @@ pubsub.subscribersByTopic('some_message_not_existing');
```
<a name="PubSub+alias"></a>

### pubSub.alias(aliasMap) ⇒ <code>[PubSub](#PubSub)</code>
### alias(aliasMap) ⇒ <code>[PubSub](#PubSub)</code>
Creates aliases for public methods.

**Kind**: instance method of <code>[PubSub](#PubSub)</code>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "PubSub",
"version": "3.5.0",
"version": "3.6.0",
"description": "Javascript implementation of the Publish/Subscribe pattern.",
"main": "src/pubsub.js",
"files": [
Expand Down
52 changes: 46 additions & 6 deletions src/pubsub.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@

var OLD_PUBLIC_API = (context || {})[name];

function assign(target) {
var to, index, nextSource, nextKey;

if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}

to = Object(target);

for (index = 1; index < arguments.length; index++) {
nextSource = arguments[index];

if (nextSource != null) {
for (nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
}

function forOwn(obj, callback, thisArg) {
var key;

Expand Down Expand Up @@ -44,10 +67,17 @@
token = subscribers[i].token;
currentSubscriber = subscribers[i];

currentSubscriber.callback(data, {
name: topic,
token: token
});
if (!instance._options.immediateExceptions) {
try {
currentSubscriber.callback(data, { name: topic, token: token });
} catch (exception) {
setTimeout(function () {
throw exception;
}, 0);
}
} else {
currentSubscriber.callback(data, { name: topic, token: token });
}

// Unsubscribe from event based on tokenized reference,
// if subscriber's property once is set to true.
Expand Down Expand Up @@ -79,14 +109,24 @@
/**
* Creates a PubSub instance.
* @constructor PubSub
*
* @param {object} [options] User options
* @param {boolean} [options.immediateExceptions=false] Forces exceptions to be thrown immediately instead of delayed exceptions
*/
function PubSub() {
function PubSub(options) {
var defaults = {
immediateExceptions: false
};

options = assign({}, defaults, options);

if (!(this instanceof PubSub)) {
return new PubSub();
return new PubSub(options);
}

this._pubsub_topics = {}; // Storage for topics that can be broadcast or listened to.
this._pubsub_uid = -1; // A topic identifier.
this._options = options;
return this;
}

Expand Down

0 comments on commit 5208044

Please sign in to comment.