-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
95 lines (72 loc) · 2.11 KB
/
index.js
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";
var partial = require("ap").partial
, slice = Array.prototype.slice
, globalScope = typeof global === "undefined" ? window : global
compose.async = composeAsync
compose.cc = cc
module.exports = compose
function compose() {
return slice.call(arguments).reduce(combineFunctions)
}
function combineFunctions(memo, current) {
return partial(applyInOrder, current, memo)
}
function applyInOrder(first, second) {
var result = first.apply(this, slice.call(arguments, 2))
if (Array.isArray(result)) {
return second.apply(this, result)
}
return second.call(this, result)
}
function composeAsync() {
return createAsyncComposite(slice.call(arguments))
}
function createAsyncComposite(fns) {
var index = fns.length - 1
, thisValue
, finishCallback
return callFirst
function callNext() {
var args = slice.call(arguments)
, f = fns[index--]
, functionIndex = f.length - 1
, callbackIndex = args.length
if (callbackIndex < functionIndex) {
callbackIndex = functionIndex
}
if (index === -1) {
args[callbackIndex] = finishCallback
} else {
args[callbackIndex] = callNext
}
f.apply(thisValue, args)
}
function callFirst() {
var args = slice.call(arguments)
, f = fns[index--]
, functionIndex = f.length - 1
, callbackIndex = args.length
, lastArg = args[callbackIndex - 1]
thisValue = this
if (typeof lastArg === "function") {
finishCallback = lastArg.bind(thisValue)
args.pop()
callbackIndex--
}
if (callbackIndex < functionIndex) {
callbackIndex = functionIndex
}
args[callbackIndex] = callNext
f.apply(thisValue, args)
}
}
function cc() {
var composite = composeAsync.apply(null, arguments)
return caller
function caller() {
var args = [].slice.call(arguments)
args.push(noop)
composite.apply({}, args)
}
}
function noop() {}