UNPKG

meses-messaging

Version:

Meses messaging SDK in JavaScript

225 lines (202 loc) 7.68 kB
import MesesMessagingService from './services/MesesMessagingService' import Conversation from './classes/Conversation' import PreviousConversationListQuery from './classes/PreviousConversationListQuery' import ConversationUpdateHandler from './classes/ConversationUpdateHandler' import NewMessageUpdateHandler from './classes/NewMessageUpdateHandler' class MesesMessagingApp { constructor(uri, applicationId) { this._service = new MesesMessagingService(uri, applicationId) this._user = null this._updateHandlers = [] } onBeforeDisconnect() { } /** * Connect client app with a user * * @param {String} username - an entity name * @return {Promise} user and its properties if connect succeeded (fulfilled). */ connect(username) { if (this._user && this._user.username != username) { this.onBeforeDisconnect() this.detachAllUpdateHandlers() } const service = this._service return new Promise(function(resolve, reject) { service.getEntity(username) .then(function(result) { this._user = Object.assign({ username: username }, result) resolve(this._user) }.bind(this)) .catch(err => reject(err)) }.bind(this)) } /** * Disconnect client app from the connected user * This method will also detach all update handlers * * @return {Promise} fulfilled if disconnect succeeded. */ disconnect() { return new Promise(function(resolve, reject) { if (this._user == null) reject('USER_NOT_CONNECTED') else { this.onBeforeDisconnect() this.detachAllUpdateHandlers() this._user = null; resolve() } }.bind(this)) } /** * Create a new entity with the specified properties * * @param {String} username - entity name of the new user * @param {String} displayName - name that will be displayed in messaging UI * @param {Object} properties * @return {Promise} new user and its properties if user creation succeeded (fulfilled). */ createUser(username, displayName, properties) { const service = this._service return new Promise(function(resolve, reject) { service.checkEntityNotExists(username) .then(result => { service.createEntity(username, displayName, properties) }) .then(() => { resolve(Object.assign({ username: username }, properties)) }) .catch(err => reject(err)) }) } /** * Append/update properties of the currently connected user. * This method will also update the connected user with new properties. * * @param {Object} properties * @return {Promise} new user state if update user succeeded (fulfilled). */ updateUserInfo(properties) { return new Promise(function(resolve, reject) { if (this._user == null) { reject('USER_NOT_CONNECTED') } else { const username = this._user.username const service = this._service service.upsertEntityProperties(username, properties) .then(function() { this._user = Object.assign(this._user, properties) resolve(this._user) }.bind(this)) .catch(err => reject(err)) } }.bind(this)) } /** * Retrieve a conversation object of the specified conversation name. * * @param {String} conversationName * @return {Promise} Conversation and its properties if retrieval succeeded (fulfilled). */ getConversation(conversationName) { if (this._user == null) return new Promise(function(resolve, reject) { reject('USER_NOT_CONNECTED')} ) const username = this._user.username const service = this._service return new Promise(function(resolve, reject) { service.getConversation(conversationName) .then(properties => resolve(new Conversation(service, conversationName, username, properties))) .catch(err => reject(err)) }) } /** * Create a new conversation with specified properties and subscribers * * @param {String} conversationName * @param {String} title * @param {Object} properties * @param {Array.<String>} subscribers - array of subscriber names * @return {Promise} Conversation and its properties if creation succeeded (fulfilled). */ createConversation(conversationName, title, properties, subscribers) { if (this._user == null) return new Promise(function(resolve, reject) { reject('USER_NOT_CONNECTED') }) const username = this._user.username const service = this._service return new Promise(function(resolve, reject) { service.checkConversationNotExists(conversationName) .then(() => service.createConversation(conversationName, title, properties)) .then(() => { let found = subscribers.find(name => name === username) if (!found) subscribers.push(username) return service.createSubscriptions(conversationName, subscribers) }) .then(() => service.getConversation(conversationName)) .then(result => { resolve(new Conversation(service, conversationName, username, result)) }) .catch(err => reject(err)) }) } /** * Create a previous conversation list query. * * @param {Number} start - query param for first conversation's message time * @return {PreviousConversationListQuery} * @throws {Error} if user is not connected */ createPreviousConversationListQuery(start) { if (this._user == null) throw new Error('USER_NOT_CONNECTED') start = start ? start : null const service = this._service const username = this._user.username return new PreviousConversationListQuery(service, username, start) } /** * Create a conversation update handler. * * @param {String} identifier - unique identifier of update handler * @param {Function(err, result)} callback function for conversation updates * @param {Number} timeout - refresh rate (in milliseconds) * @return {ConversationUpdateHandler} * @throws {Error} if user is not connected */ createConversationUpdateHandler(identifier, callback, timeout) { if (this._user == null) throw new Error('USER_NOT_CONNECTED') const service = this._service const username = this._user.username return new ConversationUpdateHandler(service, username, identifier, callback, timeout) } /** * Attach an update handler * * @param {ConversationUpdateHandler | NewMessageUpdateHandler} handler - update handler * @return {Void} * @throws {Error} if invalid handler type */ attachUpdateHandler(handler) { if (handler instanceof ConversationUpdateHandler || handler instanceof NewMessageUpdateHandler) { let found = this._updateHandlers.find(x => { return x._identifier === handler._identifier && x.constructor.name === handler.constructor.name }) if (found == null) { this._updateHandlers.push(handler) handler.activate() } } else throw new Error('INVALID_HANDLER_TYPE') } /** * Detach all update handlers * * @return {Void} */ detachAllUpdateHandlers() { this._updateHandlers.map(x => x.destroy()); this._updateHandlers = [] } /** * Detach update handler with specified identifier * * @param {String} identifier * @return {Void} */ detachUpdateHandler(identifier) { let indexes = [] this._updateHandlers.map(function(x, i) { if (x._identifier === identifier) { x.destroy(); indexes.push(i) } }) indexes.reverse() indexes.map(function(x) { this._updateHandlers.splice(x, 1) } .bind(this)) } } export default MesesMessagingApp