--- /dev/null
+\r
+module.exports = function first(stuff, done) {\r
+ if (!Array.isArray(stuff))\r
+ throw new TypeError('arg must be an array of [ee, events...] arrays')\r
+\r
+ var cleanups = []\r
+\r
+ for (var i = 0; i < stuff.length; i++) {\r
+ var arr = stuff[i]\r
+\r
+ if (!Array.isArray(arr) || arr.length < 2)\r
+ throw new TypeError('each array member must be [ee, events...]')\r
+\r
+ var ee = arr[0]\r
+\r
+ for (var j = 1; j < arr.length; j++) {\r
+ var event = arr[j]\r
+ var fn = listener(event, callback)\r
+\r
+ // listen to the event\r
+ ee.on(event, fn)\r
+ // push this listener to the list of cleanups\r
+ cleanups.push({\r
+ ee: ee,\r
+ event: event,\r
+ fn: fn,\r
+ })\r
+ }\r
+ }\r
+\r
+ function callback() {\r
+ cleanup()\r
+ done.apply(null, arguments)\r
+ }\r
+\r
+ function cleanup() {\r
+ var x\r
+ for (var i = 0; i < cleanups.length; i++) {\r
+ x = cleanups[i]\r
+ x.ee.removeListener(x.event, x.fn)\r
+ }\r
+ }\r
+\r
+ function thunk(fn) {\r
+ done = fn\r
+ }\r
+\r
+ thunk.cancel = cleanup\r
+\r
+ return thunk\r
+}\r
+\r
+function listener(event, done) {\r
+ return function onevent(arg1) {\r
+ var args = new Array(arguments.length)\r
+ var ee = this\r
+ var err = event === 'error'\r
+ ? arg1\r
+ : null\r
+\r
+ // copy args to prevent arguments escaping scope\r
+ for (var i = 0; i < args.length; i++) {\r
+ args[i] = arguments[i]\r
+ }\r
+\r
+ done(err, ee, event, args)\r
+ }\r
+}\r