File size: 1,737 Bytes
f56a29b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
'use strict';

function noop() {}

function getOptions(args) {
  // TODO: use `.at(-1)` when the API is available
  var lastArg = args.slice(-1)[0];

  if (typeof lastArg !== 'function') {
    return lastArg;
  }
}

function filterSuccess(elem) {
  return elem.state === 'success';
}

function filterError(elem) {
  return elem.state === 'error';
}

function pluckValue(elem) {
  return elem.value;
}

function buildOnSettled(done) {
  if (typeof done !== 'function') {
    done = noop;
  }

  function onSettled(error, result) {
    if (error) {
      return done(error, null);
    }

    if (!Array.isArray(result)) {
      result = [];
    }

    var settledErrors = result.filter(filterError);
    var settledResults = result.filter(filterSuccess);

    var errors = null;
    if (settledErrors.length) {
      errors = settledErrors.map(pluckValue);
    }

    var results = null;
    if (settledResults.length) {
      results = settledResults.map(pluckValue);
    }

    done(errors, results);
  }

  return onSettled;
}

function verifyArguments(args) {
  args = Array.prototype.concat.apply([], args);

  if (!args.length) {
    throw new Error('A set of functions to combine is required');
  }

  args.forEach(verifyEachArg);

  return args;
}

function verifyEachArg(arg, argIdx, args) {
  var isFunction = typeof arg === 'function';
  if (isFunction) {
    return;
  }

  if (argIdx === args.length - 1) {
    // Last arg can be an object of extension points
    return;
  }

  var msg =
    'Only functions can be combined, got ' +
    typeof arg +
    ' for argument ' +
    argIdx;
  throw new Error(msg);
}

module.exports = {
  getOptions: getOptions,
  onSettled: buildOnSettled,
  verifyArguments: verifyArguments,
};