diff --git a/README.md b/README.md index 5b6aad2..1e035ef 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,9 @@ successful. Otherwise it'll be rejected with the error. ------------------------------------------------------------ ###Asteroid.subscribe(name, [param1, param2, ...]) -Subscribes to the specified subscription. +Subscribes to the specified subscription. If a subscription +by that name is already present (and successful), first +Asteroid unsubscribes from it. #####Arguments diff --git a/bower.json b/bower.json index 883a71a..e0ac1e3 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "asteroid", - "version": "0.2.2", + "version": "0.2.3", "homepage": "https://github.com/mondora/asteroid", "authors": [ "Paolo Scanferla " diff --git a/dist/asteroid.js b/dist/asteroid.js index 5fe1361..b091a30 100644 --- a/dist/asteroid.js +++ b/dist/asteroid.js @@ -243,9 +243,11 @@ Asteroid.prototype._onChanged = function (data) { Asteroid.prototype.subscribe = function (name /* , param1, param2, ... */) { // Assert name must be a string must.beString(name); - // If we're already subscribed, return the subscription - if (this.subscriptions[name]) { - return this.subscriptions[name]; + // If we're already subscribed, unsubscribe before re-subscribing + var subPromise = this.subscriptions[name]; + if (subPromise && subPromise.isFulfilled()) { + var subId = subPromise.inspect().value; + this.unsubscribe(subId); } // Init the promise that will be returned var deferred = Q.defer(); @@ -258,7 +260,7 @@ Asteroid.prototype.subscribe = function (name /* , param1, param2, ... */) { // This is the onReady/onNoSub callback if (err) { // Reject the promise if the server answered nosub - deferred.reject(err, id); + deferred.reject(err); } else { // Resolve the promise if the server answered ready deferred.resolve(id); diff --git a/dist/asteroid.min.js b/dist/asteroid.min.js index 79a09d6..90b1869 100644 --- a/dist/asteroid.min.js +++ b/dist/asteroid.min.js @@ -1 +1 @@ -!function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.Asteroid=e()}(this,function(){"use strict";function t(t){if("undefined"!=typeof EJSON)return EJSON.clone(t);var e=typeof t;switch(e){case"undefined":case"function":return void 0;case"string":case"number":case"boolean":return t;case"object":return null===t?null:JSON.parse(JSON.stringify(t));default:return}}function e(t){var e="";for(var o in t)e+=o+"="+t[o]+"&";return e=e.slice(0,-1)}function o(){for(var t="",e=0;8>e;e++)t+=Math.floor(65536*(1+Math.random())).toString(16).substring(1);return t}var i=function(){};i.prototype={constructor:i,on:function(t,e){this._events||(this._events={}),this._events[t]=this._events[t]||[],this._events[t].push(e)},off:function(t,e){this._events||(this._events={}),this._events[t]&&this._events[t].splice(this._events[t].indexOf(e),1)},_emit:function(t){if(this._events||(this._events={}),this._events[t]){var e=arguments,o=this;this._events[t].forEach(function(t){t.apply(o,Array.prototype.slice.call(e,1))})}}};var n={};n._toString=function(t){return Object.prototype.toString.call(t).slice(8,-1)},n.beString=function(t){var e=this._toString(t);if("String"!==e)throw new Error("Assertion failed: expected String, instead got "+e)},n.beObject=function(t){var e=this._toString(t);if("Object"!==e)throw new Error("Assertion failed: expected Object, instead got "+e)};var r=function(t,e,o){n.beString(t),this._host=(e?"https://":"http://")+t,this._ddpOptions={endpoint:(e?"wss://":"ws://")+t+(window.SockJS?"/sockjs":"/websocket"),SocketConstructor:window.SockJS||window.WebSocket,debug:o},this.collections={},this.subscriptions={},this._init()};r.prototype=Object.create(i.prototype),r.prototype.constructor=r,r.prototype._init=function(){var t=this;t.ddp=new DDP(this._ddpOptions),t.ddp.on("connected",function(){t._tryResumeLogin(),t.ddp.sub("meteor.loginServiceConfiguration"),t._emit("connected")}),t.ddp.on("added",function(e){t._onAdded(e)}),t.ddp.on("changed",function(e){t._onChanged(e)}),t.ddp.on("removed",function(e){t._onRemoved(e)})},r.prototype._onAdded=function(t){var e=t.collection;this.collections[e]||(this.collections[e]=new r._Collection(e,this));var o=t.fields||{};o._id=t.id,this.collections[e]._remoteToLocalInsert(o)},r.prototype._onRemoved=function(t){this.collections[t.collection]&&this.collections[t.collection]._remoteToLocalRemove(t.id)},r.prototype._onChanged=function(t){this.collections[t.collection]&&(t.fields||(t.fields={}),t.cleared&&t.cleared.forEach(function(e){t.fields[e]=void 0}),this.collections[t.collection]._remoteToLocalUpdate(t.id,t.fields))},r.prototype.subscribe=function(t){if(n.beString(t),this.subscriptions[t])return this.subscriptions[t];var e=Q.defer();this.subscriptions[t]=e.promise;var o=Array.prototype.slice.call(arguments,1);return this.ddp.sub(t,o,function(t,o){t?e.reject(t,o):e.resolve(o)}),this.subscriptions[t]},r.prototype.unsubscribe=function(t){this.ddp.unsub(t)},r.prototype.call=function(t){n.beString(t);var e=Array.prototype.slice.call(arguments,1);return this.apply(t,e)},r.prototype.apply=function(t,e){n.beString(t);var o=Q.defer(),i=Q.defer(),r=function(t,e){t?(o.reject(t),i.reject()):o.resolve(e)},s=function(){i.resolve()};return this.ddp.method(t,e,r,s),{result:o.promise,updated:i.promise}},r.prototype.createCollection=function(t){return n.beString(t),this.collections[t]||(this.collections[t]=new r._Collection(t,this)),this.collections[t]};var s="__del__",c="__upd__",u=function(t){var e=s.length,o=c.length,i=t.slice(-1*e),n=t.slice(-1*o);return i===s||n===c},l=function(t,e){this.name=t,this.asteroid=e,this._set=new _};l.prototype.constructor=l,l.prototype._localToLocalInsert=function(t){if(this._set.contains(t._id))throw new Error("Item "+t._id+" already exists");return this._set.put(t._id,t),Q(t._id)},l.prototype._remoteToLocalInsert=function(t){this._set.put(t._id,t)},l.prototype._localToRemoteInsert=function(t){var e=this,o=Q.defer(),i="/"+e.name+"/insert";return e.asteroid.ddp.method(i,[t],function(i){i?(e._set.del(t._id),o.reject(i)):o.resolve(t._id)}),o.promise},l.prototype.insert=function(t){return t._id||(t._id=o()),{local:this._localToLocalInsert(t),remote:this._localToRemoteInsert(t)}},l.prototype._localToLocalRemove=function(t){var e=this._set.get(t);return e&&(this._set.put(t+s,e),this._set.del(t)),Q(t)},l.prototype._remoteToLocalRemove=function(t){this._set.del(t)},l.prototype._localToRemoteRemove=function(t){var e=this,o=Q.defer(),i="/"+e.name+"/remove";return e.asteroid.ddp.method(i,[{_id:t}],function(i){if(i){var n=e._set.get(t+s);n&&(e._set.put(t,n),e._set.del(t+s)),o.reject(i)}else e._set.del(t+s),o.resolve(t)}),o.promise},l.prototype.remove=function(t){return{local:this._localToLocalRemove(t),remote:this._localToRemoteRemove(t)}},l.prototype._localToLocalUpdate=function(t,e){var o=this._set.get(t);if(!o)throw new Error("Item "+t+" doesn't exist");if(e._id&&e._id!==t)throw new Error("Modifying the _id of a document is not allowed");this._set.put(t+c,o);for(var i in e)o[i]=e[i];return this._set.put(t,o),Q(t)},l.prototype._remoteToLocalUpdate=function(t,e){var o=this._set.get(t);if(!o)return void console.warn("Server misbehaviour: item "+t+" doesn't exist");for(var i in e){if("_id"===i&&e._id!==t)return void console.warn("Server misbehaviour: modifying the _id of a document is not allowed");o[i]=e[i]}this._set.put(t,o)},l.prototype._localToRemoteUpdate=function(t,e){var o=this,i=Q.defer(),n="/"+o.name+"/update",r={_id:t},s={$set:e};return o.asteroid.ddp.method(n,[r,s],function(e){if(e){var n=o._set.get(t+c);o._set.put(t,n),o._set.del(t+c),i.reject(e)}else o._set.del(t+c),i.resolve(t)}),i.promise},l.prototype.update=function(t,e){return{local:this._localToLocalUpdate(t,e),remote:this._localToRemoteUpdate(t,e)}};var a=function(t){var e=this;e.result=[],e._set=t,e._getResult(),e._set.on("put",function(t){e._getResult(),e._emit("change",t)}),e._set.on("del",function(t){e._getResult(),e._emit("change",t)})};a.prototype=Object.create(i.prototype),a.constructor=a,a.prototype._getResult=function(){this.result=this._set.toArray()};var d=function(t){return function(e,o){if(u(e))return!1;var i=function(t,e){return e.split(".").reduce(function(t,e){return t?t=t[e]:t},t)};for(var n in t){var r=i(o,n);if(r!==t[n])return!1}return!0}};l.prototype.reactiveQuery=function(t){var e;e="function"==typeof t?t:d(t);var o=this._set.filter(e);return new a(o)},r._Collection=l,r.prototype._getOauthClientId=function(t){var e="meteor_accounts_loginServiceConfiguration",o=this.collections[e],i=o.reactiveQuery({service:t}).result[0];return i.clientId},r.prototype._initOauthLogin=function(t,e,o){var i=this;return Q().then(function(){var t=Q.defer(),e=window.open(o,"Login");e.focus&&e.focus();var i=setInterval(function(){(e.closed||void 0===e.closed)&&(clearInterval(i),t.resolve())},100);return t.promise}).then(function(){var t=Q.defer(),o={oauth:{credentialToken:e}};return i.ddp.method("login",[o],function(e,o){e?(delete i.userId,delete i.loggedIn,delete localStorage[i._host+"__login_token__"],t.reject(e),i._emit("loginError",e)):(i.userId=o.id,i.loggedIn=!0,localStorage[i._host+"__login_token__"]=o.token,i._emit("login",o.id),t.resolve(o.id))}),t.promise})},r.prototype._tryResumeLogin=function(){var t=this,e=localStorage[t._host+"__login_token__"];return e?Q().then(function(){var o=Q.defer(),i={resume:e};return t.ddp.method("login",[i],function(e,i){e?(delete t.userId,delete t.loggedIn,delete localStorage[t._host+"__login_token__"],t._emit("loginError",e),o.reject(e)):(t.userId=i.id,t.loggedIn=!0,localStorage[t._host+"__login_token__"]=i.token,t._emit("login",i.id),o.resolve(i.id))}),o.promise}):void 0},r.prototype.loginWithFacebook=function(t){var i=o(),n={client_id:this._getOauthClientId("facebook"),redirect_uri:this._host+"/_oauth/facebook?close",state:i,scope:t||"email"},r="https://www.facebook.com/dialog/oauth?"+e(n);return this._initOauthLogin("facebook",i,r)},r.prototype.loginWithGoogle=function(t){var i=o(),n={response_type:"code",client_id:this._getOauthClientId("google"),redirect_uri:this._host+"/_oauth/google?close",state:i,scope:t||"openid email"},r="https://accounts.google.com/o/oauth2/auth?"+e(n);return this._initOauthLogin("google",i,r)},r.prototype.loginWithGithub=function(t){var i=o(),n={client_id:this._getOauthClientId("github"),redirect_uri:this._host+"/_oauth/github?close",state:i,scope:t||"email"},r="https://github.com/login/oauth/authorize?"+e(n);return this._initOauthLogin("github",i,r)},r.prototype.loginWithTwitter=function(){var t=o(),i=this._host+"/_oauth/twitter?close&state="+t,n={requestTokenAndRedirect:encodeURIComponent(i),state:t},r=this._host+"/_oauth/twitter/?"+e(n);return this._initOauthLogin("twitter",t,r)},r.prototype.logout=function(){var t=this,e=Q.defer();return t.ddp.method("logout",[],function(o){o?(t._emit("logoutError",o),e.reject(o)):(delete t.userId,delete t.loggedIn,delete localStorage[t._host+"__login_token__"],t._emit("logout"),e.resolve())}),e.promise};var _=function(t){t&&(this._put=this.put,this._del=this.del,this.put=this.del=function(){throw new Error("Attempt to modify readonly set")}),this._items={}};return _.prototype=Object.create(i.prototype),_.constructor=_,_.prototype.put=function(e,o){return n.beString(e),n.beObject(o),this._items[e]=t(o),this._emit("put",e),this},_.prototype.del=function(t){return n.beString(t),delete this._items[t],this._emit("del",t),this},_.prototype.get=function(e){return n.beString(e),t(this._items[e])},_.prototype.contains=function(t){return n.beString(t),!!this._items[t]},_.prototype.filter=function(e){var o=new _(!0),i=this._items,n=Object.keys(i);return n.forEach(function(n){var r=t(i[n]),s=e(n,r);s&&(o._items[n]=i[n])}),this.on("put",function(n){var r=t(i[n]),s=e(n,r);s&&o._put(n,i[n])}),this.on("del",function(t){o._del(t)}),o},_.prototype.toArray=function(){var e=[],o=this._items,i=Object.keys(this._items);return i.forEach(function(t){e.push(o[t])}),t(e)},_.prototype.toHash=function(){return t(this._items)},r.Set=_,r}); \ No newline at end of file +!function(t,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.Asteroid=e()}(this,function(){"use strict";function t(t){if("undefined"!=typeof EJSON)return EJSON.clone(t);var e=typeof t;switch(e){case"undefined":case"function":return void 0;case"string":case"number":case"boolean":return t;case"object":return null===t?null:JSON.parse(JSON.stringify(t));default:return}}function e(t){var e="";for(var o in t)e+=o+"="+t[o]+"&";return e=e.slice(0,-1)}function o(){for(var t="",e=0;8>e;e++)t+=Math.floor(65536*(1+Math.random())).toString(16).substring(1);return t}var i=function(){};i.prototype={constructor:i,on:function(t,e){this._events||(this._events={}),this._events[t]=this._events[t]||[],this._events[t].push(e)},off:function(t,e){this._events||(this._events={}),this._events[t]&&this._events[t].splice(this._events[t].indexOf(e),1)},_emit:function(t){if(this._events||(this._events={}),this._events[t]){var e=arguments,o=this;this._events[t].forEach(function(t){t.apply(o,Array.prototype.slice.call(e,1))})}}};var n={};n._toString=function(t){return Object.prototype.toString.call(t).slice(8,-1)},n.beString=function(t){var e=this._toString(t);if("String"!==e)throw new Error("Assertion failed: expected String, instead got "+e)},n.beObject=function(t){var e=this._toString(t);if("Object"!==e)throw new Error("Assertion failed: expected Object, instead got "+e)};var r=function(t,e,o){n.beString(t),this._host=(e?"https://":"http://")+t,this._ddpOptions={endpoint:(e?"wss://":"ws://")+t+(window.SockJS?"/sockjs":"/websocket"),SocketConstructor:window.SockJS||window.WebSocket,debug:o},this.collections={},this.subscriptions={},this._init()};r.prototype=Object.create(i.prototype),r.prototype.constructor=r,r.prototype._init=function(){var t=this;t.ddp=new DDP(this._ddpOptions),t.ddp.on("connected",function(){t._tryResumeLogin(),t.ddp.sub("meteor.loginServiceConfiguration"),t._emit("connected")}),t.ddp.on("added",function(e){t._onAdded(e)}),t.ddp.on("changed",function(e){t._onChanged(e)}),t.ddp.on("removed",function(e){t._onRemoved(e)})},r.prototype._onAdded=function(t){var e=t.collection;this.collections[e]||(this.collections[e]=new r._Collection(e,this));var o=t.fields||{};o._id=t.id,this.collections[e]._remoteToLocalInsert(o)},r.prototype._onRemoved=function(t){this.collections[t.collection]&&this.collections[t.collection]._remoteToLocalRemove(t.id)},r.prototype._onChanged=function(t){this.collections[t.collection]&&(t.fields||(t.fields={}),t.cleared&&t.cleared.forEach(function(e){t.fields[e]=void 0}),this.collections[t.collection]._remoteToLocalUpdate(t.id,t.fields))},r.prototype.subscribe=function(t){n.beString(t);var e=this.subscriptions[t];if(e&&e.isFulfilled()){var o=e.inspect().value;this.unsubscribe(o)}var i=Q.defer();this.subscriptions[t]=i.promise;var r=Array.prototype.slice.call(arguments,1);return this.ddp.sub(t,r,function(t,e){t?i.reject(t):i.resolve(e)}),this.subscriptions[t]},r.prototype.unsubscribe=function(t){this.ddp.unsub(t)},r.prototype.call=function(t){n.beString(t);var e=Array.prototype.slice.call(arguments,1);return this.apply(t,e)},r.prototype.apply=function(t,e){n.beString(t);var o=Q.defer(),i=Q.defer(),r=function(t,e){t?(o.reject(t),i.reject()):o.resolve(e)},s=function(){i.resolve()};return this.ddp.method(t,e,r,s),{result:o.promise,updated:i.promise}},r.prototype.createCollection=function(t){return n.beString(t),this.collections[t]||(this.collections[t]=new r._Collection(t,this)),this.collections[t]};var s="__del__",c="__upd__",u=function(t){var e=s.length,o=c.length,i=t.slice(-1*e),n=t.slice(-1*o);return i===s||n===c},l=function(t,e){this.name=t,this.asteroid=e,this._set=new _};l.prototype.constructor=l,l.prototype._localToLocalInsert=function(t){if(this._set.contains(t._id))throw new Error("Item "+t._id+" already exists");return this._set.put(t._id,t),Q(t._id)},l.prototype._remoteToLocalInsert=function(t){this._set.put(t._id,t)},l.prototype._localToRemoteInsert=function(t){var e=this,o=Q.defer(),i="/"+e.name+"/insert";return e.asteroid.ddp.method(i,[t],function(i){i?(e._set.del(t._id),o.reject(i)):o.resolve(t._id)}),o.promise},l.prototype.insert=function(t){return t._id||(t._id=o()),{local:this._localToLocalInsert(t),remote:this._localToRemoteInsert(t)}},l.prototype._localToLocalRemove=function(t){var e=this._set.get(t);return e&&(this._set.put(t+s,e),this._set.del(t)),Q(t)},l.prototype._remoteToLocalRemove=function(t){this._set.del(t)},l.prototype._localToRemoteRemove=function(t){var e=this,o=Q.defer(),i="/"+e.name+"/remove";return e.asteroid.ddp.method(i,[{_id:t}],function(i){if(i){var n=e._set.get(t+s);n&&(e._set.put(t,n),e._set.del(t+s)),o.reject(i)}else e._set.del(t+s),o.resolve(t)}),o.promise},l.prototype.remove=function(t){return{local:this._localToLocalRemove(t),remote:this._localToRemoteRemove(t)}},l.prototype._localToLocalUpdate=function(t,e){var o=this._set.get(t);if(!o)throw new Error("Item "+t+" doesn't exist");if(e._id&&e._id!==t)throw new Error("Modifying the _id of a document is not allowed");this._set.put(t+c,o);for(var i in e)o[i]=e[i];return this._set.put(t,o),Q(t)},l.prototype._remoteToLocalUpdate=function(t,e){var o=this._set.get(t);if(!o)return void console.warn("Server misbehaviour: item "+t+" doesn't exist");for(var i in e){if("_id"===i&&e._id!==t)return void console.warn("Server misbehaviour: modifying the _id of a document is not allowed");o[i]=e[i]}this._set.put(t,o)},l.prototype._localToRemoteUpdate=function(t,e){var o=this,i=Q.defer(),n="/"+o.name+"/update",r={_id:t},s={$set:e};return o.asteroid.ddp.method(n,[r,s],function(e){if(e){var n=o._set.get(t+c);o._set.put(t,n),o._set.del(t+c),i.reject(e)}else o._set.del(t+c),i.resolve(t)}),i.promise},l.prototype.update=function(t,e){return{local:this._localToLocalUpdate(t,e),remote:this._localToRemoteUpdate(t,e)}};var a=function(t){var e=this;e.result=[],e._set=t,e._getResult(),e._set.on("put",function(t){e._getResult(),e._emit("change",t)}),e._set.on("del",function(t){e._getResult(),e._emit("change",t)})};a.prototype=Object.create(i.prototype),a.constructor=a,a.prototype._getResult=function(){this.result=this._set.toArray()};var d=function(t){return function(e,o){if(u(e))return!1;var i=function(t,e){return e.split(".").reduce(function(t,e){return t?t=t[e]:t},t)};for(var n in t){var r=i(o,n);if(r!==t[n])return!1}return!0}};l.prototype.reactiveQuery=function(t){var e;e="function"==typeof t?t:d(t);var o=this._set.filter(e);return new a(o)},r._Collection=l,r.prototype._getOauthClientId=function(t){var e="meteor_accounts_loginServiceConfiguration",o=this.collections[e],i=o.reactiveQuery({service:t}).result[0];return i.clientId},r.prototype._initOauthLogin=function(t,e,o){var i=this;return Q().then(function(){var t=Q.defer(),e=window.open(o,"Login");e.focus&&e.focus();var i=setInterval(function(){(e.closed||void 0===e.closed)&&(clearInterval(i),t.resolve())},100);return t.promise}).then(function(){var t=Q.defer(),o={oauth:{credentialToken:e}};return i.ddp.method("login",[o],function(e,o){e?(delete i.userId,delete i.loggedIn,delete localStorage[i._host+"__login_token__"],t.reject(e),i._emit("loginError",e)):(i.userId=o.id,i.loggedIn=!0,localStorage[i._host+"__login_token__"]=o.token,i._emit("login",o.id),t.resolve(o.id))}),t.promise})},r.prototype._tryResumeLogin=function(){var t=this,e=localStorage[t._host+"__login_token__"];return e?Q().then(function(){var o=Q.defer(),i={resume:e};return t.ddp.method("login",[i],function(e,i){e?(delete t.userId,delete t.loggedIn,delete localStorage[t._host+"__login_token__"],t._emit("loginError",e),o.reject(e)):(t.userId=i.id,t.loggedIn=!0,localStorage[t._host+"__login_token__"]=i.token,t._emit("login",i.id),o.resolve(i.id))}),o.promise}):void 0},r.prototype.loginWithFacebook=function(t){var i=o(),n={client_id:this._getOauthClientId("facebook"),redirect_uri:this._host+"/_oauth/facebook?close",state:i,scope:t||"email"},r="https://www.facebook.com/dialog/oauth?"+e(n);return this._initOauthLogin("facebook",i,r)},r.prototype.loginWithGoogle=function(t){var i=o(),n={response_type:"code",client_id:this._getOauthClientId("google"),redirect_uri:this._host+"/_oauth/google?close",state:i,scope:t||"openid email"},r="https://accounts.google.com/o/oauth2/auth?"+e(n);return this._initOauthLogin("google",i,r)},r.prototype.loginWithGithub=function(t){var i=o(),n={client_id:this._getOauthClientId("github"),redirect_uri:this._host+"/_oauth/github?close",state:i,scope:t||"email"},r="https://github.com/login/oauth/authorize?"+e(n);return this._initOauthLogin("github",i,r)},r.prototype.loginWithTwitter=function(){var t=o(),i=this._host+"/_oauth/twitter?close&state="+t,n={requestTokenAndRedirect:encodeURIComponent(i),state:t},r=this._host+"/_oauth/twitter/?"+e(n);return this._initOauthLogin("twitter",t,r)},r.prototype.logout=function(){var t=this,e=Q.defer();return t.ddp.method("logout",[],function(o){o?(t._emit("logoutError",o),e.reject(o)):(delete t.userId,delete t.loggedIn,delete localStorage[t._host+"__login_token__"],t._emit("logout"),e.resolve())}),e.promise};var _=function(t){t&&(this._put=this.put,this._del=this.del,this.put=this.del=function(){throw new Error("Attempt to modify readonly set")}),this._items={}};return _.prototype=Object.create(i.prototype),_.constructor=_,_.prototype.put=function(e,o){return n.beString(e),n.beObject(o),this._items[e]=t(o),this._emit("put",e),this},_.prototype.del=function(t){return n.beString(t),delete this._items[t],this._emit("del",t),this},_.prototype.get=function(e){return n.beString(e),t(this._items[e])},_.prototype.contains=function(t){return n.beString(t),!!this._items[t]},_.prototype.filter=function(e){var o=new _(!0),i=this._items,n=Object.keys(i);return n.forEach(function(n){var r=t(i[n]),s=e(n,r);s&&(o._items[n]=i[n])}),this.on("put",function(n){var r=t(i[n]),s=e(n,r);s&&o._put(n,i[n])}),this.on("del",function(t){o._del(t)}),o},_.prototype.toArray=function(){var e=[],o=this._items,i=Object.keys(this._items);return i.forEach(function(t){e.push(o[t])}),t(e)},_.prototype.toHash=function(){return t(this._items)},r.Set=_,r}); \ No newline at end of file diff --git a/docs/asteroid.md b/docs/asteroid.md index cc07195..f0afc39 100644 --- a/docs/asteroid.md +++ b/docs/asteroid.md @@ -121,7 +121,9 @@ successful. Otherwise it'll be rejected with the error. ------------------------------------------------------------ ###Asteroid.subscribe(name, [param1, param2, ...]) -Subscribes to the specified subscription. +Subscribes to the specified subscription. If a subscription +by that name is already present (and successful), first +Asteroid unsubscribes from it. #####Arguments diff --git a/package.json b/package.json index 2e76040..4e8acd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "asteroid", - "version": "0.2.2", + "version": "0.2.3", "description": "Aletrnative Meteor client", "main": "dist/asteroid.js", "scripts": { diff --git a/src/asteroid.js b/src/asteroid.js index d65a1c0..278d332 100644 --- a/src/asteroid.js +++ b/src/asteroid.js @@ -135,9 +135,11 @@ Asteroid.prototype._onChanged = function (data) { Asteroid.prototype.subscribe = function (name /* , param1, param2, ... */) { // Assert name must be a string must.beString(name); - // If we're already subscribed, return the subscription - if (this.subscriptions[name]) { - return this.subscriptions[name]; + // If we're already subscribed, unsubscribe before re-subscribing + var subPromise = this.subscriptions[name]; + if (subPromise && subPromise.isFulfilled()) { + var subId = subPromise.inspect().value; + this.unsubscribe(subId); } // Init the promise that will be returned var deferred = Q.defer(); @@ -150,7 +152,7 @@ Asteroid.prototype.subscribe = function (name /* , param1, param2, ... */) { // This is the onReady/onNoSub callback if (err) { // Reject the promise if the server answered nosub - deferred.reject(err, id); + deferred.reject(err); } else { // Resolve the promise if the server answered ready deferred.resolve(id);