/*global Blob, Polymer, Worker, window */
(function () {

	"use strict";

	Polymer({
		is: 'cosmoz-web-worker',
		properties: {
			/**
			 * Number of workers to create for round robin distribution of work
			 * @type Number
			 */
			numThreads: {
				type: Number,
				value: 2
			},
			_callbacks: {
				type: Object,
				value: function () {
					return {};
				}
			},
			_currentThreadIndex: {
				type: Number,
				value: 0
			},
			_threads: {
				type: Array,
				value: function () {
					return [];
				}
			},
			_workerRun: {
				type: Number,
				value: 0
			}
		},
		/**
		 * The process method will relay data to the available worker thread
		 * @param  {Mixed} data The data for the worker
		 */
		process: function (data) {
			this._threads[this._currentThreadIndex].postMessage(data);
			if (this._currentThreadIndex + 1 < this.numThreads) {
				this._currentThreadIndex += 1;
			} else if (this._currentThreadIndex > 0) {
				this._currentThreadIndex  = 0;
			}
		},
		processWithCallback: function (data, callback) {
			this._workerRun += 1;
			this._callbacks[this._workerRun] = callback;
			this.process({ workerRun: this._workerRun, data: data });
		},
		ready: function () {
			var i = 0,
				jsMimeType = { type: "text/javascript" },
				worker,
				workerScriptType = 'script[type="text/worker"]',
				workerScripts = Polymer.dom(this).querySelectorAll(workerScriptType),
				workerCodeExtractor = function (oScript) { return oScript.textContent; },
				workerCode = Array.prototype.map.call(workerScripts, workerCodeExtractor),
				workerMessageHandler = this._handleWorkerMessage.bind(this),
				blob = new Blob(workerCode, jsMimeType),
				objectUrl = window.URL.createObjectURL(blob);

			for (i = 0; i < this.numThreads; i += 1) {
				worker = new Worker(objectUrl);
				worker.addEventListener('message', workerMessageHandler);
				this._threads.push(worker);
			}
		},
		_handleWorkerMessage: function (event) {
			var callback,
				data = event.data,
				workerRun = event.data.workerRun;

			if (workerRun) {
				callback = this._callbacks[workerRun];
				data = data.data;
				if (callback) {
					callback(data);
					delete this._callbacks[workerRun];
				}
			}
			this.fire('message', data);
		}
	});
}());
@@ -700,16 +700,93 @@
  worker%0A
+%09%09 * @param  %7BFunction%7D callback (optional) Callback to run for the response%0A
 %09%09 */%0A%09%09
@@ -808,16 +808,26 @@
 on (data
+, callback
 ) %7B%0A%09%09%09t
@@ -835,428 +835,399 @@
 is._
-threads%5Bthis._currentThreadIndex%5D.postMessage(data);%0A%09%09%09if (this._currentThreadIndex + 1 %3C this.numThreads) %7B%0A%09%09%09%09this._currentThreadIndex += 1;%0A%09%09%09%7D else if (this._currentThreadIndex %3E 0) %7B%0A%09%09%09%09this._currentThreadIndex  = 0;%0A%09%09%09%7D%0A%09%09%7D,%0A%09%09processWithCallback: function (data, callback) %7B%0A%09%09%09this._workerRun += 1;%0A%09%09%09this._callbacks%5Bthis._workerRun%5D = callback;%0A%09%09%09this.process(%7B workerRun: this._workerRun, data: data %7D);
+workerRun += 1;%0A%09%09%09if (callback !== undefined) %7B%0A%09%09%09%09this._callbacks%5Bthis._workerRun%5D = callback;%0A%09%09%09%7D%0A%09%09%09this._threads%5Bthis._currentThreadIndex%5D.postMessage(%7B%0A%09%09%09%09workerRun: this._workerRun,%0A%09%09%09%09data: data%0A%09%09%09%7D);%0A%09%09%09if (this._currentThreadIndex + 1 %3C this.numThreads) %7B%0A%09%09%09%09this._currentThreadIndex += 1;%0A%09%09%09%7D else if (this._currentThreadIndex %3E 0) %7B%0A%09%09%09%09this._currentThreadIndex  = 0;%0A%09%09%09%7D
 %0A%09%09%7D
@@ -2008,22 +2008,8 @@
 var 
-callback,%0A%09%09%09%09
 data
@@ -2021,16 +2021,21 @@
 ent.data
+.data
 ,%0A%09%09%09%09wo
@@ -2068,30 +2068,9 @@
 rRun
-;%0A%0A%09%09%09if (workerRun) %7B
+,
 %0A%09%09%09
@@ -2113,34 +2113,12 @@
 n%5D;%0A
-%09%09%09%09data = data.data;
 %0A%09%09%09
-%09
 if (
@@ -2125,25 +2125,24 @@
 callback) %7B%0A
-%09
 %09%09%09%09callback
@@ -2153,17 +2153,16 @@
 a);%0A%09%09%09%09
-%09
 delete t
@@ -2188,26 +2188,21 @@
 erRun%5D;%0A
-%09
 %09%09%09%7D%0A
-%09%09%09%7D
 %0A%09%09%09this

Use same process method with optional callback to unify data flow