yatis 0.2.1

Yet Another T-bank Investment Sdk
Documentation
const wsErrorCodes = {
  1000: "Normal Closure",
  1001: "Going Away",
  1002: "Protocol error",
  1003: "Unsupported Data",
  1005: "No Status Rcvd",
  1006: "Abnormal Closure",
  1007: "Invalid frame payload data",
  1008: "Policy Violation",
  1009: "Message Too Big",
  1010: "Mandatory Ext.",
  1011: "Internal Error",
  1012: "Service Restart",
  1013: "Try Again Later",
  1014: "The server was acting as a gateway or proxy and received an invalid response from the upstream server.",
  1015: "TLS handshake",
  3000: "Unauthorized",
  3003: "Forbidden",
};
export default {
  state() {
    return {
      method: "unknown",
      request: { json: "{}" },
      responses: [],
      streamLog: [],
      connection_state: -1,
      websocketIndex: 0,
      websocket: null,
      url: "wss://invest-public-api.tinkoff.ru/ws/",
      method:
        "tinkoff.public.invest.api.contract.v1.MarketDataStreamService/MarketDataStream",
      error: null,
      token: sessionStorage
        ? sessionStorage.getItem("tinkoff.auth.token")
        : null,
      init: null,
      disposables: {},
    };
  },
  mutations: {
    init(state, init) {
      state.init = init;
    },
    onMessage(state, payload) {
      state.streamLog.push({
        id: state.streamLog.length,
        label: "message@" + new Date().toISOString(),
        type: "message",
        payload: payload,
        data: JSON.stringify(payload, null, 2),
      });
    },
    onError(state, error) {
      state.connection_state = -2;
      state.error = error;
    },
    onConnectPending(state, websocket) {
      if (state.connection_state == 1) {
        console.error("pending connection close error", state.websocket);
      }
      state.websocket = websocket;
      state.connection_state = 1;
      state.error = null;
      state.disposables[state.websocketIndex] = (() => {
        websocket.onclose = null;
        websocket.close();
      });
      state.websocketIndex = state.websocketIndex + 1;
    },
    onConnected(state) {
      state.connection_state = 0;
    },
    onDisconnect(state, index) {
      if (!index) index = state.websocketIndex;
      if (index < state.websocketIndex) {
        Object.keys(state.disposables)
        .filter(d => !!state.disposables[d])
        .filter(d => d < index)
        .forEach((d) => {
          state.disposables[d]();
          state.disposables[d] = null;
        });
      } else {
        if (state.websocket != null) {
          try {
            state.websocket.close();
          } catch (error) {
            console.error("error", error);
          }
        }
        state.connection_state = -1;
        state.websocket = null;
      }    
    },
    onSend(state, request) {
      state.request.json = request;
      state.streamLog.push({
        id: state.streamLog.length,
        label: "request@" + new Date().toISOString(),
        type: "request",
        data: request,
      });
    },
    onAuthToken(state, token) {
      state.token = token;
      if (sessionStorage) sessionStorage.setItem("tinkoff.auth.token", token);
    },
    updateRequest(state, request) {
      state.request.json = request;
    },
    onRouteChange(state, meta) {
      state.responses = [];
      state.streamLog = [];
      state.request = meta.request;
      state.method = meta.methodName.substr(1);
      state.error = null;

      Object.keys(state.disposables)
      .filter(d => !!state.disposables[d])
      .forEach((d) => state.disposables[d]());
      state.disposables = {};
      state.connection_state = -1;
      state.websocket = null;
    },
  },
  actions: {
    connect(context, params) {
      var state = context.state;
      var websocketIndex = state.websocketIndex;
      try {
        if (state.connection_state == 1) {
          console.error("connection is pending", context.state.websocket);
          return;
        } else if (state.connection_state == 0 && state.websocket != null) {
          context.commit("onSend", params);
          try {
            state.websocket.send(state.request.json);
          } catch (error) {
            console.error("error", error);
          }
          return;
        } else if (state.websocket != null) {
          try {
            state.websocket.close();
          } catch (error) {
            console.error("error", error);
          }
          context.commit("onDisconnect", websocketIndex);
        }
        if (!state.token) {
          context.commit("onError", "token required");
          return;
        }
        var ws = new WebSocket(state.url + state.method, [
          "json",
          state.token.trim(),
        ]);
        console.log("ws created", params);
        context.commit("onConnectPending", ws);
        context.commit("onSend", params);
        ws.onmessage = (e) => {
          var data = JSON.parse(e.data);
          context.commit("onMessage", data);
        };
        ws.onerror = (error) => {
          console.log("error", error);
          context.commit("onError", error);
          try {
            ws.close();
          } catch (error) {
            console.error("error", error);
          }

          context.commit("onDisconnect", websocketIndex);
        };
        ws.onopen = function () {
          try {
            ws.send(state.request.json);
            context.commit("onConnected");
          } catch (error) {
            try {
              ws.close();
            } catch (error) {
              console.error("error", error);
            }
            console.error("error", error);
            context.commit("onError", error);
          }
        };
        ws.onclose = (event) => {
          console.log("The connection has been closed", event);
          context.commit("onDisconnect", websocketIndex);
          if (state.init) {
            if (!event.code || event.code == 1000) {
              state.init.notifyOk(
                "The connection has been closed successfully."
              );
            } else {
              state.init.notifyError(
                "The connection has been closed with " +
                  (wsErrorCodes[event.code]
                    ? wsErrorCodes[event.code]
                    : event.code)
              );
            }
          }
        };
      } catch (error) {
        console.error("error", error);
        context.commit("onError", error);
      }
    },
    disconnect(context) {
      context.commit("onDisconnect");
    },
  },
};