You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.9 KiB
174 lines
4.9 KiB
/**
|
|
* @module flitter-socket/Transaction
|
|
*/
|
|
|
|
const uuid = require('uuid/v4')
|
|
|
|
/**
|
|
* Object representing one exchange between two parties in
|
|
* a websocket connection. Handles response sending and request
|
|
* data.
|
|
* @class
|
|
*/
|
|
class Transaction {
|
|
|
|
constructor(data, connection_manager){
|
|
/**
|
|
* Whether the transaction has completed. That is, has the
|
|
* recipient sent a response.
|
|
* @type {boolean}
|
|
*/
|
|
this.resolved = false
|
|
|
|
/**
|
|
* Universally-unique id of this transaction. Used by both
|
|
* parties to match up requests and responses.
|
|
* @type {string}
|
|
*/
|
|
this.id = data.transaction_id ? data.transaction_id : uuid()
|
|
|
|
/**
|
|
* The open websocket used for communication
|
|
* @type {Socket}
|
|
*/
|
|
this.socket = connection_manager.socket
|
|
|
|
/**
|
|
* Contains the outgoing data for the transaction.
|
|
* That is, the data sent/to be sent back to the sender.
|
|
* @type {Object}
|
|
*/
|
|
this.outgoing = data.outgoing ? data.outgoing : {}
|
|
|
|
/**
|
|
* Contains the incoming data for the transaction.
|
|
* That is, the data from the sender.
|
|
* @type {Object}
|
|
*/
|
|
this.incoming = data.incoming ? data.incoming : {}
|
|
|
|
/**
|
|
* Unique ID of the websocket client's connection in the connection manager.
|
|
* @type {string}
|
|
*/
|
|
this.connection_id = connection_manager.id
|
|
|
|
/**
|
|
* Is this a request or a response-type transaction?
|
|
* @type {"request"|"response"}
|
|
*/
|
|
this.type = data.type ? data.type : 'request'
|
|
|
|
/**
|
|
* Set to true if 1. this transaction is a response and 2. the response has been sent
|
|
* @type {boolean}
|
|
*/
|
|
this.sent = false
|
|
|
|
/**
|
|
* Set to true if 1. the transaction was awaiting data and 2. the data has been received
|
|
* @type {boolean}
|
|
*/
|
|
this.received = false
|
|
|
|
/**
|
|
* HTTP-equivalent status code for this transaction. Use this.status() to get/set.
|
|
* @type {number}
|
|
* @private
|
|
*/
|
|
this._status = 200
|
|
|
|
/**
|
|
* Message to be included in the response. User this.message() to get/set.
|
|
* @type {string}
|
|
* @private
|
|
*/
|
|
this._message = ""
|
|
|
|
/**
|
|
* The connection manager that spawned this transaction.
|
|
* @type {module:flitter-socket/ConnectionManager~ConnectionManager}
|
|
*/
|
|
this.cm = connection_manager
|
|
}
|
|
|
|
/**
|
|
* Mark the transaction as resolved.
|
|
*/
|
|
resolve(){
|
|
this.resolved = true
|
|
}
|
|
|
|
/**
|
|
* Get or set the status code. If a new code is provided, set the status code and return
|
|
* this for chaining. Otherwise, get the current status code.
|
|
* @param {number} [code]
|
|
* @returns {Transaction|number} - if code is provided, set the code and return this; otherwise return the current code
|
|
*/
|
|
status(code = null){
|
|
if ( code ){
|
|
this._status = code
|
|
return this
|
|
}
|
|
|
|
return this._status
|
|
}
|
|
|
|
/**
|
|
* Get or set the message. If a new message is provided, set the message and return
|
|
* this for chaining. Otherwise get the current message.
|
|
* @param {string} [msg]
|
|
* @returns {Transaction|string} - if message is provided, set the message and return this; otherwise return the current message
|
|
*/
|
|
message(msg = null){
|
|
if ( msg ){
|
|
this._message = msg
|
|
return this
|
|
}
|
|
|
|
return this._message
|
|
}
|
|
|
|
/**
|
|
* Send data to the recipient of this transaction as stringified JSON, and resolve the transaction.
|
|
* @param data
|
|
* @returns {*|boolean|void}
|
|
*/
|
|
send(data){
|
|
if ( this.type === 'request' ){
|
|
if ( this.resolved ) throw new Error(`Transaction can only be sent once per request. (ID: ${this.id})`)
|
|
|
|
const obj = {
|
|
status: this._status,
|
|
transaction_id: this.id,
|
|
type: 'response',
|
|
... (this._message && {message: this._message}),
|
|
... (data && {data}),
|
|
... ((!data && this.outgoing) && {data: this.outgoing})
|
|
}
|
|
|
|
this.json = JSON.stringify(obj)
|
|
this.resolve()
|
|
}
|
|
else if ( this.type === 'response' ){
|
|
if ( this.sent ) throw new Error(`Request can only be sent once per Transaction. (ID: ${this.id})`)
|
|
|
|
const obj = {
|
|
endpoint: this.endpoint,
|
|
transaction_id: this.id,
|
|
type: 'request',
|
|
... (data && {data}),
|
|
... ((!data && this.outgoing) && {data: this.outgoing})
|
|
}
|
|
|
|
this.json = JSON.stringify(obj)
|
|
}
|
|
|
|
this.sent = true
|
|
return this.socket.send(this.json)
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = exports = Transaction
|