UNPKG

spincycle

Version:

A reactive message router and object manager that lets clients subscribe to object property changes on the server

1,111 lines (1,068 loc) 41.2 kB
// Generated by CoffeeScript 1.12.6 (function() { var ClientEndpoints, DB, ObjectManager, ResolveModule, SuperModel, debug, defer, e, error, objStore, util, uuid, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; util = require('util'); defer = require('node-promise').defer; SuperModel = require('./SuperModel'); e = require('./EventManager'); DB = require('./DB'); ClientEndpoints = require('./ClientEndpoints'); objStore = require('./OStore'); error = require('./Error').error; ResolveModule = require('./ResolveModule'); uuid = require('node-uuid'); debug = process.env["DEBUG"]; ObjectManager = (function() { function ObjectManager(messageRouter) { this.messageRouter = messageRouter; this.resolveReferences = bind(this.resolveReferences, this); this.onDeregisterForPopulationChanges = bind(this.onDeregisterForPopulationChanges, this); this.onRegisterForPopulationChanges = bind(this.onRegisterForPopulationChanges, this); this.onDeregisterForUpdatesOn = bind(this.onDeregisterForUpdatesOn, this); this.onRegisterForUpdatesOn = bind(this.onRegisterForUpdatesOn, this); this.persistUpdates = bind(this.persistUpdates, this); this.onUpdateObject = bind(this.onUpdateObject, this); this.getObjectPullThrough = bind(this.getObjectPullThrough, this); this.expose = bind(this.expose, this); this.parseList = bind(this.parseList, this); this._countObjects = bind(this._countObjects, this); this._listObjects = bind(this._listObjects, this); this.getAggregateObjects = bind(this.getAggregateObjects, this); this._getObject = bind(this._getObject, this); this._updateObject = bind(this._updateObject, this); this._deleteObject = bind(this._deleteObject, this); this._createObject = bind(this._createObject, this); this.getModelFor = bind(this.getModelFor, this); this.onGetModelFor = bind(this.onGetModelFor, this); this.onGetAccessTypesFor = bind(this.onGetAccessTypesFor, this); this.onListTypes = bind(this.onListTypes, this); this.getTypes = bind(this.getTypes, this); this.registerUpdateObjectHook = bind(this.registerUpdateObjectHook, this); this.setup = bind(this.setup, this); this.updateObjectHooks = []; this.populationListeners = []; SuperModel.onCreate((function(_this) { return function(newmodel) { var client, k, results, sublist; sublist = _this.populationListeners[newmodel.type] || {}; results = []; for (k in sublist) { client = sublist[k]; if (ClientEndpoints.exists(client)) { console.log('sending population update create to client ' + client); results.push(ClientEndpoints.sendToEndpoint(client, { status: e.general.SUCCESS, info: 'POPULATION_UPDATE', payload: { added: newmodel.toClient() } })); } else { results.push(void 0); } } return results; }; })(this)); } ObjectManager.prototype.setup = function() { this.messageRouter.addTarget('registerForUpdatesOn', 'obj', this.onRegisterForUpdatesOn); this.messageRouter.addTarget('deRegisterForUpdatesOn', 'id,listenerid', this.onDeregisterForUpdatesOn); this.messageRouter.addTarget('updateObject', 'obj', this.onUpdateObject); this.messageRouter.addTarget('listTypes', '<noargs>', this.onListTypes); this.messageRouter.addTarget('getModelFor', 'modelname', this.onGetModelFor); this.messageRouter.addTarget('getAccessTypesFor', 'modelname', this.onGetAccessTypesFor); this.messageRouter.addTarget('registerForPopulationChangesFor', 'type', this.onRegisterForPopulationChanges); return this.messageRouter.addTarget('deRegisterForPopulationChangesFor', 'id,listenerid', this.onDeregisterForPopulationChanges); }; ObjectManager.prototype.registerUpdateObjectHook = function(hook) { return this.updateObjectHooks.push(hook); }; ObjectManager.prototype.getTypes = function() { var k, ref, types, v; types = []; ref = ResolveModule.modulecache; for (k in ref) { v = ref[k]; types.push(k.toLowerCase()); } return types; }; ObjectManager.prototype.onListTypes = function(msg) { var k, ref, types, v; types = []; ref = ResolveModule.modulecache; for (k in ref) { v = ref[k]; types.push(k); } return msg.replyFunc({ status: e.general.SUCCESS, info: 'list types', payload: types }); }; ObjectManager.prototype.onGetAccessTypesFor = function(msg) { var rv; if (msg.modelname) { rv = { create: this.messageRouter.authMgr.canUserCreateThisObject(msg.modelname, msg.user, msg.sessionId), read: this.messageRouter.authMgr.canUserReadFromThisObject(msg.modelname, msg.user, msg.sessionId), write: this.messageRouter.authMgr.canUserWriteToThisObject(msg.modelname, msg.user, msg.sessionId), list: this.messageRouter.authMgr.canUserListTheseObjects(msg.modelname, msg.user, msg.sessionId) }; return msg.replyFunc({ status: e.general.SUCCESS, info: 'access types for ' + msg.modelname, payload: rv }); } else { return msg.replyFunc({ status: e.general.FAILURE, info: "getAccessTypesFor missing parameter", payload: null }); } }; ObjectManager.prototype.onGetModelFor = function(msg) { if (msg.modelname) { return this.messageRouter.resolver.resolve(msg.modelname, (function(_this) { return function(path) { var rv; if (debug) { console.log('onGetModelFor ' + msg.modelname + ' got back require path ' + path); } rv = _this.getModelFor(msg.modelname); return msg.replyFunc({ status: e.general.SUCCESS, info: 'get model', payload: rv }); }; })(this)); } else { return msg.replyFunc({ status: e.general.FAILURE, info: "getModelFor missing parameter", payload: null }); } }; ObjectManager.prototype.getModelFor = function(modelname) { var k, model, ref, rv, v; model = ResolveModule.modulecache[modelname] || ResolveModule.modulecache[modelname.toLowerCase()]; if (!model) { ref = ResolveModule.modulecache; for (k in ref) { v = ref[k]; console.log('------- model in modulecache : ' + k); } } rv = []; model.model.forEach(function(property) { if (property["public"]) { return rv.push(property); } }); return rv; }; ObjectManager.prototype._createObject = function(msg) { var ref; console.log('objmgr.createObject called'); if (msg.obj && msg.obj.type) { if (ref = msg.obj.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { if (this.messageRouter.authMgr.canUserCreateThisObject(msg.obj.type, msg.user, msg.sessionId)) { if (debug) { console.dir(msg); } msg.obj.createdAt = Date.now(); msg.obj.modifiedAt = Date.now(); msg.obj.createdBy = msg.user.id; msg.obj.userRef = msg.user.id; return SuperModel.resolver.createObjectFrom(msg.obj).then((function(_this) { return function(o) { return o.serialize().then(function() { _this.messageRouter.gaugeMetric('create', 1, { type: msg.obj.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); return msg.replyFunc({ status: e.general.SUCCESS, info: 'new ' + msg.obj.type, payload: o }); }); }; })(this)); } else { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to create objects of that type', payload: msg.obj.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'unkown model type', payload: msg.obj.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: '_createObject missing parameter', payload: null }); } }; ObjectManager.prototype._deleteObject = function(msg) { var ref; if (msg.obj && msg.obj.type && msg.obj.id) { console.log('delete got type ' + msg.obj.type + ', and id ' + msg.obj.id); if (ref = msg.obj.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { return this.getObjectPullThrough(msg.obj.id, msg.obj.type).then((function(_this) { return function(obj) { if (obj) { if (_this.messageRouter.authMgr.canUserWriteToThisObject(obj, msg.user, msg.obj, msg.sessionId)) { return DB.remove(obj, function(removestatus) { var client, k, sublist; _this.messageRouter.gaugeMetric('delete', 1, { type: msg.obj.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); sublist = _this.populationListeners[msg.type] || {}; for (k in sublist) { client = sublist[k]; if (ClientEndpoints.exists(client)) { ClientEndpoints.sendToEndpoint(client, { status: e.general.SUCCESS, info: 'POPULATION_UPDATE', payload: { removed: obj.toClient() } }); } } objStore.removeObject(obj); return msg.replyFunc({ status: e.general.SUCCESS, info: 'delete object', payload: obj.id }); }); } else { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to delete object', payload: msg.obj.id }); } } else { console.log('No object found with id ' + msg.obj.id); console.dir(objStore.objects.map(function(o) { return o.type === msg.obj.type; })); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: e.gamemanager.NO_SUCH_OBJECT, payload: msg.obj.id }); } }; })(this)); } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'unkown model type', payload: msg.obj.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: '_deleteObject missing parameter', payload: null }); } }; ObjectManager.prototype._updateObject = function(msg) { return this.onUpdateObject(msg); }; ObjectManager.prototype._getObject = function(msg) { var id, ref; if (msg.type && ((msg.obj && msg.obj.id) || msg.id)) { if (ref = msg.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { id = msg.id || msg.obj.id; if (id.indexOf && id.indexOf('all_') > -1) { return this.getAggregateObjects(msg); } else { if (typeof id !== 'object') { return this.getObjectPullThrough(id, msg.type).then((function(_this) { return function(obj) { var tc; if (obj) { if (_this.messageRouter.authMgr.canUserReadFromThisObject(obj, msg.user, msg.sessionId)) { tc = obj.toClient(); _this.messageRouter.gaugeMetric('get', 1, { type: msg.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); if (_this.messageRouter.authMgr.filterOutgoing) { return _this.messageRouter.authMgr.filterOutgoing(tc, msg.user).then(function(ftc) { if (ftc) { if (debug) { console.log('_getObject for filteroutgoing ' + msg.type + ' returns ' + JSON.stringify(tc)); } return msg.replyFunc({ status: e.general.SUCCESS, info: 'update object', payload: ftc }); } else { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to read from that object', payload: obj.id, statuscode: 403 }); } }); } else { if (debug) { console.log('_getObject for ' + msg.type + ' returns ' + JSON.stringify(tc)); } return msg.replyFunc({ status: e.general.SUCCESS, info: 'get object', payload: tc }); } } else { console.log('_getObject got NOT ALLOWED for user ' + msg.user.id + ' for ' + msg.type + ' id ' + obj.id); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to read from that object', payload: id, statuscode: 403 }); } } else { console.log('_getObject No object found with id ' + id + ' of type ' + msg.type); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'no such object', payload: id, statuscode: 404 }); } }; })(this)); } else { console.log('_getObject provided id ' + id + ' of type ' + msg.type + ' is an object!!'); console.dir(id); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'id value is an object!!!', payload: id, statuscode: 400 }); } } } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'unkown model type', payload: msg.obj.type, statuscode: 417 }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: '_getObject for ' + msg.type + ' missing parameter', payload: null, statuscode: 417 }); } }; ObjectManager.prototype.getAggregateObjects = function(msg) { var obj, rv; if (!this.messageRouter.authMgr.canUserListTheseObjects(msg.type, msg.user, msg.sessionId)) { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to list objects of type ' + msg.type, payload: msg.type }); } else { rv = objStore.listObjectsByType(msg.obj.type); obj = { id: msg.obj.id, list: rv }; return msg.replyFunc({ status: e.general.SUCCESS, info: 'get object', payload: obj }); } }; ObjectManager.prototype._listObjects = function(msg) { var ref; if (typeof msg.type !== 'undefined') { if (ref = msg.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { if (this.messageRouter.authMgr.canUserListTheseObjects(msg.type, msg.user, msg.sessionId) === false) { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to list objects of type ' + msg.type, payload: msg.type }); } else { if (msg.query) { if (debug) { console.log('executing query for property ' + msg.query.property + ', value ' + msg.query.value); } if (msg.query.limit || msg.query.skip || msg.query.sort || msg.query.wildcard) { if (msg.query.value && msg.query.value !== '') { return DB.findQuery(msg.type, msg.query).then((function(_this) { return function(records) { return _this.parseList(records, msg); }; })(this)); } else { return DB.all(msg.type, msg.query, (function(_this) { return function(records) { return _this.parseList(records, msg); }; })(this)); } } else { return DB.findMany(msg.type, msg.query.property, msg.query.value).then((function(_this) { return function(records) { return _this.parseList(records, msg); }; })(this)); } } else { return DB.all(msg.type, msg.query, (function(_this) { return function(records) { return _this.parseList(records, msg); }; })(this)); } } } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'unkown model type', payload: msg.obj.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: '_listObjects missing parameter', payload: null }); } }; ObjectManager.prototype._countObjects = function(msg) { var ref; if (typeof msg.type !== 'undefined') { if (ref = msg.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { if (this.messageRouter.authMgr.canUserListTheseObjects(msg.type, msg.user, msg.sessionId) === false) { this.messageRouter.gaugeMetric('count', 1, { type: msg.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'not allowed to count objects of type ' + msg.type, payload: msg.type }); } else { return DB.count(msg.type).then((function(_this) { return function(v) { return msg.replyFunc({ status: e.general.SUCCESS, info: 'count objects', payload: v }); }; })(this)); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'unknown model type', payload: msg.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: '_listObjects missing parameter', payload: null }); } }; ObjectManager.prototype.parseList = function(_records, msg) { var checkFinish, count, rv; this.messageRouter.gaugeMetric('list', 1, { type: msg.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); checkFinish = (function(_this) { return function(rv) { if (--count === 0) { if (debug) { console.log('ObjectManager.parseList returns ' + rv.length + ' records'); } return msg.replyFunc({ status: e.general.SUCCESS, info: 'list objects', payload: rv }); } }; })(this); count = _records.length; if (debug) { console.log('ObjectManager.parseList resolving ' + count + ' records'); } if (count === 0) { if (debug) { console.log('ObjectManager.parseList -- returning empty set'); } return msg.replyFunc({ status: e.general.SUCCESS, info: 'list objects', payload: [] }); } else { rv = []; return _records.forEach((function(_this) { return function(r) { if (debug) { console.log('ObjectManager.parseList calling DB.get for id ' + r.id); } return DB.get(r.type, [r.id]).then(function(record) { var tc; if (record && record[0]) { tc = record[0]; if (_this.messageRouter.authMgr.filterOutgoing) { return _this.messageRouter.authMgr.filterOutgoing(tc, msg.user).then(function(tres) { if (debug) { console.log('parseList got reply from filterOutgoing and it was a ' + tres + ' count = ' + count); } if (debug) { console.dir(tres); } if (tres) { rv.push(tres); } return checkFinish(rv); }); } else { rv.push(tc); return checkFinish(rv); } } else { if (debug) { console.log(' empty records for ' + r.id); } return checkFinish(rv); } }); }; })(this)); } }; ObjectManager.prototype.expose = function(type) { objStore.types[type] = type; this.messageRouter.addTarget('_create' + type, 'obj', (function(_this) { return function(msg) { msg.type = type; return _this._createObject(msg); }; })(this)); this.messageRouter.addTarget('_delete' + type, 'obj', (function(_this) { return function(msg) { msg.type = type; return _this._deleteObject(msg); }; })(this)); this.messageRouter.addTarget('_update' + type, 'obj', (function(_this) { return function(msg) { msg.type = type; return _this._updateObject(msg); }; })(this)); this.messageRouter.addTarget('_get' + type, 'obj', (function(_this) { return function(msg) { msg.type = type; return _this._getObject(msg); }; })(this)); this.messageRouter.addTarget('_list' + type + 's', '<noargs>', (function(_this) { return function(msg) { msg.type = type; return _this._listObjects(msg); }; })(this)); return this.messageRouter.addTarget('_count' + type + 's', '<noargs>', (function(_this) { return function(msg) { msg.type = type; return _this._countObjects(msg); }; })(this)); }; ObjectManager.prototype.getObjectPullThrough = function(id, type) { var q; q = defer(); if (!type) { console.log('- Objectmanager::getObjectPullThrough called with null type.'); q.resolve(); } else if (!id || id === null || id === 'null') { console.log('- Objectmanager::getObjectPullThrough called with null id for type ' + type); q.resolve(); } else { objStore.getObject(id, type).then((function(_this) { return function(o) { if (!o) { if (debug) { console.log('- getObjectPullThrough did not find object type ' + type + ' id ' + id + ' in ostore, getting from db'); } return DB.get(type, [id]).then(function(record) { if (debug) { console.log('- getObjectPullThrough getting record from db'); } if (debug) { console.dir(record); } if (!record || !record[0] || record[0] === null) { if (debug) { console.log('- getObjectPullThrough got null record. resolving null'); } return q.resolve(null); } else { return _this.messageRouter.resolver.createObjectFrom(record).then(function(oo) { if (debug) { console.log('- getObjectPullThrough got object ' + oo.id + ' ' + oo.type); } return q.resolve(oo); }); } }); } else { return q.resolve(o); } }; })(this)); } return q; }; ObjectManager.prototype.onUpdateObject = function(msg) { var ref; if (msg.obj && msg.obj.type && msg.obj.id) { if (ref = msg.obj.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { return DB.getFromStoreOrDB(msg.obj.type, msg.obj.id).then((function(_this) { return function(obj) { var canwrite; if (obj) { canwrite = _this.messageRouter.authMgr.canUserWriteToThisObject(obj, msg.user, msg.obj, msg.sessionId); if (canwrite) { if (!_this.areDataTrashed(msg.obj)) { return _this.persistUpdates(obj, msg.obj).then(function(res) { if (!res) { return msg.replyFunc({ status: e.general.FAILURE, info: 'db error for object update', payload: msg.obj.id }); } else { _this.messageRouter.gaugeMetric('update', 1, { type: msg.obj.type, 'username': msg.user.name, 'useremail': msg.user.email, 'provider': msg.user.provider, 'organization': msg.user.organization }); return msg.replyFunc({ status: e.general.SUCCESS, info: e.gamemanager.UPDATE_OBJECT_SUCCESS, payload: msg.obj.id }); } }); } else { console.log('object update fail: data is TRASHED!!!!'); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'one or more arrays have ben contaminated with null values', payload: msg.obj.id }); } } else { console.log('object update fail: not allowed to write'); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: e.gamemanager.UPDATE_OBJECT_FAIL, payload: msg.obj.id }); } } else { console.log('No object of type ' + msg.obj.type + ' found with id ' + msg.obj.id); return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: e.gamemanager.NO_SUCH_OBJECT, payload: msg.obj.id }); } }; })(this)); } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'missing parameter(s) for object update', payload: msg.obj }); } } else { console.log('onUpdateObject got wrong or missing parameters'); console.dir(msg.obj); return msg.replyFunc({ status: e.general.FAILURE, info: 'missing parameter(s) for object update', payload: msg.obj }); } }; ObjectManager.prototype.persistUpdates = function(obj, robj, force) { var borked, model, q; q = defer(); model = this.getModelFor(obj.type); borked = false; model.forEach((function(_this) { return function(row) { if (row.array && robj[row.name] && !Array.isArray(robj[row.name])) { console.log('BORK detected for property ' + row.name); return borked = true; } }; })(this)); if (borked) { console.log('borketh object entered. scalar where there should be an array..'); console.log('---------------------------------------------------------------'); console.dir(robj); q.resolve(false); } else { obj.record = {}; model.forEach((function(_this) { return function(m) { var add, k, v; k = m.name; v = robj[k]; if (k !== 'id' && k !== 'type' && k !== 'createdAt' && k !== 'modifiedAt') { add = true; if (!v) { add = false; } if (add) { return obj.record[k] = v; } } }; })(this)); obj.loadFromIds(obj.constructor.model).then((function(_this) { return function() { objStore.storeObject(obj); objStore.updateObj(obj, force); if (debug) { console.log('persisting ' + obj.id + ' type ' + obj.type + ' in db. modifiedAt = ' + obj.modifiedAt + ' createdAt = ' + obj.createdAt); } return obj.serialize(robj).then(function(res) { var record; if (!res) { console.log('persisting failed'); console.dir(obj); return q.resolve(false); } else { record = obj.toClient(); _this.updateObjectHooks.forEach(function(hook) { return hook(record); }); return q.resolve(true); } }); }; })(this)); } return q; }; ObjectManager.prototype.areDataTrashed = function(obj) { var k, trashed, v; trashed = false; for (k in obj) { v = obj[k]; if (Array.isArray(v)) { v.forEach(function(el) { if (el === null || !el) { trashed = true; } }); } } return trashed; }; ObjectManager.prototype.onRegisterForUpdatesOn = function(msg) { if (msg.obj || !msg.obj.id || !msg.obj.type) { if (debug) { console.log('onRegisterForUpdatesOn called for ' + msg.obj.type + ' ' + msg.obj.id); } return DB.getFromStoreOrDB(msg.obj.type, msg.obj.id).then((function(_this) { return function(obj) { var listenerId, rememberedListenerId; if (obj && obj.id) { if (_this.messageRouter.authMgr.canUserReadFromThisObject(obj, msg.user, msg.sessionId)) { rememberedListenerId = void 0; listenerId = objStore.addListenerFor(msg.obj.id, msg.obj.type, function(uobj) { var toclient; toclient = uobj.toClient(); if (debug) { console.dir(toclient); } if (ClientEndpoints.exists(msg.client)) { return ClientEndpoints.sendToEndpoint(msg.client, { status: e.general.SUCCESS, info: 'OBJECT_UPDATE', payload: toclient }); } else { console.log('removing dangling endpoint from object updates for obj id ' + msg.id + ' and listenerId ' + rememberedListenerId); return objStore.removeListenerFor(msg.id, rememberedListenerId); } }); rememberedListenerId = listenerId; ClientEndpoints.onDisconnect(function(adr) { if (adr === msg.client) { return objStore.removeListenerFor(msg.obj.id, listenerId); } }); return msg.replyFunc({ status: e.general.SUCCESS, info: e.gamemanager.REGISTER_UPDATES, payload: listenerId }); } else { return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: 'Not allowed to register for updates on that object', payload: msg.obj.id }); } } else { if (debug) { console.log('Could not find object: ' + msg.obj.type + ' id ' + msg.obj.id); } return msg.replyFunc({ status: e.general.NOT_ALLOWED, info: e.gamemanager.NO_SUCH_OBJECT, payload: msg.obj.id }); } }; })(this), error); } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'onRegisterForUpdatesOn missing parameter', payload: null }); } }; ObjectManager.prototype.onDeregisterForUpdatesOn = function(msg) { if (debug) { console.log('onDeregisterForUpdatesOn called for id ' + msg.id + ' and listener id ' + msg.listenerid); } if (msg.id && msg.listenerid && msg.type) { objStore.removeListenerFor(msg.id, msg.listenerid); return msg.replyFunc({ status: e.general.SUCCESS, info: 'deregistered listener for object', payload: msg.id }); } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'onDeregisterForUpdatesOn missing parameter', payload: null }); } }; ObjectManager.prototype.onRegisterForPopulationChanges = function(msg) { var poplistenid, ref, sublist; if (msg.type) { if (ref = msg.type.toLowerCase(), indexOf.call(this.getTypes(), ref) >= 0) { poplistenid = uuid.v4(); sublist = this.populationListeners[msg.type] || {}; sublist[poplistenid] = msg.client; this.populationListeners[msg.type] = sublist; msg.replyFunc({ status: e.general.SUCCESS, info: 'registered for population changes for type ' + msg.type, payload: poplistenid }); return ClientEndpoints.onDisconnect((function(_this) { return function(adr) { if (adr === msg.client) { sublist = _this.populationListeners[msg.type] || {}; return delete sublist[poplistenid]; } }; })(this)); } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'onRegisterForPopulationChanges unknown type', payload: msg.type }); } } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'onRegisterForPopulationChanges missing parameter', payload: null }); } }; ObjectManager.prototype.onDeregisterForPopulationChanges = function(msg) { var sublist; if (msg.type && msg.listenerid) { sublist = this.populationListeners[msg.type] || {}; return delete sublist[poplistenid]; } else { return msg.replyFunc({ status: e.general.FAILURE, info: 'onDeregisterForPopulationChanges missing parameter', payload: null }); } }; ObjectManager.prototype.resolveReferences = function(record, model) { var checkFinished, count, q, rv; rv = { id: record.id }; q = defer(); count = model.length; checkFinished = function(pname) { if (--count === 0) { return q.resolve(rv); } }; model.forEach((function(_this) { return function(property) { var acount, arr, harr, hcount, resolvedarr, resolvedhash; if (property.array) { resolvedarr = []; arr = record[property.name] || []; arr = arr.filter(function(el) { return el && el !== null && el !== 'null' && el !== 'undefined'; }); acount = arr.length; if (acount === 0) { rv[property.name] = []; return checkFinished(property.name); } else { return arr.forEach(function(idorobj) { var id; id = idorobj; if (typeof idorobj === 'object') { id = idorobj.id; } return _this.getObjectPullThrough(id, property.type).then(function(o) { if (o) { resolvedarr.push(o); } if (--acount === 0) { rv[property.name] = resolvedarr; return checkFinished(property.name); } }); }); } } else if (property.hashtable) { if (debug) { console.log('======================================== going through hashtable property ' + property.name); } resolvedhash = {}; if (record[property.name]) { harr = record[property.name] || []; if (!harr.length) { harr = []; } if (debug) { console.dir(harr); } if (typeof harr === 'string') { harr = [harr]; } hcount = harr.length; if (!hcount || hcount === 0) { rv[property.name] = []; return checkFinished(property.name); } else { return harr.forEach(function(id) { return _this.getObjectPullThrough(id, property.type).then(function(o) { if (o) { resolvedhash[o.name] = o; } if (--hcount === 0) { rv[property.name] = resolvedhash; return checkFinished(property.name); } }); }); } } else { rv[property.name] = []; return checkFinished(property.name); } } else { if (property.type && property.value) { return _this.getObjectPullThrough(record[property.name], property.type).then(function(o) { rv[property.name] = o; return checkFinished(property.name); }); } else { rv[property.name] = record[property.name]; return checkFinished(property.name); } } }; })(this)); return q; }; return ObjectManager; })(); module.exports = ObjectManager; }).call(this); //# sourceMappingURL=ObjectManager.js.map