Comparing version
@@ -20,2 +20,3 @@ (function() { | ||
getAbsyncProvider.$inject = ["$provide", "absyncCache"]; | ||
angular | ||
@@ -34,3 +35,2 @@ .module( "absync" ) | ||
} | ||
getAbsyncProvider.$inject = ["$provide", "absyncCache"]; | ||
@@ -303,2 +303,3 @@ /** | ||
*/ | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absync ) { | ||
@@ -369,3 +370,5 @@ var self = this; | ||
absync.on( configuration.entityName, self.__onEntityOnWebsocket.bind( self ) ); | ||
absync.on( configuration.collectionName, self.__onCollectionOnWebsocket.bind( self ) ); | ||
if( configuration.collectionName ) { | ||
absync.on( configuration.collectionName, self.__onCollectionOnWebsocket.bind( self ) ); | ||
} | ||
@@ -375,3 +378,5 @@ // Now we listen on the root scope for the same events we're firing above. | ||
$rootScope.$on( configuration.entityName, self.__onEntityReceived.bind( self ) ); | ||
$rootScope.$on( configuration.collectionName, self.__onCollectionReceived.bind( self ) ); | ||
if( configuration.collectionName ) { | ||
$rootScope.$on( configuration.collectionName, self.__onCollectionReceived.bind( self ) ); | ||
} | ||
@@ -384,3 +389,2 @@ // Wait for data to be available. | ||
} | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync"]; | ||
@@ -497,3 +501,3 @@ /** | ||
* @param {Boolean} [forceReload=false] Should the data be loaded, even if the service already has a local cache? | ||
* @returns {Promise<Array<configuration.model>>|IPromise<Array>|IPromise<void>|Q.Promise<Array<configuration.model>>} | ||
* @returns {Promise<Array<configuration.model>>|IPromise<Array>|IPromise<void>|Q.Promise<Array<configuration.model>>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -595,3 +599,3 @@ CacheService.prototype.ensureLoaded = function CacheService$ensureLoaded( forceReload ) { | ||
* @param {Boolean} [forceReload=false] Should the entity be retrieved from the server, even if it is already in the cache? | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>} | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -654,3 +658,3 @@ CacheService.prototype.read = function CacheService$read( id, forceReload ) { | ||
* @param {String} id The ID of the entity. | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>} | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>|angular.IPromise<TResult>} | ||
* @private | ||
@@ -688,3 +692,3 @@ */ | ||
* @param {configuration.model} entity | ||
* @return {Promise<configuration.model>|IPromise<TResult>} A promise that will be resolved with the updated entity. | ||
* @return {Promise<configuration.model>|IPromise<TResult>|angular.IPromise<TResult>} A promise that will be resolved with the updated entity. | ||
*/ | ||
@@ -707,3 +711,3 @@ CacheService.prototype.update = function CacheService$update( entity ) { | ||
.put( configuration.entityUri + "/" + entity.id, wrappedEntity ) | ||
.then( afterEntityStored, onEntityStorageFailure ); | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
@@ -714,34 +718,26 @@ } else { | ||
.post( configuration.collectionUri, wrappedEntity ) | ||
.then( afterEntityStored, onEntityStorageFailure ); | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
} | ||
}; | ||
/** | ||
* Invoked when the entity was stored on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function afterEntityStored( serverResponse ) { | ||
// Writing an entity to the backend will usually invoke an update event to be | ||
// broadcast over websockets, where we would also retrieve the updated record. | ||
// We still put the updated record we receive here into the cache to ensure early consistency. | ||
// TODO: This might actually not be optimal. Consider only handling the websocket update. | ||
if( serverResponse.data[ configuration.entityName ] ) { | ||
var newEntity = self.deserializer( serverResponse.data[ configuration.entityName ] ); | ||
CacheService.prototype.patch = function CacheService$patch( entity ) { | ||
var self = this; | ||
// If early cache updates are forced, put the return entity into the cache. | ||
if( self.forceEarlyCacheUpdate ) { | ||
self.__updateCacheWithEntity( newEntity ); | ||
} | ||
return newEntity; | ||
} | ||
throw new Error( "The response from the server was not in the expected format. It should have a member named '" + configuration.entityName + "'." ); | ||
} | ||
// First create a copy of the object, which has complex properties reduced to their respective IDs. | ||
var reduced = self.reduceComplex( entity ); | ||
// Now serialize the object. | ||
var serialized = self.serializer( reduced ); | ||
/** | ||
* Invoked when there was an error while trying to store the entity on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function onEntityStorageFailure( serverResponse ) { | ||
self.logInterface.error( self.logPrefix + "Unable to store entity on the server.", | ||
serverResponse ); | ||
self.logInterface.error( serverResponse ); | ||
// Wrap the entity in a new object, with a single property, named after the entity type. | ||
var wrappedEntity = {}; | ||
wrappedEntity[ configuration.entityName ] = serialized; | ||
// Check if the entity has an "id" property, if it has, we will update. Otherwise, we create. | ||
if( "undefined" !== typeof entity.id ) { | ||
return self.httpInterface | ||
.patch( configuration.entityUri + "/" + entity.id, wrappedEntity ) | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
} else { | ||
throw new Error( "Attempted to patch an entity that was never stored on the server." ); | ||
} | ||
@@ -756,2 +752,37 @@ }; | ||
/** | ||
* Invoked when the entity was stored on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function afterEntityStored( serverResponse ) { | ||
var self = this; | ||
// Writing an entity to the backend will usually invoke an update event to be | ||
// broadcast over websockets, where we would also retrieve the updated record. | ||
// We still put the updated record we receive here into the cache to ensure early consistency. | ||
// TODO: This might actually not be optimal. Consider only handling the websocket update. | ||
if( serverResponse.data[ configuration.entityName ] ) { | ||
var newEntity = self.deserializer( serverResponse.data[ configuration.entityName ] ); | ||
// If early cache updates are forced, put the return entity into the cache. | ||
if( self.forceEarlyCacheUpdate ) { | ||
self.__updateCacheWithEntity( newEntity ); | ||
} | ||
return newEntity; | ||
} | ||
throw new Error( "The response from the server was not in the expected format. It should have a member named '" + configuration.entityName + "'." ); | ||
} | ||
/** | ||
* Invoked when there was an error while trying to store the entity on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function onEntityStorageFailure( serverResponse ) { | ||
var self = this; | ||
self.logInterface.error( self.logPrefix + "Unable to store entity on the server.", | ||
serverResponse ); | ||
self.logInterface.error( serverResponse ); | ||
} | ||
/** | ||
* Remove an entity from the cache and have it deleted on the backend. | ||
@@ -972,3 +1003,3 @@ * @param {Object} entity | ||
* instances in cache; otherwise, only properties that are string representations of complex type IDs will be replaced. | ||
* @returns {IPromise<TResult>|IPromise<any[]>|IPromise<{}>} | ||
* @returns {IPromise<TResult>|IPromise<any[]>|IPromise<{}>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -975,0 +1006,0 @@ CacheService.prototype.populateComplex = function CacheService$populateComplex( entity, propertyName, cache, force ) { |
@@ -15,2 +15,3 @@ (function() { | ||
getAbsyncProvider.$inject = ["$provide", "absyncCache"]; | ||
angular | ||
@@ -29,3 +30,2 @@ .module( "absync" ) | ||
} | ||
getAbsyncProvider.$inject = ["$provide", "absyncCache"]; | ||
@@ -32,0 +32,0 @@ /** |
@@ -41,2 +41,3 @@ (function() { | ||
*/ | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync"]; | ||
function CacheService( $http, $injector, $log, $q, $rootScope, absync ) { | ||
@@ -107,3 +108,5 @@ var self = this; | ||
absync.on( configuration.entityName, self.__onEntityOnWebsocket.bind( self ) ); | ||
absync.on( configuration.collectionName, self.__onCollectionOnWebsocket.bind( self ) ); | ||
if( configuration.collectionName ) { | ||
absync.on( configuration.collectionName, self.__onCollectionOnWebsocket.bind( self ) ); | ||
} | ||
@@ -113,3 +116,5 @@ // Now we listen on the root scope for the same events we're firing above. | ||
$rootScope.$on( configuration.entityName, self.__onEntityReceived.bind( self ) ); | ||
$rootScope.$on( configuration.collectionName, self.__onCollectionReceived.bind( self ) ); | ||
if( configuration.collectionName ) { | ||
$rootScope.$on( configuration.collectionName, self.__onCollectionReceived.bind( self ) ); | ||
} | ||
@@ -122,3 +127,2 @@ // Wait for data to be available. | ||
} | ||
CacheService.$inject = ["$http", "$injector", "$log", "$q", "$rootScope", "absync"]; | ||
@@ -235,3 +239,3 @@ /** | ||
* @param {Boolean} [forceReload=false] Should the data be loaded, even if the service already has a local cache? | ||
* @returns {Promise<Array<configuration.model>>|IPromise<Array>|IPromise<void>|Q.Promise<Array<configuration.model>>} | ||
* @returns {Promise<Array<configuration.model>>|IPromise<Array>|IPromise<void>|Q.Promise<Array<configuration.model>>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -333,3 +337,3 @@ CacheService.prototype.ensureLoaded = function CacheService$ensureLoaded( forceReload ) { | ||
* @param {Boolean} [forceReload=false] Should the entity be retrieved from the server, even if it is already in the cache? | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>} | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -392,3 +396,3 @@ CacheService.prototype.read = function CacheService$read( id, forceReload ) { | ||
* @param {String} id The ID of the entity. | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>} | ||
* @returns {Promise<configuration.model>|IPromise<TResult>|IPromise<void>|angular.IPromise<TResult>} | ||
* @private | ||
@@ -426,3 +430,3 @@ */ | ||
* @param {configuration.model} entity | ||
* @return {Promise<configuration.model>|IPromise<TResult>} A promise that will be resolved with the updated entity. | ||
* @return {Promise<configuration.model>|IPromise<TResult>|angular.IPromise<TResult>} A promise that will be resolved with the updated entity. | ||
*/ | ||
@@ -445,3 +449,3 @@ CacheService.prototype.update = function CacheService$update( entity ) { | ||
.put( configuration.entityUri + "/" + entity.id, wrappedEntity ) | ||
.then( afterEntityStored, onEntityStorageFailure ); | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
@@ -452,34 +456,26 @@ } else { | ||
.post( configuration.collectionUri, wrappedEntity ) | ||
.then( afterEntityStored, onEntityStorageFailure ); | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
} | ||
}; | ||
/** | ||
* Invoked when the entity was stored on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function afterEntityStored( serverResponse ) { | ||
// Writing an entity to the backend will usually invoke an update event to be | ||
// broadcast over websockets, where we would also retrieve the updated record. | ||
// We still put the updated record we receive here into the cache to ensure early consistency. | ||
// TODO: This might actually not be optimal. Consider only handling the websocket update. | ||
if( serverResponse.data[ configuration.entityName ] ) { | ||
var newEntity = self.deserializer( serverResponse.data[ configuration.entityName ] ); | ||
CacheService.prototype.patch = function CacheService$patch( entity ) { | ||
var self = this; | ||
// If early cache updates are forced, put the return entity into the cache. | ||
if( self.forceEarlyCacheUpdate ) { | ||
self.__updateCacheWithEntity( newEntity ); | ||
} | ||
return newEntity; | ||
} | ||
throw new Error( "The response from the server was not in the expected format. It should have a member named '" + configuration.entityName + "'." ); | ||
} | ||
// First create a copy of the object, which has complex properties reduced to their respective IDs. | ||
var reduced = self.reduceComplex( entity ); | ||
// Now serialize the object. | ||
var serialized = self.serializer( reduced ); | ||
/** | ||
* Invoked when there was an error while trying to store the entity on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function onEntityStorageFailure( serverResponse ) { | ||
self.logInterface.error( self.logPrefix + "Unable to store entity on the server.", | ||
serverResponse ); | ||
self.logInterface.error( serverResponse ); | ||
// Wrap the entity in a new object, with a single property, named after the entity type. | ||
var wrappedEntity = {}; | ||
wrappedEntity[ configuration.entityName ] = serialized; | ||
// Check if the entity has an "id" property, if it has, we will update. Otherwise, we create. | ||
if( "undefined" !== typeof entity.id ) { | ||
return self.httpInterface | ||
.patch( configuration.entityUri + "/" + entity.id, wrappedEntity ) | ||
.then( afterEntityStored.bind( self ), onEntityStorageFailure.bind( self ) ); | ||
} else { | ||
throw new Error( "Attempted to patch an entity that was never stored on the server." ); | ||
} | ||
@@ -494,2 +490,37 @@ }; | ||
/** | ||
* Invoked when the entity was stored on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function afterEntityStored( serverResponse ) { | ||
var self = this; | ||
// Writing an entity to the backend will usually invoke an update event to be | ||
// broadcast over websockets, where we would also retrieve the updated record. | ||
// We still put the updated record we receive here into the cache to ensure early consistency. | ||
// TODO: This might actually not be optimal. Consider only handling the websocket update. | ||
if( serverResponse.data[ configuration.entityName ] ) { | ||
var newEntity = self.deserializer( serverResponse.data[ configuration.entityName ] ); | ||
// If early cache updates are forced, put the return entity into the cache. | ||
if( self.forceEarlyCacheUpdate ) { | ||
self.__updateCacheWithEntity( newEntity ); | ||
} | ||
return newEntity; | ||
} | ||
throw new Error( "The response from the server was not in the expected format. It should have a member named '" + configuration.entityName + "'." ); | ||
} | ||
/** | ||
* Invoked when there was an error while trying to store the entity on the server. | ||
* @param {angular.IHttpPromiseCallbackArg|Object} serverResponse The reply sent from the server. | ||
*/ | ||
function onEntityStorageFailure( serverResponse ) { | ||
var self = this; | ||
self.logInterface.error( self.logPrefix + "Unable to store entity on the server.", | ||
serverResponse ); | ||
self.logInterface.error( serverResponse ); | ||
} | ||
/** | ||
* Remove an entity from the cache and have it deleted on the backend. | ||
@@ -710,3 +741,3 @@ * @param {Object} entity | ||
* instances in cache; otherwise, only properties that are string representations of complex type IDs will be replaced. | ||
* @returns {IPromise<TResult>|IPromise<any[]>|IPromise<{}>} | ||
* @returns {IPromise<TResult>|IPromise<any[]>|IPromise<{}>|angular.IPromise<TResult>} | ||
*/ | ||
@@ -713,0 +744,0 @@ CacheService.prototype.populateComplex = function CacheService$populateComplex( entity, propertyName, cache, force ) { |
@@ -1,2 +0,2 @@ | ||
!function(){"use strict";angular.module("absync",[])}(),function(){"use strict";function e(e,n){return new t(e,n)}function t(e,t){var n=this;n.__provide=e,n.__absyncCache=t,n.__ioSocket=null,n.__registerLater=[],n.__collections={},n.__entities={}}function n(e){this.__absyncProvider=e}angular.module("absync").provider("absync",e),e.$inject=["$provide","absyncCache"],t.prototype.configure=function(e){var t=this,n=e.socket||e,r=io&&io.Socket&&n instanceof io.Socket;if("function"==typeof n)t.__ioSocket=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&&(t.__registerLater.forEach(t.__registerListener.bind(t)),t.__registerLater=[])},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.");n.__collections[e]=n.__absyncCache(e,t),n.__provide.service(e,n.__collections[e])},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.");n.__entities[e]=n.__absyncCache(e,t),n.__provide.service(e,n.__entities[e])},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){var l=this,h=n.injector||i,y=h.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?h.get(n.model):n.model,d=f.serialize||n.serialize||t,u=f.deserialize||n.deserialize||t;l.name=e,l.configuration=n,l.entityCache=n.collectionName?[]:{},l.__entityCacheRaw=null,l.enableRequestCache=!0,l.__requestCache={},l.__dataAvailableDeferred=a.defer(),l.__objectsAvailableDeferred=a.defer(),l.dataAvailable=l.__dataAvailableDeferred.promise,l.objectsAvailable=l.__objectsAvailableDeferred.promise,l.httpInterface=r,l.logInterface=o,l.scope=c,l.q=a,l.logPrefix="absync:"+e.toLocaleUpperCase()+" ",l.forceEarlyCacheUpdate=!1,l.serializer=d,l.deserializer=u,s.on(n.entityName,l.__onEntityOnWebsocket.bind(l)),s.on(n.collectionName,l.__onCollectionOnWebsocket.bind(l)),c.$on(n.entityName,l.__onEntityReceived.bind(l)),c.$on(n.collectionName,l.__onCollectionReceived.bind(l)),l.dataAvailable.then(l.__onDataAvailable.bind(l)),l.logInterface.info(l.logPrefix+"service was instantiated.")}return r.$inject=["$http","$injector","$log","$q","$rootScope","absync"],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))e[n.collectionName].forEach(t),r.__objectsAvailableDeferred.resolve(r.entityCache),r.scope.$broadcast("collectionNew",{service:r,cache:r.entityCache});else{var i=r.deserializer(e[n.entityName]);r.__updateCacheWithEntity(i),r.__objectsAvailableDeferred.resolve(r.entityCache)}},r.prototype.__onEntityReceived=function(e,t){var n=this,r=t;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,i.forEach(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+"'.");a.__entityCacheRaw=e.data,a.__dataAvailableDeferred.resolve(e.data)}function r(e){a.logInterface.error(a.logPrefix+"Unable to retrieve the collection from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",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.__dataAvailableDeferred.resolve(e.data)}function o(e){a.logInterface.error(a.logPrefix+"Unable to retrieve the entity from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e)}var a=this;if(e=e===!0,null===a.__entityCacheRaw||e)if(a.__entityCacheRaw=[],n.collectionName&&n.collectionUri)a.logInterface.info(a.logPrefix+"Retrieving '"+n.collectionName+"' collection…"),a.httpInterface.get(n.collectionUri).then(t,r);else{if(!n.entityName||!n.entityUri)return a.q.when([]);a.__entityCacheRaw={},a.httpInterface.get(n.entityUri).then(i,o)}return a.q.all([a.dataAvailable,a.objectsAvailable]).then(function(){return a.entityCache})},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){o.logInterface.error(o.logPrefix+"Unable to retrieve entity with ID '"+e+"' from the server.",t),o.scope.$emit("absyncError",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(i).then(t.bind(r,e));return r.enableRequestCache&&r.__requestCache&&(r.__requestCache[e]=o),o},r.prototype.update=function(e){function t(e){if(e.data[n.entityName]){var t=i.deserializer(e.data[n.entityName]);return i.forceEarlyCacheUpdate&&i.__updateCacheWithEntity(t),t}throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.")}function r(e){i.logInterface.error(i.logPrefix+"Unable to store entity on the server.",e),i.logInterface.error(e)}var i=this,o=i.reduceComplex(e),a=i.serializer(o),c={};return c[n.entityName]=a,"undefined"!=typeof e.id?i.httpInterface.put(n.entityUri+"/"+e.id,c).then(t,r):i.httpInterface.post(n.collectionUri,c).then(t,r)},r.prototype.create=r.prototype.update,r.prototype["delete"]=function(e){function t(e){return i.__removeEntityFromCache(o)}function r(e){throw i.logInterface.error(e.data),new Error("Unable to delete entity.")}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}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){this.model=e,this.collectionUri=t,this.entityUri=n;var s=e.prototype.constructor.name.toLowerCase();this.collectionName=r||s+"s",this.entityName=i||s,this.deserialize=o||void 0,this.serialize=a||void 0,this.injector=c||void 0}angular.module("absync").service("AbsyncServiceConfiguration",e)}(); | ||
!function(){"use strict";angular.module("absync",[])}(),function(){"use strict";function e(e,n){return new t(e,n)}function t(e,t){var n=this;n.__provide=e,n.__absyncCache=t,n.__ioSocket=null,n.__registerLater=[],n.__collections={},n.__entities={}}function n(e){this.__absyncProvider=e}e.$inject=["$provide","absyncCache"],angular.module("absync").provider("absync",e),t.prototype.configure=function(e){var t=this,n=e.socket||e,r=io&&io.Socket&&n instanceof io.Socket;if("function"==typeof n)t.__ioSocket=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&&(t.__registerLater.forEach(t.__registerListener.bind(t)),t.__registerLater=[])},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.");n.__collections[e]=n.__absyncCache(e,t),n.__provide.service(e,n.__collections[e])},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.");n.__entities[e]=n.__absyncCache(e,t),n.__provide.service(e,n.__entities[e])},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){var l=this,h=n.injector||i,d=h.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 y="string"==typeof n.model?h.get(n.model):n.model,f=y.serialize||n.serialize||t,u=y.deserialize||n.deserialize||t;l.name=e,l.configuration=n,l.entityCache=n.collectionName?[]:{},l.__entityCacheRaw=null,l.enableRequestCache=!0,l.__requestCache={},l.__dataAvailableDeferred=a.defer(),l.__objectsAvailableDeferred=a.defer(),l.dataAvailable=l.__dataAvailableDeferred.promise,l.objectsAvailable=l.__objectsAvailableDeferred.promise,l.httpInterface=r,l.logInterface=o,l.scope=c,l.q=a,l.logPrefix="absync:"+e.toLocaleUpperCase()+" ",l.forceEarlyCacheUpdate=!1,l.serializer=f,l.deserializer=u,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.dataAvailable.then(l.__onDataAvailable.bind(l)),l.logInterface.info(l.logPrefix+"service was instantiated.")}function i(e){var t=this;if(e.data[n.entityName]){var r=t.deserializer(e.data[n.entityName]);return t.forceEarlyCacheUpdate&&t.__updateCacheWithEntity(r),r}throw new Error("The response from the server was not in the expected format. It should have a member named '"+n.entityName+"'.")}function o(e){var t=this;t.logInterface.error(t.logPrefix+"Unable to store entity on the server.",e),t.logInterface.error(e)}return r.$inject=["$http","$injector","$log","$q","$rootScope","absync"],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))e[n.collectionName].forEach(t),r.__objectsAvailableDeferred.resolve(r.entityCache),r.scope.$broadcast("collectionNew",{service:r,cache:r.entityCache});else{var i=r.deserializer(e[n.entityName]);r.__updateCacheWithEntity(i),r.__objectsAvailableDeferred.resolve(r.entityCache)}},r.prototype.__onEntityReceived=function(e,t){var n=this,r=t;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,i.forEach(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+"'.");a.__entityCacheRaw=e.data,a.__dataAvailableDeferred.resolve(e.data)}function r(e){a.logInterface.error(a.logPrefix+"Unable to retrieve the collection from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",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.__dataAvailableDeferred.resolve(e.data)}function o(e){a.logInterface.error(a.logPrefix+"Unable to retrieve the entity from the server.",e),a.__entityCacheRaw=null,a.scope.$emit("absyncError",e)}var a=this;if(e=e===!0,null===a.__entityCacheRaw||e)if(a.__entityCacheRaw=[],n.collectionName&&n.collectionUri)a.logInterface.info(a.logPrefix+"Retrieving '"+n.collectionName+"' collection…"),a.httpInterface.get(n.collectionUri).then(t,r);else{if(!n.entityName||!n.entityUri)return a.q.when([]);a.__entityCacheRaw={},a.httpInterface.get(n.entityUri).then(i,o)}return a.q.all([a.dataAvailable,a.objectsAvailable]).then(function(){return a.entityCache})},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){o.logInterface.error(o.logPrefix+"Unable to retrieve entity with ID '"+e+"' from the server.",t),o.scope.$emit("absyncError",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(i).then(t.bind(r,e));return r.enableRequestCache&&r.__requestCache&&(r.__requestCache[e]=o),o},r.prototype.update=function(e){var t=this,r=t.reduceComplex(e),a=t.serializer(r),c={};return c[n.entityName]=a,"undefined"!=typeof e.id?t.httpInterface.put(n.entityUri+"/"+e.id,c).then(i.bind(t),o.bind(t)):t.httpInterface.post(n.collectionUri,c).then(i.bind(t),o.bind(t))},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){throw i.logInterface.error(e.data),new Error("Unable to delete entity.")}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}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){this.model=e,this.collectionUri=t,this.entityUri=n;var s=e.prototype.constructor.name.toLowerCase();this.collectionName=r||s+"s",this.entityName=i||s,this.deserialize=o||void 0,this.serialize=a||void 0,this.injector=c||void 0}angular.module("absync").service("AbsyncServiceConfiguration",e)}(); | ||
//# sourceMappingURL=maps/absync.concat.min.js.map |
{ | ||
"name": "absync", | ||
"version": "2.4.0", | ||
"version": "2.4.1", | ||
"description": "absync", | ||
@@ -5,0 +5,0 @@ "main": "dist/development/absync.concat.js", |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
851966
0.7%9238
0.53%0
-100%