All files / src/payload-stack index.js

100% Statements 16/16
100% Branches 2/2
100% Functions 4/4
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63  1x 1x                         11x 11x               11x                     8x 8x 8x   8x 1x     7x 7x   7x   7x                 7x       1x  
const
Payload                 = require('./payload'),
IncompleteMessageError  = require('./error/incomplete-message')
 
/**
 * Stacking payloads in a buffer. When you recieve a message through the
 * network, it's added to the stack. As mesages can come in partial chunks,
 * they need to be buffered until we have recieved the complete message.
 * Messages can also be recieved in a batch of multiple messages, requiring an
 * instance to segregate the message stack.
 */
class PayloadStack
{
  static from()
  {
    const buffer = Buffer.from('')
    return new PayloadStack(buffer)
  }
 
  /**
   * @param {Buffer} buffer initial buffer
   */
  constructor(buffer)
  {
    this.stack = buffer
  }
 
  /**
   * Attempts to cut out the first message of the stack
   * @throws ERR_OUT_OF_RANGE
   * @throws ERR_INCOMPLETE_MESSAGE
   */
  shift()
  {
    const
    headerSize  = Payload.HEADER_SIZE,
    dtoSize     = this.stack.readInt32BE(0),
    payloadSize = dtoSize + headerSize
 
    if(this.stack.length < payloadSize)
      throw new IncompleteMessageError
 
    const
    payload = this.stack.slice(headerSize, payloadSize).toString(),
    dto     = JSON.parse(payload)
 
    this.stack  = this.stack.slice(payloadSize)
 
    return new Payload(dto.event, dto.data)
  }
 
  /**
   * Adds a buffer to the stack
   * @param {...Buffer} buffer buffers to add to the stack
   */
  push(...buffer)
  {
    this.stack = Buffer.concat([this.stack, ...buffer])
  }
}
 
module.exports = PayloadStack