<commit_before>/// <reference path="../typings/main.d.ts" />

import debug = require('debug');
const EventEmitter = require('events');
const logEvents = debug('TelegramBotApi:events');
const log = debug('TelegramBotApi:update');
const _extend = require('lodash/extend');

import TelegramBotApiMethods from './telegram-bot-methods'

logEvents('init');

/**
 * @class TelegramBotApi
 */
export default class TelegramBotApi extends TelegramBotApiMethods{
  public events = new EventEmitter();

  public options = {
    autoUpdate: false,
    updateInterval: 1000,
    updateLimit: 50,
    updatePoolingTimeout: 0
  }

  /**
   * create a TelegramBotApi
   * @param {string} token
   * @param {Object} options
   */
  constructor(token?: string, options?: {
    autoUpdate?: boolean,
    updateInterval?: number
  }) {
    super(token)
    logEvents('constructor');
    _extend(this.options, options);

    if (this.options.autoUpdate) {
      this.startAutoUpdate();
    }
  }

  /**
   * Add event listener to events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  on(eventName: string, listener: Function) {
    logEvents(`on ${eventName}`);
    this.events.addListener(eventName, listener);
  }

  /**
   * Add one time event listener to events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  once(eventName: string, listener: Function) {
    logEvents(`once ${eventName}`);
    this.events.once(eventName, listener);
  }

  /**
   * Remove special listener from events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  off(eventName: string, listener: Function) {
    logEvents(`off ${eventName}`);
    this.events.removeListener(eventName, listener);
  }

  /**
   * Remove all listeners form events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  offAll(eventName?: string) {
    logEvents(`offAll ${eventName}`);
    if (eventName) {
      this.events.removeAllListeners(eventName);
    } else {
      this.events.removeAllListeners();
    }
  }

  /**
   * Emit special event
   * @param  {string} eventName
   * @param  {Function} listener
   */
  emit(eventName: string, ...args) {
    logEvents(`Emit ${eventName}`);
    this.events.emit(eventName, ...args);
  }

  private _setTimeout: NodeJS.Timer;

  private _updateOffset: number = 0;

  static async _getUpdates(_this: TelegramBotApi) {
    log('_getUpdates');

    try {
      let data = await _this.getUpdates({
        offset: _this._updateOffset,
        limit: _this.options.updateLimit,
        timeout: _this.options.updatePoolingTimeout
      });

      if(data && data.ok && data.result) {
        data.result.forEach((item) => {
          _this._updateOffset = item.update_id + 1;

          let eventName;
          if ('message' in item) eventName = 'message';
          if ('inline_query' in item) eventName = 'inline_query';
          if ('chosen_inline_result' in item) eventName = 'chosen_inline_result';
          if ('callback_query' in item) eventName = 'callback_query';

          setImmediate(() => {
            _this.events.emit('update', data);
            _this.events.emit(`update.${eventName}`, data);
          });
        });
      }
    }<commit_msg>perf(events): skip for on empty results<commit_after>/// <reference path="../typings/main.d.ts" />

import debug = require('debug');
const EventEmitter = require('events');
const logEvents = debug('TelegramBotApi:events');
const log = debug('TelegramBotApi:update');
const _extend = require('lodash/extend');

import TelegramBotApiMethods from './telegram-bot-methods'

logEvents('init');

/**
 * @class TelegramBotApi
 */
export default class TelegramBotApi extends TelegramBotApiMethods{
  public events = new EventEmitter();

  public options = {
    autoUpdate: false,
    updateInterval: 1000,
    updateLimit: 50,
    updatePoolingTimeout: 0
  }

  /**
   * create a TelegramBotApi
   * @param {string} token
   * @param {Object} options
   */
  constructor(token?: string, options?: {
    autoUpdate?: boolean,
    updateInterval?: number
  }) {
    super(token)
    logEvents('constructor');
    _extend(this.options, options);

    if (this.options.autoUpdate) {
      this.startAutoUpdate();
    }
  }

  /**
   * Add event listener to events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  on(eventName: string, listener: Function) {
    logEvents(`on ${eventName}`);
    this.events.addListener(eventName, listener);
  }

  /**
   * Add one time event listener to events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  once(eventName: string, listener: Function) {
    logEvents(`once ${eventName}`);
    this.events.once(eventName, listener);
  }

  /**
   * Remove special listener from events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  off(eventName: string, listener: Function) {
    logEvents(`off ${eventName}`);
    this.events.removeListener(eventName, listener);
  }

  /**
   * Remove all listeners form events
   * @param  {string} eventName
   * @param  {Function} listener
   */
  offAll(eventName?: string) {
    logEvents(`offAll ${eventName}`);
    if (eventName) {
      this.events.removeAllListeners(eventName);
    } else {
      this.events.removeAllListeners();
    }
  }

  /**
   * Emit special event
   * @param  {string} eventName
   * @param  {Function} listener
   */
  emit(eventName: string, ...args) {
    logEvents(`Emit ${eventName}`);
    this.events.emit(eventName, ...args);
  }

  private _setTimeout: NodeJS.Timer;

  private _updateOffset: number = 0;

  static async _getUpdates(_this: TelegramBotApi) {
    log('_getUpdates');

    try {
      let data = await _this.getUpdates({
        offset: _this._updateOffset,
        limit: _this.options.updateLimit,
        timeout: _this.options.updatePoolingTimeout
      });

      if(data && data.ok && data.result && data.result.length) {
        log('new update');
        data.result.forEach((item) => {
          _this._updateOffset = item.update_id + 1;

          let eventName;
          if ('message' in item) eventName = 'message';
          if ('inline_query' in item) eventName = 'inline_query';
          if ('chosen_inline_result' in item) eventName = 'chosen_inline_result';
          if ('callback_query' in item) eventName = 'callback_query';

          setImmediate(() => {
            _this.events.emit('update', data);
            _this.events.emit(`update.${eventName}`, data);
            }

          });
        });
      }
    }
{'fraction_non_alphanumeric': 0.1379677517493155, 'fraction_numerical': 0.0027380590203833284, 'mean_word_length': 2.9277180406212664, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '91170', 'n_tokens_mistral': 2034, 'n_tokens_neox': 2001, 'n_words': 456}