Source: osc/osc-server.js

const osc = require('node-osc');
const { EventEmitter } = require('events');

/**
 * A class used to receive messages from the Sonic Pi server.
 */
class SonicPiOSCServer {

  /**
   * Creates an instance of the `SonicPiOSCServer` Class
   * @constructor
   * @classdesc A class used to receive and acknowledge messages from the Sonic Pi server.
   * @param {string} ip - the IP address of this OSC server
   * @param {number} port - the port to listen on
   * @param {string} spider_ip - the IP address of the Sonic Pi server
   * @param {number} spider_port - the port to send acknowledgements to
   *
   */
  constructor(ip, port, spider_ip, spider_port) {
    let _this = this;

    this.m_port = port;
    this.m_ip = ip;
    this.emitter = new EventEmitter();
    this.osc_client = new osc.Client(spider_ip, spider_port);

    this.osc_server = new osc.Server(port, ip, () => {
      console.log(`OSC server is listening on ${ip}:${port}`);
    });

    this.osc_server.on('message', function (msg) {
      switch (msg[0]) {
        /**
         * Logging
         *
         * @event SonicPiOSCServer#log
         * @type {object}
         * @property {string} type - `info`, `error` or `multi_message`
         * @property {object[]} message_info - Varies depending on the type
         */
        case "/log/info":
          _this.emitter.emit('log', {
            type: "info",
            message_info: msg.slice(1)
          });
          break;
        case "/log/error":
          _this.emitter.emit('log', {
            type: "error",
            message_info: msg.slice(1)
          });
          break;
        case "/log/multi_message":
          _this.emitter.emit('log', {
            type: "multi_message",
            message_info: msg.slice(1)
          });
          break;

        // Boot errors
        case "/exited-with-boot-error":
          var info = {
            message: msg[1]
          };
          _this.emitter.emit("boot_error", info);
          break;


        /**
         * Runtime/syntax errors
         *
         * @event SonicPiOSCServer#error
         * @type {object}
         * @property {string} type - Either `runtime_error` or `syntax_error`
         * @property {number} job_id
         * @property {string} message
         * @property {number} line_number
         * @property {string} line_number_string - Syntax errors only
         * @property {string} line_string - Syntax errors only
         * @property {string} backtrace - Runtime errors only
         */
        case "/error":
          var error_info = {
            type: "runtime_error",
            job_id: parseInt(msg[1]),
            message: msg[2],
            backtrace: msg[3],
            line_number: parseInt(msg[4])
          }
          _this.emitter.emit("error", error_info);
          break;
        case "/syntax_error":
          var error_info = {
            type: "syntax_error",
            job_id: parseInt(msg[1]),
            message: msg[2],
            line_string: msg[3],
            line_number: parseInt(msg[4]),
            line_number_string: msg[5]
          }
          _this.emitter.emit("error", error_info);
          break;

        /**
         * Emitted when the Sonic Pi server exits.
         *
         * @event SonicPiOSCServer#exited
         */
        case "/exited":
          _this.emitter.emit('exited');

        /**
         * Emitted when the Sonic Pi server acknowledges a message.
         *
         * @event SonicPiOSCServer#ack
         * @type {object}
         * @property {object} id
         */
        case "/ack":
          var info = {
            id: msg[1]
          }
          _this.emitter.emit('ack', info);

        default:

      }
      console.log(`Message recieved: ${msg}`);
      _this.osc_client.send("/ack");
    })
  }

  destructor() {
    this.osc_server.close();
    this.emitter.dispose();
  }
}

module.exports = {
  SonicPiOSCServer
};