"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const isomorphic_ws_1 = tslib_1.__importDefault(require("isomorphic-ws"));
const log_1 = tslib_1.__importDefault(require("../log"));
/**
 * An adapter to use any kind of websocket and interface it with
 * a browser compatible type of websocket
 */
class WebSocketAdapter {
    constructor(path) {
        this.path = path;
    }
}
exports.WebSocketAdapter = WebSocketAdapter;
/**
 * This adapter basically binds the browser websocket interface. Note that
 * the websocket will try to open right after instantiation.
 */
class BrowserWebSocketAdapter extends WebSocketAdapter {
    constructor(path) {
        super(path);
        this.ws = new isomorphic_ws_1.default(path);
        // to prevent the browser to use blob
        this.ws.binaryType = "arraybuffer";
    }
    /** @inheritdoc */
    onOpen(callback) {
        this.ws.onopen = callback;
    }
    /** @inheritdoc */
    onMessage(callback) {
        this.ws.onmessage = (evt) => {
            if (evt.data instanceof Buffer || evt.data instanceof ArrayBuffer) {
                callback(Buffer.from(evt.data));
            }
            else {
                // In theory, any type of data could be sent through but we only
                // allow protobuf encoded messages
                log_1.default.lvl2(`got an unknown websocket message type: ${typeof evt.data}`);
            }
        };
    }
    /** @inheritdoc */
    onClose(callback) {
        this.ws.onclose = (evt) => {
            callback(evt.code, evt.reason);
        };
    }
    /** @inheritdoc */
    onError(callback) {
        this.ws.onerror = (evt) => {
            callback(evt.error);
        };
    }
    /** @inheritdoc */
    send(bytes) {
        this.ws.send(bytes);
    }
    /** @inheritdoc */
    close(code, reason = "") {
        this.ws.close(code, reason);
    }
}
exports.BrowserWebSocketAdapter = BrowserWebSocketAdapter;
