{"size": 1596, "ext": "js", "max_stars_repo_path": "src/index.js", "max_stars_repo_name": "nuintun/microtask", "max_stars_repo_stars_event_min_datetime": "2020-06-03T23:25:38.000Z", "max_stars_repo_stars_event_max_datetime": "2020-06-03T23:25:38.000Z", "max_issues_repo_path": "src/index.js", "max_issues_repo_name": "nuintun/microtask", "max_issues_repo_issues_event_min_datetime": "2018-06-21T11:31:29.000Z", "max_issues_repo_issues_event_max_datetime": "2021-06-30T04:11:56.000Z", "max_forks_repo_path": "src/index.js", "max_forks_repo_name": "nuintun/microtask", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": 329, "max_forks_count": null, "avg_line_length": 18.7764705882, "max_line_length": 74, "alphanum_fraction": 0.6347117794}
/**
 * @module index
 * @author nuintun
 * @license MIT
 */

import Task from './task';
import promise from './schedule/promise';
import mutation from './schedule/mutation';
import channel from './schedule/channel';
import script from './schedule/script';
import timeout from './schedule/timeout';

var schedule;
var queue = [];
var draining = false;
// Use chain: promise > mutation > channel > script > timeout
var schedules = [promise, mutation, channel, script, timeout];

/**
 * @function drain
 */
function drain() {
  for (var i = 0; i < queue.length; i++) {
    queue[i].run();
  }

  queue = [];
  draining = false;
}

// Install schedule
for (var i = 0, length = schedules.length; i < length; i++) {
  schedule = schedules[i];

  if (schedule.support()) {
    schedule = schedule.install(drain);

    break;
  }
}

/**
 * @function slice
 * @description Faster slice arguments
 * @param {Array|arguments} args
 * @param {number} start
 * @returns {Array}
 * @see https://github.com/teambition/then.js
 */
function slice(args, start) {
  start = start >>> 0;

  var length = args.length;

  if (start >= length) {
    return [];
  }

  var rest = new Array(length - start);

  while (length-- > start) {
    rest[length - start] = args[length];
  }

  return rest;
}

/**
 * @function microtask
 * @param {Function} task
 */
export default function microtask(task) {
  var args = slice(arguments, 1);

  // Equivalent to push, but avoids a function call. It's faster then push
  queue[queue.length] = new Task(task, args);

  if (!draining) {
    draining = true;

    schedule();
  }
}
