Comparing version 3.1.0 to 3.2.0
@@ -59,2 +59,4 @@ (function() { | ||
self.__registerLater = []; | ||
// References to all registered event listeners. | ||
self.__listeners = []; | ||
@@ -124,5 +126,36 @@ // The collections that absync provides. | ||
/** | ||
* Detaches absync from the websocket. | ||
* @param {Boolean} [disconnectSocket=false] Should the underlying socket.io connection be disconnected as well? | ||
*/ | ||
AbsyncProvider.prototype.disconnect = function AbsyncProvider$disconnect( disconnectSocket ) { | ||
var self = this; | ||
disconnectSocket = disconnectSocket || false; | ||
angular.forEach( self.__listeners, function unregisterListener( listener ) { | ||
listener.unregister(); | ||
delete listener.unregister; | ||
self.__registerLater.push( listener ); | ||
} ); | ||
if( disconnectSocket ) { | ||
self.__ioSocket.disconnect(); | ||
self.__ioSocket = null; | ||
} | ||
}; | ||
/** | ||
* Register an event listener with socket.io. | ||
* @param {Object} listener | ||
* @private | ||
*/ | ||
AbsyncProvider.prototype.__registerListener = function AbsyncProvider$registerListener( listener ) { | ||
var self = this; | ||
self.$get().__handleEntityEvent( listener.eventName, listener.callback ); | ||
// Remember this listener. | ||
self.__listeners.push( listener ); | ||
// Register the listener and remember the function to use when the listener should be unregistered. | ||
listener.unregister = self.__handleEntityEvent( listener.eventName, listener.callback ); | ||
}; | ||
@@ -196,36 +229,4 @@ | ||
/** | ||
* Register the service factory. | ||
* @returns {AbsyncService} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return new AbsyncService( this ); | ||
}; | ||
/** | ||
* The service that is received when injecting "absync". | ||
* This service is primarily used internally to set up the connection between socket.io and the individual | ||
* caching services. | ||
* @param {AbsyncProvider|Object} parentProvider The AbsyncProvider that provides this service. | ||
* @constructor | ||
*/ | ||
function AbsyncService( parentProvider ) { | ||
this.__absyncProvider = parentProvider; | ||
} | ||
/** | ||
* Configure the socket.io connection for absync. | ||
* This configuration of absync should usually be performed through the absyncProvider in the configuration | ||
* phase of a module. | ||
* @param {Object} configuration The configuration for the absync provider. | ||
* Can have a member `socket`, pointing to the socket.io instance or constructor to use. | ||
* Can have a member `debug`, enabling debugging, if set to true. | ||
*/ | ||
AbsyncService.prototype.configure = function AbsyncService$configure( configuration ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
_absyncProvider.configure( configuration ); | ||
}; | ||
/** | ||
* Register an event listener that is called when a specific entity is received on the websocket. | ||
@@ -238,10 +239,9 @@ * @param {String} eventName The event name, usually the name of the entity. | ||
*/ | ||
AbsyncService.prototype.on = function AbsyncService$on( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
var self = this; | ||
AbsyncProvider.prototype.on = function AbsyncProvider$on( eventName, callback ) { | ||
var self = this; | ||
// If we have no configured socket.io connection yet, remember to register it later. | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
if( _absyncProvider.__registerLater.length > 8192 ) { | ||
if( self.__registerLater.length > 8192 ) { | ||
// Be defensive, something is probably not right here. | ||
@@ -252,3 +252,3 @@ return null; | ||
// TODO: Use promises here, so that we can always return the event listener removal function. | ||
_absyncProvider.__registerLater.push( { | ||
self.__registerLater.push( { | ||
eventName : eventName, | ||
@@ -260,3 +260,6 @@ callback : callback | ||
return self.__handleEntityEvent( eventName, callback ); | ||
return self.__registerListener( { | ||
eventName : eventName, | ||
callback : callback | ||
} ); | ||
}; | ||
@@ -270,11 +273,11 @@ | ||
*/ | ||
AbsyncService.prototype.__handleEntityEvent = function AbsyncService$handleEntityEvent( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.__handleEntityEvent = function AbsyncProvider$handleEntityEvent( eventName, callback ) { | ||
var self = this; | ||
// Register the callback with socket.io. | ||
_absyncProvider.__ioSocket.on( eventName, callback ); | ||
self.__ioSocket.on( eventName, callback ); | ||
// Return a function that removes the listener. | ||
return function removeListener() { | ||
_absyncProvider.__ioSocket.removeListener( eventName, callback ); | ||
self.__ioSocket.removeListener( eventName, callback ); | ||
}; | ||
@@ -284,3 +287,3 @@ }; | ||
/** | ||
* Convenience method to allow the user to emit() from the websocket. | ||
* Convenience method to allow the user to emit() from the socket.io connection. | ||
* This is not utilized in absync internally. | ||
@@ -291,15 +294,24 @@ * @param {String} eventName | ||
*/ | ||
AbsyncService.prototype.emit = function AbsyncService$emit( eventName, data, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.emit = function AbsyncProvider$emit( eventName, data, callback ) { | ||
var self = this; | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
throw new Error( "socket.io is not initialized." ); | ||
} | ||
_absyncProvider.__ioSocket.emit( eventName, data, function afterEmit() { | ||
self.__ioSocket.emit( eventName, data, function afterEmit() { | ||
if( callback ) { | ||
callback.apply( _absyncProvider.__ioSocket, arguments ); | ||
callback.apply( self.__ioSocket, arguments ); | ||
} | ||
} ); | ||
}; | ||
/** | ||
* The service is just used as a convenience to access the provider. | ||
* @returns {AbsyncProvider} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return this; | ||
}; | ||
}());;(function() { | ||
@@ -341,3 +353,3 @@ "use strict"; | ||
* @param {angular.IRootScopeService|Object} $rootScope | ||
* @param {AbsyncService} absync | ||
* @param {AbsyncProvider} absync | ||
* @param {Object} absyncNoopLog A log interface that does nothing. | ||
@@ -348,4 +360,4 @@ * @param {Object} absyncUncachedFilter A filter that mutates URLs so they will bypass the browser cache. | ||
*/ | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync", "absyncNoopLog", "absyncUncachedFilter"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absync, absyncNoopLog, absyncUncachedFilter ) { | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absyncNoopLog", "absync", "absyncUncachedFilter"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absyncNoopLog, absync, absyncUncachedFilter ) { | ||
var self = this; | ||
@@ -352,0 +364,0 @@ |
@@ -54,2 +54,4 @@ (function() { | ||
self.__registerLater = []; | ||
// References to all registered event listeners. | ||
self.__listeners = []; | ||
@@ -119,5 +121,36 @@ // The collections that absync provides. | ||
/** | ||
* Detaches absync from the websocket. | ||
* @param {Boolean} [disconnectSocket=false] Should the underlying socket.io connection be disconnected as well? | ||
*/ | ||
AbsyncProvider.prototype.disconnect = function AbsyncProvider$disconnect( disconnectSocket ) { | ||
var self = this; | ||
disconnectSocket = disconnectSocket || false; | ||
angular.forEach( self.__listeners, function unregisterListener( listener ) { | ||
listener.unregister(); | ||
delete listener.unregister; | ||
self.__registerLater.push( listener ); | ||
} ); | ||
if( disconnectSocket ) { | ||
self.__ioSocket.disconnect(); | ||
self.__ioSocket = null; | ||
} | ||
}; | ||
/** | ||
* Register an event listener with socket.io. | ||
* @param {Object} listener | ||
* @private | ||
*/ | ||
AbsyncProvider.prototype.__registerListener = function AbsyncProvider$registerListener( listener ) { | ||
var self = this; | ||
self.$get().__handleEntityEvent( listener.eventName, listener.callback ); | ||
// Remember this listener. | ||
self.__listeners.push( listener ); | ||
// Register the listener and remember the function to use when the listener should be unregistered. | ||
listener.unregister = self.__handleEntityEvent( listener.eventName, listener.callback ); | ||
}; | ||
@@ -191,36 +224,4 @@ | ||
/** | ||
* Register the service factory. | ||
* @returns {AbsyncService} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return new AbsyncService( this ); | ||
}; | ||
/** | ||
* The service that is received when injecting "absync". | ||
* This service is primarily used internally to set up the connection between socket.io and the individual | ||
* caching services. | ||
* @param {AbsyncProvider|Object} parentProvider The AbsyncProvider that provides this service. | ||
* @constructor | ||
*/ | ||
function AbsyncService( parentProvider ) { | ||
this.__absyncProvider = parentProvider; | ||
} | ||
/** | ||
* Configure the socket.io connection for absync. | ||
* This configuration of absync should usually be performed through the absyncProvider in the configuration | ||
* phase of a module. | ||
* @param {Object} configuration The configuration for the absync provider. | ||
* Can have a member `socket`, pointing to the socket.io instance or constructor to use. | ||
* Can have a member `debug`, enabling debugging, if set to true. | ||
*/ | ||
AbsyncService.prototype.configure = function AbsyncService$configure( configuration ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
_absyncProvider.configure( configuration ); | ||
}; | ||
/** | ||
* Register an event listener that is called when a specific entity is received on the websocket. | ||
@@ -233,10 +234,9 @@ * @param {String} eventName The event name, usually the name of the entity. | ||
*/ | ||
AbsyncService.prototype.on = function AbsyncService$on( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
var self = this; | ||
AbsyncProvider.prototype.on = function AbsyncProvider$on( eventName, callback ) { | ||
var self = this; | ||
// If we have no configured socket.io connection yet, remember to register it later. | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
if( _absyncProvider.__registerLater.length > 8192 ) { | ||
if( self.__registerLater.length > 8192 ) { | ||
// Be defensive, something is probably not right here. | ||
@@ -247,3 +247,3 @@ return null; | ||
// TODO: Use promises here, so that we can always return the event listener removal function. | ||
_absyncProvider.__registerLater.push( { | ||
self.__registerLater.push( { | ||
eventName : eventName, | ||
@@ -255,3 +255,6 @@ callback : callback | ||
return self.__handleEntityEvent( eventName, callback ); | ||
return self.__registerListener( { | ||
eventName : eventName, | ||
callback : callback | ||
} ); | ||
}; | ||
@@ -265,11 +268,11 @@ | ||
*/ | ||
AbsyncService.prototype.__handleEntityEvent = function AbsyncService$handleEntityEvent( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.__handleEntityEvent = function AbsyncProvider$handleEntityEvent( eventName, callback ) { | ||
var self = this; | ||
// Register the callback with socket.io. | ||
_absyncProvider.__ioSocket.on( eventName, callback ); | ||
self.__ioSocket.on( eventName, callback ); | ||
// Return a function that removes the listener. | ||
return function removeListener() { | ||
_absyncProvider.__ioSocket.removeListener( eventName, callback ); | ||
self.__ioSocket.removeListener( eventName, callback ); | ||
}; | ||
@@ -279,3 +282,3 @@ }; | ||
/** | ||
* Convenience method to allow the user to emit() from the websocket. | ||
* Convenience method to allow the user to emit() from the socket.io connection. | ||
* This is not utilized in absync internally. | ||
@@ -286,15 +289,24 @@ * @param {String} eventName | ||
*/ | ||
AbsyncService.prototype.emit = function AbsyncService$emit( eventName, data, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.emit = function AbsyncProvider$emit( eventName, data, callback ) { | ||
var self = this; | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
throw new Error( "socket.io is not initialized." ); | ||
} | ||
_absyncProvider.__ioSocket.emit( eventName, data, function afterEmit() { | ||
self.__ioSocket.emit( eventName, data, function afterEmit() { | ||
if( callback ) { | ||
callback.apply( _absyncProvider.__ioSocket, arguments ); | ||
callback.apply( self.__ioSocket, arguments ); | ||
} | ||
} ); | ||
}; | ||
/** | ||
* The service is just used as a convenience to access the provider. | ||
* @returns {AbsyncProvider} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return this; | ||
}; | ||
}()); |
@@ -37,3 +37,3 @@ (function() { | ||
* @param {angular.IRootScopeService|Object} $rootScope | ||
* @param {AbsyncService} absync | ||
* @param {AbsyncProvider} absync | ||
* @param {Object} absyncNoopLog A log interface that does nothing. | ||
@@ -44,4 +44,4 @@ * @param {Object} absyncUncachedFilter A filter that mutates URLs so they will bypass the browser cache. | ||
*/ | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync", "absyncNoopLog", "absyncUncachedFilter"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absync, absyncNoopLog, absyncUncachedFilter ) { | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absyncNoopLog", "absync", "absyncUncachedFilter"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absyncNoopLog, absync, absyncUncachedFilter ) { | ||
var self = this; | ||
@@ -48,0 +48,0 @@ |
@@ -1,2 +0,2 @@ | ||
!function(){"use strict";angular.module("absync",[])}(),function(){"use strict";function e(e,n,r){return new t(e,n,r)}function t(e,t,n){var r=this;r.__injector=e,r.__provide=t,r.__absyncCache=n,r.__ioSocket=null,r.__registerLater=[],r.__collections={},r.__entities={},r.debug=void 0}function n(e){this.__absyncProvider=e}e.$inject=["$injector","$provide","absyncCache"],angular.module("absync").provider("absync",e),t.prototype.configure=function(e){var t=this;if("undefined"!=typeof e.socket){var n=e.socket,r="undefined"!=typeof io&&io.Socket&&n instanceof io.Socket;if("function"==typeof n)t.__ioSocket=new n;else{if(!r)throw new Error("configure() expects input to be a function or a socket.io Socket instance.");t.__ioSocket=n}t.__registerLater.length&&(angular.forEach(t.__registerLater,t.__registerListener.bind(t)),t.__registerLater=[])}"undefined"!=typeof e.debug&&(t.debug=e.debug||!1),t.debug&&(angular.forEach(t.__collections,function(e){e.configuration.debug=!0}),angular.forEach(t.__entities,function(e){e.configuration.debug=!0}))},t.prototype.__registerListener=function(e){var t=this;t.$get().__handleEntityEvent(e.eventName,e.callback)},t.prototype.collection=function(e,t){var n=this;if(n.__collections[e])throw new Error("A collection with the name '"+e+"' was already requested. Names for collections must be unique.");if(n.__entities[e])throw new Error("An entity with the name '"+e+"' was already requested. Names for collections must be unique and can't be shared with entities.");t.debug="undefined"==typeof t.debug?n.debug:t.debug,n.__collections[e]={constructor:n.__absyncCache(e,t),configuration:t},n.__provide.service(e,n.__collections[e].constructor)},t.prototype.entity=function(e,t){var n=this;if(n.__entities[e])throw new Error("An entity with the name '"+e+"' was already requested. Names for entities must be unique.");if(n.__collections[e])throw new Error("A collection with the name '"+e+"' was already requested. Names for entities must be unique and can't be shared with collections.");t.debug="undefined"==typeof t.debug?n.debug:t.debug,n.__entities[e]={constructor:n.__absyncCache(e,t),configuration:t},n.__provide.service(e,n.__entities[e].constructor)},t.prototype.$get=function(){return new n(this)},n.prototype.configure=function(e){var t=this.__absyncProvider;t.configure(e)},n.prototype.on=function(e,t){var n=this.__absyncProvider,r=this;return n.__ioSocket?r.__handleEntityEvent(e,t):n.__registerLater.length>8192?null:(n.__registerLater.push({eventName:e,callback:t}),null)},n.prototype.__handleEntityEvent=function(e,t){var n=this.__absyncProvider;return n.__ioSocket.on(e,t),function(){n.__ioSocket.removeListener(e,t)}},n.prototype.emit=function(e,t,n){var r=this.__absyncProvider;if(!r.__ioSocket)throw new Error("socket.io is not initialized.");r.__ioSocket.emit(e,t,function(){n&&n.apply(r.__ioSocket,arguments)})}}(),function(){"use strict";function e(e,n){function r(r,i,o,a,c,s,h,u){var l=this,y=n.injector||i,d=y.has(n.model);if(!d)throw new Error("Unable to construct the '"+e+"' service, because the referenced model '"+n.model+"' is not available for injection.");var f="string"==typeof n.model?y.get(n.model):n.model,_=f.serialize||n.serialize||t,p=f.deserialize||n.deserialize||t;l.name=e,l.configuration=n,l.entityCache=n.collectionName?[]:{},l.__entityCacheRaw=null,l.enableRequestCache=!0,l.__requestCache={},l.allowBrowserCache=(angular.merge||angular.extend)({},{sync:!0,request:!0},n.allowBrowserCache),l.__uncached=u,l.httpInterface=r,l.logInterface=n.debug?o:h,l.scope=c,l.q=a,l.logPrefix="absync:"+e.toLocaleUpperCase()+" ",l.forceEarlyCacheUpdate=!1,l.throwFailures=!0,l.serializer=_,l.deserializer=p,s.on(n.entityName,l.__onEntityOnWebsocket.bind(l)),n.collectionName&&s.on(n.collectionName,l.__onCollectionOnWebsocket.bind(l)),c.$on(n.entityName,l.__onEntityReceived.bind(l)),n.collectionName&&c.$on(n.collectionName,l.__onCollectionReceived.bind(l)),l.logInterface.info(l.logPrefix+"service was instantiated.")}function i(e,t){var r=this;if((e||r.forceEarlyCacheUpdate)&&t.data[n.entityName]){var i=t.data[n.entityName];if(r.forceEarlyCacheUpdate){var o=r.deserializer(i);if(r.__updateCacheWithEntity(o),e)return o}if(e)return i}}function o(e){var t=this;if(t.logInterface.error(t.logPrefix+"Unable to store entity on the server.",e),t.logInterface.error(e),t.scope.$emit("absyncError",e),t.throwFailures)throw e}return r.$inject=["$http","$injector","$log","$q","$rootScope","absync","absyncNoopLog","absyncUncachedFilter"],r.prototype.__onEntityOnWebsocket=function(e){var t=this;t.scope.$broadcast(n.entityName,e[n.entityName])},r.prototype.__onCollectionOnWebsocket=function(e){var t=this;t.scope.$broadcast(n.collectionName,e[n.collectionName])},r.prototype.__onDataAvailable=function(e){function t(e){r.entityCache.push(r.deserializer(e))}var r=this;if(Array.isArray(r.entityCache))angular.forEach(e[n.collectionName],t),r.scope.$broadcast("collectionNew",{service:r,cache:r.entityCache});else{var i=r.deserializer(e[n.entityName]);r.__updateCacheWithEntity(i)}return r.entityCache},r.prototype.__onEntityReceived=function(e,t){var n=this,r=t;return 1===Object.keys(r).length&&r.hasOwnProperty("id")?(n.logInterface.info(n.logPrefix+"Entity was deleted from the server. Updating cache…"),n.__removeEntityFromCache(r.id)):(n.logInterface.debug(n.logPrefix+"Entity was updated on the server. Updating cache…"),n.__updateCacheWithEntity(n.deserializer(r)))},r.prototype.__onCollectionReceived=function(e,t){function n(e){var t=r.deserializer(e);r.__updateCacheWithEntity(t)}var r=this,i=t;r.entityCache.length=0,angular.forEach(i,n)},r.prototype.ensureLoaded=function(e){function t(e){if(!e.data[n.collectionName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.collectionName+"'.");return a.__entityCacheRaw=e.data,a.entityCache.splice(0,a.entityCache.length),a.__onDataAvailable(e.data)}function r(e){if(a.logInterface.error(a.logPrefix+"Unable to retrieve the collection from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e),a.throwFailures)throw e}function i(e){if(!e.data[n.entityName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.");a.__entityCacheRaw=e.data,a.__onDataAvailable(e.data)}function o(e){if(a.logInterface.error(a.logPrefix+"Unable to retrieve the entity from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e),a.throwFailures)throw e}var a=this;return e=e===!0,null===a.__entityCacheRaw||e?n.collectionName&&n.collectionUri?(a.logInterface.info(a.logPrefix+"Retrieving '"+n.collectionName+"' collection…"),a.httpInterface.get(a.allowBrowserCache.sync?n.collectionUri:a.__uncached(n.collectionUri)).then(t,r)):n.entityName&&n.entityUri?a.httpInterface.get(a.allowBrowserCache.sync?n.entityUri:a.__uncached(n.entityUri)).then(i,o):a.q.when([]):a.q.when(a.entityCache)},r.prototype.seed=function(e){var t=this;return t.__entityCacheRaw=e,t.__onDataAvailable(t.__entityCacheRaw)},r.prototype.sync=function(){var e=this;return e.__entityCacheRaw=null,e.ensureLoaded(!0)},r.prototype.read=function(e,t){function r(e){if(!e.data[n.entityName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.");var t=o.deserializer(e.data[n.entityName]);return o.__updateCacheWithEntity(t),t}function i(t){if(o.logInterface.error(o.logPrefix+"Unable to retrieve entity with ID '"+e+"' from the server.",t),o.scope.$emit("absyncError",t),o.throwFailures)throw t}var o=this;if(t=t===!0,o.logInterface.debug(o.logPrefix+"Requesting entity '"+e+"' (forceReload:"+t+")…"),!t)for(var a=0,c=o.entityCache[0];a<o.entityCache.length;++a,c=o.entityCache[a])if(c.id===e)return o.logInterface.debug(o.logPrefix+"Requested entity '"+e+"' is served from cache."),o.q.when(c);return o.logInterface.debug(o.logPrefix+"Requested entity '"+e+"' is fetched from backend."),o.__requestEntity(e).then(r,i)},r.prototype.__requestEntity=function(e){function t(e,t){return delete r.__requestCache[e],t}var r=this;if(r.enableRequestCache&&r.__requestCache&&r.__requestCache[e])return r.logInterface.debug(r.logPrefix+"Entity request '"+e+"' served from request cache."),r.__requestCache[e];var i=n.entityUri+(e?"/"+e:""),o=r.httpInterface.get(r.allowBrowserCache.request?i:r.__uncached(i)).then(t.bind(r,e));return r.enableRequestCache&&r.__requestCache&&(r.__requestCache[e]=o),o},r.prototype.update=function(e,t){var r=this;t=t||!1;var a=r.reduceComplex(e),c=r.serializer(a),s={};return s[n.entityName]=c,"undefined"!=typeof e.id?r.httpInterface.put(n.entityUri+"/"+e.id,s).then(i.bind(r,t),o.bind(r)):r.httpInterface.post(n.collectionUri,s).then(i.bind(r,t),o.bind(r))},r.prototype.patch=function(e){var t=this,r=t.reduceComplex(e),a=t.serializer(r),c={};if(c[n.entityName]=a,"undefined"!=typeof e.id)return t.httpInterface.patch(n.entityUri+"/"+e.id,c).then(i.bind(t),o.bind(t));throw new Error("Attempted to patch an entity that was never stored on the server.")},r.prototype.create=r.prototype.update,r.prototype["delete"]=function(e){function t(e){return i.__removeEntityFromCache(o)}function r(e){if(i.logInterface.error(e.data),i.scope.$emit("absyncError",e),i.throwFailures)throw e}var i=this,o=e.id;return i.httpInterface["delete"](n.entityUri+"/"+o).then(t)["catch"](r)},r.prototype.__updateCacheWithEntity=function(e){var t=this;if(t.logInterface.info(t.logPrefix+"Updating entity '"+(e.id||t.name)+"' in cache…",e),!Array.isArray(t.entityCache))return t.scope.$broadcast("beforeEntityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache,updated:e}),"function"==typeof t.entityCache.copyFrom?t.entityCache.copyFrom(e):angular.extend(t.entityCache,e),void t.scope.$broadcast("entityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache});for(var n=!1,r=0,i=t.entityCache[0];r<t.entityCache.length;++r,i=t.entityCache[r])if(i.id==e.id){t.scope.$broadcast("beforeEntityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache[r],updated:e});var o=t.entityCache[r];"function"==typeof o.copyFrom?o.copyFrom(e):angular.extend(o,e),n=!0,t.scope.$broadcast("entityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache[r]});break}n||(t.scope.$broadcast("beforeEntityNew",{service:t,cache:t.entityCache,entity:e}),t.entityCache.push(e),t.scope.$broadcast("entityNew",{service:t,cache:t.entityCache,entity:e}))},r.prototype.__removeEntityFromCache=function(e){for(var t=this,n=0,r=t.entityCache[0];n<t.entityCache.length;++n,r=t.entityCache[n])if(r.id==e){t.scope.$broadcast("beforeEntityRemoved",{service:t,cache:t.entityCache,entity:r}),t.entityCache.splice(n,1),t.scope.$broadcast("entityRemoved",{service:t,cache:t.entityCache,entity:r});break}},r.prototype.lookupTableById=function(){for(var e=this,t=[],n=0;n<e.entityCache.length;++n)t[e.entityCache[n].id]=e.entityCache[n];return t},r.prototype.reduceComplex=function(e,t){var n=this,r=t?[]:{};for(var i in e)e.hasOwnProperty(i)&&(Array.isArray(e[i])?r[i]=n.reduceComplex(e[i],!0):e[i]&&e[i].id?r[i]=e[i].id:r[i]=e[i]);return r},r.prototype.populateComplex=function(e,t,n,r){function i(i,o){function c(n){return e[t][o]=n,e}if("string"!=typeof e[t][o]){if(!r||"object"!=typeof e[t][o]||"string"!=typeof e[t][o].id)return a.q.when(!1);e[t][o]=e[t][o].id}return n.read(e[t][o]).then(c)}function o(n){e[t]=n}var a=this;if(Array.isArray(e[t])){var c=e[t].map(i);return a.q.all(c)}if("string"!=typeof e[t]){if(!r||"object"!=typeof e[t]||"string"!=typeof e[t].id)return a.q.when(!1);e[t]=e[t].id}return n.read(e[t]).then(o)},r.prototype.reset=function(){var e=this;e.entityCache=e.configuration.collectionName?[]:{},e.__entityCacheRaw=null,e.__requestCache={}},r}function t(e){return e}angular.module("absync").constant("absyncCache",e)}(),function(){"use strict";function e(){return t}function t(e,t,n,r,i,o,a,c,s,h){this.model=e,this.collectionUri=t,this.entityUri=n;var u=e.prototype.constructor.name.toLowerCase();this.collectionName=r||u+"s",this.entityName=i||u,this.deserialize=o||void 0,this.serialize=a||void 0,this.injector=c||void 0,this.debug=s||!1,this.allowBrowserCache=angular.merge({},{sync:!0,request:!0},h)}angular.module("absync").service("AbsyncServiceConfiguration",e)}(),function(){"use strict";angular.module("absync").constant("absyncNoopLog",{debug:angular.noop,info:angular.noop,error:angular.noop})}(),function(){"use strict";function e(){function e(e){if(!e)return e;var t=-1<e.indexOf("?")?"&":"?",n=(new Date).getTime();return e+t+"t="+n}return e}angular.module("absync").filter("absyncUncached",e)}(); | ||
!function(){"use strict";angular.module("absync",[])}(),function(){"use strict";function e(e,n,r){return new t(e,n,r)}function t(e,t,n){var r=this;r.__injector=e,r.__provide=t,r.__absyncCache=n,r.__ioSocket=null,r.__registerLater=[],r.__listeners=[],r.__collections={},r.__entities={},r.debug=void 0}e.$inject=["$injector","$provide","absyncCache"],angular.module("absync").provider("absync",e),t.prototype.configure=function(e){var t=this;if("undefined"!=typeof e.socket){var n=e.socket,r="undefined"!=typeof io&&io.Socket&&n instanceof io.Socket;if("function"==typeof n)t.__ioSocket=new n;else{if(!r)throw new Error("configure() expects input to be a function or a socket.io Socket instance.");t.__ioSocket=n}t.__registerLater.length&&(angular.forEach(t.__registerLater,t.__registerListener.bind(t)),t.__registerLater=[])}"undefined"!=typeof e.debug&&(t.debug=e.debug||!1),t.debug&&(angular.forEach(t.__collections,function(e){e.configuration.debug=!0}),angular.forEach(t.__entities,function(e){e.configuration.debug=!0}))},t.prototype.disconnect=function(e){var t=this;e=e||!1,angular.forEach(t.__listeners,function(e){e.unregister(),delete e.unregister,t.__registerLater.push(e)}),e&&(t.__ioSocket.disconnect(),t.__ioSocket=null)},t.prototype.__registerListener=function(e){var t=this;t.__listeners.push(e),e.unregister=t.__handleEntityEvent(e.eventName,e.callback)},t.prototype.collection=function(e,t){var n=this;if(n.__collections[e])throw new Error("A collection with the name '"+e+"' was already requested. Names for collections must be unique.");if(n.__entities[e])throw new Error("An entity with the name '"+e+"' was already requested. Names for collections must be unique and can't be shared with entities.");t.debug="undefined"==typeof t.debug?n.debug:t.debug,n.__collections[e]={constructor:n.__absyncCache(e,t),configuration:t},n.__provide.service(e,n.__collections[e].constructor)},t.prototype.entity=function(e,t){var n=this;if(n.__entities[e])throw new Error("An entity with the name '"+e+"' was already requested. Names for entities must be unique.");if(n.__collections[e])throw new Error("A collection with the name '"+e+"' was already requested. Names for entities must be unique and can't be shared with collections.");t.debug="undefined"==typeof t.debug?n.debug:t.debug,n.__entities[e]={constructor:n.__absyncCache(e,t),configuration:t},n.__provide.service(e,n.__entities[e].constructor)},t.prototype.on=function(e,t){var n=this;return n.__ioSocket?n.__registerListener({eventName:e,callback:t}):n.__registerLater.length>8192?null:(n.__registerLater.push({eventName:e,callback:t}),null)},t.prototype.__handleEntityEvent=function(e,t){var n=this;return n.__ioSocket.on(e,t),function(){n.__ioSocket.removeListener(e,t)}},t.prototype.emit=function(e,t,n){var r=this;if(!r.__ioSocket)throw new Error("socket.io is not initialized.");r.__ioSocket.emit(e,t,function(){n&&n.apply(r.__ioSocket,arguments)})},t.prototype.$get=function(){return this}}(),function(){"use strict";function e(e,n){function r(r,i,o,a,c,s,u,h){var l=this,d=n.injector||i,y=d.has(n.model);if(!y)throw new Error("Unable to construct the '"+e+"' service, because the referenced model '"+n.model+"' is not available for injection.");var f="string"==typeof n.model?d.get(n.model):n.model,_=f.serialize||n.serialize||t,p=f.deserialize||n.deserialize||t;l.name=e,l.configuration=n,l.entityCache=n.collectionName?[]:{},l.__entityCacheRaw=null,l.enableRequestCache=!0,l.__requestCache={},l.allowBrowserCache=(angular.merge||angular.extend)({},{sync:!0,request:!0},n.allowBrowserCache),l.__uncached=h,l.httpInterface=r,l.logInterface=n.debug?o:s,l.scope=c,l.q=a,l.logPrefix="absync:"+e.toLocaleUpperCase()+" ",l.forceEarlyCacheUpdate=!1,l.throwFailures=!0,l.serializer=_,l.deserializer=p,u.on(n.entityName,l.__onEntityOnWebsocket.bind(l)),n.collectionName&&u.on(n.collectionName,l.__onCollectionOnWebsocket.bind(l)),c.$on(n.entityName,l.__onEntityReceived.bind(l)),n.collectionName&&c.$on(n.collectionName,l.__onCollectionReceived.bind(l)),l.logInterface.info(l.logPrefix+"service was instantiated.")}function i(e,t){var r=this;if((e||r.forceEarlyCacheUpdate)&&t.data[n.entityName]){var i=t.data[n.entityName];if(r.forceEarlyCacheUpdate){var o=r.deserializer(i);if(r.__updateCacheWithEntity(o),e)return o}if(e)return i}}function o(e){var t=this;if(t.logInterface.error(t.logPrefix+"Unable to store entity on the server.",e),t.logInterface.error(e),t.scope.$emit("absyncError",e),t.throwFailures)throw e}return r.$inject=["$http","$injector","$log","$q","$rootScope","absyncNoopLog","absync","absyncUncachedFilter"],r.prototype.__onEntityOnWebsocket=function(e){var t=this;t.scope.$broadcast(n.entityName,e[n.entityName])},r.prototype.__onCollectionOnWebsocket=function(e){var t=this;t.scope.$broadcast(n.collectionName,e[n.collectionName])},r.prototype.__onDataAvailable=function(e){function t(e){r.entityCache.push(r.deserializer(e))}var r=this;if(Array.isArray(r.entityCache))angular.forEach(e[n.collectionName],t),r.scope.$broadcast("collectionNew",{service:r,cache:r.entityCache});else{var i=r.deserializer(e[n.entityName]);r.__updateCacheWithEntity(i)}return r.entityCache},r.prototype.__onEntityReceived=function(e,t){var n=this,r=t;return 1===Object.keys(r).length&&r.hasOwnProperty("id")?(n.logInterface.info(n.logPrefix+"Entity was deleted from the server. Updating cache…"),n.__removeEntityFromCache(r.id)):(n.logInterface.debug(n.logPrefix+"Entity was updated on the server. Updating cache…"),n.__updateCacheWithEntity(n.deserializer(r)))},r.prototype.__onCollectionReceived=function(e,t){function n(e){var t=r.deserializer(e);r.__updateCacheWithEntity(t)}var r=this,i=t;r.entityCache.length=0,angular.forEach(i,n)},r.prototype.ensureLoaded=function(e){function t(e){if(!e.data[n.collectionName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.collectionName+"'.");return a.__entityCacheRaw=e.data,a.entityCache.splice(0,a.entityCache.length),a.__onDataAvailable(e.data)}function r(e){if(a.logInterface.error(a.logPrefix+"Unable to retrieve the collection from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e),a.throwFailures)throw e}function i(e){if(!e.data[n.entityName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.");a.__entityCacheRaw=e.data,a.__onDataAvailable(e.data)}function o(e){if(a.logInterface.error(a.logPrefix+"Unable to retrieve the entity from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e),a.throwFailures)throw e}var a=this;return e=e===!0,null===a.__entityCacheRaw||e?n.collectionName&&n.collectionUri?(a.logInterface.info(a.logPrefix+"Retrieving '"+n.collectionName+"' collection…"),a.httpInterface.get(a.allowBrowserCache.sync?n.collectionUri:a.__uncached(n.collectionUri)).then(t,r)):n.entityName&&n.entityUri?a.httpInterface.get(a.allowBrowserCache.sync?n.entityUri:a.__uncached(n.entityUri)).then(i,o):a.q.when([]):a.q.when(a.entityCache)},r.prototype.seed=function(e){var t=this;return t.__entityCacheRaw=e,t.__onDataAvailable(t.__entityCacheRaw)},r.prototype.sync=function(){var e=this;return e.__entityCacheRaw=null,e.ensureLoaded(!0)},r.prototype.read=function(e,t){function r(e){if(!e.data[n.entityName])throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.");var t=o.deserializer(e.data[n.entityName]);return o.__updateCacheWithEntity(t),t}function i(t){if(o.logInterface.error(o.logPrefix+"Unable to retrieve entity with ID '"+e+"' from the server.",t),o.scope.$emit("absyncError",t),o.throwFailures)throw t}var o=this;if(t=t===!0,o.logInterface.debug(o.logPrefix+"Requesting entity '"+e+"' (forceReload:"+t+")…"),!t)for(var a=0,c=o.entityCache[0];a<o.entityCache.length;++a,c=o.entityCache[a])if(c.id===e)return o.logInterface.debug(o.logPrefix+"Requested entity '"+e+"' is served from cache."),o.q.when(c);return o.logInterface.debug(o.logPrefix+"Requested entity '"+e+"' is fetched from backend."),o.__requestEntity(e).then(r,i)},r.prototype.__requestEntity=function(e){function t(e,t){return delete r.__requestCache[e],t}var r=this;if(r.enableRequestCache&&r.__requestCache&&r.__requestCache[e])return r.logInterface.debug(r.logPrefix+"Entity request '"+e+"' served from request cache."),r.__requestCache[e];var i=n.entityUri+(e?"/"+e:""),o=r.httpInterface.get(r.allowBrowserCache.request?i:r.__uncached(i)).then(t.bind(r,e));return r.enableRequestCache&&r.__requestCache&&(r.__requestCache[e]=o),o},r.prototype.update=function(e,t){var r=this;t=t||!1;var a=r.reduceComplex(e),c=r.serializer(a),s={};return s[n.entityName]=c,"undefined"!=typeof e.id?r.httpInterface.put(n.entityUri+"/"+e.id,s).then(i.bind(r,t),o.bind(r)):r.httpInterface.post(n.collectionUri,s).then(i.bind(r,t),o.bind(r))},r.prototype.patch=function(e){var t=this,r=t.reduceComplex(e),a=t.serializer(r),c={};if(c[n.entityName]=a,"undefined"!=typeof e.id)return t.httpInterface.patch(n.entityUri+"/"+e.id,c).then(i.bind(t),o.bind(t));throw new Error("Attempted to patch an entity that was never stored on the server.")},r.prototype.create=r.prototype.update,r.prototype["delete"]=function(e){function t(e){return i.__removeEntityFromCache(o)}function r(e){if(i.logInterface.error(e.data),i.scope.$emit("absyncError",e),i.throwFailures)throw e}var i=this,o=e.id;return i.httpInterface["delete"](n.entityUri+"/"+o).then(t)["catch"](r)},r.prototype.__updateCacheWithEntity=function(e){var t=this;if(t.logInterface.info(t.logPrefix+"Updating entity '"+(e.id||t.name)+"' in cache…",e),!Array.isArray(t.entityCache))return t.scope.$broadcast("beforeEntityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache,updated:e}),"function"==typeof t.entityCache.copyFrom?t.entityCache.copyFrom(e):angular.extend(t.entityCache,e),void t.scope.$broadcast("entityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache});for(var n=!1,r=0,i=t.entityCache[0];r<t.entityCache.length;++r,i=t.entityCache[r])if(i.id==e.id){t.scope.$broadcast("beforeEntityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache[r],updated:e});var o=t.entityCache[r];"function"==typeof o.copyFrom?o.copyFrom(e):angular.extend(o,e),n=!0,t.scope.$broadcast("entityUpdated",{service:t,cache:t.entityCache,entity:t.entityCache[r]});break}n||(t.scope.$broadcast("beforeEntityNew",{service:t,cache:t.entityCache,entity:e}),t.entityCache.push(e),t.scope.$broadcast("entityNew",{service:t,cache:t.entityCache,entity:e}))},r.prototype.__removeEntityFromCache=function(e){for(var t=this,n=0,r=t.entityCache[0];n<t.entityCache.length;++n,r=t.entityCache[n])if(r.id==e){t.scope.$broadcast("beforeEntityRemoved",{service:t,cache:t.entityCache,entity:r}),t.entityCache.splice(n,1),t.scope.$broadcast("entityRemoved",{service:t,cache:t.entityCache,entity:r});break}},r.prototype.lookupTableById=function(){for(var e=this,t=[],n=0;n<e.entityCache.length;++n)t[e.entityCache[n].id]=e.entityCache[n];return t},r.prototype.reduceComplex=function(e,t){var n=this,r=t?[]:{};for(var i in e)e.hasOwnProperty(i)&&(Array.isArray(e[i])?r[i]=n.reduceComplex(e[i],!0):e[i]&&e[i].id?r[i]=e[i].id:r[i]=e[i]);return r},r.prototype.populateComplex=function(e,t,n,r){function i(i,o){function c(n){return e[t][o]=n,e}if("string"!=typeof e[t][o]){if(!r||"object"!=typeof e[t][o]||"string"!=typeof e[t][o].id)return a.q.when(!1);e[t][o]=e[t][o].id}return n.read(e[t][o]).then(c)}function o(n){e[t]=n}var a=this;if(Array.isArray(e[t])){var c=e[t].map(i);return a.q.all(c)}if("string"!=typeof e[t]){if(!r||"object"!=typeof e[t]||"string"!=typeof e[t].id)return a.q.when(!1);e[t]=e[t].id}return n.read(e[t]).then(o)},r.prototype.reset=function(){var e=this;e.entityCache=e.configuration.collectionName?[]:{},e.__entityCacheRaw=null,e.__requestCache={}},r}function t(e){return e}angular.module("absync").constant("absyncCache",e)}(),function(){"use strict";function e(){return t}function t(e,t,n,r,i,o,a,c,s,u){this.model=e,this.collectionUri=t,this.entityUri=n;var h=e.prototype.constructor.name.toLowerCase();this.collectionName=r||h+"s",this.entityName=i||h,this.deserialize=o||void 0,this.serialize=a||void 0,this.injector=c||void 0,this.debug=s||!1,this.allowBrowserCache=angular.merge({},{sync:!0,request:!0},u)}angular.module("absync").service("AbsyncServiceConfiguration",e)}(),function(){"use strict";angular.module("absync").constant("absyncNoopLog",{debug:angular.noop,info:angular.noop,error:angular.noop})}(),function(){"use strict";function e(){function e(e){if(!e)return e;var t=-1<e.indexOf("?")?"&":"?",n=(new Date).getTime();return e+t+"t="+n}return e}angular.module("absync").filter("absyncUncached",e)}(); | ||
//# sourceMappingURL=maps/absync.concat.min.js.map |
{ | ||
"name": "absync", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "absync", | ||
@@ -5,0 +5,0 @@ "main": "dist/development/absync.concat.js", |
@@ -51,2 +51,4 @@ /* globals angular, io */ | ||
self.__registerLater = []; | ||
// References to all registered event listeners. | ||
self.__listeners = []; | ||
@@ -116,5 +118,36 @@ // The collections that absync provides. | ||
/** | ||
* Detaches absync from the websocket. | ||
* @param {Boolean} [disconnectSocket=false] Should the underlying socket.io connection be disconnected as well? | ||
*/ | ||
AbsyncProvider.prototype.disconnect = function AbsyncProvider$disconnect( disconnectSocket ) { | ||
var self = this; | ||
disconnectSocket = disconnectSocket || false; | ||
angular.forEach( self.__listeners, function unregisterListener( listener ) { | ||
listener.unregister(); | ||
delete listener.unregister; | ||
self.__registerLater.push( listener ); | ||
} ); | ||
if( disconnectSocket ) { | ||
self.__ioSocket.disconnect(); | ||
self.__ioSocket = null; | ||
} | ||
}; | ||
/** | ||
* Register an event listener with socket.io. | ||
* @param {Object} listener | ||
* @private | ||
*/ | ||
AbsyncProvider.prototype.__registerListener = function AbsyncProvider$registerListener( listener ) { | ||
var self = this; | ||
self.$get().__handleEntityEvent( listener.eventName, listener.callback ); | ||
// Remember this listener. | ||
self.__listeners.push( listener ); | ||
// Register the listener and remember the function to use when the listener should be unregistered. | ||
listener.unregister = self.__handleEntityEvent( listener.eventName, listener.callback ); | ||
}; | ||
@@ -188,36 +221,4 @@ | ||
/** | ||
* Register the service factory. | ||
* @returns {AbsyncService} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return new AbsyncService( this ); | ||
}; | ||
/** | ||
* The service that is received when injecting "absync". | ||
* This service is primarily used internally to set up the connection between socket.io and the individual | ||
* caching services. | ||
* @param {AbsyncProvider|Object} parentProvider The AbsyncProvider that provides this service. | ||
* @constructor | ||
*/ | ||
function AbsyncService( parentProvider ) { | ||
this.__absyncProvider = parentProvider; | ||
} | ||
/** | ||
* Configure the socket.io connection for absync. | ||
* This configuration of absync should usually be performed through the absyncProvider in the configuration | ||
* phase of a module. | ||
* @param {Object} configuration The configuration for the absync provider. | ||
* Can have a member `socket`, pointing to the socket.io instance or constructor to use. | ||
* Can have a member `debug`, enabling debugging, if set to true. | ||
*/ | ||
AbsyncService.prototype.configure = function AbsyncService$configure( configuration ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
_absyncProvider.configure( configuration ); | ||
}; | ||
/** | ||
* Register an event listener that is called when a specific entity is received on the websocket. | ||
@@ -230,10 +231,9 @@ * @param {String} eventName The event name, usually the name of the entity. | ||
*/ | ||
AbsyncService.prototype.on = function AbsyncService$on( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
var self = this; | ||
AbsyncProvider.prototype.on = function AbsyncProvider$on( eventName, callback ) { | ||
var self = this; | ||
// If we have no configured socket.io connection yet, remember to register it later. | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
if( _absyncProvider.__registerLater.length > 8192 ) { | ||
if( self.__registerLater.length > 8192 ) { | ||
// Be defensive, something is probably not right here. | ||
@@ -244,3 +244,3 @@ return null; | ||
// TODO: Use promises here, so that we can always return the event listener removal function. | ||
_absyncProvider.__registerLater.push( { | ||
self.__registerLater.push( { | ||
eventName : eventName, | ||
@@ -252,3 +252,6 @@ callback : callback | ||
return self.__handleEntityEvent( eventName, callback ); | ||
return self.__registerListener( { | ||
eventName : eventName, | ||
callback : callback | ||
} ); | ||
}; | ||
@@ -262,11 +265,11 @@ | ||
*/ | ||
AbsyncService.prototype.__handleEntityEvent = function AbsyncService$handleEntityEvent( eventName, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.__handleEntityEvent = function AbsyncProvider$handleEntityEvent( eventName, callback ) { | ||
var self = this; | ||
// Register the callback with socket.io. | ||
_absyncProvider.__ioSocket.on( eventName, callback ); | ||
self.__ioSocket.on( eventName, callback ); | ||
// Return a function that removes the listener. | ||
return function removeListener() { | ||
_absyncProvider.__ioSocket.removeListener( eventName, callback ); | ||
self.__ioSocket.removeListener( eventName, callback ); | ||
}; | ||
@@ -276,3 +279,3 @@ }; | ||
/** | ||
* Convenience method to allow the user to emit() from the websocket. | ||
* Convenience method to allow the user to emit() from the socket.io connection. | ||
* This is not utilized in absync internally. | ||
@@ -283,14 +286,23 @@ * @param {String} eventName | ||
*/ | ||
AbsyncService.prototype.emit = function AbsyncService$emit( eventName, data, callback ) { | ||
var _absyncProvider = this.__absyncProvider; | ||
AbsyncProvider.prototype.emit = function AbsyncProvider$emit( eventName, data, callback ) { | ||
var self = this; | ||
if( !_absyncProvider.__ioSocket ) { | ||
if( !self.__ioSocket ) { | ||
throw new Error( "socket.io is not initialized." ); | ||
} | ||
_absyncProvider.__ioSocket.emit( eventName, data, function afterEmit() { | ||
self.__ioSocket.emit( eventName, data, function afterEmit() { | ||
if( callback ) { | ||
callback.apply( _absyncProvider.__ioSocket, arguments ); | ||
callback.apply( self.__ioSocket, arguments ); | ||
} | ||
} ); | ||
}; | ||
/** | ||
* The service is just used as a convenience to access the provider. | ||
* @returns {AbsyncProvider} | ||
* @ngInject | ||
*/ | ||
AbsyncProvider.prototype.$get = function AbsyncProvider$$get() { | ||
return this; | ||
}; |
@@ -35,3 +35,3 @@ /* globals angular */ | ||
* @param {angular.IRootScopeService|Object} $rootScope | ||
* @param {AbsyncService} absync | ||
* @param {AbsyncProvider} absync | ||
* @param {Object} absyncNoopLog A log interface that does nothing. | ||
@@ -42,3 +42,3 @@ * @param {Object} absyncUncachedFilter A filter that mutates URLs so they will bypass the browser cache. | ||
*/ | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absync, absyncNoopLog, absyncUncachedFilter ) { | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absyncNoopLog, absync, absyncUncachedFilter ) { | ||
var self = this; | ||
@@ -45,0 +45,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
121134
7471335