<commit_before>/*globals fdom:true, handleEvents, eachProp, Blob, ArrayBuffer */
/*jslint indent:2, white:true, node:true, sloppy:true, browser:true */
if (typeof fdom === 'undefined') {
  fdom = {};
}
fdom.proxy = fdom.proxy || {};

fdom.proxy.ApiInterface = function(def, onMsg, emit, id) {
  var inflight = {},
      events = null,
      emitter = null,
      reqId = 0;

  eachProp(def, function(prop, name) {
    switch(prop.type) {
      case 'property':
        //TODO(willscott): how should asynchronous properties work?
        break;
      case 'method':
        this[name] = function() {
          // Note: inflight should be registered before message is passed
          // in order to prepare for synchronous in-window pipes.
          var deferred = fdom.proxy.Deferred();
          inflight[reqId] = deferred;
          emit({
            to: id,
            action: 'method',
            type: name,
            reqId: reqId,
            value: fdom.proxy.conform(prop.value, arguments)
          });
          reqId += 1;
          return deferred.promise();
        };
        break;
      case 'event':
        if(!events) {
          handleEvents(this);
          emitter = this.emit;
          delete this.emit;
          events = {};
        }
        events[name] = prop;
        break;
    }
  }.bind(this));

  onMsg(function(type, msg) {
    if (!msg) {
      return;
    }
    if (type === 'method') {
      if (inflight[msg.reqId]) {
        var deferred = inflight[msg.reqId];
        delete inflight[msg.reqId];
        deferred.resolve(msg.value);
      } else {
        console.log('Dropped response message with id ' + msg.reqId);
      }
    } else if (type === 'event') {
      if (events[msg.type]) {
        emitter(msg.type, fdom.proxy.conform(events[msg.type].value, msg.value));
      }
    }
  }.bind(this));

  emit({
    'type': 'construct',
    'to': id
  });
};

/**
 * Force a collection of values to look like the types and length of an API template.
 */
fdom.proxy.conform = function(template, value) {
  switch(template) {
    case 'string':
      return String('') + value;
    case 'number':
      return Number(1) * value;
    case 'bool':
      return Boolean(value === true);
    case 'object':
      // TODO(willscott): Allow removal if sandboxing enforces this.
      return JSON.parse(JSON.stringify(value));
    case 'blob':
      return value instanceof Blob ? value : new Blob([]);
    case 'buffer':
      return value instanceof ArrayBuffer ? value : new ArrayBuffer(0);
    case 'data':
      // TODO(willscott): should be opaque to non-creator.
      return value;
    case 'proxy':
      if (Array.isArray(value)) {
        return value;
      } else {
        // TODO: make proxy.
        return value;
      }
  }
  var val, i;
  if (Array.isArray(template)) {
    val = [];
    i = 0;
    if (template.length === 2 && template[0] === 'array') {
      //console.log("template is array, value is " + JSON.stringify(value));
      for (i = 0; i < value.length; i += 1) {
        val.push(fdom.proxy.conform(template[1], value[i]));
      }
    } else {<commit_msg>linting errors picked up by jshint<commit_after>/*globals fdom:true, handleEvents, eachProp, Blob, ArrayBuffer */
/*jslint indent:2, white:true, node:true, sloppy:true, browser:true */
if (typeof fdom === 'undefined') {
  fdom = {};
}
fdom.proxy = fdom.proxy || {};

fdom.proxy.ApiInterface = function(def, onMsg, emit, id) {
  var inflight = {},
      events = null,
      emitter = null,
      reqId = 0;

  eachProp(def, function(prop, name) {
    switch(prop.type) {
    case 'property':
      //TODO(willscott): how should asynchronous properties work?
      break;
    case 'method':
      this[name] = function() {
        // Note: inflight should be registered before message is passed
        // in order to prepare for synchronous in-window pipes.
        var deferred = fdom.proxy.Deferred();
        inflight[reqId] = deferred;
        emit({
          to: id,
          action: 'method',
          type: name,
          reqId: reqId,
          value: fdom.proxy.conform(prop.value, arguments)
        });
        reqId += 1;
        return deferred.promise();
      };
      break;
    case 'event':
      if(!events) {
        handleEvents(this);
        emitter = this.emit;
        delete this.emit;
        events = {};
      }
      events[name] = prop;
      break;
    }
  }.bind(this));

  onMsg(function(type, msg) {
    if (!msg) {
      return;
    }
    if (type === 'method') {
      if (inflight[msg.reqId]) {
        var deferred = inflight[msg.reqId];
        delete inflight[msg.reqId];
        deferred.resolve(msg.value);
      } else {
        console.log('Dropped response message with id ' + msg.reqId);
      }
    } else if (type === 'event') {
      if (events[msg.type]) {
        emitter(msg.type, fdom.proxy.conform(events[msg.type].value, msg.value));
      }
    }
  }.bind(this));

  emit({
    'type': 'construct',
    'to': id
  });
};

/**
 * Force a collection of values to look like the types and length of an API template.
 */
fdom.proxy.conform = function(template, value) {
  switch(template) {
  case 'string':
    return String('') + value;
  case 'number':
    return Number(1) * value;
  case 'bool':
    return Boolean(value === true);
  case 'object':
    // TODO(willscott): Allow removal if sandboxing enforces this.
    return JSON.parse(JSON.stringify(value));
  case 'blob':
    return value instanceof Blob ? value : new Blob([]);
  case 'buffer':
    return value instanceof ArrayBuffer ? value : new ArrayBuffer(0);
  case 'data':
    // TODO(willscott): should be opaque to non-creator.
    return value;
  case 'proxy':
    if (Array.isArray(value)) {
      return value;
    } else {
      // TODO: make proxy.
      return value;
    }
  }
  var val, i;
  if (Array.isArray(template)) {
    val = [];
    i = 0;
    if (template.length === 2 && template[0] === 'array') {
      //console.log("template is array, value is " + JSON.stringify(value));
      for (i = 0; i < value.length; i += 1) {
        val.push(fdom.proxy.conform(template[1], value[i]));
      }
    } else {
{'fraction_non_alphanumeric': 0.14704453441295545, 'fraction_numerical': 0.003562753036437247, 'mean_word_length': 2.1933815925542914, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, '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': '6115871', 'n_tokens_mistral': 1971, 'n_tokens_neox': 1924, 'n_words': 513}