From f357e44835d1e3bcc5aeb18361b3c70b47fa9d73 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 9 Oct 2014 13:58:32 -0400 Subject: [PATCH 01/45] Refactor Architect#ajax - Simple version of $.ajax --- app/assets/javascripts/architect.coffee.erb | 18 +++++-- .../architect/workers/ajax_worker.coffee | 43 ++++++++++++--- .../javascripts/workers/ajax_worker.coffee | 54 ++++++++++++++++--- lib/architect/version.rb | 2 +- static/architect.min.js | 6 +-- static/workers/ajax_worker.min.js | 6 +-- static/workers/jsonp_worker.min.js | 4 +- static/workers/proxy_worker.min.js | 4 +- 8 files changed, 108 insertions(+), 29 deletions(-) diff --git a/app/assets/javascripts/architect.coffee.erb b/app/assets/javascripts/architect.coffee.erb index 94dadbb..064d561 100644 --- a/app/assets/javascripts/architect.coffee.erb +++ b/app/assets/javascripts/architect.coffee.erb @@ -27,12 +27,20 @@ spawnWorker = (type) -> worker.postMessage(data) worker.addEventListener 'message', (e) -> worker.terminate() - callback(e.data) + callback?(e.data) @Architect.proxy = (data, callback) => @Architect.work(data, 'proxy', callback) -@Architect.ajax = (url, callback) => @Architect.work(url, 'ajax', callback) @Architect.jsonp = (url, callback) => @Architect.work(url, 'jsonp', callback) +@Architect.ajax = (opts) => + { success, error } = opts + delete opts.success + delete opts.error + + @Architect.work opts, 'ajax', (data) => + success?(result) if result = data.success + error?(xhr) if xhr = data.error + # Long-lived workers jobs = {} @Architect.workOn = (jobName, data, type, @workOnCallback) -> @@ -43,7 +51,7 @@ jobs = {} return if alreadySpawned worker.addEventListener 'message', (e) => - @workOnCallback(e.data) + @workOnCallback?(e.data) @Architect.endJob = (jobName) -> return unless worker = jobs[jobName] @@ -66,8 +74,8 @@ jobs = {} worker.postMessage(data) worker.addEventListener 'message', (e) -> worker.terminate() - callback(e.data) + callback?(e.data) else if fallback - callback(fallback(data)) + callback?(fallback(data)) else console.warn "No fallback provided for #{workerPath}" diff --git a/app/assets/javascripts/architect/workers/ajax_worker.coffee b/app/assets/javascripts/architect/workers/ajax_worker.coffee index 69174be..fc56587 100644 --- a/app/assets/javascripts/architect/workers/ajax_worker.coffee +++ b/app/assets/javascripts/architect/workers/ajax_worker.coffee @@ -1,12 +1,43 @@ class @Architect.AjaxWorker extends @Architect.Worker + handleSuccess: (result) -> this.handleRequest(success: result) + handleError: (xhr) -> this.handleRequest(error: xhr) + + postMessage: (opts) -> + { type, url, data, dataType, contentType, headers } = e.data + + type ||= 'GET' + + headers ||= {} + headers['X-Requested-With'] = 'XMLHttpRequest' + + if contentType isnt false + headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' - postMessage: (url) -> xhr = new XMLHttpRequest - xhr.open('GET', url) - xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') + xhr.open(type, url) + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers xhr.onreadystatechange = (e) => - return unless xhr.readyState is 4 && xhr.status is 200 - this.handleRequest(xhr.responseText) + return unless xhr.readyState is 4 + + # Success + if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 + result = xhr.responseText + + try + if dataType is 'script' + `(1,eval)(result)` + else if dataType is 'xml' + result = xhr.responseXML + else if dataType is 'json' + result = if /^\s*$/.test(result) then null else JSON.parse(result) + catch error + + return this.handleError(xhr) if error + this.handleSuccess(result) + + # Error + else + this.handleError(xhr) - xhr.send() + xhr.send(data) diff --git a/app/assets/javascripts/workers/ajax_worker.coffee b/app/assets/javascripts/workers/ajax_worker.coffee index 16280f4..659250f 100644 --- a/app/assets/javascripts/workers/ajax_worker.coffee +++ b/app/assets/javascripts/workers/ajax_worker.coffee @@ -1,13 +1,53 @@ -handleRequest = (data) -> - postMessage(data) +handleSuccess = (result) -> postMessage(success: result) +handleError = (xhr) -> + # Returning xhr directly throws DataCloneError + result = {} + result[key] = xhr[key] for key in [ + 'response' + 'responseText' + 'responseType' + 'status' + 'statusText' + ] + + postMessage(error: result) addEventListener 'message', (e) -> + { type, url, data, dataType, contentType, headers } = e.data + + type ||= 'GET' + + headers ||= {} + headers['X-Requested-With'] = 'XMLHttpRequest' + + if contentType isnt false + headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' + xhr = new XMLHttpRequest - xhr.open('GET', e.data) - xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest') + xhr.open(type, url) + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers xhr.onreadystatechange = (e) -> - return unless xhr.readyState is 4 && xhr.status is 200 - handleRequest(xhr.responseText) + return unless xhr.readyState is 4 + + # Success + if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 + result = xhr.responseText + + try + if dataType is 'script' + `(1,eval)(result)` + else if dataType is 'xml' + result = xhr.responseXML + else if dataType is 'json' + result = if /^\s*$/.test(result) then null else JSON.parse(result) + catch error + + return handleError(xhr) if error + handleSuccess(result) + + # Error + else + handleError(xhr) - xhr.send() + xhr.send(data) diff --git a/lib/architect/version.rb b/lib/architect/version.rb index dc242f1..6fa2817 100644 --- a/lib/architect/version.rb +++ b/lib/architect/version.rb @@ -1,3 +1,3 @@ module Architect - VERSION = '0.1.0' + VERSION = '0.2.0' end diff --git a/static/architect.min.js b/static/architect.min.js index 4bed16b..a86be05 100644 --- a/static/architect.min.js +++ b/static/architect.min.js @@ -1,10 +1,10 @@ /* -* Architect v0.1.0 +* Architect v0.2.0 * http://architectjs.org * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license * -* Date: 2013-12-09 22:51:38 -0500 +* Date: 2014-10-09 13:42:43 -0400 */ -(function(){this.Architect={},this.Architect.VERSION="0.1.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t,r={}.hasOwnProperty,e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t};this.Architect.AjaxWorker=function(r){function n(){return t=n.__super__.constructor.apply(this,arguments)}return e(n,r),n.prototype.postMessage=function(t){var r,e=this;return r=new XMLHttpRequest,r.open("GET",t),r.setRequestHeader("X-Requested-With","XMLHttpRequest"),r.onreadystatechange=function(){return 4===r.readyState&&200===r.status?e.handleRequest(r.responseText):void 0},r.send()},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e,n=this;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return delete window[r],document.head.removeChild(e),n.handleRequest(t)},e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t,r={}.hasOwnProperty,e=function(t,e){function n(){this.constructor=t}for(var o in e)r.call(e,o)&&(t[o]=e[o]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t};this.Architect.ProxyWorker=function(r){function n(){return t=n.__super__.constructor.apply(this,arguments)}return e(n,r),n.prototype.postMessage=function(t){return this.handleRequest(t)},n}(this.Architect.Worker)}.call(this),function(){var t,r,e,n=this;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return n.Architect.workersPath=t.replace(/\/$/,"")},this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),n(t.data)})},this.Architect.proxy=function(t,r){return n.Architect.work(t,"proxy",r)},this.Architect.ajax=function(t,r){return n.Architect.work(t,"ajax",r)},this.Architect.jsonp=function(t,r){return n.Architect.work(t,"jsonp",r)},r={},this.Architect.workOn=function(t,n,o,c){var i,s,a=this;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return a.workOnCallback(t.data)})},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t,r,e){return n.Architect.workOn(t,r,"proxy",e)},this.Architect.ajaxOn=function(t,r,e){return n.Architect.workOn(t,r,"ajax",e)},this.Architect.jsonpOn=function(t,r,e){return n.Architect.workOn(t,r,"jsonp",e)},this.Architect.workFrom=function(t,r,e,o){var c;return null==e&&(e=null),void 0===o&&(o=e,e=null),n.Architect.SUPPORT_WORKER?(c=new Worker(t),c.postMessage(r),c.addEventListener("message",function(t){return c.terminate(),o(t.data)})):e?o(e(r)):console.warn("No fallback provided for "+t)}}.call(this); +(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,c,i,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,i=h.headers,s||(s="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",t!==!1&&(i["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in i)c=i[o],a.setRequestHeader(o,c);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,n;return n=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){var r,o;return(r=t.success)&&"function"==typeof n&&n(r),(o=t.error)?"function"==typeof e?e(o):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,c){var i,s;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var c;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(c=new Worker(r),c.postMessage(e),c.addEventListener("message",function(t){return c.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); diff --git a/static/workers/ajax_worker.min.js b/static/workers/ajax_worker.min.js index 6919f46..921dd24 100644 --- a/static/workers/ajax_worker.min.js +++ b/static/workers/ajax_worker.min.js @@ -1,10 +1,10 @@ /* -* Architect v0.1.0 +* Architect v0.2.0 * http://architectjs.org * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license * -* Date: 2013-12-09 22:51:38 -0500 +* Date: 2014-10-09 13:42:43 -0400 */ -(function(){var e;e=function(e){return postMessage(e)},addEventListener("message",function(t){var n;return n=new XMLHttpRequest,n.open("GET",t.data),n.setRequestHeader("X-Requested-With","XMLHttpRequest"),n.onreadystatechange=function(){return 4===n.readyState&&200===n.status?e(n.responseText):void 0},n.send()})}).call(this); +(function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e){var t,s,n,r,a;for(s={},a=["response","responseText","responseType","status","statusText"],n=0,r=a.length;r>n;n++)t=a[n],s[t]=e[t];return postMessage({error:s})},addEventListener("message",function(s){var n,r,a,o,u,p,c,i,d,f;f=s.data,c=f.type,i=f.url,r=f.data,a=f.dataType,n=f.contentType,p=f.headers,c||(c="GET"),p||(p={}),p["X-Requested-With"]="XMLHttpRequest",n!==!1&&(p["Content-Type"]=n||"application/x-www-form-urlencoded"),d=new XMLHttpRequest,d.open(c,i);for(o in p)u=p[o],d.setRequestHeader(o,u);return d.onreadystatechange=function(){var s,n;if(4===d.readyState){if(d.status>=200&&d.status<300||304===d.status){n=d.responseText;try{"script"===a?(1,eval)(n):"xml"===a?n=d.responseXML:"json"===a&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(r){s=r}return s?e(d):t(n)}return e(d)}},d.send(r)})}).call(this); diff --git a/static/workers/jsonp_worker.min.js b/static/workers/jsonp_worker.min.js index 35e72c3..5a52fd9 100644 --- a/static/workers/jsonp_worker.min.js +++ b/static/workers/jsonp_worker.min.js @@ -1,10 +1,10 @@ /* -* Architect v0.1.0 +* Architect v0.2.0 * http://architectjs.org * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license * -* Date: 2013-12-09 22:51:38 -0500 +* Date: 2014-10-09 13:42:43 -0400 */ (function(){var e;self.handleRequest=function(e){return postMessage(e)},e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(t){var n;return n=e(t.data,"callback=handleRequest"),importScripts(n)})}).call(this); diff --git a/static/workers/proxy_worker.min.js b/static/workers/proxy_worker.min.js index 85f3179..f3aecbd 100644 --- a/static/workers/proxy_worker.min.js +++ b/static/workers/proxy_worker.min.js @@ -1,10 +1,10 @@ /* -* Architect v0.1.0 +* Architect v0.2.0 * http://architectjs.org * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license * -* Date: 2013-12-09 22:51:38 -0500 +* Date: 2014-10-09 13:42:43 -0400 */ (function(){addEventListener("message",function(e){return postMessage(e.data)})}).call(this); From c3a546bf20d2b69f9a7bdb82b67bd577828ad488 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 31 Oct 2014 16:44:54 -0400 Subject: [PATCH 02/45] Remove date from compiled files --- Rakefile | 2 -- static/architect.min.js | 2 -- static/workers/ajax_worker.min.js | 2 -- static/workers/jsonp_worker.min.js | 2 -- static/workers/proxy_worker.min.js | 2 -- 5 files changed, 10 deletions(-) diff --git a/Rakefile b/Rakefile index 9d1196d..390c579 100644 --- a/Rakefile +++ b/Rakefile @@ -46,8 +46,6 @@ def copyright * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license -* -* Date: #{Time.now} */ EOS end diff --git a/static/architect.min.js b/static/architect.min.js index a86be05..0554a2b 100644 --- a/static/architect.min.js +++ b/static/architect.min.js @@ -4,7 +4,5 @@ * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license -* -* Date: 2014-10-09 13:42:43 -0400 */ (function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,c,i,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,i=h.headers,s||(s="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",t!==!1&&(i["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in i)c=i[o],a.setRequestHeader(o,c);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,n;return n=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){var r,o;return(r=t.success)&&"function"==typeof n&&n(r),(o=t.error)?"function"==typeof e?e(o):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,c){var i,s;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var c;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(c=new Worker(r),c.postMessage(e),c.addEventListener("message",function(t){return c.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); diff --git a/static/workers/ajax_worker.min.js b/static/workers/ajax_worker.min.js index 921dd24..01417bb 100644 --- a/static/workers/ajax_worker.min.js +++ b/static/workers/ajax_worker.min.js @@ -4,7 +4,5 @@ * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license -* -* Date: 2014-10-09 13:42:43 -0400 */ (function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e){var t,s,n,r,a;for(s={},a=["response","responseText","responseType","status","statusText"],n=0,r=a.length;r>n;n++)t=a[n],s[t]=e[t];return postMessage({error:s})},addEventListener("message",function(s){var n,r,a,o,u,p,c,i,d,f;f=s.data,c=f.type,i=f.url,r=f.data,a=f.dataType,n=f.contentType,p=f.headers,c||(c="GET"),p||(p={}),p["X-Requested-With"]="XMLHttpRequest",n!==!1&&(p["Content-Type"]=n||"application/x-www-form-urlencoded"),d=new XMLHttpRequest,d.open(c,i);for(o in p)u=p[o],d.setRequestHeader(o,u);return d.onreadystatechange=function(){var s,n;if(4===d.readyState){if(d.status>=200&&d.status<300||304===d.status){n=d.responseText;try{"script"===a?(1,eval)(n):"xml"===a?n=d.responseXML:"json"===a&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(r){s=r}return s?e(d):t(n)}return e(d)}},d.send(r)})}).call(this); diff --git a/static/workers/jsonp_worker.min.js b/static/workers/jsonp_worker.min.js index 5a52fd9..4314e2c 100644 --- a/static/workers/jsonp_worker.min.js +++ b/static/workers/jsonp_worker.min.js @@ -4,7 +4,5 @@ * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license -* -* Date: 2014-10-09 13:42:43 -0400 */ (function(){var e;self.handleRequest=function(e){return postMessage(e)},e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(t){var n;return n=e(t.data,"callback=handleRequest"),importScripts(n)})}).call(this); diff --git a/static/workers/proxy_worker.min.js b/static/workers/proxy_worker.min.js index f3aecbd..2c4f903 100644 --- a/static/workers/proxy_worker.min.js +++ b/static/workers/proxy_worker.min.js @@ -4,7 +4,5 @@ * * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license -* -* Date: 2014-10-09 13:42:43 -0400 */ (function(){addEventListener("message",function(e){return postMessage(e.data)})}).call(this); From 81c7a7bb4ab92974c10b80141982cc2c2bcea1b6 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 31 Oct 2014 16:45:31 -0400 Subject: [PATCH 03/45] Use `in` operator to verify if object has key --- app/assets/javascripts/architect.coffee.erb | 4 ++-- static/architect.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/architect.coffee.erb b/app/assets/javascripts/architect.coffee.erb index 064d561..0dbca05 100644 --- a/app/assets/javascripts/architect.coffee.erb +++ b/app/assets/javascripts/architect.coffee.erb @@ -38,8 +38,8 @@ spawnWorker = (type) -> delete opts.error @Architect.work opts, 'ajax', (data) => - success?(result) if result = data.success - error?(xhr) if xhr = data.error + success?(data.success) if 'success' in data + error?(data.error) if 'error' in data # Long-lived workers jobs = {} diff --git a/static/architect.min.js b/static/architect.min.js index 0554a2b..39f7b6b 100644 --- a/static/architect.min.js +++ b/static/architect.min.js @@ -5,4 +5,4 @@ * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license */ -(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,c,i,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,i=h.headers,s||(s="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",t!==!1&&(i["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in i)c=i[o],a.setRequestHeader(o,c);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,n;return n=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){var r,o;return(r=t.success)&&"function"==typeof n&&n(r),(o=t.error)?"function"==typeof e?e(o):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,c){var i,s;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var c;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(c=new Worker(r),c.postMessage(e),c.addEventListener("message",function(t){return c.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); +(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,i,c,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,c=h.headers,s||(s="GET"),c||(c={}),c["X-Requested-With"]="XMLHttpRequest",t!==!1&&(c["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in c)i=c[o],a.setRequestHeader(o,i);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e,n=[].indexOf||function(t){for(var r=0,e=this.length;e>r;r++)if(r in this&&this[r]===t)return r;return-1};this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,o;return o=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){return n.call(t,"success")>=0&&"function"==typeof o&&o(t.success),n.call(t,"error")>=0?"function"==typeof e?e(t.error):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,i){var c,s;return this.workOnCallback=i,c=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),c?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var i;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(i=new Worker(r),i.postMessage(e),i.addEventListener("message",function(t){return i.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); From 47da137a57f45c6beac0790ea8b7822152b0699d Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 31 Oct 2014 16:53:02 -0400 Subject: [PATCH 04/45] Holy CoffeeScript --- app/assets/javascripts/architect.coffee.erb | 4 ++-- static/architect.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/architect.coffee.erb b/app/assets/javascripts/architect.coffee.erb index 0dbca05..f220e2a 100644 --- a/app/assets/javascripts/architect.coffee.erb +++ b/app/assets/javascripts/architect.coffee.erb @@ -38,8 +38,8 @@ spawnWorker = (type) -> delete opts.error @Architect.work opts, 'ajax', (data) => - success?(data.success) if 'success' in data - error?(data.error) if 'error' in data + success?(data.success) if 'success' of data + error?(data.error) if 'error' of data # Long-lived workers jobs = {} diff --git a/static/architect.min.js b/static/architect.min.js index 39f7b6b..8e4af79 100644 --- a/static/architect.min.js +++ b/static/architect.min.js @@ -5,4 +5,4 @@ * Copyright 2013, Etienne Lemay http://heliom.ca * Released under the MIT license */ -(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,i,c,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,c=h.headers,s||(s="GET"),c||(c={}),c["X-Requested-With"]="XMLHttpRequest",t!==!1&&(c["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in c)i=c[o],a.setRequestHeader(o,i);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e,n=[].indexOf||function(t){for(var r=0,e=this.length;e>r;r++)if(r in this&&this[r]===t)return r;return-1};this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,o;return o=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){return n.call(t,"success")>=0&&"function"==typeof o&&o(t.success),n.call(t,"error")>=0?"function"==typeof e?e(t.error):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,i){var c,s;return this.workOnCallback=i,c=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),c?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var i;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(i=new Worker(r),i.postMessage(e),i.addEventListener("message",function(t){return i.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); +(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,c,i,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,i=h.headers,s||(s="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",t!==!1&&(i["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in i)c=i[o],a.setRequestHeader(o,c);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,n;return n=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){return"success"in t&&"function"==typeof n&&n(t.success),"error"in t?"function"==typeof e?e(t.error):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,c){var i,s;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var c;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(c=new Worker(r),c.postMessage(e),c.addEventListener("message",function(t){return c.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); From bf2be214013d14cc4f15aa5c4bc41d32fbebef0a Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Wed, 18 Mar 2015 16:45:41 -0400 Subject: [PATCH 05/45] [cleanup] --- .gitignore | 3 +- CHANGELOG.md | 25 ---- Gemfile | 2 - MIT-LICENSE => LICENSE | 0 Rakefile | 51 ------- app/assets/javascripts/architect.coffee.erb | 81 ---------- .../javascripts/architect/version.coffee.erb | 2 - .../javascripts/architect/worker.coffee | 27 ---- .../architect/workers/ajax_worker.coffee | 43 ------ .../architect/workers/jsonp_worker.coffee | 21 --- .../architect/workers/proxy_worker.coffee | 4 - .../javascripts/workers/ajax_worker.coffee | 53 ------- .../javascripts/workers/jsonp_worker.coffee | 9 -- .../javascripts/workers/proxy_worker.coffee | 2 - architect.gemspec | 21 --- lib/architect.rb | 3 - lib/architect/engine.rb | 7 - lib/architect/helpers.rb | 12 -- lib/architect/version.rb | 3 - lib/tasks/task_helpers.rb | 18 --- static/architect.min.js | 8 - static/workers/ajax_worker.min.js | 8 - static/workers/jsonp_worker.min.js | 8 - static/workers/proxy_worker.min.js | 8 - test/fixture/foozle_worker.js | 4 - test/index.html | 19 --- test/runner.js | 139 ------------------ test/unit/architect/polyfill_test.js | 54 ------- test/unit/architect_test.js | 49 ------ 29 files changed, 2 insertions(+), 682 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 Gemfile rename MIT-LICENSE => LICENSE (100%) delete mode 100644 Rakefile delete mode 100644 app/assets/javascripts/architect.coffee.erb delete mode 100644 app/assets/javascripts/architect/version.coffee.erb delete mode 100644 app/assets/javascripts/architect/worker.coffee delete mode 100644 app/assets/javascripts/architect/workers/ajax_worker.coffee delete mode 100644 app/assets/javascripts/architect/workers/jsonp_worker.coffee delete mode 100644 app/assets/javascripts/architect/workers/proxy_worker.coffee delete mode 100644 app/assets/javascripts/workers/ajax_worker.coffee delete mode 100644 app/assets/javascripts/workers/jsonp_worker.coffee delete mode 100644 app/assets/javascripts/workers/proxy_worker.coffee delete mode 100644 architect.gemspec delete mode 100644 lib/architect.rb delete mode 100644 lib/architect/engine.rb delete mode 100644 lib/architect/helpers.rb delete mode 100644 lib/architect/version.rb delete mode 100644 lib/tasks/task_helpers.rb delete mode 100644 static/architect.min.js delete mode 100644 static/workers/ajax_worker.min.js delete mode 100644 static/workers/jsonp_worker.min.js delete mode 100644 static/workers/proxy_worker.min.js delete mode 100644 test/fixture/foozle_worker.js delete mode 100644 test/index.html delete mode 100644 test/runner.js delete mode 100644 test/unit/architect/polyfill_test.js delete mode 100644 test/unit/architect_test.js diff --git a/.gitignore b/.gitignore index b844b14..e3fbd98 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -Gemfile.lock +build +node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 770c2a2..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,25 +0,0 @@ -## [v0.1.0](https://github.com/EtienneLem/architect/tree/v0.1.0) -- Add X-Requested-With header to xhr request - -## [v0.0.7](https://github.com/EtienneLem/architect/tree/v0.0.7) -- Serve your workers from any path -- Make `workFrom` fallback optional - -## [v0.0.6](https://github.com/EtienneLem/architect/tree/v0.0.6) -- Custom workers support - -## [v0.0.5](https://github.com/EtienneLem/architect/tree/v0.0.5) -- Make JSONP callback count a global variable - -## [v0.0.4](https://github.com/EtienneLem/architect/tree/v0.0.4) -- Add worker files to precompile list - -## [v0.0.3](https://github.com/EtienneLem/architect/tree/v0.0.3) -- Fix long-lived workers callback bug - -## [v0.0.2](https://github.com/EtienneLem/architect/tree/v0.0.2) -- Long-lived workers - -## [v0.0.1](https://github.com/EtienneLem/architect/tree/v0.0.1) -Initial release -- Short-lived workers diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 851fabc..0000000 --- a/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source 'https://rubygems.org' -gemspec diff --git a/MIT-LICENSE b/LICENSE similarity index 100% rename from MIT-LICENSE rename to LICENSE diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 390c579..0000000 --- a/Rakefile +++ /dev/null @@ -1,51 +0,0 @@ -$:.unshift File.join(File.dirname(__FILE__), *%w[lib]) -require 'tasks/task_helpers' - -# Rubygems -require 'bundler' -Bundler::GemHelper.install_tasks - -# Dependencies -require 'uglifier' -require 'architect' -require 'sprockets' - -# Tasks -desc 'Merge, compiles and minify CoffeeScript files' -task :compile do - @environment = Sprockets::Environment.new - @environment.append_path 'app/assets/javascripts' - @environment.js_compressor = Uglifier.new(mangle: true) - - compile('architect.js') - compile('workers/proxy_worker.js') - compile('workers/ajax_worker.js') - compile('workers/jsonp_worker.js') -end - -desc 'Run tests' -task :test do - puts `phantomjs test/runner.js test/index.html` -end - -task :default => :compile - -def compile(file) - minjs = @environment[file].to_s - out = "static/#{file.sub('.js', '.min.js')}" - - File.open(out, 'w') { |f| f.write(copyright + minjs + "\n") } - success "Compiled #{out}" -end - -def copyright - @copyright ||= <<-EOS -/* -* Architect v#{Architect::VERSION} -* http://architectjs.org -* -* Copyright 2013, Etienne Lemay http://heliom.ca -* Released under the MIT license -*/ -EOS -end diff --git a/app/assets/javascripts/architect.coffee.erb b/app/assets/javascripts/architect.coffee.erb deleted file mode 100644 index f220e2a..0000000 --- a/app/assets/javascripts/architect.coffee.erb +++ /dev/null @@ -1,81 +0,0 @@ -#= require ./architect/version -#= require ./architect/worker - -# Constants -@Architect.SUPPORT_WORKER = !!window.Worker -@Architect.WORKERS = - proxy: { polyfill: @Architect.ProxyWorker, workerPath: '<%= Architect.worker_path("proxy") %>' } - ajax: { polyfill: @Architect.AjaxWorker, workerPath: '<%= Architect.worker_path("ajax") %>' } - jsonp: { polyfill: @Architect.JSONPWorker, workerPath: '<%= Architect.worker_path("jsonp") %>' } - -# Private methods -getWorkersPath = (type) -> - return @Architect.WORKERS[type].workerPath unless @Architect.workersPath - "#{@Architect.workersPath}/#{type}_worker.min.js" - -spawnWorker = (type) -> - return new @Architect.WORKERS[type].polyfill unless @Architect.SUPPORT_WORKER - new Worker(getWorkersPath(type)) - -# Config -@Architect.setupWorkersPath = (path) => - @Architect.workersPath = path.replace(/\/$/, '') - -# Short-lived workers -@Architect.work = (data, type, callback) -> - worker = spawnWorker(type) - worker.postMessage(data) - worker.addEventListener 'message', (e) -> - worker.terminate() - callback?(e.data) - -@Architect.proxy = (data, callback) => @Architect.work(data, 'proxy', callback) -@Architect.jsonp = (url, callback) => @Architect.work(url, 'jsonp', callback) - -@Architect.ajax = (opts) => - { success, error } = opts - delete opts.success - delete opts.error - - @Architect.work opts, 'ajax', (data) => - success?(data.success) if 'success' of data - error?(data.error) if 'error' of data - -# Long-lived workers -jobs = {} -@Architect.workOn = (jobName, data, type, @workOnCallback) -> - alreadySpawned = !!jobs[jobName] - - worker = jobs[jobName] ||= spawnWorker(type) - worker.postMessage(data) - - return if alreadySpawned - worker.addEventListener 'message', (e) => - @workOnCallback?(e.data) - -@Architect.endJob = (jobName) -> - return unless worker = jobs[jobName] - - worker.terminate() - delete jobs[jobName] - -@Architect.proxyOn = (jobName, data, callback) => @Architect.workOn(jobName, data, 'proxy', callback) -@Architect.ajaxOn = (jobName, url, callback) => @Architect.workOn(jobName, url, 'ajax', callback) -@Architect.jsonpOn = (jobName, url, callback) => @Architect.workOn(jobName, url, 'jsonp', callback) - -# Custom workers -@Architect.workFrom = (workerPath, data, fallback=null, callback) => - if callback is undefined - callback = fallback - fallback = null - - if @Architect.SUPPORT_WORKER - worker = new Worker(workerPath) - worker.postMessage(data) - worker.addEventListener 'message', (e) -> - worker.terminate() - callback?(e.data) - else if fallback - callback?(fallback(data)) - else - console.warn "No fallback provided for #{workerPath}" diff --git a/app/assets/javascripts/architect/version.coffee.erb b/app/assets/javascripts/architect/version.coffee.erb deleted file mode 100644 index 6a84073..0000000 --- a/app/assets/javascripts/architect/version.coffee.erb +++ /dev/null @@ -1,2 +0,0 @@ -@Architect = {} -@Architect.VERSION = '<%= Architect::VERSION %>' diff --git a/app/assets/javascripts/architect/worker.coffee b/app/assets/javascripts/architect/worker.coffee deleted file mode 100644 index 20bd272..0000000 --- a/app/assets/javascripts/architect/worker.coffee +++ /dev/null @@ -1,27 +0,0 @@ -#= require_self -#= require_tree ./workers - -class @Architect.Worker - - constructor: -> - @callbacks = {} - @callbacksQueue = {} - - addEventListener: (type, callback) -> - @callbacks[type] = callback - - return unless data = @callbacksQueue[type] - delete @callbacksQueue[type] - - this.dispatch(type, data) - - dispatch: (type, data) -> - if @callbacks[type] - @callbacks[type]({data: data}) - else - @callbacksQueue[type] = data - - handleRequest: (data) -> - this.dispatch('message', data) - - terminate: -> # This is meant to be empty diff --git a/app/assets/javascripts/architect/workers/ajax_worker.coffee b/app/assets/javascripts/architect/workers/ajax_worker.coffee deleted file mode 100644 index fc56587..0000000 --- a/app/assets/javascripts/architect/workers/ajax_worker.coffee +++ /dev/null @@ -1,43 +0,0 @@ -class @Architect.AjaxWorker extends @Architect.Worker - handleSuccess: (result) -> this.handleRequest(success: result) - handleError: (xhr) -> this.handleRequest(error: xhr) - - postMessage: (opts) -> - { type, url, data, dataType, contentType, headers } = e.data - - type ||= 'GET' - - headers ||= {} - headers['X-Requested-With'] = 'XMLHttpRequest' - - if contentType isnt false - headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' - - xhr = new XMLHttpRequest - xhr.open(type, url) - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers - - xhr.onreadystatechange = (e) => - return unless xhr.readyState is 4 - - # Success - if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 - result = xhr.responseText - - try - if dataType is 'script' - `(1,eval)(result)` - else if dataType is 'xml' - result = xhr.responseXML - else if dataType is 'json' - result = if /^\s*$/.test(result) then null else JSON.parse(result) - catch error - - return this.handleError(xhr) if error - this.handleSuccess(result) - - # Error - else - this.handleError(xhr) - - xhr.send(data) diff --git a/app/assets/javascripts/architect/workers/jsonp_worker.coffee b/app/assets/javascripts/architect/workers/jsonp_worker.coffee deleted file mode 100644 index 2df57e2..0000000 --- a/app/assets/javascripts/architect/workers/jsonp_worker.coffee +++ /dev/null @@ -1,21 +0,0 @@ -class @Architect.JSONPWorker extends @Architect.Worker - - constructor: -> - super() - window.jsonpID ||= 0 - - postMessage: (url) -> - tmpScript = document.createElement('script') - - callbackName = 'architect_jsonp' + (++window.jsonpID) - window[callbackName] = (data) => - delete window[callbackName] - document.head.removeChild(tmpScript) - - this.handleRequest(data) - - tmpScript.src = this.appendQuery(url, "callback=#{callbackName}") - document.head.appendChild(tmpScript) - - appendQuery: (url, query) -> - (url + '&' + query).replace(/[&?]{1,2}/, '?') diff --git a/app/assets/javascripts/architect/workers/proxy_worker.coffee b/app/assets/javascripts/architect/workers/proxy_worker.coffee deleted file mode 100644 index 30ae249..0000000 --- a/app/assets/javascripts/architect/workers/proxy_worker.coffee +++ /dev/null @@ -1,4 +0,0 @@ -class @Architect.ProxyWorker extends @Architect.Worker - - postMessage: (data) -> - this.handleRequest(data) diff --git a/app/assets/javascripts/workers/ajax_worker.coffee b/app/assets/javascripts/workers/ajax_worker.coffee deleted file mode 100644 index 659250f..0000000 --- a/app/assets/javascripts/workers/ajax_worker.coffee +++ /dev/null @@ -1,53 +0,0 @@ -handleSuccess = (result) -> postMessage(success: result) -handleError = (xhr) -> - # Returning xhr directly throws DataCloneError - result = {} - result[key] = xhr[key] for key in [ - 'response' - 'responseText' - 'responseType' - 'status' - 'statusText' - ] - - postMessage(error: result) - -addEventListener 'message', (e) -> - { type, url, data, dataType, contentType, headers } = e.data - - type ||= 'GET' - - headers ||= {} - headers['X-Requested-With'] = 'XMLHttpRequest' - - if contentType isnt false - headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' - - xhr = new XMLHttpRequest - xhr.open(type, url) - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers - - xhr.onreadystatechange = (e) -> - return unless xhr.readyState is 4 - - # Success - if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 - result = xhr.responseText - - try - if dataType is 'script' - `(1,eval)(result)` - else if dataType is 'xml' - result = xhr.responseXML - else if dataType is 'json' - result = if /^\s*$/.test(result) then null else JSON.parse(result) - catch error - - return handleError(xhr) if error - handleSuccess(result) - - # Error - else - handleError(xhr) - - xhr.send(data) diff --git a/app/assets/javascripts/workers/jsonp_worker.coffee b/app/assets/javascripts/workers/jsonp_worker.coffee deleted file mode 100644 index 3b1d0d1..0000000 --- a/app/assets/javascripts/workers/jsonp_worker.coffee +++ /dev/null @@ -1,9 +0,0 @@ -self.handleRequest = (data) -> - postMessage(data) - -appendQuery = (url, query) -> - (url + '&' + query).replace(/[&?]{1,2}/, '?') - -addEventListener 'message', (e) -> - url = appendQuery(e.data, 'callback=handleRequest') - importScripts(url) diff --git a/app/assets/javascripts/workers/proxy_worker.coffee b/app/assets/javascripts/workers/proxy_worker.coffee deleted file mode 100644 index 254a379..0000000 --- a/app/assets/javascripts/workers/proxy_worker.coffee +++ /dev/null @@ -1,2 +0,0 @@ -addEventListener 'message', (e) -> - postMessage(e.data) diff --git a/architect.gemspec b/architect.gemspec deleted file mode 100644 index 46bfa1d..0000000 --- a/architect.gemspec +++ /dev/null @@ -1,21 +0,0 @@ -require './lib/architect/version' - -Gem::Specification.new do |s| - s.name = 'architect' - s.version = Architect::VERSION - s.authors = ['Etienne Lemay'] - s.email = ['etienne@heliom.ca'] - s.homepage = 'http://architectjs.org' - s.summary = 'Your web workers’ supervisor' - s.description = 'Architect is a JavaScript library built on top of Web Workers that will handle and polyfill HTML Web Workers.' - s.license = 'MIT' - - s.files = `git ls-files`.split($/) - s.test_files = s.files.grep(%r{^(test)/}) - - s.add_dependency 'coffee-rails' - - s.add_development_dependency 'rake' - s.add_development_dependency 'uglifier' - s.add_development_dependency 'sprockets' -end diff --git a/lib/architect.rb b/lib/architect.rb deleted file mode 100644 index dbecacf..0000000 --- a/lib/architect.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'architect/version' -require 'architect/helpers' -require 'architect/engine' if defined?(Rails) && Rails::VERSION::MAJOR >= 3 diff --git a/lib/architect/engine.rb b/lib/architect/engine.rb deleted file mode 100644 index 6c9bd57..0000000 --- a/lib/architect/engine.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Architect - class Engine < ::Rails::Engine - initializer 'architect.assets.precompile' do |app| - app.config.assets.precompile << 'workers/*' - end - end -end diff --git a/lib/architect/helpers.rb b/lib/architect/helpers.rb deleted file mode 100644 index 56a9186..0000000 --- a/lib/architect/helpers.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Architect - def self.worker_path(type) - worker_filename = "#{type}_worker.js" - return "architect/#{worker_filename.sub('.js', '.min.js')}" unless defined?(Rails) - - # Cacheable digest path on main domain because of same-origin policy - File.join( - Rails.application.config.assets.prefix, - Rails.application.assets["workers/#{worker_filename}"].digest_path - ) - end -end diff --git a/lib/architect/version.rb b/lib/architect/version.rb deleted file mode 100644 index 6fa2817..0000000 --- a/lib/architect/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Architect - VERSION = '0.2.0' -end diff --git a/lib/tasks/task_helpers.rb b/lib/tasks/task_helpers.rb deleted file mode 100644 index 46ae56e..0000000 --- a/lib/tasks/task_helpers.rb +++ /dev/null @@ -1,18 +0,0 @@ -def colorize(text, color_code) - "\e[#{color_code}m#{text}\e[0m" -end - -{ # See: http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/ - 31 => 'red', - 32 => 'green', - 33 => 'yellow', - 34 => 'blue', - 35 => 'magenta', - 36 => 'cyan', -}.each do |code, color| - Kernel.send(:define_method, color) { |text| colorize(text, code) } -end - -def error(text); puts red('ERROR: ') + text; end -def success(text); puts green('SUCCESS: ') + text; end -def warn(text); puts yellow('WARNING: ') + text; end diff --git a/static/architect.min.js b/static/architect.min.js deleted file mode 100644 index 8e4af79..0000000 --- a/static/architect.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -* Architect v0.2.0 -* http://architectjs.org -* -* Copyright 2013, Etienne Lemay http://heliom.ca -* Released under the MIT license -*/ -(function(){this.Architect={},this.Architect.VERSION="0.2.0"}).call(this),function(){this.Architect.Worker=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,r){var e;return this.callbacks[t]=r,(e=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,e)):void 0},t.prototype.dispatch=function(t,r){return this.callbacks[t]?this.callbacks[t]({data:r}):this.callbacksQueue[t]=r},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.terminate=function(){},t}()}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.AjaxWorker=function(t){function n(){return n.__super__.constructor.apply(this,arguments)}return r(n,t),n.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},n.prototype.handleError=function(t){return this.handleRequest({error:t})},n.prototype.postMessage=function(){var t,r,n,o,c,i,s,u,a,h;h=e.data,s=h.type,u=h.url,r=h.data,n=h.dataType,t=h.contentType,i=h.headers,s||(s="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",t!==!1&&(i["Content-Type"]=t||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(s,u);for(o in i)c=i[o],a.setRequestHeader(o,c);return a.onreadystatechange=function(t){return function(){var r,e;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){e=a.responseText;try{"script"===n?(1,eval)(e):"xml"===n?e=a.responseXML:"json"===n&&(e=/^\s*$/.test(e)?null:JSON.parse(e))}catch(o){r=o}return r?t.handleError(a):t.handleSuccess(e)}return t.handleError(a)}}}(this),a.send(r)},n}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.JSONPWorker=function(t){function e(){e.__super__.constructor.call(this),window.jsonpID||(window.jsonpID=0)}return r(e,t),e.prototype.postMessage=function(t){var r,e;return e=document.createElement("script"),r="architect_jsonp"+ ++window.jsonpID,window[r]=function(t){return function(n){return delete window[r],document.head.removeChild(e),t.handleRequest(n)}}(this),e.src=this.appendQuery(t,"callback="+r),document.head.appendChild(e)},e.prototype.appendQuery=function(t,r){return(t+"&"+r).replace(/[&?]{1,2}/,"?")},e}(this.Architect.Worker)}.call(this),function(){var t={}.hasOwnProperty,r=function(r,e){function n(){this.constructor=r}for(var o in e)t.call(e,o)&&(r[o]=e[o]);return n.prototype=e.prototype,r.prototype=new n,r.__super__=e.prototype,r};this.Architect.ProxyWorker=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return r(e,t),e.prototype.postMessage=function(t){return this.handleRequest(t)},e}(this.Architect.Worker)}.call(this),function(){var t,r,e;this.Architect.SUPPORT_WORKER=!!window.Worker,this.Architect.WORKERS={proxy:{polyfill:this.Architect.ProxyWorker,workerPath:"architect/proxy_worker.min.js"},ajax:{polyfill:this.Architect.AjaxWorker,workerPath:"architect/ajax_worker.min.js"},jsonp:{polyfill:this.Architect.JSONPWorker,workerPath:"architect/jsonp_worker.min.js"}},t=function(t){return this.Architect.workersPath?""+this.Architect.workersPath+"/"+t+"_worker.min.js":this.Architect.WORKERS[t].workerPath},e=function(r){return this.Architect.SUPPORT_WORKER?new Worker(t(r)):new this.Architect.WORKERS[r].polyfill},this.Architect.setupWorkersPath=function(t){return function(r){return t.Architect.workersPath=r.replace(/\/$/,"")}}(this),this.Architect.work=function(t,r,n){var o;return o=e(r),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),"function"==typeof n?n(t.data):void 0})},this.Architect.proxy=function(t){return function(r,e){return t.Architect.work(r,"proxy",e)}}(this),this.Architect.jsonp=function(t){return function(r,e){return t.Architect.work(r,"jsonp",e)}}(this),this.Architect.ajax=function(t){return function(r){var e,n;return n=r.success,e=r.error,delete r.success,delete r.error,t.Architect.work(r,"ajax",function(t){return"success"in t&&"function"==typeof n&&n(t.success),"error"in t?"function"==typeof e?e(t.error):void 0:void 0})}}(this),r={},this.Architect.workOn=function(t,n,o,c){var i,s;return this.workOnCallback=c,i=!!r[t],s=r[t]||(r[t]=e(o)),s.postMessage(n),i?void 0:s.addEventListener("message",function(t){return function(r){return"function"==typeof t.workOnCallback?t.workOnCallback(r.data):void 0}}(this))},this.Architect.endJob=function(t){var e;if(e=r[t])return e.terminate(),delete r[t]},this.Architect.proxyOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"proxy",n)}}(this),this.Architect.ajaxOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"ajax",n)}}(this),this.Architect.jsonpOn=function(t){return function(r,e,n){return t.Architect.workOn(r,e,"jsonp",n)}}(this),this.Architect.workFrom=function(t){return function(r,e,n,o){var c;return null==n&&(n=null),void 0===o&&(o=n,n=null),t.Architect.SUPPORT_WORKER?(c=new Worker(r),c.postMessage(e),c.addEventListener("message",function(t){return c.terminate(),"function"==typeof o?o(t.data):void 0})):n?"function"==typeof o?o(n(e)):void 0:console.warn("No fallback provided for "+r)}}(this)}.call(this); diff --git a/static/workers/ajax_worker.min.js b/static/workers/ajax_worker.min.js deleted file mode 100644 index 01417bb..0000000 --- a/static/workers/ajax_worker.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -* Architect v0.2.0 -* http://architectjs.org -* -* Copyright 2013, Etienne Lemay http://heliom.ca -* Released under the MIT license -*/ -(function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e){var t,s,n,r,a;for(s={},a=["response","responseText","responseType","status","statusText"],n=0,r=a.length;r>n;n++)t=a[n],s[t]=e[t];return postMessage({error:s})},addEventListener("message",function(s){var n,r,a,o,u,p,c,i,d,f;f=s.data,c=f.type,i=f.url,r=f.data,a=f.dataType,n=f.contentType,p=f.headers,c||(c="GET"),p||(p={}),p["X-Requested-With"]="XMLHttpRequest",n!==!1&&(p["Content-Type"]=n||"application/x-www-form-urlencoded"),d=new XMLHttpRequest,d.open(c,i);for(o in p)u=p[o],d.setRequestHeader(o,u);return d.onreadystatechange=function(){var s,n;if(4===d.readyState){if(d.status>=200&&d.status<300||304===d.status){n=d.responseText;try{"script"===a?(1,eval)(n):"xml"===a?n=d.responseXML:"json"===a&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(r){s=r}return s?e(d):t(n)}return e(d)}},d.send(r)})}).call(this); diff --git a/static/workers/jsonp_worker.min.js b/static/workers/jsonp_worker.min.js deleted file mode 100644 index 4314e2c..0000000 --- a/static/workers/jsonp_worker.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -* Architect v0.2.0 -* http://architectjs.org -* -* Copyright 2013, Etienne Lemay http://heliom.ca -* Released under the MIT license -*/ -(function(){var e;self.handleRequest=function(e){return postMessage(e)},e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(t){var n;return n=e(t.data,"callback=handleRequest"),importScripts(n)})}).call(this); diff --git a/static/workers/proxy_worker.min.js b/static/workers/proxy_worker.min.js deleted file mode 100644 index 2c4f903..0000000 --- a/static/workers/proxy_worker.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -* Architect v0.2.0 -* http://architectjs.org -* -* Copyright 2013, Etienne Lemay http://heliom.ca -* Released under the MIT license -*/ -(function(){addEventListener("message",function(e){return postMessage(e.data)})}).call(this); diff --git a/test/fixture/foozle_worker.js b/test/fixture/foozle_worker.js deleted file mode 100644 index 77225fc..0000000 --- a/test/fixture/foozle_worker.js +++ /dev/null @@ -1,4 +0,0 @@ -addEventListener('message', function(e) { - data = e.data + 'zle' - postMessage(data.toUpperCase()) -}) diff --git a/test/index.html b/test/index.html deleted file mode 100644 index cee22a6..0000000 --- a/test/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - QUnit Example - - - -
-
- - - - - - - - - diff --git a/test/runner.js b/test/runner.js deleted file mode 100644 index 92e7b93..0000000 --- a/test/runner.js +++ /dev/null @@ -1,139 +0,0 @@ -/* - * QtWebKit-powered headless test runner using PhantomJS - * - * PhantomJS binaries: http://phantomjs.org/download.html - * Requires PhantomJS 1.6+ (1.7+ recommended) - * - * Run with: - * phantomjs runner.js [url-of-your-qunit-testsuite] - * - * e.g. - * phantomjs runner.js http://localhost/qunit/test/index.html - */ - -/*global phantom:false, require:false, console:false, window:false, QUnit:false */ - -(function() { - 'use strict'; - - var url, page, timeout, - args = require('system').args; - - // arg[0]: scriptName, args[1...]: arguments - if (args.length < 2 || args.length > 3) { - console.error('Usage:\n phantomjs runner.js [url-of-your-qunit-testsuite] [timeout-in-seconds]'); - phantom.exit(1); - } - - url = args[1]; - page = require('webpage').create(); - if (args[2] !== undefined) { - timeout = parseInt(args[2], 10); - } - - // Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`) - page.onConsoleMessage = function(msg) { - console.log(msg); - }; - - page.onInitialized = function() { - page.evaluate(addLogging); - }; - - page.onCallback = function(message) { - var result, - failed; - - if (message) { - if (message.name === 'QUnit.done') { - result = message.data; - failed = !result || result.failed; - - phantom.exit(failed ? 1 : 0); - } - } - }; - - page.open(url, function(status) { - if (status !== 'success') { - console.error('Unable to access network: ' + status); - phantom.exit(1); - } else { - // Cannot do this verification with the 'DOMContentLoaded' handler because it - // will be too late to attach it if a page does not have any script tags. - var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); }); - if (qunitMissing) { - console.error('The `QUnit` object is not present on this page.'); - phantom.exit(1); - } - - // Set a timeout on the test running, otherwise tests with async problems will hang forever - if (typeof timeout === 'number') { - setTimeout(function() { - console.error('The specified timeout of ' + timeout + ' seconds has expired. Aborting...'); - phantom.exit(1); - }, timeout * 1000); - } - - // Do nothing... the callback mechanism will handle everything! - } - }); - - function addLogging() { - window.document.addEventListener('DOMContentLoaded', function() { - var currentTestAssertions = []; - - QUnit.log(function(details) { - var response; - - // Ignore passing assertions - if (details.result) { - return; - } - - response = details.message || ''; - - if (typeof details.expected !== 'undefined') { - if (response) { - response += ', '; - } - - response += 'expected: ' + details.expected + ', but was: ' + details.actual; - } - - if (details.source) { - response += "\n" + details.source; - } - - currentTestAssertions.push('Failed assertion: ' + response); - }); - - QUnit.testDone(function(result) { - var i, - len, - name = result.module + ': ' + result.name; - - if (result.failed) { - console.log('Test failed: ' + name); - - for (i = 0, len = currentTestAssertions.length; i < len; i++) { - console.log(' ' + currentTestAssertions[i]); - } - } - - currentTestAssertions.length = 0; - }); - - QUnit.done(function(result) { - console.log('Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.'); - - if (typeof window.callPhantom === 'function') { - window.callPhantom({ - 'name': 'QUnit.done', - 'data': result - }); - } - }); - }, false); - } -})(); diff --git a/test/unit/architect/polyfill_test.js b/test/unit/architect/polyfill_test.js deleted file mode 100644 index 6f38fc4..0000000 --- a/test/unit/architect/polyfill_test.js +++ /dev/null @@ -1,54 +0,0 @@ -// Helpers -var disableWorkers = function() { - Architect.SUPPORT_WORKER = false -} - -var makeSureWorkersAreDisabled = function() { - ok(Architect.SUPPORT_WORKER === false, 'Workers are disabled') -} - -// Default Workers -asyncTest('Proxy Polyfill', function() { - disableWorkers() - makeSureWorkersAreDisabled() - - Architect.proxy('Foo', function(data) { - ok(data === 'Foo') - start() - }) -}) - -asyncTest('Ajax Polyfill', function() { - disableWorkers() - makeSureWorkersAreDisabled() - - Architect.ajax('https://api.github.com/users/etiennelem', function(data) { - ok(JSON.parse(data).login === 'EtienneLem') - start() - }) -}) - -asyncTest('JSONP Polyfill', function() { - disableWorkers() - makeSureWorkersAreDisabled() - - Architect.jsonp('https://api.github.com/users/etiennelem', function(data) { - ok(data.data.login === 'EtienneLem') - start() - }) -}) - -// Custom Workers -asyncTest('Custom Fallback', function() { - disableWorkers() - makeSureWorkersAreDisabled() - - var foozleWorkerFallback = function(data) { - return (data + 'zle_doo').toUpperCase() - } - - Architect.workFrom('./fixture/foozle_worker.js', 'foo', foozleWorkerFallback, function(data) { - ok(data === 'FOOZLE_DOO') - start() - }) -}) diff --git a/test/unit/architect_test.js b/test/unit/architect_test.js deleted file mode 100644 index 40968ff..0000000 --- a/test/unit/architect_test.js +++ /dev/null @@ -1,49 +0,0 @@ -// Config -test('Worker Support', function() { - ok(Architect.SUPPORT_WORKER === true) -}) - -test('Custom Workers Path', function() { - initialWorkerPath = Architect.workersPath - - Architect.setupWorkersPath('fake/path') - ok(Architect.workersPath === 'fake/path', 'Custom path') - - Architect.setupWorkersPath('./fake/path') - ok(Architect.workersPath === './fake/path', 'Relative path') - - Architect.setupWorkersPath('fake/path/') - ok(Architect.workersPath === 'fake/path', 'Removes trailing slash') - - Architect.setupWorkersPath(initialWorkerPath) -}) - -// Default Workers -asyncTest('Proxy Worker', function() { - Architect.proxy('Foo', function(data) { - ok(data === 'Foo') - start() - }) -}) - -asyncTest('Ajax Worker', function() { - Architect.ajax('https://api.github.com/users/etiennelem', function(data) { - ok(JSON.parse(data).login === 'EtienneLem') - start() - }) -}) - -asyncTest('JSONP Worker', function() { - Architect.jsonp('https://api.github.com/users/etiennelem', function(data) { - ok(data.data.login === 'EtienneLem') - start() - }) -}) - -// Custom Workers -asyncTest('Custom Worker', function() { - Architect.workFrom('./fixture/foozle_worker.js', 'foo', function(data) { - ok(data === 'FOOZLE') - start() - }) -}) From 80bbc8fcc940e3b93d5828a825c18ad94400ed1b Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 19 Mar 2015 15:37:54 -0400 Subject: [PATCH 06/45] Port the whole thing to CommonJS - Get rid of Rails engine - Make JSONP much more configurable - A standalone version is available in /dist --- dist/architect.min.js | 1 + dist/workers/ajax_worker.min.js | 1 + dist/workers/jsonp_worker.min.js | 1 + examples/short_lived_workers/app.js | 23 +++++ examples/short_lived_workers/index.html | 9 ++ gulpfile.js | 50 +++++++++++ lib/architect.coffee | 56 ++++++++++++ .../polyfills/worker_polyfill.coffee | 27 ++++++ .../workers/ajax_worker_polyfill.coffee | 48 ++++++++++ .../workers/jsonp_worker_polyfill.coffee | 35 ++++++++ lib/workers/ajax_worker.coffee | 60 +++++++++++++ lib/workers/jsonp_worker.coffee | 17 ++++ package.json | 34 +++++++ webpack.config.js | 89 +++++++++++++++++++ 14 files changed, 451 insertions(+) create mode 100644 dist/architect.min.js create mode 100644 dist/workers/ajax_worker.min.js create mode 100644 dist/workers/jsonp_worker.min.js create mode 100644 examples/short_lived_workers/app.js create mode 100644 examples/short_lived_workers/index.html create mode 100644 gulpfile.js create mode 100644 lib/architect.coffee create mode 100644 lib/architect/polyfills/worker_polyfill.coffee create mode 100644 lib/architect/polyfills/workers/ajax_worker_polyfill.coffee create mode 100644 lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee create mode 100644 lib/workers/ajax_worker.coffee create mode 100644 lib/workers/jsonp_worker.coffee create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/dist/architect.min.js b/dist/architect.min.js new file mode 100644 index 0000000..4a11eea --- /dev/null +++ b/dist/architect.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,i,p;for(o={},i=["ajax","jsonp"],s=0,u=i.length;u>s;s++)p=i[s],o[p]=r(1)("./"+p+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t,e){return new Promise(function(r){return function(n){var o;return o=r.spawnWorker(e),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),n(t.data)})}}(this))},t.prototype.jsonp=function(t,e){return null==e&&(e={}),"string"==typeof t&&(t={url:t}),this.work(t,"jsonp")},t.prototype.ajax=function(t){var e,r;return null==t&&(t={}),r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work(t,"ajax").then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,i,p,a;u=t,i=u.type,p=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(i,p);for(n in s)o=s[n],a.setRequestHeader(n,o);return a.onreadystatechange=function(t){return function(){var e,n;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){n=a.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=a.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(a):t.handleSuccess(n)}return t.handleError(a)}}}(this),a.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(e){return delete window[r],t.removeScript(),t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js new file mode 100644 index 0000000..b67874c --- /dev/null +++ b/dist/workers/ajax_worker.min.js @@ -0,0 +1 @@ +!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e,t){var s,r,n,a,o,p,u;for(u={},o=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],r=0,a=o.length;a>r;r++)n=o[r],u[n]=e[n];try{"json"===t&&(p=u.response,u.response=/^\s*$/.test(p)?null:JSON.parse(p))}catch(c){s=c}return postMessage({error:u})},addEventListener("message",function(s){var r,n,a,o,p,u,c,i,d,l;c=s.data,i=c.type,d=c.url,n=c.data,a=c.dataType,r=c.contentType,u=c.headers,i||(i="GET"),u||(u={}),u["X-Requested-With"]="XMLHttpRequest",r!==!1&&(u["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(i,d);for(o in u)p=u[o],l.setRequestHeader(o,p);return l.onreadystatechange=function(){var s,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===a?(1,eval)(r):"xml"===a?r=l.responseXML:"json"===a&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){s=n}return s?e(l,a):t(r)}return e(l,a)}},l.send(n)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js new file mode 100644 index 0000000..f253dc2 --- /dev/null +++ b/dist/workers/jsonp_worker.min.js @@ -0,0 +1 @@ +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(t){var r,s,n,a,o;return n=t.data,o=n.url,r=n.callbackAttribute,s=n.callbackFnName,void 0===r&&(r="callback"),void 0===s&&(s="handleRequest"),self[s]=function(e){return postMessage(e)},a=r?e(o,r+"="+s):o,importScripts(a)})}]); \ No newline at end of file diff --git a/examples/short_lived_workers/app.js b/examples/short_lived_workers/app.js new file mode 100644 index 0000000..66dbb69 --- /dev/null +++ b/examples/short_lived_workers/app.js @@ -0,0 +1,23 @@ +var Architect = require('architect') + +architect = new Architect({ + workersPath: '/build/workers', + workersSuffix: '_worker.js', +}) + +// JSONP +architect.jsonp({ + url: 'https://api.github.com/users/etiennelem' +}).then(function(e) { console.log('JSONP:', e) }) + +// Ajax +architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) + .then(function(e) { console.log('AJAX:', e) }) + .catch(function(e) { console.log('AJAX ERROR:', e) }) + +// $.ajax style +architect.ajax({ + url: 'https://api.github.com/users/etiennelem', + dataType: 'json', + success: function(e) { console.log('AJAX:', e) } +}) diff --git a/examples/short_lived_workers/index.html b/examples/short_lived_workers/index.html new file mode 100644 index 0000000..f251881 --- /dev/null +++ b/examples/short_lived_workers/index.html @@ -0,0 +1,9 @@ + + + + Architect: Short-lived Workers + + + + + diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..3199b13 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,50 @@ +var gulp = require('gulp'); +var del = require('del'); +var connect = require('gulp-connect'); +var webpack = require('gulp-webpack'); +var webpackConfig = require('./webpack.config.js'); + +var port = process.env.PORT || 8080; +var reloadPort = process.env.RELOAD_PORT || 35729; + +var webpackFor = function(target) { + del([target]) + + configs = webpackConfig[target] + if (!Array.isArray(configs)) { configs = [configs] } + + for (var i = 0; i < configs.length; i++) { + config = configs[i] + + webpack(config) + .pipe(gulp.dest(target)) + } +} + +gulp.task('build', function () { + webpackFor('build') +}); + +gulp.task('dist', function() { + webpackFor('dist') +}) + +gulp.task('serve', function () { + connect.server({ + port: port, + livereload: { + port: reloadPort + } + }); +}); + +gulp.task('reload-js', function () { + return gulp.src('./build/*.js') + .pipe(connect.reload()); +}); + +gulp.task('watch', function () { + gulp.watch(['./build/*.js'], ['reload-js']); +}); + +gulp.task('default', ['build', 'serve', 'watch']); diff --git a/lib/architect.coffee b/lib/architect.coffee new file mode 100644 index 0000000..560eabb --- /dev/null +++ b/lib/architect.coffee @@ -0,0 +1,56 @@ +# Requires +Polyfills = {} +for type in ['ajax', 'jsonp'] + Polyfills[type] = require("./architect/polyfills/workers/#{type}_worker_polyfill.coffee") + +# Architect +class Architect + constructor: ({ workersPath, workersSuffix } = {}) -> + @jobs = {} + @workersPath = workersPath || '/workers' + @workersSuffix = workersSuffix || '_worker.min.js' + + spawnWorker: (type) -> + return this.getPolyfillForType(type) unless this.workersAreSupported() + new Worker(this.getWorkersPathForType(type)) + + getWorkersPathForType: (type) -> + "#{@workersPath}/#{type}#{@workersSuffix}" + + getPolyfillForType: (type) -> + new Polyfills[type] + + workersAreSupported: -> + @workersSupported ?= !!window.Worker + + # Short-lived workers + work: (data, type) -> + new Promise (resolve) => + worker = this.spawnWorker(type) + worker.postMessage(data) + worker.addEventListener 'message', (e) -> + worker.terminate() + resolve(e.data) + + jsonp: (data, options = {}) -> + if typeof data is 'string' + data = { url: data } + + this.work(data, 'jsonp') + + ajax: (options = {}) -> + { success, error } = options + delete options.success + delete options.error + + new Promise (resolve, reject) => + this.work(options, 'ajax').then (data) -> + if 'success' of data + resolve(data.success) + success?(data.success) + else if 'error' of data + reject(data.error) + error?(data.error) + +# Export +module.exports = Architect diff --git a/lib/architect/polyfills/worker_polyfill.coffee b/lib/architect/polyfills/worker_polyfill.coffee new file mode 100644 index 0000000..32379aa --- /dev/null +++ b/lib/architect/polyfills/worker_polyfill.coffee @@ -0,0 +1,27 @@ +class WorkerPolyfill + constructor: -> + @callbacks = {} + @callbacksQueue = {} + + addEventListener: (type, callback) -> + @callbacks[type] = callback + + return unless data = @callbacksQueue[type] + delete @callbacksQueue[type] + + this.dispatch(type, data) + + dispatch: (type, data) -> + if @callbacks[type] + @callbacks[type]({data: data}) + else + @callbacksQueue[type] = data + + handleRequest: (data) -> + this.dispatch('message', data) + + postMessage: -> # Implemented in child polyfills + terminate: -> # This is meant to be empty + +# Export +module.exports = WorkerPolyfill diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee new file mode 100644 index 0000000..b785a5d --- /dev/null +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -0,0 +1,48 @@ +WorkerPolyfill = require('../worker_polyfill.coffee') + +class AjaxWorkerPolyfill extends WorkerPolyfill + handleSuccess: (result) -> this.handleRequest(success: result) + handleError: (xhr) -> this.handleRequest(error: xhr) + + postMessage: (data) -> + { type, url, data, dataType, contentType, headers } = data + + type ||= 'GET' + + headers ||= {} + headers['X-Requested-With'] = 'XMLHttpRequest' + + if contentType isnt false + headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' + + xhr = new XMLHttpRequest + xhr.open(type, url) + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers + + xhr.onreadystatechange = (e) => + return unless xhr.readyState is 4 + + # Success + if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 + result = xhr.responseText + + try + if dataType is 'script' + `(1,eval)(result)` + else if dataType is 'xml' + result = xhr.responseXML + else if dataType is 'json' + result = if /^\s*$/.test(result) then null else JSON.parse(result) + catch error + + return this.handleError(xhr) if error + this.handleSuccess(result) + + # Error + else + this.handleError(xhr) + + xhr.send(data) + +# Export +module.exports = AjaxWorkerPolyfill diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee new file mode 100644 index 0000000..0fce101 --- /dev/null +++ b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee @@ -0,0 +1,35 @@ +WorkerPolyfill = require('../worker_polyfill.coffee') + +class JSONPWorkerPolyfill extends WorkerPolyfill + postMessage: (data) -> + { url, callbackAttribute, callbackFnName } = data + + if callbackAttribute is undefined + callbackAttribute = 'callback' + + if callbackFnName is undefined + @jsonpID ||= 0 + callbackFnName = 'architect_jsonp' + (++@jsonpID) + + window[callbackFnName] = (response) => + delete window[callbackFnName] + this.removeScript() + this.handleRequest(response) + + request = if callbackAttribute then this.appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url + this.addScript(request) + + addScript: (request) -> + @tmpScript = document.createElement('script') + @tmpScript.src = request + + document.head.appendChild(@tmpScript) + + removeScript: -> + document.head.removeChild(@tmpScript) + + appendQuery: (url, query) -> + (url + '&' + query).replace(/[&?]{1,2}/, '?') + +# Export +module.exports = JSONPWorkerPolyfill diff --git a/lib/workers/ajax_worker.coffee b/lib/workers/ajax_worker.coffee new file mode 100644 index 0000000..6aa172d --- /dev/null +++ b/lib/workers/ajax_worker.coffee @@ -0,0 +1,60 @@ +handleSuccess = (result) -> postMessage(success: result) +handleError = (xhr, dataType) -> + # Returning xhr directly throws DataCloneError + result = {} + result[key] = xhr[key] for key in [ + 'response', 'responseType', 'responseText', 'responseXML', 'responseURL' + 'status', 'statusText' + 'withCredentials' + 'readyState' + 'timeout' + ] + + # Parse response if dataType is json + try + if dataType is 'json' + response = result['response'] + result['response'] = if /^\s*$/.test(response) then null else JSON.parse(response) + catch error + + postMessage(error: result) + +addEventListener 'message', (e) -> + { type, url, data, dataType, contentType, headers } = e.data + + type ||= 'GET' + + headers ||= {} + headers['X-Requested-With'] = 'XMLHttpRequest' + + if contentType isnt false + headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' + + xhr = new XMLHttpRequest + xhr.open(type, url) + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers + + xhr.onreadystatechange = (e) -> + return unless xhr.readyState is 4 + + # Success + if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 + result = xhr.responseText + + try + if dataType is 'script' + `(1,eval)(result)` + else if dataType is 'xml' + result = xhr.responseXML + else if dataType is 'json' + result = if /^\s*$/.test(result) then null else JSON.parse(result) + catch error + + return handleError(xhr, dataType) if error + handleSuccess(result) + + # Error + else + handleError(xhr, dataType) + + xhr.send(data) diff --git a/lib/workers/jsonp_worker.coffee b/lib/workers/jsonp_worker.coffee new file mode 100644 index 0000000..b9a9161 --- /dev/null +++ b/lib/workers/jsonp_worker.coffee @@ -0,0 +1,17 @@ +appendQuery = (url, query) -> + (url + '&' + query).replace(/[&?]{1,2}/, '?') + +addEventListener 'message', (e) -> + { url, callbackAttribute, callbackFnName } = e.data + + if callbackAttribute is undefined + callbackAttribute = 'callback' + + if callbackFnName is undefined + callbackFnName = 'handleRequest' + + self[callbackFnName] = (response) -> + postMessage(response) + + request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url + importScripts(request) diff --git a/package.json b/package.json new file mode 100644 index 0000000..4f237ed --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "architect", + "version": "0.2.0", + "description": "Architect is a JavaScript library built on top of Web Workers that will handle and polyfill HTML Web Workers", + "main": "dist/architect.min.js", + "repository": { + "type": "git", + "url": "https://github.com/EtienneLem/architect.git" + }, + "scripts": { + "start": "./node_modules/.bin/gulp" + }, + "keywords": [ + "architect", + "workers", + "web workers" + ], + "author": "Etienne Lemay ", + "license": "MIT", + "homepage": "https://github.com/EtienneLem/architect", + "bugs": { + "url": "https://github.com/EtienneLem/architect/issues" + }, + "devDependencies": { + "coffee-script": "^1.7.1", + "del": "^1.1.1", + "gulp": "^3.8.10", + "gulp-connect": "^2.2.0", + "gulp-webpack": "^1.2.0", + "expose-loader": "^0.6.0", + "coffee-loader": "^0.7.2", + "webpack": "^1.5.3" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..3905645 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,89 @@ +var webpack = require('webpack') + +// Examples +var examples = { + cache: true, + watch: true, + + entry: { + 'short_lived_workers_example': ['./examples/short_lived_workers/app.js'], + }, + + output: { + filename: '[name].js' + }, + + module: { + loaders: [ + { test: /\.coffee$/, loader: 'coffee-loader' }, + ] + }, + + resolve: { + root: __dirname, + alias: { + 'architect': 'lib/architect.coffee' + } + }, +} + +// Workers +var workers = function(dist) { + var configs = { + cache: true, + watch: true, + + entry: { + 'workers/ajax_worker': ['./lib/workers/ajax_worker.coffee'], + 'workers/jsonp_worker': ['./lib/workers/jsonp_worker.coffee'], + }, + + output: { + filename: '[name].js' + }, + + module: { + loaders: [ + { test: /\.coffee$/, loader: 'coffee-loader' }, + ] + }, + } + + if (dist) { + configs.output.filename = '[name].min.js' + configs.watch = false + configs.plugins = architect.plugins + } + + return configs +} + +// Architect +var architect = { + cache: true, + + entry: './lib/architect.coffee', + output: { + filename: 'architect.min.js', + library: 'Architect', + libraryTarget: 'umd', + }, + + module: { + loaders: [ + { test: /\.coffee$/, loader: 'coffee-loader' }, + ] + }, + + plugins: [ + new webpack.optimize.UglifyJsPlugin({ + compressor: { warnings: false } + }) + ], +} + +// Export +module.exports = { + build: [examples, workers(false)], + dist: [architect, workers(true)], +} From 562900159c4c7854699775a4e6b6e12e916e64e7 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 20 Mar 2015 10:53:40 -0400 Subject: [PATCH 07/45] Add custom workers --- dist/architect.min.js | 2 +- examples/custom_workers/app.js | 14 +++++++++++ examples/custom_workers/index.html | 9 ++++++++ .../custom_workers/workers/custom_worker.js | 4 ++++ lib/architect.coffee | 23 ++++++++++++++----- webpack.config.js | 2 ++ 6 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 examples/custom_workers/app.js create mode 100644 examples/custom_workers/index.html create mode 100644 examples/custom_workers/workers/custom_worker.js diff --git a/dist/architect.min.js b/dist/architect.min.js index 4a11eea..ee6c201 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,i,p;for(o={},i=["ajax","jsonp"],s=0,u=i.length;u>s;s++)p=i[s],o[p]=r(1)("./"+p+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t,e){return new Promise(function(r){return function(n){var o;return o=r.spawnWorker(e),o.postMessage(t),o.addEventListener("message",function(t){return o.terminate(),n(t.data)})}}(this))},t.prototype.jsonp=function(t,e){return null==e&&(e={}),"string"==typeof t&&(t={url:t}),this.work(t,"jsonp")},t.prototype.ajax=function(t){var e,r;return null==t&&(t={}),r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work(t,"ajax").then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,i,p,a;u=t,i=u.type,p=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),a=new XMLHttpRequest,a.open(i,p);for(n in s)o=s[n],a.setRequestHeader(n,o);return a.onreadystatechange=function(t){return function(){var e,n;if(4===a.readyState){if(a.status>=200&&a.status<300||304===a.status){n=a.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=a.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(a):t.handleSuccess(n)}return t.handleError(a)}}}(this),a.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(e){return delete window[r],t.removeScript(),t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,p,a;for(o={},p=["ajax","jsonp"],s=0,u=p.length;u>s;s++)a=p[s],o[a]=r(1)("./"+a+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t){var e,r,n;return e=t.data,r=t.type,n=t.worker,new Promise(function(t){return function(o){return n||(n=t.spawnWorker(r)),n.postMessage(e),n.addEventListener("message",function(t){return n.terminate(),o(t.data)})}}(this))},t.prototype.jsonp=function(t){return"string"==typeof t&&(t={url:t}),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r;return r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work({data:t,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n;return n=t.path,e=t.data,r=t.fallback,new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,p,a,i;u=t,p=u.type,a=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,p||(p="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),i=new XMLHttpRequest,i.open(p,a);for(n in s)o=s[n],i.setRequestHeader(n,o);return i.onreadystatechange=function(t){return function(){var e,n;if(4===i.readyState){if(i.status>=200&&i.status<300||304===i.status){n=i.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=i.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(i):t.handleSuccess(n)}return t.handleError(i)}}}(this),i.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(e){return delete window[r],t.removeScript(),t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/examples/custom_workers/app.js b/examples/custom_workers/app.js new file mode 100644 index 0000000..e3e0769 --- /dev/null +++ b/examples/custom_workers/app.js @@ -0,0 +1,14 @@ +var Architect = require('architect') + +architect = new Architect({ + workersPath: '/build/workers', + workersSuffix: '_worker.js', +}) + +architect.custom({ + path: '/build/workers/custom_worker.js', + data: 'foo', + fallback: function(data) { return (data + 'zle (fallback)').toUpperCase() } +}).then(function(data) { + console.log('Custom:', data) +}) diff --git a/examples/custom_workers/index.html b/examples/custom_workers/index.html new file mode 100644 index 0000000..72badd7 --- /dev/null +++ b/examples/custom_workers/index.html @@ -0,0 +1,9 @@ + + + + Architect: Custom Workers + + + + + diff --git a/examples/custom_workers/workers/custom_worker.js b/examples/custom_workers/workers/custom_worker.js new file mode 100644 index 0000000..77225fc --- /dev/null +++ b/examples/custom_workers/workers/custom_worker.js @@ -0,0 +1,4 @@ +addEventListener('message', function(e) { + data = e.data + 'zle' + postMessage(data.toUpperCase()) +}) diff --git a/lib/architect.coffee b/lib/architect.coffee index 560eabb..eb6c0cf 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -24,27 +24,27 @@ class Architect @workersSupported ?= !!window.Worker # Short-lived workers - work: (data, type) -> + work: ({ data, type, worker }) -> new Promise (resolve) => - worker = this.spawnWorker(type) + worker ||= this.spawnWorker(type) worker.postMessage(data) worker.addEventListener 'message', (e) -> worker.terminate() resolve(e.data) - jsonp: (data, options = {}) -> + jsonp: (data) -> if typeof data is 'string' data = { url: data } - this.work(data, 'jsonp') + this.work(data: data, type: 'jsonp') - ajax: (options = {}) -> + ajax: (options) -> { success, error } = options delete options.success delete options.error new Promise (resolve, reject) => - this.work(options, 'ajax').then (data) -> + this.work(data: options, type: 'ajax').then (data) -> if 'success' of data resolve(data.success) success?(data.success) @@ -52,5 +52,16 @@ class Architect reject(data.error) error?(data.error) + # Custom workers + custom: ({ path, data, fallback }) -> + new Promise (resolve, reject) => + if this.workersAreSupported() + worker = new Worker(path) + this.work(data: data, worker: worker).then(resolve) + else if fallback + resolve(fallback(data)) + else + reject("Workers not supported and fallback not provided for #{path}") + # Export module.exports = Architect diff --git a/webpack.config.js b/webpack.config.js index 3905645..2847ddb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,6 +7,8 @@ var examples = { entry: { 'short_lived_workers_example': ['./examples/short_lived_workers/app.js'], + 'custom_workers_example': ['./examples/custom_workers/app.js'], + 'workers/custom_worker': ['./examples/custom_workers/workers/custom_worker.js'], }, output: { From 52a602bff385243735ddc434e5c1bd330af36696 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 20 Mar 2015 13:21:10 -0400 Subject: [PATCH 08/45] Handle JSONP multiple arguments --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee | 5 +++-- lib/workers/jsonp_worker.coffee | 5 +++-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index ee6c201..b1265f3 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,p,a;for(o={},p=["ajax","jsonp"],s=0,u=p.length;u>s;s++)a=p[s],o[a]=r(1)("./"+a+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t){var e,r,n;return e=t.data,r=t.type,n=t.worker,new Promise(function(t){return function(o){return n||(n=t.spawnWorker(r)),n.postMessage(e),n.addEventListener("message",function(t){return n.terminate(),o(t.data)})}}(this))},t.prototype.jsonp=function(t){return"string"==typeof t&&(t={url:t}),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r;return r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work({data:t,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n;return n=t.path,e=t.data,r=t.fallback,new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,p,a,i;u=t,p=u.type,a=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,p||(p="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),i=new XMLHttpRequest,i.open(p,a);for(n in s)o=s[n],i.setRequestHeader(n,o);return i.onreadystatechange=function(t){return function(){var e,n;if(4===i.readyState){if(i.status>=200&&i.status<300||304===i.status){n=i.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=i.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(i):t.handleSuccess(n)}return t.handleError(i)}}}(this),i.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(e){return delete window[r],t.removeScript(),t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,a,p;for(o={},a=["ajax","jsonp"],s=0,u=a.length;u>s;s++)p=a[s],o[p]=r(1)("./"+p+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t){var e,r,n;return e=t.data,r=t.type,n=t.worker,new Promise(function(t){return function(o){return n||(n=t.spawnWorker(r)),n.postMessage(e),n.addEventListener("message",function(t){return n.terminate(),o(t.data)})}}(this))},t.prototype.jsonp=function(t){return"string"==typeof t&&(t={url:t}),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r;return r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work({data:t,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n;return n=t.path,e=t.data,r=t.fallback,new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,a,p,i;u=t,a=u.type,p=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,a||(a="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),i=new XMLHttpRequest,i.open(a,p);for(n in s)o=s[n],i.setRequestHeader(n,o);return i.onreadystatechange=function(t){return function(){var e,n;if(4===i.readyState){if(i.status>=200&&i.status<300||304===i.status){n=i.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=i.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(i):t.handleSuccess(n)}return t.handleError(i)}}}(this),i.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty,a=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index b67874c..4aa0b77 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e,t){var s,r,n,a,o,p,u;for(u={},o=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],r=0,a=o.length;a>r;r++)n=o[r],u[n]=e[n];try{"json"===t&&(p=u.response,u.response=/^\s*$/.test(p)?null:JSON.parse(p))}catch(c){s=c}return postMessage({error:u})},addEventListener("message",function(s){var r,n,a,o,p,u,c,i,d,l;c=s.data,i=c.type,d=c.url,n=c.data,a=c.dataType,r=c.contentType,u=c.headers,i||(i="GET"),u||(u={}),u["X-Requested-With"]="XMLHttpRequest",r!==!1&&(u["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(i,d);for(o in u)p=u[o],l.setRequestHeader(o,p);return l.onreadystatechange=function(){var s,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===a?(1,eval)(r):"xml"===a?r=l.responseXML:"json"===a&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){s=n}return s?e(l,a):t(r)}return e(l,a)}},l.send(n)})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e,t){var r,s,n,a,o,u,p;for(p={},o=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],s=0,a=o.length;a>s;s++)n=o[s],p[n]=e[n];try{"json"===t&&(u=p.response,p.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(c){r=c}return postMessage({error:p})},addEventListener("message",function(r){var s,n,a,o,u,p,c,i,l,d;c=r.data,i=c.type,l=c.url,n=c.data,a=c.dataType,s=c.contentType,p=c.headers,i||(i="GET"),p||(p={}),p["X-Requested-With"]="XMLHttpRequest",s!==!1&&(p["Content-Type"]=s||"application/x-www-form-urlencoded"),d=new XMLHttpRequest,d.open(i,l);for(o in p)u=p[o],d.setRequestHeader(o,u);return d.onreadystatechange=function(){var r,s;if(4===d.readyState){if(d.status>=200&&d.status<300||304===d.status){s=d.responseText;try{"script"===a?(1,eval)(s):"xml"===a?s=d.responseXML:"json"===a&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(d,a):t(s)}return e(d,a)}},d.send(n)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index f253dc2..6010adb 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(t){var r,s,n,a,o;return n=t.data,o=n.url,r=n.callbackAttribute,s=n.callbackFnName,void 0===r&&(r="callback"),void 0===s&&(s="handleRequest"),self[s]=function(e){return postMessage(e)},a=r?e(o,r+"="+s):o,importScripts(a)})}]); \ No newline at end of file +!function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var n,a,c,l,o;return c=r.data,o=c.url,n=c.callbackAttribute,a=c.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage(e)},l=n?e(o,n+"="+a):o,importScripts(l)})}]); \ No newline at end of file diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee index 0fce101..37ca632 100644 --- a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee @@ -11,10 +11,11 @@ class JSONPWorkerPolyfill extends WorkerPolyfill @jsonpID ||= 0 callbackFnName = 'architect_jsonp' + (++@jsonpID) - window[callbackFnName] = (response) => + window[callbackFnName] = (args...) => delete window[callbackFnName] this.removeScript() - this.handleRequest(response) + args = if args.length > 1 then args else args[0] + this.handleRequest(args) request = if callbackAttribute then this.appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url this.addScript(request) diff --git a/lib/workers/jsonp_worker.coffee b/lib/workers/jsonp_worker.coffee index b9a9161..ffacc78 100644 --- a/lib/workers/jsonp_worker.coffee +++ b/lib/workers/jsonp_worker.coffee @@ -10,8 +10,9 @@ addEventListener 'message', (e) -> if callbackFnName is undefined callbackFnName = 'handleRequest' - self[callbackFnName] = (response) -> - postMessage(response) + self[callbackFnName] = (args...) -> + args = if args.length > 1 then args else args[0] + postMessage(args) request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url importScripts(request) From 1574de909c322a20686f43cf662e753997ff8376 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 23 Mar 2015 22:13:16 -0400 Subject: [PATCH 09/45] Add specs --- lib/architect.coffee | 30 +++-- package.json | 8 +- specs/architect_spec.coffee | 154 ++++++++++++++++++++++ specs/fixtures/workers/fake_worker.coffee | 2 + specs/index.html | 9 ++ specs/index.js | 1 + specs/spec_helper.coffee | 37 ++++++ webpack.config.js | 9 +- 8 files changed, 235 insertions(+), 15 deletions(-) create mode 100644 specs/architect_spec.coffee create mode 100644 specs/fixtures/workers/fake_worker.coffee create mode 100644 specs/index.html create mode 100644 specs/index.js create mode 100644 specs/spec_helper.coffee diff --git a/lib/architect.coffee b/lib/architect.coffee index eb6c0cf..29938d3 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -7,8 +7,8 @@ for type in ['ajax', 'jsonp'] class Architect constructor: ({ workersPath, workersSuffix } = {}) -> @jobs = {} - @workersPath = workersPath || '/workers' - @workersSuffix = workersSuffix || '_worker.min.js' + @workersPath = if workersPath then "/#{workersPath.replace(/^\//, '')}" else '/workers' + @workersSuffix = if workersSuffix then "#{workersSuffix.replace(/\.js$/, '')}.js" else '_worker.min.js' spawnWorker: (type) -> return this.getPolyfillForType(type) unless this.workersAreSupported() @@ -18,10 +18,15 @@ class Architect "#{@workersPath}/#{type}#{@workersSuffix}" getPolyfillForType: (type) -> - new Polyfills[type] + klass = Polyfills[type] - workersAreSupported: -> - @workersSupported ?= !!window.Worker + unless klass + throw new Error("#{type} is not a valid type") + + new klass + + workersAreSupported: (scope = window) -> + @workersSupported ?= 'Worker' of scope # Short-lived workers work: ({ data, type, worker }) -> @@ -32,19 +37,24 @@ class Architect worker.terminate() resolve(e.data) - jsonp: (data) -> + jsonp: (data = {}) -> if typeof data is 'string' data = { url: data } + throw new Error("Missing required “url” parameter") unless 'url' of data this.work(data: data, type: 'jsonp') - ajax: (options) -> + ajax: (options = {}) -> + throw new Error("Missing required “url” parameter") unless 'url' of options { success, error } = options - delete options.success - delete options.error + + # Clone options without callback functions + opts = JSON.parse(JSON.stringify(options)) + delete opts.success + delete opts.error new Promise (resolve, reject) => - this.work(data: options, type: 'ajax').then (data) -> + this.work(data: opts, type: 'ajax').then (data) -> if 'success' of data resolve(data.success) success?(data.success) diff --git a/package.json b/package.json index 4f237ed..471a89d 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,17 @@ "url": "https://github.com/EtienneLem/architect/issues" }, "devDependencies": { + "chai": "^2.1.2", + "chai-as-promised": "^4.3.0", + "coffee-loader": "^0.7.2", "coffee-script": "^1.7.1", "del": "^1.1.1", + "expose-loader": "^0.6.0", "gulp": "^3.8.10", "gulp-connect": "^2.2.0", "gulp-webpack": "^1.2.0", - "expose-loader": "^0.6.0", - "coffee-loader": "^0.7.2", + "mocha-loader": "^0.7.1", + "simple-mock": "^0.2.9", "webpack": "^1.5.3" } } diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee new file mode 100644 index 0000000..1b3c7ab --- /dev/null +++ b/specs/architect_spec.coffee @@ -0,0 +1,154 @@ +{ Architect, simple, expect, helpers } = require('./spec_helper.coffee') + +describe 'Architect', -> + beforeEach -> + @architect = new Architect + workersPath: '/build/workers' + workersSuffix: '_worker.js' + + describe '#getWorkersPathForType', -> + it 'returns a relative worker path', -> + architect = new Architect + expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foo_worker.min.js') + + architect = new Architect(workersPath: '/specs') + expect(architect.getWorkersPathForType('foo')).to.eq('/specs/foo_worker.min.js') + + architect = new Architect(workersPath: 'specs') + expect(architect.getWorkersPathForType('foo')).to.eq('/specs/foo_worker.min.js') + + architect = new Architect(workersSuffix: 'specs.js') + expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foospecs.js') + + architect = new Architect(workersSuffix: '_specs.bar') + expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foo_specs.bar.js') + + describe '#getPolyfillForType', -> + it 'returns a worker polyfill', -> + architect = new Architect + expect(architect.getPolyfillForType('ajax').constructor.name).to.eq('AjaxWorkerPolyfill') + expect(architect.getPolyfillForType('jsonp').constructor.name).to.eq('JSONPWorkerPolyfill') + expect(-> architect.getPolyfillForType('specs')).to.throw('specs is not a valid type') + + describe '#workersAreSupported', -> + beforeEach -> @architect = new Architect + + describe 'when workers are supported', -> + it 'returns true', -> expect(@architect.workersAreSupported({ Worker: true })).to.be.true + + describe 'when workers are not supported', -> + it 'returns false', -> expect(@architect.workersAreSupported({})).to.be.false + + describe '#spawnWorker', -> + describe 'when workers are supported', -> + it 'returns a WebWorker', -> + worker = @architect.spawnWorker('ajax') + expect(worker).to.be.an.instanceof(window.Worker) + + describe 'when workers are not supported', -> + beforeEach -> simple.mock(@architect, 'workersAreSupported', -> false) + it 'returns a WorkerPolyfill', -> + worker = @architect.spawnWorker('ajax') + expect(worker.constructor.name).to.eq('AjaxWorkerPolyfill') + + describe 'Short-lived workers', -> + describe '#work', -> + it 'returns a promise', -> + promise = @architect.work(type: 'fake', data: { foo: 'bar' }) + expect(promise).to.be.an.instanceof(window.Promise) + + result = @architect.work(type: 'fake', data: { foo: 'bar' }) + expect(result).to.eventually.deep.equal(foo: 'bar') + + it 'can receive and work on an existing worker', -> + worker = @architect.spawnWorker('fake') + simple.mock(worker, 'postMessage') + + @architect.work(worker: worker) + expect(worker.postMessage.calls.length).to.eq(1) + + it 'terminates a worker when done', (done) -> + worker = @architect.spawnWorker('fake') + simple.mock(worker, 'terminate') + + @architect.work(worker: worker).then => + expect(worker.terminate.calls.length).to.eq(1) + done() + + describe 'aliases', -> + beforeEach -> + simple.mock @architect, 'work', -> + new Promise (resolve) -> resolve({}) + + describe '#ajax', -> + it 'is an alias for Architect#work(type: "ajax")', -> + @architect.ajax(url: '') + expect(@architect.work.calls.length).to.eq(1) + expect(@architect.work.calls[0].args[0].type).to.eq('ajax') + + it 'requires url: parameter', -> + expect(=> @architect.ajax()).to.throw('Missing required “url” parameter') + expect(=> @architect.ajax(url: '')).not.to.throw() + + it 'supports $.ajax-style success/error options', (done) -> + simple.mock @architect, 'work', helpers.callbackSequence [ + => new Promise (resolve) => resolve + success: { foo: 'bar' } + => new Promise (resolve) => resolve + error: { bar: 'foo' } + ] + + options = + url: '' + success: simple.spy() + error: simple.spy() + + @architect.ajax(options) + helpers.delay 0, => + expect(options.success.calls.length).to.eq(1) + expect(options.error.calls.length).to.eq(0) + + @architect.ajax(options).catch(->) + helpers.delay 0, done, -> + expect(options.success.calls.length).to.eq(1) + expect(options.error.calls.length).to.eq(1) + + describe '#jsonp', -> + it 'is an alias for Architect#work(type: "jsonp")', -> + @architect.jsonp(url: '') + expect(@architect.work.calls.length).to.eq(1) + expect(@architect.work.calls[0].args[0].type).to.eq('jsonp') + + it 'requires url: parameter', -> + expect(=> @architect.jsonp()).to.throw('Missing required “url” parameter') + expect(=> @architect.jsonp(url: '')).not.to.throw() + + describe 'Custom workers', -> + describe '#custom', -> + describe 'when workers are supported', -> + beforeEach -> + simple.mock @architect, 'work', -> + new Promise (resolve) -> resolve({}) + + it 'is an alias for Architect#work(worker:)', -> + @architect.custom(path: '/build/workers/fake_worker.js', data: { foo: 'bar' }) + expect(@architect.work.calls.length).to.eq(1) + expect(@architect.work.calls[0].args[0].data).to.deep.equal(foo: 'bar') + expect(@architect.work.calls[0].args[0].worker).to.be.an.instanceof(window.Worker) + + describe 'when workers are not supported', -> + beforeEach -> simple.mock(@architect, 'workersAreSupported', -> false) + + describe 'when a fallback is provided', -> + beforeEach -> + @fallback = simple.spy((data) -> data.fake = true; data) + + it 'uses the fallback in the main thread', -> + result = @architect.custom(path: '/build/workers/fake_worker.js', data: { foo: 'bar' }, fallback: @fallback) + expect(@fallback.calls.length).to.equal(1) + expect(result).to.eventually.deep.equal(foo: 'bar', fake: true) + + describe 'when a fallback is not provided', -> + it 'rejects the promise', -> + result = @architect.custom(path: '/build/workers/fake_worker.js', data: { foo: 'bar' }) + expect(result).to.be.rejectedWith('Workers not supported and fallback not provided for /build/workers/fake_worker.js') diff --git a/specs/fixtures/workers/fake_worker.coffee b/specs/fixtures/workers/fake_worker.coffee new file mode 100644 index 0000000..254a379 --- /dev/null +++ b/specs/fixtures/workers/fake_worker.coffee @@ -0,0 +1,2 @@ +addEventListener 'message', (e) -> + postMessage(e.data) diff --git a/specs/index.html b/specs/index.html new file mode 100644 index 0000000..dd049d5 --- /dev/null +++ b/specs/index.html @@ -0,0 +1,9 @@ + + + + Architect Specs + + + + + diff --git a/specs/index.js b/specs/index.js new file mode 100644 index 0000000..fa5e725 --- /dev/null +++ b/specs/index.js @@ -0,0 +1 @@ +require('./architect_spec.coffee') diff --git a/specs/spec_helper.coffee b/specs/spec_helper.coffee new file mode 100644 index 0000000..5e7d1d9 --- /dev/null +++ b/specs/spec_helper.coffee @@ -0,0 +1,37 @@ +# Mocks +simple = require('simple-mock') + +# Chai +chai = require('chai') +chai.use(require('chai-as-promised')) + +# Mocha +afterEach -> + simple.restore() + +# Helpers +helpers = + delay: (duration, done, asserts) => + [asserts, done] = [done, null] if !asserts + + setTimeout => + asserts() + done?() + , duration + + callbackSequence: (callbacks) -> + fn = -> + returnValue = @_callbacks[@_nextIndex]() + @_nextIndex += 1 unless @_nextIndex == @_callbacks.length - 1 + returnValue + + fn._callbacks = callbacks + fn._nextIndex = 0 + fn.bind(fn) + +# Export +module.exports = + Architect: require('architect') + simple: simple + expect: chai.expect + helpers: helpers diff --git a/webpack.config.js b/webpack.config.js index 2847ddb..73405b5 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,11 +1,14 @@ var webpack = require('webpack') // Examples -var examples = { +var examples_and_specs = { cache: true, watch: true, entry: { + 'specs': ['mocha!./specs'], + 'workers/fake_worker': ['./specs/fixtures/workers/fake_worker.coffee'], + 'short_lived_workers_example': ['./examples/short_lived_workers/app.js'], 'custom_workers_example': ['./examples/custom_workers/app.js'], 'workers/custom_worker': ['./examples/custom_workers/workers/custom_worker.js'], @@ -86,6 +89,6 @@ var architect = { // Export module.exports = { - build: [examples, workers(false)], - dist: [architect, workers(true)], + build: [workers(false), examples_and_specs], + dist: [workers(true), architect], } From 53516cfdcf5f885dbafe032465a8c14bd95afb30 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 10:32:58 -0400 Subject: [PATCH 10/45] Refactor/DRY required params --- lib/architect.coffee | 29 +++++++++++++++++++++++++---- specs/architect_spec.coffee | 29 +++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 29938d3..43694d3 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -28,8 +28,27 @@ class Architect workersAreSupported: (scope = window) -> @workersSupported ?= 'Worker' of scope + requireParams: (requiredParams, params = {}) -> + missing = [] + requiredParams = [requiredParams] unless Array.isArray(requiredParams) + + for requiredParam in requiredParams when !(requiredParam of params) + if (splits = requiredParam.split(/\s?\|\|\s?/)).length > 1 + optional = [] + for split in splits when (split of params) + optional.push(split) + + missing.push(requiredParam) unless optional.length + else + missing.push(requiredParam) + + return unless missing.length + throw new Error("Missing required “#{missing.join(', ')}” parameter#{if missing.length > 1 then 's' else ''}") + # Short-lived workers - work: ({ data, type, worker }) -> + work: ({ data, type, worker } = {}) -> + this.requireParams('type || worker', arguments[0]) + new Promise (resolve) => worker ||= this.spawnWorker(type) worker.postMessage(data) @@ -41,11 +60,11 @@ class Architect if typeof data is 'string' data = { url: data } - throw new Error("Missing required “url” parameter") unless 'url' of data + this.requireParams('url', data) this.work(data: data, type: 'jsonp') ajax: (options = {}) -> - throw new Error("Missing required “url” parameter") unless 'url' of options + this.requireParams('url', options) { success, error } = options # Clone options without callback functions @@ -63,7 +82,9 @@ class Architect error?(data.error) # Custom workers - custom: ({ path, data, fallback }) -> + custom: ({ path, data, fallback } = {}) -> + this.requireParams('path', arguments[0]) + new Promise (resolve, reject) => if this.workersAreSupported() worker = new Worker(path) diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 1b3c7ab..2491424 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -51,6 +51,23 @@ describe 'Architect', -> worker = @architect.spawnWorker('ajax') expect(worker.constructor.name).to.eq('AjaxWorkerPolyfill') + describe '#requireParams', -> + it 'throws an error when parameter is missing', -> + expect(=> @architect.requireParams('foo', {})).to.throw('Missing required “foo” parameter') + expect(=> @architect.requireParams('foo', { foo: 'bar' })).not.to.throw() + + it 'handles multiple parameters', -> + expect(=> @architect.requireParams(['foo', 'bar'], {})).to.throw('Missing required “foo, bar” parameters') + expect(=> @architect.requireParams(['foo', 'bar'], { foo: 'bar' })).to.throw('Missing required “bar” parameter') + expect(=> @architect.requireParams(['foo', 'bar'], { foo: 'bar', bar: 'foo' })).not.to.throw() + + it 'handles “||” operator', -> + expect(=> @architect.requireParams('foo || bar', {})).to.throw('Missing required “foo || bar” parameter') + expect(=> @architect.requireParams('foo||bar', { foo: 'bar' })).not.to.throw() + expect(=> @architect.requireParams('foo ||bar', { bar: 'foo' })).not.to.throw() + expect(=> @architect.requireParams(['foo || bar', 'twiz'], { bar: 'foo' })).to.throw('Missing required “twiz” parameter') + expect(=> @architect.requireParams(['foo || bar', 'twiz'], {})).to.throw('Missing required “foo || bar, twiz” parameter') + describe 'Short-lived workers', -> describe '#work', -> it 'returns a promise', -> @@ -125,11 +142,15 @@ describe 'Architect', -> describe 'Custom workers', -> describe '#custom', -> - describe 'when workers are supported', -> - beforeEach -> - simple.mock @architect, 'work', -> - new Promise (resolve) -> resolve({}) + beforeEach -> + simple.mock @architect, 'work', -> + new Promise (resolve) -> resolve({}) + + it 'requires path: parameter', -> + expect(=> @architect.custom()).to.throw('Missing required “path” parameter') + expect(=> @architect.custom(path: '/build/workers/fake_worker.js')).not.to.throw() + describe 'when workers are supported', -> it 'is an alias for Architect#work(worker:)', -> @architect.custom(path: '/build/workers/fake_worker.js', data: { foo: 'bar' }) expect(@architect.work.calls.length).to.eq(1) From fa2dc129e92b4fe32d598070940df6a7eb72b1a5 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 10:44:06 -0400 Subject: [PATCH 11/45] Mock workers process --- specs/architect_spec.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 2491424..8469f61 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -6,6 +6,13 @@ describe 'Architect', -> workersPath: '/build/workers' workersSuffix: '_worker.js' + simple.mock window.Worker.prototype, 'postMessage', (data) -> + setTimeout => + event = new Event('message') + event.data = data + this.dispatchEvent(event) + , 0 + describe '#getWorkersPathForType', -> it 'returns a relative worker path', -> architect = new Architect From a1377dae857ad73b54010b28afd7761833ce3358 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 11:47:28 -0400 Subject: [PATCH 12/45] Do not append .js to workersSuffix - Would break any path with a cache queryString --- lib/architect.coffee | 2 +- specs/architect_spec.coffee | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 43694d3..991298a 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -8,7 +8,7 @@ class Architect constructor: ({ workersPath, workersSuffix } = {}) -> @jobs = {} @workersPath = if workersPath then "/#{workersPath.replace(/^\//, '')}" else '/workers' - @workersSuffix = if workersSuffix then "#{workersSuffix.replace(/\.js$/, '')}.js" else '_worker.min.js' + @workersSuffix = workersSuffix || '_worker.min.js' spawnWorker: (type) -> return this.getPolyfillForType(type) unless this.workersAreSupported() diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 8469f61..08f1890 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -27,9 +27,6 @@ describe 'Architect', -> architect = new Architect(workersSuffix: 'specs.js') expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foospecs.js') - architect = new Architect(workersSuffix: '_specs.bar') - expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foo_specs.bar.js') - describe '#getPolyfillForType', -> it 'returns a worker polyfill', -> architect = new Architect From d95b31072d828b6d56acd5c90c74dc72a312a06e Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 14:27:41 -0400 Subject: [PATCH 13/45] Enqueue jobs and add maximum threads --- lib/architect.coffee | 38 +++++++++++++++++++++++++++----- specs/architect_spec.coffee | 44 ++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 991298a..90c95dd 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -5,8 +5,10 @@ for type in ['ajax', 'jsonp'] # Architect class Architect - constructor: ({ workersPath, workersSuffix } = {}) -> + constructor: ({ workersPath, workersSuffix, threads } = {}) -> @jobs = {} + @queue = [] + @threads = threads || 5 @workersPath = if workersPath then "/#{workersPath.replace(/^\//, '')}" else '/workers' @workersSuffix = workersSuffix || '_worker.min.js' @@ -45,16 +47,23 @@ class Architect return unless missing.length throw new Error("Missing required “#{missing.join(', ')}” parameter#{if missing.length > 1 then 's' else ''}") + getJobId: -> + @jobId ||= 1 + @jobId++ + # Short-lived workers work: ({ data, type, worker } = {}) -> this.requireParams('type || worker', arguments[0]) + jobId = this.getJobId() new Promise (resolve) => - worker ||= this.spawnWorker(type) - worker.postMessage(data) - worker.addEventListener 'message', (e) -> - worker.terminate() - resolve(e.data) + this.enqueue(jobId).then => + @jobs[jobId] = worker ||= this.spawnWorker(type) + worker.postMessage(data) + worker.addEventListener 'message', (e) => + this.clearJob(jobId) + worker.terminate() + resolve(e.data) jsonp: (data = {}) -> if typeof data is 'string' @@ -94,5 +103,22 @@ class Architect else reject("Workers not supported and fallback not provided for #{path}") + # Threads + enqueue: (jobId) -> + new Promise (resolve) => + setTimeout => + if Object.keys(@jobs).length < @threads + resolve() + else + @queue.push({ resolve: resolve }) + , 0 + + clearJob: (jobId) -> + delete @jobs[jobId] + + return unless @queue.length + job = @queue.shift() + job.resolve() + # Export module.exports = Architect diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 08f1890..cae937d 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -72,6 +72,43 @@ describe 'Architect', -> expect(=> @architect.requireParams(['foo || bar', 'twiz'], { bar: 'foo' })).to.throw('Missing required “twiz” parameter') expect(=> @architect.requireParams(['foo || bar', 'twiz'], {})).to.throw('Missing required “foo || bar, twiz” parameter') + describe 'Threads', -> + it 'has a job qeueue', (done) -> + for i in [1..8] + @architect.work(worker: @architect.spawnWorker('fake')) + + helpers.delay 0, => + expect(Object.keys(@architect.jobs).length).to.eq(5) + expect(@architect.jobs).to.have.property(ii) for ii in [1..5] + + helpers.delay 0, => + expect(Object.keys(@architect.jobs).length).to.eq(3) + expect(@architect.jobs).to.have.property(ii) for ii in [6..8] + + helpers.delay 0, done, => + expect(Object.keys(@architect.jobs).length).to.eq(0) + + it 'is configurable', (done) -> + architect = new Architect + workersPath: '/build/workers' + workersSuffix: '_worker.js' + threads: 3 + + for i in [1..8] + architect.work(worker: architect.spawnWorker('fake')) + + helpers.delay 0, => + expect(Object.keys(architect.jobs).length).to.eq(3) + expect(architect.jobs).to.have.property(ii) for ii in [1..3] + + helpers.delay 0, => + expect(Object.keys(architect.jobs).length).to.eq(3) + expect(architect.jobs).to.have.property(ii) for ii in [4..6] + + helpers.delay 0, done, => + expect(Object.keys(architect.jobs).length).to.eq(2) + expect(architect.jobs).to.have.property(ii) for ii in [7..8] + describe 'Short-lived workers', -> describe '#work', -> it 'returns a promise', -> @@ -81,12 +118,13 @@ describe 'Architect', -> result = @architect.work(type: 'fake', data: { foo: 'bar' }) expect(result).to.eventually.deep.equal(foo: 'bar') - it 'can receive and work on an existing worker', -> + it 'can receive and work on an existing worker', (done) -> worker = @architect.spawnWorker('fake') simple.mock(worker, 'postMessage') - @architect.work(worker: worker) - expect(worker.postMessage.calls.length).to.eq(1) + @architect.work(worker: worker).then => + expect(worker.postMessage.calls.length).to.eq(1) + done() it 'terminates a worker when done', (done) -> worker = @architect.spawnWorker('fake') From 37debd59079c513fe45f7af71dea1eee2945475c Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 14:33:35 -0400 Subject: [PATCH 14/45] Spec defaults --- specs/architect_spec.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index cae937d..cacf01c 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -13,6 +13,12 @@ describe 'Architect', -> this.dispatchEvent(event) , 0 + it 'has defaults', -> + architect = new Architect + expect(architect.workersPath).to.eq('/workers') + expect(architect.workersSuffix).to.eq('_worker.min.js') + expect(architect.threads).to.eq(5) + describe '#getWorkersPathForType', -> it 'returns a relative worker path', -> architect = new Architect From 577a30a3fae620a4210afedf1b9f15015e8439aa Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 24 Mar 2015 14:38:54 -0400 Subject: [PATCH 15/45] [dist] --- dist/architect.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index b1265f3..8d08546 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,a,p;for(o={},a=["ajax","jsonp"],s=0,u=a.length;u>s;s++)p=a[s],o[p]=r(1)("./"+p+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n;e=null!=t?t:{},r=e.workersPath,n=e.workersSuffix,this.jobs={},this.workersPath=r||"/workers",this.workersSuffix=n||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){return new o[t]},t.prototype.workersAreSupported=function(){return null!=this.workersSupported?this.workersSupported:this.workersSupported=!!window.Worker},t.prototype.work=function(t){var e,r,n;return e=t.data,r=t.type,n=t.worker,new Promise(function(t){return function(o){return n||(n=t.spawnWorker(r)),n.postMessage(e),n.addEventListener("message",function(t){return n.terminate(),o(t.data)})}}(this))},t.prototype.jsonp=function(t){return"string"==typeof t&&(t={url:t}),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r;return r=t.success,e=t.error,delete t.success,delete t.error,new Promise(function(n){return function(o,s){return n.work({data:t,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof r?r(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n;return n=t.path,e=t.data,r=t.fallback,new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill.coffee":2,"./jsonp_worker_polyfill.coffee":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,u,a,p,i;u=t,a=u.type,p=u.url,t=u.data,r=u.dataType,e=u.contentType,s=u.headers,a||(a="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),i=new XMLHttpRequest,i.open(a,p);for(n in s)o=s[n],i.setRequestHeader(n,o);return i.onreadystatechange=function(t){return function(){var e,n;if(4===i.readyState){if(i.status>=200&&i.status<300||304===i.status){n=i.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=i.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(i):t.handleSuccess(n)}return t.handleError(i)}}}(this),i.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty,a=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,i,a;for(o={},i=["ajax","jsonp"],s=0,u=i.length;u>s;s++)a=i[s],o[a]=r(1)("./"+a+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.jobs={},this.queue=[],this.threads=r||5,this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,u,i,a,p,c;for(null==e&&(e={}),u=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(a=t[r],!(a in e))if((c=a.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||u.push(a)}else u.push(a);if(u.length)throw new Error("Missing required “"+u.join(", ")+"” parameter"+(u.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o,s;return n=null!=t?t:{},e=n.data,o=n.type,s=n.worker,this.requireParams("type || worker",arguments[0]),r=this.getJobId(),new Promise(function(t){return function(n){return t.enqueue(r).then(function(){return t.jobs[r]=s||(s=t.spawnWorker(o)),s.postMessage(e),s.addEventListener("message",function(e){return t.clearJob(r),s.terminate(),n(e.data)})})}}(this))},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof n?n(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t.prototype.enqueue=function(){return new Promise(function(t){return function(e){return setTimeout(function(){return Object.keys(t.jobs).length=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file From b52fc3dcded442837379e7b27c9751e7d2dd15d0 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 25 Jun 2015 15:51:42 -0400 Subject: [PATCH 16/45] =?UTF-8?q?Rename=20=E2=80=9CgetWorkersPathForType?= =?UTF-8?q?=E2=80=9D=20->=20=E2=80=9CgetWorkerPathForType=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/architect.coffee | 4 ++-- specs/architect_spec.coffee | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 90c95dd..63bba6a 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -14,9 +14,9 @@ class Architect spawnWorker: (type) -> return this.getPolyfillForType(type) unless this.workersAreSupported() - new Worker(this.getWorkersPathForType(type)) + new Worker(this.getWorkerPathForType(type)) - getWorkersPathForType: (type) -> + getWorkerPathForType: (type) -> "#{@workersPath}/#{type}#{@workersSuffix}" getPolyfillForType: (type) -> diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index cacf01c..af171e5 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -19,19 +19,19 @@ describe 'Architect', -> expect(architect.workersSuffix).to.eq('_worker.min.js') expect(architect.threads).to.eq(5) - describe '#getWorkersPathForType', -> + describe '#getWorkerPathForType', -> it 'returns a relative worker path', -> architect = new Architect - expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foo_worker.min.js') + expect(architect.getWorkerPathForType('foo')).to.eq('/workers/foo_worker.min.js') architect = new Architect(workersPath: '/specs') - expect(architect.getWorkersPathForType('foo')).to.eq('/specs/foo_worker.min.js') + expect(architect.getWorkerPathForType('foo')).to.eq('/specs/foo_worker.min.js') architect = new Architect(workersPath: 'specs') - expect(architect.getWorkersPathForType('foo')).to.eq('/specs/foo_worker.min.js') + expect(architect.getWorkerPathForType('foo')).to.eq('/specs/foo_worker.min.js') architect = new Architect(workersSuffix: 'specs.js') - expect(architect.getWorkersPathForType('foo')).to.eq('/workers/foospecs.js') + expect(architect.getWorkerPathForType('foo')).to.eq('/workers/foospecs.js') describe '#getPolyfillForType', -> it 'returns a worker polyfill', -> From 0d032fa06f397536c3f44a5282929f4883d60810 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 25 Jun 2015 16:01:14 -0400 Subject: [PATCH 17/45] :lipstick: --- specs/architect_spec.coffee | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index af171e5..658cb1d 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -1,4 +1,5 @@ { Architect, simple, expect, helpers } = require('./spec_helper.coffee') +{ delay, callbackSequence } = helpers describe 'Architect', -> beforeEach -> @@ -83,15 +84,15 @@ describe 'Architect', -> for i in [1..8] @architect.work(worker: @architect.spawnWorker('fake')) - helpers.delay 0, => + delay 0, => expect(Object.keys(@architect.jobs).length).to.eq(5) expect(@architect.jobs).to.have.property(ii) for ii in [1..5] - helpers.delay 0, => + delay 0, => expect(Object.keys(@architect.jobs).length).to.eq(3) expect(@architect.jobs).to.have.property(ii) for ii in [6..8] - helpers.delay 0, done, => + delay 0, done, => expect(Object.keys(@architect.jobs).length).to.eq(0) it 'is configurable', (done) -> @@ -103,15 +104,15 @@ describe 'Architect', -> for i in [1..8] architect.work(worker: architect.spawnWorker('fake')) - helpers.delay 0, => + delay 0, => expect(Object.keys(architect.jobs).length).to.eq(3) expect(architect.jobs).to.have.property(ii) for ii in [1..3] - helpers.delay 0, => + delay 0, => expect(Object.keys(architect.jobs).length).to.eq(3) expect(architect.jobs).to.have.property(ii) for ii in [4..6] - helpers.delay 0, done, => + delay 0, done, => expect(Object.keys(architect.jobs).length).to.eq(2) expect(architect.jobs).to.have.property(ii) for ii in [7..8] @@ -156,7 +157,7 @@ describe 'Architect', -> expect(=> @architect.ajax(url: '')).not.to.throw() it 'supports $.ajax-style success/error options', (done) -> - simple.mock @architect, 'work', helpers.callbackSequence [ + simple.mock @architect, 'work', callbackSequence [ => new Promise (resolve) => resolve success: { foo: 'bar' } => new Promise (resolve) => resolve @@ -169,12 +170,12 @@ describe 'Architect', -> error: simple.spy() @architect.ajax(options) - helpers.delay 0, => + delay 0, => expect(options.success.calls.length).to.eq(1) expect(options.error.calls.length).to.eq(0) @architect.ajax(options).catch(->) - helpers.delay 0, done, -> + delay 0, done, -> expect(options.success.calls.length).to.eq(1) expect(options.error.calls.length).to.eq(1) From df3744393abc6287a69ce5d44d55e45a546176d3 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 29 Jun 2015 11:18:04 -0400 Subject: [PATCH 18/45] [webpack] Resolve .js & .coffee files --- lib/architect.coffee | 2 +- .../polyfills/workers/ajax_worker_polyfill.coffee | 2 +- .../polyfills/workers/jsonp_worker_polyfill.coffee | 2 +- specs/architect_spec.coffee | 2 +- specs/index.js | 2 +- webpack.config.js | 11 ++++++++++- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 63bba6a..7ceefe3 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -1,7 +1,7 @@ # Requires Polyfills = {} for type in ['ajax', 'jsonp'] - Polyfills[type] = require("./architect/polyfills/workers/#{type}_worker_polyfill.coffee") + Polyfills[type] = require("./architect/polyfills/workers/#{type}_worker_polyfill") # Architect class Architect diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee index b785a5d..f7b29ca 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -1,4 +1,4 @@ -WorkerPolyfill = require('../worker_polyfill.coffee') +WorkerPolyfill = require('../worker_polyfill') class AjaxWorkerPolyfill extends WorkerPolyfill handleSuccess: (result) -> this.handleRequest(success: result) diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee index 37ca632..f254a7a 100644 --- a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee @@ -1,4 +1,4 @@ -WorkerPolyfill = require('../worker_polyfill.coffee') +WorkerPolyfill = require('../worker_polyfill') class JSONPWorkerPolyfill extends WorkerPolyfill postMessage: (data) -> diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 658cb1d..895b474 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -1,4 +1,4 @@ -{ Architect, simple, expect, helpers } = require('./spec_helper.coffee') +{ Architect, simple, expect, helpers } = require('./spec_helper') { delay, callbackSequence } = helpers describe 'Architect', -> diff --git a/specs/index.js b/specs/index.js index fa5e725..2751938 100644 --- a/specs/index.js +++ b/specs/index.js @@ -1 +1 @@ -require('./architect_spec.coffee') +require('./architect_spec') diff --git a/webpack.config.js b/webpack.config.js index 73405b5..65f8655 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -28,7 +28,8 @@ var examples_and_specs = { root: __dirname, alias: { 'architect': 'lib/architect.coffee' - } + }, + extensions: ['', '.js', '.coffee'] }, } @@ -52,6 +53,10 @@ var workers = function(dist) { { test: /\.coffee$/, loader: 'coffee-loader' }, ] }, + + resolve: { + extensions: ['', '.js', '.coffee'] + }, } if (dist) { @@ -80,6 +85,10 @@ var architect = { ] }, + resolve: { + extensions: ['', '.js', '.coffee'] + }, + plugins: [ new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false } From f704be80d2693e6a8750a21d60ef88207820cabf Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 29 Jun 2015 13:50:04 -0400 Subject: [PATCH 19/45] =?UTF-8?q?No=20more=20short-lived=20workers=20-=20A?= =?UTF-8?q?ll=20workers=20are=20long-lived.=20Short-lived=20overhead=20was?= =?UTF-8?q?n=E2=80=99t=20worth=20it.=20-=20Updated=20workers=20accordingly?= =?UTF-8?q?:=20=20=20-=20Receives=20id:=20and=20args:=20=20=20-=20Returns?= =?UTF-8?q?=20id:=20and=20resolve:=20or=20reject:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/architect.coffee | 73 +++++++++++-------------- lib/workers/ajax_worker.coffee | 15 ++--- lib/workers/jsonp_worker.coffee | 5 +- specs/architect_spec.coffee | 97 ++++++++++++++------------------- 4 files changed, 82 insertions(+), 108 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index 7ceefe3..d4df49a 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -7,8 +7,7 @@ for type in ['ajax', 'jsonp'] class Architect constructor: ({ workersPath, workersSuffix, threads } = {}) -> @jobs = {} - @queue = [] - @threads = threads || 5 + @workers = {} @workersPath = if workersPath then "/#{workersPath.replace(/^\//, '')}" else '/workers' @workersSuffix = workersSuffix || '_worker.min.js' @@ -51,19 +50,31 @@ class Architect @jobId ||= 1 @jobId++ - # Short-lived workers - work: ({ data, type, worker } = {}) -> - this.requireParams('type || worker', arguments[0]) - jobId = this.getJobId() + # Workers + work: ({ data, type, path } = {}) -> + this.requireParams('type || path', arguments[0]) - new Promise (resolve) => - this.enqueue(jobId).then => - @jobs[jobId] = worker ||= this.spawnWorker(type) - worker.postMessage(data) - worker.addEventListener 'message', (e) => - this.clearJob(jobId) - worker.terminate() - resolve(e.data) + new Promise (resolve, reject) => + id = this.getJobId() + @jobs[id] = { id: id, resolve: resolve, reject: reject } + + unless worker = @workers[type || path] + worker = if type then this.spawnWorker(type) else new Worker(path) + worker.addEventListener('message', this.handleMessage) + @workers[type || path] = worker + + worker.postMessage(id: id, args: data) + + handleMessage: (e) => + { id, resolve, reject } = e.data + + promise = @jobs[id] + delete @jobs[id] + + if 'resolve' of e.data + promise.resolve(resolve) + else + promise.reject(new Error(reject)) jsonp: (data = {}) -> if typeof data is 'string' @@ -81,44 +92,22 @@ class Architect delete opts.success delete opts.error + # Support both ajax opts.success & promise resolving new Promise (resolve, reject) => - this.work(data: opts, type: 'ajax').then (data) -> - if 'success' of data - resolve(data.success) - success?(data.success) - else if 'error' of data - reject(data.error) - error?(data.error) - - # Custom workers + this.work(data: opts, type: 'ajax') + .then (data) -> resolve(data); success?(data) + .catch (err) -> reject(err); error?(err) + custom: ({ path, data, fallback } = {}) -> this.requireParams('path', arguments[0]) new Promise (resolve, reject) => if this.workersAreSupported() - worker = new Worker(path) - this.work(data: data, worker: worker).then(resolve) + this.work(data: data, path: path).then(resolve) else if fallback resolve(fallback(data)) else reject("Workers not supported and fallback not provided for #{path}") - # Threads - enqueue: (jobId) -> - new Promise (resolve) => - setTimeout => - if Object.keys(@jobs).length < @threads - resolve() - else - @queue.push({ resolve: resolve }) - , 0 - - clearJob: (jobId) -> - delete @jobs[jobId] - - return unless @queue.length - job = @queue.shift() - job.resolve() - # Export module.exports = Architect diff --git a/lib/workers/ajax_worker.coffee b/lib/workers/ajax_worker.coffee index 6aa172d..6c81370 100644 --- a/lib/workers/ajax_worker.coffee +++ b/lib/workers/ajax_worker.coffee @@ -1,5 +1,5 @@ -handleSuccess = (result) -> postMessage(success: result) -handleError = (xhr, dataType) -> +handleSuccess = (id, result) -> postMessage(id: id, resolve: result) +handleError = (id, xhr, dataType) -> # Returning xhr directly throws DataCloneError result = {} result[key] = xhr[key] for key in [ @@ -17,10 +17,11 @@ handleError = (xhr, dataType) -> result['response'] = if /^\s*$/.test(response) then null else JSON.parse(response) catch error - postMessage(error: result) + postMessage(id: id, reject: result) addEventListener 'message', (e) -> - { type, url, data, dataType, contentType, headers } = e.data + { id, args } = e.data + { type, url, data, dataType, contentType, headers } = args type ||= 'GET' @@ -50,11 +51,11 @@ addEventListener 'message', (e) -> result = if /^\s*$/.test(result) then null else JSON.parse(result) catch error - return handleError(xhr, dataType) if error - handleSuccess(result) + return handleError(id, xhr, dataType) if error + handleSuccess(id, result) # Error else - handleError(xhr, dataType) + handleError(id, xhr, dataType) xhr.send(data) diff --git a/lib/workers/jsonp_worker.coffee b/lib/workers/jsonp_worker.coffee index ffacc78..2ba47ab 100644 --- a/lib/workers/jsonp_worker.coffee +++ b/lib/workers/jsonp_worker.coffee @@ -2,7 +2,8 @@ appendQuery = (url, query) -> (url + '&' + query).replace(/[&?]{1,2}/, '?') addEventListener 'message', (e) -> - { url, callbackAttribute, callbackFnName } = e.data + { id, args } = e.data + { url, callbackAttribute, callbackFnName } = args if callbackAttribute is undefined callbackAttribute = 'callback' @@ -12,7 +13,7 @@ addEventListener 'message', (e) -> self[callbackFnName] = (args...) -> args = if args.length > 1 then args else args[0] - postMessage(args) + postMessage(id: id, resolve: args) request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url importScripts(request) diff --git a/specs/architect_spec.coffee b/specs/architect_spec.coffee index 895b474..9811a46 100644 --- a/specs/architect_spec.coffee +++ b/specs/architect_spec.coffee @@ -10,7 +10,7 @@ describe 'Architect', -> simple.mock window.Worker.prototype, 'postMessage', (data) -> setTimeout => event = new Event('message') - event.data = data + event.data = { id: data.id, resolve: data.args } this.dispatchEvent(event) , 0 @@ -18,7 +18,6 @@ describe 'Architect', -> architect = new Architect expect(architect.workersPath).to.eq('/workers') expect(architect.workersSuffix).to.eq('_worker.min.js') - expect(architect.threads).to.eq(5) describe '#getWorkerPathForType', -> it 'returns a relative worker path', -> @@ -79,44 +78,7 @@ describe 'Architect', -> expect(=> @architect.requireParams(['foo || bar', 'twiz'], { bar: 'foo' })).to.throw('Missing required “twiz” parameter') expect(=> @architect.requireParams(['foo || bar', 'twiz'], {})).to.throw('Missing required “foo || bar, twiz” parameter') - describe 'Threads', -> - it 'has a job qeueue', (done) -> - for i in [1..8] - @architect.work(worker: @architect.spawnWorker('fake')) - - delay 0, => - expect(Object.keys(@architect.jobs).length).to.eq(5) - expect(@architect.jobs).to.have.property(ii) for ii in [1..5] - - delay 0, => - expect(Object.keys(@architect.jobs).length).to.eq(3) - expect(@architect.jobs).to.have.property(ii) for ii in [6..8] - - delay 0, done, => - expect(Object.keys(@architect.jobs).length).to.eq(0) - - it 'is configurable', (done) -> - architect = new Architect - workersPath: '/build/workers' - workersSuffix: '_worker.js' - threads: 3 - - for i in [1..8] - architect.work(worker: architect.spawnWorker('fake')) - - delay 0, => - expect(Object.keys(architect.jobs).length).to.eq(3) - expect(architect.jobs).to.have.property(ii) for ii in [1..3] - - delay 0, => - expect(Object.keys(architect.jobs).length).to.eq(3) - expect(architect.jobs).to.have.property(ii) for ii in [4..6] - - delay 0, done, => - expect(Object.keys(architect.jobs).length).to.eq(2) - expect(architect.jobs).to.have.property(ii) for ii in [7..8] - - describe 'Short-lived workers', -> + describe 'Workers', -> describe '#work', -> it 'returns a promise', -> promise = @architect.work(type: 'fake', data: { foo: 'bar' }) @@ -125,21 +87,42 @@ describe 'Architect', -> result = @architect.work(type: 'fake', data: { foo: 'bar' }) expect(result).to.eventually.deep.equal(foo: 'bar') - it 'can receive and work on an existing worker', (done) -> - worker = @architect.spawnWorker('fake') - simple.mock(worker, 'postMessage') + it 'stores current workers', -> + expect(Object.keys(@architect.workers).length).to.equal(0) + @architect.work(type: 'fake', data: { foo: 'bar' }) + + expect(Object.keys(@architect.workers).length).to.equal(1) + expect(@architect.workers.fake).to.be.defined + + it 'spawns a worker when working for the first time', -> + simple.mock(@architect, 'spawnWorker') + @architect.work(type: 'fake', data: { foo: 'bar' }) + + expect(@architect.spawnWorker.calls.length).to.equal(1) - @architect.work(worker: worker).then => - expect(worker.postMessage.calls.length).to.eq(1) - done() + it 'reuses existing workers', (done) -> + simple.mock(@architect, 'spawnWorker') + simple.mock(@architect, 'handleMessage') - it 'terminates a worker when done', (done) -> - worker = @architect.spawnWorker('fake') - simple.mock(worker, 'terminate') + @architect.work(type: 'fake', data: { foo: 'bar' }) + @architect.work(type: 'fake', data: { foo: 'bar' }) - @architect.work(worker: worker).then => - expect(worker.terminate.calls.length).to.eq(1) - done() + delay 0, done, => + expect(@architect.spawnWorker.calls.length).to.equal(1) + expect(@architect.handleMessage.calls.length).to.equal(2) + + it 'stores current jobs', -> + expect(Object.keys(@architect.jobs).length).to.equal(0) + + @architect.work(type: 'fake', data: { foo: 'bar' }) + @architect.work(type: 'fake', data: { foo: 'bar' }) + @architect.work(type: 'fake', data: { foo: 'bar' }) + + expect(Object.keys(@architect.jobs).length).to.equal(3) + for i in [1..3] + expect(@architect.jobs).to.have.deep.property("#{i}.id", i) + expect(@architect.jobs).to.have.deep.property("#{i}.resolve") + expect(@architect.jobs).to.have.deep.property("#{i}.reject") describe 'aliases', -> beforeEach -> @@ -159,9 +142,9 @@ describe 'Architect', -> it 'supports $.ajax-style success/error options', (done) -> simple.mock @architect, 'work', callbackSequence [ => new Promise (resolve) => resolve - success: { foo: 'bar' } - => new Promise (resolve) => resolve - error: { bar: 'foo' } + id: 1, resolve: { foo: 'bar' } + => new Promise (resolve, reject) => reject + id: 2, reject: { bar: 'foo' } ] options = @@ -200,11 +183,11 @@ describe 'Architect', -> expect(=> @architect.custom(path: '/build/workers/fake_worker.js')).not.to.throw() describe 'when workers are supported', -> - it 'is an alias for Architect#work(worker:)', -> + it 'is an alias for Architect#work(path:)', -> @architect.custom(path: '/build/workers/fake_worker.js', data: { foo: 'bar' }) expect(@architect.work.calls.length).to.eq(1) expect(@architect.work.calls[0].args[0].data).to.deep.equal(foo: 'bar') - expect(@architect.work.calls[0].args[0].worker).to.be.an.instanceof(window.Worker) + expect(@architect.work.calls[0].args[0].path).to.equal('/build/workers/fake_worker.js') describe 'when workers are not supported', -> beforeEach -> simple.mock(@architect, 'workersAreSupported', -> false) From 19f951e79d1e2548dc9b8eef47994218e357c5e6 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 29 Jun 2015 14:35:39 -0400 Subject: [PATCH 20/45] [dist] --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 8d08546..7ddb84a 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,u,i,a;for(o={},i=["ajax","jsonp"],s=0,u=i.length;u>s;s++)a=i[s],o[a]=r(1)("./"+a+"_worker_polyfill.coffee");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.jobs={},this.queue=[],this.threads=r||5,this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkersPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkersPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,u,i,a,p,c;for(null==e&&(e={}),u=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(a=t[r],!(a in e))if((c=a.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||u.push(a)}else u.push(a);if(u.length)throw new Error("Missing required “"+u.join(", ")+"” parameter"+(u.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o,s;return n=null!=t?t:{},e=n.data,o=n.type,s=n.worker,this.requireParams("type || worker",arguments[0]),r=this.getJobId(),new Promise(function(t){return function(n){return t.enqueue(r).then(function(){return t.jobs[r]=s||(s=t.spawnWorker(o)),s.postMessage(e),s.addEventListener("message",function(e){return t.clearJob(r),s.terminate(),n(e.data)})})}}(this))},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return"success"in t?(o(t.success),"function"==typeof n?n(t.success):void 0):"error"in t?(s(t.error),"function"==typeof e?e(t.error):void 0):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){var u;return t.workersAreSupported()?(u=new Worker(n),t.work({data:e,worker:u}).then(o)):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t.prototype.enqueue=function(){return new Promise(function(t){return function(e){return setTimeout(function(){return Object.keys(t.jobs).length=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)u.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},u={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(new Error(o))},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index 4aa0b77..63791bd 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e){return postMessage({success:e})},e=function(e,t){var r,s,n,a,o,u,p;for(p={},o=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],s=0,a=o.length;a>s;s++)n=o[s],p[n]=e[n];try{"json"===t&&(u=p.response,p.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(c){r=c}return postMessage({error:p})},addEventListener("message",function(r){var s,n,a,o,u,p,c,i,l,d;c=r.data,i=c.type,l=c.url,n=c.data,a=c.dataType,s=c.contentType,p=c.headers,i||(i="GET"),p||(p={}),p["X-Requested-With"]="XMLHttpRequest",s!==!1&&(p["Content-Type"]=s||"application/x-www-form-urlencoded"),d=new XMLHttpRequest,d.open(i,l);for(o in p)u=p[o],d.setRequestHeader(o,u);return d.onreadystatechange=function(){var r,s;if(4===d.readyState){if(d.status>=200&&d.status<300||304===d.status){s=d.responseText;try{"script"===a?(1,eval)(s):"xml"===a?s=d.responseXML:"json"===a&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(d,a):t(s)}return e(d,a)}},d.send(n)})}]); \ No newline at end of file +!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,s){var r,n,a,o,p,u,i;for(i={},p=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=p.length;o>n;n++)a=p[n],i[a]=t[a];try{"json"===s&&(u=i.response,i.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){r=d}return postMessage({id:e,reject:i})},addEventListener("message",function(s){var r,n,a,o,p,u,i,d,c,l,f,x;c=s.data,d=c.id,r=c.args,l=r.type,f=r.url,a=r.data,o=r.dataType,n=r.contentType,i=r.headers,l||(l="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),x=new XMLHttpRequest,x.open(l,f);for(p in i)u=i[p],x.setRequestHeader(p,u);return x.onreadystatechange=function(){var s,r;if(4===x.readyState){if(x.status>=200&&x.status<300||304===x.status){r=x.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=x.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){s=n}return s?e(d,x,o):t(d,r)}return e(d,x,o)}},x.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index 6010adb..f89348e 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var n,a,c,l,o;return c=r.data,o=c.url,n=c.callbackAttribute,a=c.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage(e)},l=n?e(o,n+"="+a):o,importScripts(l)})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var s,n,a,o,u,p,i;return u=r.data,o=u.id,s=u.args,i=s.url,n=s.callbackAttribute,a=s.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},p=n?e(i,n+"="+a):i,importScripts(p)})}]); \ No newline at end of file From 3e07c88c48dbf8ca2ce59b7de0477ed427c23ff2 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 30 Jun 2015 09:30:54 -0400 Subject: [PATCH 21/45] Do not wrap rejected worker response in new Error --- lib/architect.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index d4df49a..6bbaca6 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -74,7 +74,7 @@ class Architect if 'resolve' of e.data promise.resolve(resolve) else - promise.reject(new Error(reject)) + promise.reject(reject) jsonp: (data = {}) -> if typeof data is 'string' From df7132b430453e5d7860ba71cc743fc349d60640 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 30 Jun 2015 09:32:17 -0400 Subject: [PATCH 22/45] [dist] --- dist/architect.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 7ddb84a..92c65c4 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(new Error(o))},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file From 159f7d047bcdc190c9d8a18aa5ff883e4e4d7bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Blais=20Masson?= Date: Thu, 27 Aug 2015 10:36:06 -0400 Subject: [PATCH 23/45] Allow setting custom X-Requested-With value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Namely, setting it to `false` won’t send the header at all. --- lib/architect/polyfills/workers/ajax_worker_polyfill.coffee | 4 ++-- lib/workers/ajax_worker.coffee | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee index f7b29ca..edfff43 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -10,14 +10,14 @@ class AjaxWorkerPolyfill extends WorkerPolyfill type ||= 'GET' headers ||= {} - headers['X-Requested-With'] = 'XMLHttpRequest' + headers['X-Requested-With'] ?= 'XMLHttpRequest' if contentType isnt false headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' xhr = new XMLHttpRequest xhr.open(type, url) - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.onreadystatechange = (e) => return unless xhr.readyState is 4 diff --git a/lib/workers/ajax_worker.coffee b/lib/workers/ajax_worker.coffee index 6c81370..bf00163 100644 --- a/lib/workers/ajax_worker.coffee +++ b/lib/workers/ajax_worker.coffee @@ -26,14 +26,14 @@ addEventListener 'message', (e) -> type ||= 'GET' headers ||= {} - headers['X-Requested-With'] = 'XMLHttpRequest' + headers['X-Requested-With'] ?= 'XMLHttpRequest' if contentType isnt false headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' xhr = new XMLHttpRequest xhr.open(type, url) - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.onreadystatechange = (e) -> return unless xhr.readyState is 4 From 33834f05b17ad8a0eee9cd7d33b35beb9dacc074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Blais=20Masson?= Date: Thu, 27 Aug 2015 10:41:02 -0400 Subject: [PATCH 24/45] [dist] --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 92c65c4..488a960 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),s["X-Requested-With"]="XMLHttpRequest",e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":4};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(e){var n,o;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){o=p.responseText;try{"script"===r?(1,eval)(o):"xml"===r?o=p.responseXML:"json"===r&&(o=/^\s*$/.test(o)?null:JSON.parse(o))}catch(s){n=s}return n?t.handleError(p):t.handleSuccess(o)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e){var r;r=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=r},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index 63791bd..0fead45 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,s){var r,n,a,o,p,u,i;for(i={},p=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=p.length;o>n;n++)a=p[n],i[a]=t[a];try{"json"===s&&(u=i.response,i.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){r=d}return postMessage({id:e,reject:i})},addEventListener("message",function(s){var r,n,a,o,p,u,i,d,c,l,f,x;c=s.data,d=c.id,r=c.args,l=r.type,f=r.url,a=r.data,o=r.dataType,n=r.contentType,i=r.headers,l||(l="GET"),i||(i={}),i["X-Requested-With"]="XMLHttpRequest",n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),x=new XMLHttpRequest,x.open(l,f);for(p in i)u=i[p],x.setRequestHeader(p,u);return x.onreadystatechange=function(){var s,r;if(4===x.readyState){if(x.status>=200&&x.status<300||304===x.status){r=x.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=x.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){s=n}return s?e(d,x,o):t(d,r)}return e(d,x,o)}},x.send(a)})}]); \ No newline at end of file +!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(e,t){var s,r;r=function(e,t){return postMessage({id:e,resolve:t})},s=function(e,t,s){var r,n,a,o,u,p,i;for(i={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=u.length;o>n;n++)a=u[n],i[a]=t[a];try{"json"===s&&(p=i.response,i.response=/^\s*$/.test(p)?null:JSON.parse(p))}catch(d){r=d}return postMessage({id:e,reject:i})},addEventListener("message",function(e){var t,n,a,o,u,p,i,d,c,l,f,x;c=e.data,d=c.id,t=c.args,l=t.type,f=t.url,a=t.data,o=t.dataType,n=t.contentType,i=t.headers,l||(l="GET"),i||(i={}),null==i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),x=new XMLHttpRequest,x.open(l,f);for(u in i)p=i[u],p&&x.setRequestHeader(u,p);return x.onreadystatechange=function(e){var t,n;if(4===x.readyState){if(x.status>=200&&x.status<300||304===x.status){n=x.responseText;try{"script"===o?(1,eval)(n):"xml"===o?n=x.responseXML:"json"===o&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(a){t=a}return t?s(d,x,o):r(d,n)}return s(d,x,o)}},x.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index f89348e..b50e0b6 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var s,n,a,o,u,p,i;return u=r.data,o=u.id,s=u.args,i=s.url,n=s.callbackAttribute,a=s.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},p=n?e(i,n+"="+a):i,importScripts(p)})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(e,t){var r,s=[].slice;r=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(e){var t,n,a,o,u,i,p;return u=e.data,o=u.id,t=u.args,p=t.url,n=t.callbackAttribute,a=t.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?s.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?r(p,n+"="+a):p,importScripts(i)})}]); \ No newline at end of file From ac1920367272b121dc319da2f72d7ec931706767 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 11 Sep 2015 14:07:40 -0400 Subject: [PATCH 25/45] =?UTF-8?q?Wrap=20JSONP=20Worker=E2=80=99s=20importS?= =?UTF-8?q?cripts=20in=20try/catch=20-=20Reject=20promise=20on=20catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- lib/workers/jsonp_worker.coffee | 11 ++++++++++- specs/index.js | 1 + specs/workers/jsonp_worker_spec.coffee | 16 ++++++++++++++++ 6 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 specs/workers/jsonp_worker_spec.coffee diff --git a/dist/architect.min.js b/dist/architect.min.js index 488a960..6d8dbf8 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":4};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(e){var n,o;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){o=p.responseText;try{"script"===r?(1,eval)(o):"xml"===r?o=p.responseXML:"json"===r&&(o=/^\s*$/.test(o)?null:JSON.parse(o))}catch(s){n=s}return n?t.handleError(p):t.handleSuccess(o)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e){var r;r=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=r},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index 0fead45..4c7df6c 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(e,t){var s,r;r=function(e,t){return postMessage({id:e,resolve:t})},s=function(e,t,s){var r,n,a,o,u,p,i;for(i={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=u.length;o>n;n++)a=u[n],i[a]=t[a];try{"json"===s&&(p=i.response,i.response=/^\s*$/.test(p)?null:JSON.parse(p))}catch(d){r=d}return postMessage({id:e,reject:i})},addEventListener("message",function(e){var t,n,a,o,u,p,i,d,c,l,f,x;c=e.data,d=c.id,t=c.args,l=t.type,f=t.url,a=t.data,o=t.dataType,n=t.contentType,i=t.headers,l||(l="GET"),i||(i={}),null==i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),x=new XMLHttpRequest,x.open(l,f);for(u in i)p=i[u],p&&x.setRequestHeader(u,p);return x.onreadystatechange=function(e){var t,n;if(4===x.readyState){if(x.status>=200&&x.status<300||304===x.status){n=x.responseText;try{"script"===o?(1,eval)(n):"xml"===o?n=x.responseXML:"json"===o&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(a){t=a}return t?s(d,x,o):r(d,n)}return s(d,x,o)}},x.send(a)})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,r){var s,n,a,o,u,c,i;for(i={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=u.length;o>n;n++)a=u[n],i[a]=t[a];try{"json"===r&&(c=i.response,i.response=/^\s*$/.test(c)?null:JSON.parse(c))}catch(p){s=p}return postMessage({id:e,reject:i})},addEventListener("message",function(r){var s,n,a,o,u,c,i,p,d,l,f,v;d=r.data,p=d.id,s=d.args,l=s.type,f=s.url,a=s.data,o=s.dataType,n=s.contentType,i=s.headers,l||(l="GET"),i||(i={}),null==i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),v=new XMLHttpRequest,v.open(l,f);for(u in i)c=i[u],c&&v.setRequestHeader(u,c);return v.onreadystatechange=function(){var r,s;if(4===v.readyState){if(v.status>=200&&v.status<300||304===v.status){s=v.responseText;try{"script"===o?(1,eval)(s):"xml"===o?s=v.responseXML:"json"===o&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(p,v,o):t(p,s)}return e(p,v,o)}},v.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index b50e0b6..0950610 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(e,t){var r,s=[].slice;r=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(e){var t,n,a,o,u,i,p;return u=e.data,o=u.id,t=u.args,p=t.url,n=t.callbackAttribute,a=t.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?s.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?r(p,n+"="+a):p,importScripts(i)})}]); \ No newline at end of file +!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var a,n,s,c,o,l,i,u;l=r.data,o=l.id,a=l.args,u=a.url,n=a.callbackAttribute,s=a.callbackFnName,void 0===n&&(n="callback"),void 0===s&&(s="handleRequest"),self[s]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?e(u,n+"="+s):u;try{return importScripts(i)}catch(d){return c=d,postMessage({id:o,reject:{message:c.message,code:c.code,name:c.name}})}})}]); \ No newline at end of file diff --git a/lib/workers/jsonp_worker.coffee b/lib/workers/jsonp_worker.coffee index 2ba47ab..7f2082d 100644 --- a/lib/workers/jsonp_worker.coffee +++ b/lib/workers/jsonp_worker.coffee @@ -16,4 +16,13 @@ addEventListener 'message', (e) -> postMessage(id: id, resolve: args) request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url - importScripts(request) + + try + importScripts(request) + catch err + postMessage + id: id + reject: + message: err.message + code: err.code + name: err.name diff --git a/specs/index.js b/specs/index.js index 2751938..47c6498 100644 --- a/specs/index.js +++ b/specs/index.js @@ -1 +1,2 @@ require('./architect_spec') +require('./workers/jsonp_worker_spec') diff --git a/specs/workers/jsonp_worker_spec.coffee b/specs/workers/jsonp_worker_spec.coffee new file mode 100644 index 0000000..681e66c --- /dev/null +++ b/specs/workers/jsonp_worker_spec.coffee @@ -0,0 +1,16 @@ +{ Architect, simple, expect, helpers } = require('../spec_helper') +{ delay, callbackSequence } = helpers + +describe.only 'JSONP Worker', -> + beforeEach -> + @architect = new Architect + workersPath: '/build/workers' + workersSuffix: '_worker.js' + + it 'rejects NetworkError', (done) -> + @architect.jsonp("https://api.example.com/fake") + .then -> throw 'It shouldn’t throw' + .catch (err) => + expect(err).to.have.deep.property('code', 19) + expect(err).to.have.deep.property('name', 'NetworkError') + done() From 2f5f90dcfedabbc511ab0d54906c8a551f2af943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Blais=20Masson?= Date: Fri, 2 Oct 2015 14:04:58 -0400 Subject: [PATCH 26/45] Allow setting 'withCredentials' on XMLHttpRequest --- lib/architect/polyfills/workers/ajax_worker_polyfill.coffee | 1 + lib/workers/ajax_worker.coffee | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee index edfff43..d50f9ef 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -17,6 +17,7 @@ class AjaxWorkerPolyfill extends WorkerPolyfill xhr = new XMLHttpRequest xhr.open(type, url) + xhr.withCredentials = args.withCredentials if 'withCredentials' of args xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.onreadystatechange = (e) => diff --git a/lib/workers/ajax_worker.coffee b/lib/workers/ajax_worker.coffee index bf00163..5b593d7 100644 --- a/lib/workers/ajax_worker.coffee +++ b/lib/workers/ajax_worker.coffee @@ -33,6 +33,7 @@ addEventListener 'message', (e) -> xhr = new XMLHttpRequest xhr.open(type, url) + xhr.withCredentials = args.withCredentials if 'withCredentials' of args xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.onreadystatechange = (e) -> From 504b0a9f4bbdd4c75fbcedd39ba2f7b50499a0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Blais=20Masson?= Date: Fri, 2 Oct 2015 14:06:18 -0400 Subject: [PATCH 27/45] [dist] --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 6d8dbf8..af48df0 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(){var e,n;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){n=p.responseText;try{"script"===r?(1,eval)(n):"xml"===r?n=p.responseXML:"json"===r&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(o){e=o}return e?t.handleError(p):t.handleSuccess(n)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":4};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u),"withCredentials"in args&&(p.withCredentials=args.withCredentials);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(e){var n,o;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){o=p.responseText;try{"script"===r?(1,eval)(o):"xml"===r?o=p.responseXML:"json"===r&&(o=/^\s*$/.test(o)?null:JSON.parse(o))}catch(s){n=s}return n?t.handleError(p):t.handleSuccess(o)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e){var r;r=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=r},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index 4c7df6c..40c5e29 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,r){var s,n,a,o,u,c,i;for(i={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=u.length;o>n;n++)a=u[n],i[a]=t[a];try{"json"===r&&(c=i.response,i.response=/^\s*$/.test(c)?null:JSON.parse(c))}catch(p){s=p}return postMessage({id:e,reject:i})},addEventListener("message",function(r){var s,n,a,o,u,c,i,p,d,l,f,v;d=r.data,p=d.id,s=d.args,l=s.type,f=s.url,a=s.data,o=s.dataType,n=s.contentType,i=s.headers,l||(l="GET"),i||(i={}),null==i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(i["Content-Type"]=n||"application/x-www-form-urlencoded"),v=new XMLHttpRequest,v.open(l,f);for(u in i)c=i[u],c&&v.setRequestHeader(u,c);return v.onreadystatechange=function(){var r,s;if(4===v.readyState){if(v.status>=200&&v.status<300||304===v.status){s=v.responseText;try{"script"===o?(1,eval)(s):"xml"===o?s=v.responseXML:"json"===o&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(p,v,o):t(p,s)}return e(p,v,o)}},v.send(a)})}]); \ No newline at end of file +!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(e,t){var s,r;r=function(e,t){return postMessage({id:e,resolve:t})},s=function(e,t,s){var r,n,a,o,i,u,p;for(p={},i=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=i.length;o>n;n++)a=i[n],p[a]=t[a];try{"json"===s&&(u=p.response,p.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){r=d}return postMessage({id:e,reject:p})},addEventListener("message",function(e){var t,n,a,o,i,u,p,d,l,c,f,h;l=e.data,d=l.id,t=l.args,c=t.type,f=t.url,a=t.data,o=t.dataType,n=t.contentType,p=t.headers,c||(c="GET"),p||(p={}),null==p["X-Requested-With"]&&(p["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(p["Content-Type"]=n||"application/x-www-form-urlencoded"),h=new XMLHttpRequest,h.open(c,f),"withCredentials"in t&&(h.withCredentials=t.withCredentials);for(i in p)u=p[i],u&&h.setRequestHeader(i,u);return h.onreadystatechange=function(e){var t,n;if(4===h.readyState){if(h.status>=200&&h.status<300||304===h.status){n=h.responseText;try{"script"===o?(1,eval)(n):"xml"===o?n=h.responseXML:"json"===o&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(a){t=a}return t?s(d,h,o):r(d,n)}return s(d,h,o)}},h.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index 0950610..a43ca06 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var a,n,s,c,o,l,i,u;l=r.data,o=l.id,a=l.args,u=a.url,n=a.callbackAttribute,s=a.callbackFnName,void 0===n&&(n="callback"),void 0===s&&(s="handleRequest"),self[s]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?e(u,n+"="+s):u;try{return importScripts(i)}catch(d){return c=d,postMessage({id:o,reject:{message:c.message,code:c.code,name:c.name}})}})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(e,t){var r,s=[].slice;r=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(e){var t,n,a,o,i,u,c,p;u=e.data,i=u.id,t=u.args,p=t.url,n=t.callbackAttribute,a=t.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?s.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:i,resolve:e})},c=n?r(p,n+"="+a):p;try{return importScripts(c)}catch(d){return o=d,postMessage({id:i,reject:{message:o.message,code:o.code,name:o.name}})}})}]); \ No newline at end of file From 5e777e72cf74cdc8bfafbc508f030ceac8b7d90b Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 11 Nov 2016 16:45:56 -0500 Subject: [PATCH 28/45] Fix polyfills arguments --- lib/architect/polyfills/workers/ajax_worker_polyfill.coffee | 5 +++-- lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee index d50f9ef..173c4da 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -4,8 +4,9 @@ class AjaxWorkerPolyfill extends WorkerPolyfill handleSuccess: (result) -> this.handleRequest(success: result) handleError: (xhr) -> this.handleRequest(error: xhr) - postMessage: (data) -> - { type, url, data, dataType, contentType, headers } = data + postMessage: (e) -> + { id, args } = e + { type, url, data, dataType, contentType, headers } = args type ||= 'GET' diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee index f254a7a..22e10f4 100644 --- a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee @@ -1,8 +1,9 @@ WorkerPolyfill = require('../worker_polyfill') class JSONPWorkerPolyfill extends WorkerPolyfill - postMessage: (data) -> - { url, callbackAttribute, callbackFnName } = data + postMessage: (e) -> + { id, args } = e + { url, callbackAttribute, callbackFnName } = args if callbackAttribute is undefined callbackAttribute = 'callback' From f1452faf4b889f209cb3413b058aaa267a9f3726 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 11 Nov 2016 16:46:15 -0500 Subject: [PATCH 29/45] [dist] --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 2 +- dist/workers/jsonp_worker.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index af48df0..82cdeaf 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,a,i,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},i=["ajax","jsonp"],s=0,a=i.length;a>s;s++)u=i[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,a,i,u,p,c;for(null==e&&(e={}),a=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(i=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&i.push(p);i.length||a.push(u)}else a.push(u);if(a.length)throw new Error("Missing required “"+a.join(", ")+"” parameter"+(a.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var a,i;return a=t.getJobId(),t.jobs[a]={id:a,resolve:n,reject:s},(i=t.workers[o||r])||(i=o?t.spawnWorker(o):new Worker(r),i.addEventListener("message",t.handleMessage),t.workers[o||r]=i),i.postMessage({id:a,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":4};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,a,i,u,p;a=t,i=a.type,u=a.url,t=a.data,r=a.dataType,e=a.contentType,s=a.headers,i||(i="GET"),s||(s={}),null==s["X-Requested-With"]&&(s["X-Requested-With"]="XMLHttpRequest"),e!==!1&&(s["Content-Type"]=e||"application/x-www-form-urlencoded"),p=new XMLHttpRequest,p.open(i,u),"withCredentials"in args&&(p.withCredentials=args.withCredentials);for(n in s)o=s[n],o&&p.setRequestHeader(n,o);return p.onreadystatechange=function(t){return function(e){var n,o;if(4===p.readyState){if(p.status>=200&&p.status<300||304===p.status){o=p.responseText;try{"script"===r?(1,eval)(o):"xml"===r?o=p.responseXML:"json"===r&&(o=/^\s*$/.test(o)?null:JSON.parse(o))}catch(s){n=s}return n?t.handleError(p):t.handleSuccess(o)}return t.handleError(p)}}}(this),p.send(t)},e}(o),t.exports=n},function(t,e){var r;r=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=r},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)a.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},a={}.hasOwnProperty,i=[].slice;o=r(3),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o;return o=t.url,e=t.callbackAttribute,r=t.callbackFnName,void 0===e&&(e="callback"),void 0===r&&(this.jsonpID||(this.jsonpID=0),r="architect_jsonp"+ ++this.jsonpID),window[r]=function(t){return function(){var e;return e=1<=arguments.length?i.call(arguments,0):[],delete window[r],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),n=e?this.appendQuery(o,e+"="+r):o,this.addScript(n)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,i,a,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},a=["ajax","jsonp"],s=0,i=a.length;i>s;s++)u=a[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,i,a,u,p,c;for(null==e&&(e={}),i=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(a=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&a.push(p);a.length||i.push(u)}else i.push(u);if(i.length)throw new Error("Missing required “"+i.join(", ")+"” parameter"+(i.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var i,a;return i=t.getJobId(),t.jobs[i]={id:i,resolve:n,reject:s},(a=t.workers[o||r])||(a=o?t.spawnWorker(o):new Worker(r),a.addEventListener("message",t.handleMessage),t.workers[o||r]=a),a.postMessage({id:i,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)i.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},i={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,i,a,u,p,c,l;u=t.id,e=t.args,p=e.type,c=e.url,n=e.data,o=e.dataType,r=e.contentType,a=e.headers,p||(p="GET"),a||(a={}),null==a["X-Requested-With"]&&(a["X-Requested-With"]="XMLHttpRequest"),r!==!1&&(a["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(p,c),"withCredentials"in e&&(l.withCredentials=e.withCredentials);for(s in a)i=a[s],i&&l.setRequestHeader(s,i);return l.onreadystatechange=function(t){return function(){var e,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=l.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){e=n}return e?t.handleError(l):t.handleSuccess(r)}return t.handleError(l)}}}(this),l.send(n)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)i.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},i={}.hasOwnProperty,a=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o,s,i;return o=t.id,e=t.args,i=e.url,r=e.callbackAttribute,n=e.callbackFnName,void 0===r&&(r="callback"),void 0===n&&(this.jsonpID||(this.jsonpID=0),n="architect_jsonp"+ ++this.jsonpID),window[n]=function(t){return function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],delete window[n],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),s=r?this.appendQuery(i,r+"="+n):i,this.addScript(s)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js index 40c5e29..b363a2c 100644 --- a/dist/workers/ajax_worker.min.js +++ b/dist/workers/ajax_worker.min.js @@ -1 +1 @@ -!function(e){function t(r){if(s[r])return s[r].exports;var n=s[r]={exports:{},id:r,loaded:!1};return e[r].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var s={};return t.m=e,t.c=s,t.p="",t(0)}([function(e,t,s){e.exports=s(1)},function(e,t){var s,r;r=function(e,t){return postMessage({id:e,resolve:t})},s=function(e,t,s){var r,n,a,o,i,u,p;for(p={},i=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=i.length;o>n;n++)a=i[n],p[a]=t[a];try{"json"===s&&(u=p.response,p.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){r=d}return postMessage({id:e,reject:p})},addEventListener("message",function(e){var t,n,a,o,i,u,p,d,l,c,f,h;l=e.data,d=l.id,t=l.args,c=t.type,f=t.url,a=t.data,o=t.dataType,n=t.contentType,p=t.headers,c||(c="GET"),p||(p={}),null==p["X-Requested-With"]&&(p["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(p["Content-Type"]=n||"application/x-www-form-urlencoded"),h=new XMLHttpRequest,h.open(c,f),"withCredentials"in t&&(h.withCredentials=t.withCredentials);for(i in p)u=p[i],u&&h.setRequestHeader(i,u);return h.onreadystatechange=function(e){var t,n;if(4===h.readyState){if(h.status>=200&&h.status<300||304===h.status){n=h.responseText;try{"script"===o?(1,eval)(n):"xml"===o?n=h.responseXML:"json"===o&&(n=/^\s*$/.test(n)?null:JSON.parse(n))}catch(a){t=a}return t?s(d,h,o):r(d,n)}return s(d,h,o)}},h.send(a)})}]); \ No newline at end of file +!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,r){var s,n,a,o,i,u,c;for(c={},i=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=i.length;o>n;n++)a=i[n],c[a]=t[a];try{"json"===r&&(u=c.response,c.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){s=d}return postMessage({id:e,reject:c})},addEventListener("message",function(r){var s,n,a,o,i,u,c,d,p,l,f,v;p=r.data,d=p.id,s=p.args,l=s.type,f=s.url,a=s.data,o=s.dataType,n=s.contentType,c=s.headers,l||(l="GET"),c||(c={}),null==c["X-Requested-With"]&&(c["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(c["Content-Type"]=n||"application/x-www-form-urlencoded"),v=new XMLHttpRequest,v.open(l,f),"withCredentials"in s&&(v.withCredentials=s.withCredentials);for(i in c)u=c[i],u&&v.setRequestHeader(i,u);return v.onreadystatechange=function(){var r,s;if(4===v.readyState){if(v.status>=200&&v.status<300||304===v.status){s=v.responseText;try{"script"===o?(1,eval)(s):"xml"===o?s=v.responseXML:"json"===o&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(d,v,o):t(d,s)}return e(d,v,o)}},v.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js index a43ca06..0950610 100644 --- a/dist/workers/jsonp_worker.min.js +++ b/dist/workers/jsonp_worker.min.js @@ -1 +1 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(e,t){var r,s=[].slice;r=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(e){var t,n,a,o,i,u,c,p;u=e.data,i=u.id,t=u.args,p=t.url,n=t.callbackAttribute,a=t.callbackFnName,void 0===n&&(n="callback"),void 0===a&&(a="handleRequest"),self[a]=function(){var e;return e=1<=arguments.length?s.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:i,resolve:e})},c=n?r(p,n+"="+a):p;try{return importScripts(c)}catch(d){return o=d,postMessage({id:i,reject:{message:o.message,code:o.code,name:o.name}})}})}]); \ No newline at end of file +!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var a,n,s,c,o,l,i,u;l=r.data,o=l.id,a=l.args,u=a.url,n=a.callbackAttribute,s=a.callbackFnName,void 0===n&&(n="callback"),void 0===s&&(s="handleRequest"),self[s]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?e(u,n+"="+s):u;try{return importScripts(i)}catch(d){return c=d,postMessage({id:o,reject:{message:c.message,code:c.code,name:c.name}})}})}]); \ No newline at end of file From afa6de442d0102d920ff7006806648fc42109f9a Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 11 Nov 2016 16:59:00 -0500 Subject: [PATCH 30/45] =?UTF-8?q?Fix=20polyfills=E2=80=99=20handleRequest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../polyfills/workers/ajax_worker_polyfill.coffee | 10 +++++----- .../polyfills/workers/jsonp_worker_polyfill.coffee | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee index 173c4da..425f0c4 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee @@ -1,8 +1,8 @@ WorkerPolyfill = require('../worker_polyfill') class AjaxWorkerPolyfill extends WorkerPolyfill - handleSuccess: (result) -> this.handleRequest(success: result) - handleError: (xhr) -> this.handleRequest(error: xhr) + handleSuccess: (id, result) -> this.handleRequest(id: id, resolve: result) + handleError: (id, xhr) -> this.handleRequest(id: id, reject: xhr) postMessage: (e) -> { id, args } = e @@ -37,12 +37,12 @@ class AjaxWorkerPolyfill extends WorkerPolyfill result = if /^\s*$/.test(result) then null else JSON.parse(result) catch error - return this.handleError(xhr) if error - this.handleSuccess(result) + return this.handleError(id, xhr) if error + this.handleSuccess(id, result) # Error else - this.handleError(xhr) + this.handleError(id, xhr) xhr.send(data) diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee index 22e10f4..5b091b2 100644 --- a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee +++ b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee @@ -16,7 +16,7 @@ class JSONPWorkerPolyfill extends WorkerPolyfill delete window[callbackFnName] this.removeScript() args = if args.length > 1 then args else args[0] - this.handleRequest(args) + this.handleRequest(id: id, resolve: args) request = if callbackAttribute then this.appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url this.addScript(request) From 4e723671fdafe01d5218bee5d7fb3a4e31be4f1e Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 11 Nov 2016 17:07:00 -0500 Subject: [PATCH 31/45] [dist] --- dist/architect.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 82cdeaf..474af92 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):"object"==typeof exports?exports.Architect=e():t.Architect=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return t[n].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){var n,o,s,i,a,u,p=function(t,e){return function(){return t.apply(e,arguments)}};for(o={},a=["ajax","jsonp"],s=0,i=a.length;i>s;s++)u=a[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function t(t){var e,r,n,o;e=null!=t?t:{},n=e.workersPath,o=e.workersSuffix,r=e.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return t.prototype.spawnWorker=function(t){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(t)):this.getPolyfillForType(t)},t.prototype.getWorkerPathForType=function(t){return this.workersPath+"/"+t+this.workersSuffix},t.prototype.getPolyfillForType=function(t){var e;if(e=o[t],!e)throw new Error(t+" is not a valid type");return new e},t.prototype.workersAreSupported=function(t){return null==t&&(t=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in t},t.prototype.requireParams=function(t,e){var r,n,o,s,i,a,u,p,c;for(null==e&&(e={}),i=[],Array.isArray(t)||(t=[t]),r=0,o=t.length;o>r;r++)if(u=t[r],!(u in e))if((c=u.split(/\s?\|\|\s?/)).length>1){for(a=[],n=0,s=c.length;s>n;n++)p=c[n],p in e&&a.push(p);a.length||i.push(u)}else i.push(u);if(i.length)throw new Error("Missing required “"+i.join(", ")+"” parameter"+(i.length>1?"s":""))},t.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},t.prototype.work=function(t){var e,r,n,o;return n=null!=t?t:{},e=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(t){return function(n,s){var i,a;return i=t.getJobId(),t.jobs[i]={id:i,resolve:n,reject:s},(a=t.workers[o||r])||(a=o?t.spawnWorker(o):new Worker(r),a.addEventListener("message",t.handleMessage),t.workers[o||r]=a),a.postMessage({id:i,args:e})}}(this))},t.prototype.handleMessage=function(t){var e,r,n,o,s;return n=t.data,e=n.id,s=n.resolve,o=n.reject,r=this.jobs[e],delete this.jobs[e],"resolve"in t.data?r.resolve(s):r.reject(o)},t.prototype.jsonp=function(t){return null==t&&(t={}),"string"==typeof t&&(t={url:t}),this.requireParams("url",t),this.work({data:t,type:"jsonp"})},t.prototype.ajax=function(t){var e,r,n;return null==t&&(t={}),this.requireParams("url",t),n=t.success,e=t.error,r=JSON.parse(JSON.stringify(t)),delete r.success,delete r.error,new Promise(function(t){return function(o,s){return t.work({data:r,type:"ajax"}).then(function(t){return o(t),"function"==typeof n?n(t):void 0})["catch"](function(t){return s(t),"function"==typeof e?e(t):void 0})}}(this))},t.prototype.custom=function(t){var e,r,n,o;return o=null!=t?t:{},n=o.path,e=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(t){return function(o,s){return t.workersAreSupported()?t.work({data:e,path:n}).then(o):r?o(r(e)):s("Workers not supported and fallback not provided for "+n)}}(this))},t}(),t.exports=n},function(t,e,r){function n(t){return r(o(t))}function o(t){return s[t]||function(){throw new Error("Cannot find module '"+t+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,t.exports=n,n.id=1},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)i.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},i={}.hasOwnProperty;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.handleSuccess=function(t){return this.handleRequest({success:t})},e.prototype.handleError=function(t){return this.handleRequest({error:t})},e.prototype.postMessage=function(t){var e,r,n,o,s,i,a,u,p,c,l;u=t.id,e=t.args,p=e.type,c=e.url,n=e.data,o=e.dataType,r=e.contentType,a=e.headers,p||(p="GET"),a||(a={}),null==a["X-Requested-With"]&&(a["X-Requested-With"]="XMLHttpRequest"),r!==!1&&(a["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(p,c),"withCredentials"in e&&(l.withCredentials=e.withCredentials);for(s in a)i=a[s],i&&l.setRequestHeader(s,i);return l.onreadystatechange=function(t){return function(){var e,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=l.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){e=n}return e?t.handleError(l):t.handleSuccess(r)}return t.handleError(l)}}}(this),l.send(n)},e}(o),t.exports=n},function(t,e,r){var n,o,s=function(t,e){function r(){this.constructor=t}for(var n in e)i.call(e,n)&&(t[n]=e[n]);return r.prototype=e.prototype,t.prototype=new r,t.__super__=e.prototype,t},i={}.hasOwnProperty,a=[].slice;o=r(4),n=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return s(e,t),e.prototype.postMessage=function(t){var e,r,n,o,s,i;return o=t.id,e=t.args,i=e.url,r=e.callbackAttribute,n=e.callbackFnName,void 0===r&&(r="callback"),void 0===n&&(this.jsonpID||(this.jsonpID=0),n="architect_jsonp"+ ++this.jsonpID),window[n]=function(t){return function(){var e;return e=1<=arguments.length?a.call(arguments,0):[],delete window[n],t.removeScript(),e=e.length>1?e:e[0],t.handleRequest(e)}}(this),s=r?this.appendQuery(i,r+"="+n):i,this.addScript(s)},e.prototype.addScript=function(t){return this.tmpScript=document.createElement("script"),this.tmpScript.src=t,document.head.appendChild(this.tmpScript)},e.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},e.prototype.appendQuery=function(t,e){return(t+"&"+e).replace(/[&?]{1,2}/,"?")},e}(o),t.exports=n},function(t){var e;e=function(){function t(){this.callbacks={},this.callbacksQueue={}}return t.prototype.addEventListener=function(t,e){var r;return this.callbacks[t]=e,(r=this.callbacksQueue[t])?(delete this.callbacksQueue[t],this.dispatch(t,r)):void 0},t.prototype.dispatch=function(t,e){return this.callbacks[t]?this.callbacks[t]({data:e}):this.callbacksQueue[t]=e},t.prototype.handleRequest=function(t){return this.dispatch("message",t)},t.prototype.postMessage=function(){},t.prototype.terminate=function(){},t}(),t.exports=e}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,o,s,i,a,u,p=function(e,t){return function(){return e.apply(t,arguments)}};for(o={},a=["ajax","jsonp"],s=0,i=a.length;i>s;s++)u=a[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function e(e){var t,r,n,o;t=null!=e?e:{},n=t.workersPath,o=t.workersSuffix,r=t.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return e.prototype.spawnWorker=function(e){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(e)):this.getPolyfillForType(e)},e.prototype.getWorkerPathForType=function(e){return this.workersPath+"/"+e+this.workersSuffix},e.prototype.getPolyfillForType=function(e){var t;if(t=o[e],!t)throw new Error(e+" is not a valid type");return new t},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,o,s,i,a,u,p,c;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,o=e.length;o>r;r++)if(u=e[r],!(u in t))if((c=u.split(/\s?\|\|\s?/)).length>1){for(a=[],n=0,s=c.length;s>n;n++)p=c[n],p in t&&a.push(p);a.length||i.push(u)}else i.push(u);if(i.length)throw new Error("Missing required “"+i.join(", ")+"” parameter"+(i.length>1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,o;return n=null!=e?e:{},t=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(e){return function(n,s){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:s},(a=e.workers[o||r])||(a=o?e.spawnWorker(o):new Worker(r),a.addEventListener("message",e.handleMessage),e.workers[o||r]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,o,s;return n=e.data,t=n.id,s=n.resolve,o=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(s):r.reject(o)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(o,s){return e.work({data:r,type:"ajax"}).then(function(e){return o(e),"function"==typeof n?n(e):void 0})["catch"](function(e){return s(e),"function"==typeof t?t(e):void 0})}}(this))},e.prototype.custom=function(e){var t,r,n,o;return o=null!=e?e:{},n=o.path,t=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(e){return function(o,s){return e.workersAreSupported()?e.work({data:t,path:n}).then(o):r?o(r(t)):s("Workers not supported and fallback not provided for "+n)}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(o(e))}function o(e){return s[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,e.exports=n,n.id=1},function(e,t,r){var n,o,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},i={}.hasOwnProperty;o=r(4),n=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return s(t,e),t.prototype.handleSuccess=function(e,t){return this.handleRequest({id:e,resolve:t})},t.prototype.handleError=function(e,t){return this.handleRequest({id:e,reject:t})},t.prototype.postMessage=function(e){var t,r,n,o,s,i,a,u,p,c,l;u=e.id,t=e.args,p=t.type,c=t.url,n=t.data,o=t.dataType,r=t.contentType,a=t.headers,p||(p="GET"),a||(a={}),null==a["X-Requested-With"]&&(a["X-Requested-With"]="XMLHttpRequest"),r!==!1&&(a["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(p,c),"withCredentials"in t&&(l.withCredentials=t.withCredentials);for(s in a)i=a[s],i&&l.setRequestHeader(s,i);return l.onreadystatechange=function(e){return function(){var t,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=l.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){t=n}return t?e.handleError(u,l):e.handleSuccess(u,r)}return e.handleError(u,l)}}}(this),l.send(n)},t}(o),e.exports=n},function(e,t,r){var n,o,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},i={}.hasOwnProperty,a=[].slice;o=r(4),n=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return s(t,e),t.prototype.postMessage=function(e){var t,r,n,o,s,i;return o=e.id,t=e.args,i=t.url,r=t.callbackAttribute,n=t.callbackFnName,void 0===r&&(r="callback"),void 0===n&&(this.jsonpID||(this.jsonpID=0),n="architect_jsonp"+ ++this.jsonpID),window[n]=function(e){return function(){var t;return t=1<=arguments.length?a.call(arguments,0):[],delete window[n],e.removeScript(),t=t.length>1?t:t[0],e.handleRequest({id:o,resolve:t})}}(this),s=r?this.appendQuery(i,r+"="+n):i,this.addScript(s)},t.prototype.addScript=function(e){return this.tmpScript=document.createElement("script"),this.tmpScript.src=e,document.head.appendChild(this.tmpScript)},t.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},t.prototype.appendQuery=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},t}(o),e.exports=n},function(e){var t;t=function(){function e(){this.callbacks={},this.callbacksQueue={}}return e.prototype.addEventListener=function(e,t){var r;return this.callbacks[e]=t,(r=this.callbacksQueue[e])?(delete this.callbacksQueue[e],this.dispatch(e,r)):void 0},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(){},e.prototype.terminate=function(){},e}(),e.exports=t}])}); \ No newline at end of file From bbbbb3d8f70a40ce7af0052244e3522f9a29ba0b Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 3 Mar 2017 13:50:04 -0500 Subject: [PATCH 32/45] Use yarn --- yarn.lock | 2755 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2755 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..f402f17 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2755 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +accepts@~1.2.12, accepts@~1.2.13: + version "1.2.13" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.2.13.tgz#e5f1f3928c6d95fd96558c36ec3d9d0de4a6ecea" + dependencies: + mime-types "~2.1.6" + negotiator "0.5.3" + +accepts@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +acorn@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assertion-error@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.0.tgz#c7f85438fdd466bc7ca16ab90c81513797a5d23b" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + +async@^1.2.1, async@^1.3.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@~0.2.6: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + +base64-url@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-url/-/base64-url-1.2.1.tgz#199fd661702a0e7b7dcae6e0698bb089c52f6d78" + +base64-url@1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/base64-url/-/base64-url-1.3.3.tgz#f8b6c537f09a4fc58c99cb86e0b0e9c61461a20f" + +basic-auth-connect@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122" + +basic-auth@~1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.0.4.tgz#030935b01de7c9b94a824b29f3fccb750d3a5290" + +batch@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +body-parser@~1.13.3: + version "1.13.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.13.3.tgz#c08cf330c3358e151016a05746f13f029c97fa97" + dependencies: + bytes "2.1.0" + content-type "~1.0.1" + debug "~2.2.0" + depd "~1.0.1" + http-errors "~1.3.1" + iconv-lite "0.4.11" + on-finished "~2.3.0" + qs "4.0.0" + raw-body "~2.1.2" + type-is "~1.6.6" + +body-parser@~1.14.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9" + dependencies: + bytes "2.2.0" + content-type "~1.0.1" + debug "~2.2.0" + depd "~1.1.0" + http-errors "~1.3.1" + iconv-lite "0.4.13" + on-finished "~2.3.0" + qs "5.2.0" + raw-body "~2.1.5" + type-is "~1.6.10" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +browserify-aes@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-0.4.0.tgz#067149b668df31c4b58533e02d01e806d8608e2c" + dependencies: + inherits "^2.0.1" + +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + dependencies: + pako "~0.2.0" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +buffer@^4.9.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +bytes@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.1.0.tgz#ac93c410e2ffc9cc7cf4b464b38289067f5e47b4" + +bytes@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588" + +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chai-as-promised@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-4.3.0.tgz#0fa861b0b31bfe6867f5e770f0f877be60ece5ee" + +chai@^2.1.2: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-2.3.0.tgz#8a2f6a34748da801090fd73287b2aa739a4e909a" + dependencies: + assertion-error "1.0.0" + deep-eql "0.1.3" + +chalk@^1.0.0, chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chokidar@^1.0.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + +clone@^1.0.0, clone@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +coffee-loader@^0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.7.3.tgz#fadbc6efd6fc7ecc88c5b3046a2c292066bcb54a" + dependencies: + loader-utils "^1.0.2" + +coffee-script@^1.7.1: + version "1.12.4" + resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.4.tgz#fe1bced97fe1fb3927b998f2b45616e0658be1ff" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +compressible@~2.0.5: + version "2.0.9" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" + dependencies: + mime-db ">= 1.24.0 < 2" + +compression@~1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.5.2.tgz#b03b8d86e6f8ad29683cba8df91ddc6ffc77b395" + dependencies: + accepts "~1.2.12" + bytes "2.1.0" + compressible "~2.0.5" + debug "~2.2.0" + on-headers "~1.0.0" + vary "~1.0.1" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +connect-livereload@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/connect-livereload/-/connect-livereload-0.5.4.tgz#80157d1371c9f37cc14039ab1895970d119dc3bc" + +connect-timeout@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/connect-timeout/-/connect-timeout-1.6.2.tgz#de9a5ec61e33a12b6edaab7b5f062e98c599b88e" + dependencies: + debug "~2.2.0" + http-errors "~1.3.1" + ms "0.7.1" + on-headers "~1.0.0" + +connect@^2.30.0: + version "2.30.2" + resolved "https://registry.yarnpkg.com/connect/-/connect-2.30.2.tgz#8da9bcbe8a054d3d318d74dfec903b5c39a1b609" + dependencies: + basic-auth-connect "1.0.0" + body-parser "~1.13.3" + bytes "2.1.0" + compression "~1.5.2" + connect-timeout "~1.6.2" + content-type "~1.0.1" + cookie "0.1.3" + cookie-parser "~1.3.5" + cookie-signature "1.0.6" + csurf "~1.8.3" + debug "~2.2.0" + depd "~1.0.1" + errorhandler "~1.4.2" + express-session "~1.11.3" + finalhandler "0.4.0" + fresh "0.3.0" + http-errors "~1.3.1" + method-override "~2.3.5" + morgan "~1.6.1" + multiparty "3.3.2" + on-headers "~1.0.0" + parseurl "~1.3.0" + pause "0.1.0" + qs "4.0.0" + response-time "~2.3.1" + serve-favicon "~2.3.0" + serve-index "~1.7.2" + serve-static "~1.10.0" + type-is "~1.6.6" + utils-merge "1.0.0" + vhost "~3.0.1" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +content-type@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +cookie-parser@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.3.5.tgz#9d755570fb5d17890771227a02314d9be7cf8356" + dependencies: + cookie "0.1.3" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.3.tgz#e734a5c1417fce472d5aef82c381cabb64d1a435" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +crc@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.3.0.tgz#fa622e1bc388bf257309082d6b65200ce67090ba" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.3.0.tgz#b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c" + dependencies: + browserify-aes "0.4.0" + pbkdf2-compat "2.0.1" + ripemd160 "0.2.0" + sha.js "2.2.6" + +csrf@~3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/csrf/-/csrf-3.0.4.tgz#ba01423e5b5bea7b655e38b0bdd1323954cbdaa5" + dependencies: + base64-url "1.3.3" + rndm "1.2.0" + tsscmp "1.0.5" + uid-safe "2.1.3" + +css-loader@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.9.1.tgz#2e1aa00ce7e30ef2c6a7a4b300a080a7c979e0dc" + dependencies: + csso "1.3.x" + loader-utils "~0.2.2" + source-map "~0.1.38" + +csso@1.3.x: + version "1.3.12" + resolved "https://registry.yarnpkg.com/csso/-/csso-1.3.12.tgz#fc628694a2d38938aaac4996753218fd311cdb9e" + +csurf@~1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/csurf/-/csurf-1.8.3.tgz#23f2a13bf1d8fce1d0c996588394442cba86a56a" + dependencies: + cookie "0.1.3" + cookie-signature "1.0.6" + csrf "~3.0.0" + http-errors "~1.3.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +dateformat@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" + +debug@2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +decamelize@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-eql@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +defaults@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + +del@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/del/-/del-1.2.1.tgz#aed6e5bcd7cb7325df34f563125fa265b2c1a014" + dependencies: + each-async "^1.0.0" + globby "^2.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.0.1.tgz#80aec64c9d6d97e65cc2a9caa93c0aa6abf73aaa" + +depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +deprecated@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-file@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" + dependencies: + fs-exists-sync "^0.1.0" + +domain-browser@^1.1.1: + version "1.1.7" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + +duplexer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +each-async@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/each-async/-/each-async-1.1.1.tgz#dee5229bdf0ab6ba2012a395e1b869abf8813473" + dependencies: + onetime "^1.0.0" + set-immediate-shim "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +end-of-stream@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" + dependencies: + once "~1.3.0" + +enhanced-resolve@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.2.0" + tapable "^0.1.8" + +errno@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + +errorhandler@~1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.4.3.tgz#b7b70ed8f359e9db88092f2d20c0f831420ad83f" + dependencies: + accepts "~1.3.0" + escape-html "~1.0.3" + +escape-html@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.2.tgz#d77d32fa98e38c2f41ae85e9278e0e0e6ba1022c" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +etag@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" + +event-stream@^3.3.2: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expand-tilde@^1.2.1, expand-tilde@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" + dependencies: + os-homedir "^1.0.1" + +expose-loader@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/expose-loader/-/expose-loader-0.6.0.tgz#4579f53065d4a9a11f76b479f2747155457a599b" + +express-session@~1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.11.3.tgz#5cc98f3f5ff84ed835f91cbf0aabd0c7107400af" + dependencies: + cookie "0.1.3" + cookie-signature "1.0.6" + crc "3.3.0" + debug "~2.2.0" + depd "~1.0.1" + on-headers "~1.0.0" + parseurl "~1.3.0" + uid-safe "~2.0.0" + utils-merge "1.0.0" + +extend@^3.0.0, extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fancy-log@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" + dependencies: + chalk "^1.1.1" + time-stamp "^1.0.0" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.4.0.tgz#965a52d9e8d05d2b857548541fb89b53a2497d9b" + dependencies: + debug "~2.2.0" + escape-html "1.0.2" + on-finished "~2.3.0" + unpipe "~1.0.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + +findup-sync@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" + dependencies: + detect-file "^0.1.0" + is-glob "^2.0.1" + micromatch "^2.3.7" + resolve-dir "^0.1.0" + +fined@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" + dependencies: + expand-tilde "^1.2.1" + lodash.assignwith "^4.0.7" + lodash.isempty "^4.2.1" + lodash.isplainobject "^4.0.4" + lodash.isstring "^4.0.1" + lodash.pick "^4.2.1" + parse-filepath "^1.0.1" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + +flagged-respawn@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fresh@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" + +from@~0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.3.tgz#ef63ac2062ac32acf7862e0d40b44b896f22f3bc" + +fs-exists-sync@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gauge@~2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + dependencies: + globule "~0.1.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-stream@^3.1.5: + version "3.1.18" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" + dependencies: + glob "^4.3.1" + glob2base "^0.0.12" + minimatch "^2.0.1" + ordered-read-streams "^0.1.0" + through2 "^0.6.1" + unique-stream "^1.0.0" + +glob-watcher@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" + dependencies: + gaze "^0.5.1" + +glob2base@^0.0.12: + version "0.0.12" + resolved "http://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + dependencies: + find-index "^0.1.1" + +glob@^4.3.1: + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@^5.0.3: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~3.1.21: + version "3.1.21" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + dependencies: + graceful-fs "~1.2.0" + inherits "1" + minimatch "~0.2.11" + +global-modules@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" + dependencies: + global-prefix "^0.1.4" + is-windows "^0.2.0" + +global-prefix@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" + dependencies: + homedir-polyfill "^1.0.0" + ini "^1.3.4" + is-windows "^0.2.0" + which "^1.2.12" + +globby@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-2.1.0.tgz#9e9192bcd33f4ab6a4f894e5e7ea8b713213c482" + dependencies: + array-union "^1.0.1" + async "^1.2.1" + glob "^5.0.3" + object-assign "^3.0.0" + +globule@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + dependencies: + glob "~3.1.21" + lodash "~1.0.1" + minimatch "~0.2.11" + +glogg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" + dependencies: + sparkles "^1.0.0" + +graceful-fs@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + dependencies: + natives "^1.1.0" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +gulp-connect@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/gulp-connect/-/gulp-connect-2.3.1.tgz#14ae7173328b691252b01fc1930a39cbb24fb33c" + dependencies: + connect "^2.30.0" + connect-livereload "^0.5.4" + event-stream "^3.3.2" + gulp-util "^3.0.6" + tiny-lr "^0.2.1" + +"gulp-util@>=3.0.0 <3.1.0-0", gulp-util@^3.0.0, gulp-util@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp-webpack@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/gulp-webpack/-/gulp-webpack-1.5.0.tgz#7aa683fe88c02d246148e27c7229cb6b62892dba" + dependencies: + gulp-util ">=3.0.0 <3.1.0-0" + memory-fs ">=0.2.0 <0.3.0-0" + through ">=2.3.4 <2.4.0-0" + vinyl ">=0.5.0 <0.6.0-0" + webpack ">=1.9.0 <2.0.0-0" + +gulp@^3.8.10: + version "3.9.1" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" + dependencies: + archy "^1.0.0" + chalk "^1.0.0" + deprecated "^0.0.1" + gulp-util "^3.0.0" + interpret "^1.0.0" + liftoff "^2.1.0" + minimist "^1.1.0" + orchestrator "^0.3.0" + pretty-hrtime "^1.0.0" + semver "^4.1.0" + tildify "^1.0.0" + v8flags "^2.0.2" + vinyl-fs "^0.3.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + dependencies: + glogg "^1.0.0" + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + dependencies: + sparkles "^1.0.0" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +homedir-polyfill@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + dependencies: + parse-passwd "^1.0.0" + +http-errors@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" + dependencies: + inherits "~2.0.1" + statuses "1" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" + +iconv-lite@0.4.11: + version "0.4.11" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.11.tgz#2ecb42fd294744922209a2e7c404dac8793d8ade" + +iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + +inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +interpret@^0.6.4: + version "0.6.6" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" + +interpret@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + +is-absolute@^0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" + dependencies: + is-relative "^0.2.1" + is-windows "^0.2.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.0.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-my-json-valid@^2.12.4: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-relative@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" + dependencies: + is-unc-path "^0.1.1" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-unc-path@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" + dependencies: + unc-path-regex "^0.1.0" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +liftoff@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" + dependencies: + extend "^3.0.0" + findup-sync "^0.4.2" + fined "^1.0.1" + flagged-respawn "^0.3.2" + lodash.isplainobject "^4.0.4" + lodash.isstring "^4.0.1" + lodash.mapvalues "^4.4.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +livereload-js@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" + +loader-utils@^0.2.11, loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.5: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.0.2.tgz#a9f923c865a974623391a8602d031137fad74830" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + +lodash.assignwith@^4.0.7: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + dependencies: + lodash._root "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.isempty@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" + +lodash.isplainobject@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.mapvalues@^4.4.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" + +lodash.pick@^4.2.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +map-cache@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +"memory-fs@>=0.2.0 <0.3.0-0", memory-fs@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" + +memory-fs@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +method-override@~2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/method-override/-/method-override-2.3.7.tgz#8e1d47ac480fb0cd8777083f11c896901166b2e5" + dependencies: + debug "2.3.3" + methods "~1.1.2" + parseurl "~1.3.1" + vary "~1.1.0" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +micromatch@^2.1.5, micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +"mime-db@>= 1.24.0 < 2", mime-db@~1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" + +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9: + version "2.1.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" + dependencies: + mime-db "~1.26.0" + +mime@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha-loader@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/mocha-loader/-/mocha-loader-0.7.1.tgz#68247c5e5d6cb564d09b155fec7e20eb07788173" + dependencies: + css-loader "~0.9.0" + loader-utils "~0.2.5" + script-loader "~0.6.0" + style-loader "~0.8.1" + +morgan@~1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.6.1.tgz#5fd818398c6819cba28a7cd6664f292fe1c0bbf2" + dependencies: + basic-auth "~1.0.3" + debug "~2.2.0" + depd "~1.0.1" + on-finished "~2.3.0" + on-headers "~1.0.0" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +multiparty@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/multiparty/-/multiparty-3.3.2.tgz#35de6804dc19643e5249f3d3e3bdc6c8ce301d3f" + dependencies: + readable-stream "~1.1.9" + stream-counter "~0.2.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + dependencies: + duplexer2 "0.0.2" + +nan@^2.3.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" + +natives@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" + +negotiator@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.5.3.tgz#269d5c476810ec92edbe7b6c2f28316384f9a7e8" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-libs-browser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.7.0.tgz#3e272c0819e308935e26674408d7af0e1491b83b" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.9.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "3.3.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^2.0.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.6.29: + version "0.6.33" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.1" + rc "~1.1.6" + request "^2.79.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + +npmlog@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.0, on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +once@~1.3.0, once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +optimist@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +orchestrator@^0.3.0: + version "0.3.8" + resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" + dependencies: + end-of-stream "~0.1.5" + sequencify "~0.0.7" + stream-consume "~0.1.0" + +ordered-read-streams@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" + +os-browserify@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + +parse-filepath@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" + dependencies: + is-absolute "^0.2.3" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + +parseurl@~1.3.0, parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + dependencies: + path-root-regex "^0.1.0" + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + +pause@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.1.0.tgz#ebc8a4a8619ff0b8a81ac1513c3434ff469fdb74" + +pbkdf2-compat@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@^0.11.0: + version "0.11.9" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-4.0.0.tgz#c31d9b74ec27df75e543a86c78728ed8d4623607" + +qs@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" + +qs@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" + +qs@~6.3.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.1.tgz#918c0b3bcd36679772baf135b1acb4c1651ed79d" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +range-parser@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.0.3.tgz#6872823535c692e2c2a0103826afd82c2e0ff175" + +raw-body@~2.1.2, raw-body@~2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.13" + unpipe "1.0.0" + +raw-loader@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" + +rc@~1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.7.tgz#c5ea564bb07aff9fd3a5b32e906c1d3a65940fea" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.0, readable-stream@^2.1.5: + version "2.2.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~1.1.8, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +request@^2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +resolve-dir@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" + dependencies: + expand-tilde "^1.2.2" + global-modules "^0.2.3" + +resolve@^1.1.6, resolve@^1.1.7: + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + dependencies: + path-parse "^1.0.5" + +response-time@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/response-time/-/response-time-2.3.2.tgz#ffa71bab952d62f7c1d49b7434355fbc68dffc5a" + dependencies: + depd "~1.1.0" + on-headers "~1.0.1" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.8: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +ripemd160@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce" + +rndm@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" + +script-loader@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/script-loader/-/script-loader-0.6.1.tgz#183c6103945aaf5134b46f03003b5ee2bad44ceb" + dependencies: + raw-loader "~0.5.1" + +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +send@0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.13.2.tgz#765e7607c8055452bba6f0b052595350986036de" + dependencies: + debug "~2.2.0" + depd "~1.1.0" + destroy "~1.0.4" + escape-html "~1.0.3" + etag "~1.7.0" + fresh "0.3.0" + http-errors "~1.3.1" + mime "1.3.4" + ms "0.7.1" + on-finished "~2.3.0" + range-parser "~1.0.3" + statuses "~1.2.1" + +sequencify@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + +serve-favicon@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.3.2.tgz#dd419e268de012ab72b319d337f2105013f9381f" + dependencies: + etag "~1.7.0" + fresh "0.3.0" + ms "0.7.2" + parseurl "~1.3.1" + +serve-index@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.7.3.tgz#7a057fc6ee28dc63f64566e5fa57b111a86aecd2" + dependencies: + accepts "~1.2.13" + batch "0.5.3" + debug "~2.2.0" + escape-html "~1.0.3" + http-errors "~1.3.1" + mime-types "~2.1.9" + parseurl "~1.3.1" + +serve-static@~1.10.0: + version "1.10.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.10.3.tgz#ce5a6ecd3101fed5ec09827dac22a9c29bfb0535" + dependencies: + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.13.2" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.0, set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +sha.js@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +simple-mock@^0.2.9: + version "0.2.14" + resolved "https://registry.yarnpkg.com/simple-mock/-/simple-mock-0.2.14.tgz#88e9f0ae1dc24cd212f0ecb7d1ca2aea4a78846f" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +source-list-map@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + +source-map@~0.1.38: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +sparkles@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" + +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + dependencies: + through "2" + +sshpk@^1.7.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +statuses@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +statuses@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.2.1.tgz#dded45cc18256d51ed40aec142489d5c61026d28" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + dependencies: + duplexer "~0.1.1" + +stream-consume@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +stream-counter@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-counter/-/stream-counter-0.2.0.tgz#ded266556319c8b0e222812b9cf3b26fa7d947de" + dependencies: + readable-stream "~1.1.8" + +stream-http@^2.3.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.6.3.tgz#4c3ddbf9635968ea2cfd4e48d43de5def2625ac3" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.1.0" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@^0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-bom@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" + dependencies: + first-chunk-stream "^1.0.0" + is-utf8 "^0.2.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +style-loader@~0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.8.3.tgz#f4f92eb7db63768748f15065cd6700f5a1c85357" + dependencies: + loader-utils "^0.2.5" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +tapable@^0.1.8, tapable@~0.1.8: + version "0.1.10" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +through2@^0.6.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, "through@>=2.3.4 <2.4.0-0", through@~2.3, through@~2.3.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tildify@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + dependencies: + os-homedir "^1.0.0" + +time-stamp@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151" + +timers-browserify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.2.tgz#ab4883cf597dcd50af211349a00fbca56ac86b86" + dependencies: + setimmediate "^1.0.4" + +tiny-lr@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" + dependencies: + body-parser "~1.14.0" + debug "~2.2.0" + faye-websocket "~0.10.0" + livereload-js "^2.2.0" + parseurl "~1.3.0" + qs "~5.1.0" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +tsscmp@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.5.tgz#7dc4a33af71581ab4337da91d85ca5427ebd9a97" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-is@~1.6.10, type-is@~1.6.6: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + +uglify-js@~2.7.3: + version "2.7.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" + dependencies: + async "~0.2.6" + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uid-safe@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.3.tgz#077e264a00b3187936b270bb7376a26473631071" + dependencies: + base64-url "1.3.3" + random-bytes "~1.0.0" + +uid-safe@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.0.0.tgz#a7f3c6ca64a1f6a5d04ec0ef3e4c3d5367317137" + dependencies: + base64-url "1.2.1" + +unc-path-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + +unique-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3, util@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +v8flags@^2.0.2: + version "2.0.11" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" + dependencies: + user-home "^1.1.1" + +vary@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" + +vary@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +vhost@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vhost/-/vhost-3.0.2.tgz#2fb1decd4c466aa88b0f9341af33dc1aff2478d5" + +vinyl-fs@^0.3.0: + version "0.3.14" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" + dependencies: + defaults "^1.0.0" + glob-stream "^3.1.5" + glob-watcher "^0.0.6" + graceful-fs "^3.0.0" + mkdirp "^0.5.0" + strip-bom "^1.0.0" + through2 "^0.6.1" + vinyl "^0.4.0" + +"vinyl@>=0.5.0 <0.6.0-0", vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^0.4.0: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +watchpack@^0.2.1: + version "0.2.9" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" + dependencies: + async "^0.9.0" + chokidar "^1.0.0" + graceful-fs "^4.1.2" + +webpack-core@~0.6.9: + version "0.6.9" + resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2" + dependencies: + source-list-map "~0.1.7" + source-map "~0.4.1" + +"webpack@>=1.9.0 <2.0.0-0", webpack@^1.5.3: + version "1.14.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.14.0.tgz#54f1ffb92051a328a5b2057d6ae33c289462c823" + dependencies: + acorn "^3.0.0" + async "^1.3.0" + clone "^1.0.2" + enhanced-resolve "~0.9.0" + interpret "^0.6.4" + loader-utils "^0.2.11" + memory-fs "~0.3.0" + mkdirp "~0.5.0" + node-libs-browser "^0.7.0" + optimist "~0.6.0" + supports-color "^3.1.0" + tapable "~0.1.8" + uglify-js "~2.7.3" + watchpack "^0.2.1" + webpack-core "~0.6.9" + +websocket-driver@>=0.5.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + dependencies: + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" + +which@^1.2.12: + version "1.2.12" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + dependencies: + isexe "^1.1.1" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" From e46cfd32f4173228f38b04babbb97594b47eff39 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 3 Mar 2017 13:50:34 -0500 Subject: [PATCH 33/45] [spec] Add mocha --- package.json | 1 + yarn.lock | 92 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 471a89d..3217681 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "gulp": "^3.8.10", "gulp-connect": "^2.2.0", "gulp-webpack": "^1.2.0", + "mocha": "^3.2.0", "mocha-loader": "^0.7.1", "simple-mock": "^0.2.9", "webpack": "^1.5.3" diff --git a/yarn.lock b/yarn.lock index f402f17..dce886d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -251,6 +251,10 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + browserify-aes@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-0.4.0.tgz#067149b668df31c4b58533e02d01e806d8608e2c" @@ -382,7 +386,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@^2.9.0: +commander@2.9.0, commander@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: @@ -558,18 +562,18 @@ dateformat@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" +debug@2.2.0, debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + debug@2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c" dependencies: ms "0.7.2" -debug@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - decamelize@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -631,6 +635,10 @@ detect-file@^0.1.0: dependencies: fs-exists-sync "^0.1.0" +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + domain-browser@^1.1.1: version "1.1.7" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" @@ -701,7 +709,7 @@ escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" -escape-string-regexp@^1.0.2: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -977,6 +985,17 @@ glob2base@^0.0.12: dependencies: find-index "^0.1.1" +glob@7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^4.3.1: version "4.5.3" resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" @@ -1072,6 +1091,10 @@ graceful-fs@~1.2.0: version "1.0.1" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + gulp-connect@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/gulp-connect/-/gulp-connect-2.3.1.tgz#14ae7173328b691252b01fc1930a39cbb24fb33c" @@ -1407,6 +1430,10 @@ json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -1468,10 +1495,21 @@ loader-utils@^1.0.2: emojis-list "^2.0.0" json5 "^0.5.0" +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + lodash._basetostring@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" @@ -1508,6 +1546,14 @@ lodash.assignwith@^4.0.7: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.escape@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" @@ -1674,7 +1720,7 @@ minimatch@~0.2.11: lru-cache "2" sigmund "~1.0.0" -minimist@0.0.8: +minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -1682,11 +1728,7 @@ minimist@^1.1.0, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -1701,6 +1743,22 @@ mocha-loader@^0.7.1: script-loader "~0.6.0" style-loader "~0.8.1" +mocha@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.5" + glob "7.0.5" + growl "1.9.2" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + morgan@~1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.6.1.tgz#5fd818398c6819cba28a7cd6664f292fe1c0bbf2" @@ -2422,6 +2480,12 @@ style-loader@~0.8.1: dependencies: loader-utils "^0.2.5" +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" From a032ac3925a9d664b12d61fac36ff0027d415791 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 3 Mar 2017 13:52:10 -0500 Subject: [PATCH 34/45] [spec] Fix overspecified spec --- specs/workers/jsonp_worker_spec.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specs/workers/jsonp_worker_spec.coffee b/specs/workers/jsonp_worker_spec.coffee index 681e66c..b02afe8 100644 --- a/specs/workers/jsonp_worker_spec.coffee +++ b/specs/workers/jsonp_worker_spec.coffee @@ -1,16 +1,15 @@ { Architect, simple, expect, helpers } = require('../spec_helper') { delay, callbackSequence } = helpers -describe.only 'JSONP Worker', -> +describe 'JSONP Worker', -> beforeEach -> @architect = new Architect workersPath: '/build/workers' workersSuffix: '_worker.js' - it 'rejects NetworkError', (done) -> + it 'rejects NetworkError', -> @architect.jsonp("https://api.example.com/fake") .then -> throw 'It shouldn’t throw' .catch (err) => expect(err).to.have.deep.property('code', 19) expect(err).to.have.deep.property('name', 'NetworkError') - done() From 66ee1cf00b3a065fdd02ce20fc17c392e6410a4b Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Fri, 3 Mar 2017 17:10:28 -0500 Subject: [PATCH 35/45] Use blobs --- dist/architect.min.js | 2 +- dist/workers/ajax_worker.min.js | 1 - dist/workers/jsonp_worker.min.js | 1 - examples/{short_lived_workers => }/app.js | 23 +++++- examples/custom_workers/app.js | 14 ---- examples/custom_workers/index.html | 9 --- .../custom_workers/workers/custom_worker.js | 4 -- examples/index.html | 9 +++ examples/short_lived_workers/index.html | 9 --- lib/architect.coffee | 70 +++++++++---------- .../polyfills/worker_polyfill.coffee | 27 ------- .../workers/jsonp_worker_polyfill.coffee | 37 ---------- .../ajax.coffee} | 41 +++++++---- lib/workers/ajax_worker.coffee | 62 ---------------- lib/workers/custom.coffee | 17 +++++ lib/workers/jsonp.coffee | 41 +++++++++++ lib/workers/jsonp_worker.coffee | 28 -------- lib/workers/polyfill.coffee | 50 +++++++++++++ package.json | 3 +- webpack.config.js | 45 ++---------- 20 files changed, 207 insertions(+), 286 deletions(-) delete mode 100644 dist/workers/ajax_worker.min.js delete mode 100644 dist/workers/jsonp_worker.min.js rename examples/{short_lived_workers => }/app.js (51%) delete mode 100644 examples/custom_workers/app.js delete mode 100644 examples/custom_workers/index.html delete mode 100644 examples/custom_workers/workers/custom_worker.js create mode 100644 examples/index.html delete mode 100644 examples/short_lived_workers/index.html delete mode 100644 lib/architect/polyfills/worker_polyfill.coffee delete mode 100644 lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee rename lib/{architect/polyfills/workers/ajax_worker_polyfill.coffee => workers/ajax.coffee} (52%) delete mode 100644 lib/workers/ajax_worker.coffee create mode 100644 lib/workers/custom.coffee create mode 100644 lib/workers/jsonp.coffee delete mode 100644 lib/workers/jsonp_worker.coffee create mode 100644 lib/workers/polyfill.coffee diff --git a/dist/architect.min.js b/dist/architect.min.js index 474af92..9ef30ac 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,o,s,i,a,u,p=function(e,t){return function(){return e.apply(t,arguments)}};for(o={},a=["ajax","jsonp"],s=0,i=a.length;i>s;s++)u=a[s],o[u]=r(1)("./"+u+"_worker_polyfill");n=function(){function e(e){var t,r,n,o;t=null!=e?e:{},n=t.workersPath,o=t.workersSuffix,r=t.threads,this.handleMessage=p(this.handleMessage,this),this.jobs={},this.workers={},this.workersPath=n?"/"+n.replace(/^\//,""):"/workers",this.workersSuffix=o||"_worker.min.js"}return e.prototype.spawnWorker=function(e){return this.workersAreSupported()?new Worker(this.getWorkerPathForType(e)):this.getPolyfillForType(e)},e.prototype.getWorkerPathForType=function(e){return this.workersPath+"/"+e+this.workersSuffix},e.prototype.getPolyfillForType=function(e){var t;if(t=o[e],!t)throw new Error(e+" is not a valid type");return new t},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,o,s,i,a,u,p,c;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,o=e.length;o>r;r++)if(u=e[r],!(u in t))if((c=u.split(/\s?\|\|\s?/)).length>1){for(a=[],n=0,s=c.length;s>n;n++)p=c[n],p in t&&a.push(p);a.length||i.push(u)}else i.push(u);if(i.length)throw new Error("Missing required “"+i.join(", ")+"” parameter"+(i.length>1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,o;return n=null!=e?e:{},t=n.data,o=n.type,r=n.path,this.requireParams("type || path",arguments[0]),new Promise(function(e){return function(n,s){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:s},(a=e.workers[o||r])||(a=o?e.spawnWorker(o):new Worker(r),a.addEventListener("message",e.handleMessage),e.workers[o||r]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,o,s;return n=e.data,t=n.id,s=n.resolve,o=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(s):r.reject(o)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(o,s){return e.work({data:r,type:"ajax"}).then(function(e){return o(e),"function"==typeof n?n(e):void 0})["catch"](function(e){return s(e),"function"==typeof t?t(e):void 0})}}(this))},e.prototype.custom=function(e){var t,r,n,o;return o=null!=e?e:{},n=o.path,t=o.data,r=o.fallback,this.requireParams("path",arguments[0]),new Promise(function(e){return function(o,s){return e.workersAreSupported()?e.work({data:t,path:n}).then(o):r?o(r(t)):s("Workers not supported and fallback not provided for "+n)}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(o(e))}function o(e){return s[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var s={"./ajax_worker_polyfill":2,"./jsonp_worker_polyfill":3};n.keys=function(){return Object.keys(s)},n.resolve=o,e.exports=n,n.id=1},function(e,t,r){var n,o,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},i={}.hasOwnProperty;o=r(4),n=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return s(t,e),t.prototype.handleSuccess=function(e,t){return this.handleRequest({id:e,resolve:t})},t.prototype.handleError=function(e,t){return this.handleRequest({id:e,reject:t})},t.prototype.postMessage=function(e){var t,r,n,o,s,i,a,u,p,c,l;u=e.id,t=e.args,p=t.type,c=t.url,n=t.data,o=t.dataType,r=t.contentType,a=t.headers,p||(p="GET"),a||(a={}),null==a["X-Requested-With"]&&(a["X-Requested-With"]="XMLHttpRequest"),r!==!1&&(a["Content-Type"]=r||"application/x-www-form-urlencoded"),l=new XMLHttpRequest,l.open(p,c),"withCredentials"in t&&(l.withCredentials=t.withCredentials);for(s in a)i=a[s],i&&l.setRequestHeader(s,i);return l.onreadystatechange=function(e){return function(){var t,r;if(4===l.readyState){if(l.status>=200&&l.status<300||304===l.status){r=l.responseText;try{"script"===o?(1,eval)(r):"xml"===o?r=l.responseXML:"json"===o&&(r=/^\s*$/.test(r)?null:JSON.parse(r))}catch(n){t=n}return t?e.handleError(u,l):e.handleSuccess(u,r)}return e.handleError(u,l)}}}(this),l.send(n)},t}(o),e.exports=n},function(e,t,r){var n,o,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},i={}.hasOwnProperty,a=[].slice;o=r(4),n=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return s(t,e),t.prototype.postMessage=function(e){var t,r,n,o,s,i;return o=e.id,t=e.args,i=t.url,r=t.callbackAttribute,n=t.callbackFnName,void 0===r&&(r="callback"),void 0===n&&(this.jsonpID||(this.jsonpID=0),n="architect_jsonp"+ ++this.jsonpID),window[n]=function(e){return function(){var t;return t=1<=arguments.length?a.call(arguments,0):[],delete window[n],e.removeScript(),t=t.length>1?t:t[0],e.handleRequest({id:o,resolve:t})}}(this),s=r?this.appendQuery(i,r+"="+n):i,this.addScript(s)},t.prototype.addScript=function(e){return this.tmpScript=document.createElement("script"),this.tmpScript.src=e,document.head.appendChild(this.tmpScript)},t.prototype.removeScript=function(){return document.head.removeChild(this.tmpScript)},t.prototype.appendQuery=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},t}(o),e.exports=n},function(e){var t;t=function(){function e(){this.callbacks={},this.callbacksQueue={}}return e.prototype.addEventListener=function(e,t){var r;return this.callbacks[e]=t,(r=this.callbacksQueue[e])?(delete this.callbacksQueue[e],this.dispatch(e,r)):void 0},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(){},e.prototype.terminate=function(){},e}(),e.exports=t}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(e,t){e.exports=function(){return this.onmessage=function(e){return function(t){var r,n,s,o;return s=t.data,n=s.id,r=s.args,o=e.fn?e.fn(r):work(r),o instanceof Promise?o.then(function(t){return e.postMessage({id:n,resolve:t})}).catch(function(t){return e.postMessage({id:n,reject:t})}):e.postMessage({id:n,resolve:o})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p;try{}catch(e){t=e,r=this}r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file diff --git a/dist/workers/ajax_worker.min.js b/dist/workers/ajax_worker.min.js deleted file mode 100644 index b363a2c..0000000 --- a/dist/workers/ajax_worker.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){function t(s){if(r[s])return r[s].exports;var n=r[s]={exports:{},id:s,loaded:!1};return e[s].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(){var e,t;t=function(e,t){return postMessage({id:e,resolve:t})},e=function(e,t,r){var s,n,a,o,i,u,c;for(c={},i=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],n=0,o=i.length;o>n;n++)a=i[n],c[a]=t[a];try{"json"===r&&(u=c.response,c.response=/^\s*$/.test(u)?null:JSON.parse(u))}catch(d){s=d}return postMessage({id:e,reject:c})},addEventListener("message",function(r){var s,n,a,o,i,u,c,d,p,l,f,v;p=r.data,d=p.id,s=p.args,l=s.type,f=s.url,a=s.data,o=s.dataType,n=s.contentType,c=s.headers,l||(l="GET"),c||(c={}),null==c["X-Requested-With"]&&(c["X-Requested-With"]="XMLHttpRequest"),n!==!1&&(c["Content-Type"]=n||"application/x-www-form-urlencoded"),v=new XMLHttpRequest,v.open(l,f),"withCredentials"in s&&(v.withCredentials=s.withCredentials);for(i in c)u=c[i],u&&v.setRequestHeader(i,u);return v.onreadystatechange=function(){var r,s;if(4===v.readyState){if(v.status>=200&&v.status<300||304===v.status){s=v.responseText;try{"script"===o?(1,eval)(s):"xml"===o?s=v.responseXML:"json"===o&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(n){r=n}return r?e(d,v,o):t(d,s)}return e(d,v,o)}},v.send(a)})}]); \ No newline at end of file diff --git a/dist/workers/jsonp_worker.min.js b/dist/workers/jsonp_worker.min.js deleted file mode 100644 index 0950610..0000000 --- a/dist/workers/jsonp_worker.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(2)},,function(){var e,t=[].slice;e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},addEventListener("message",function(r){var a,n,s,c,o,l,i,u;l=r.data,o=l.id,a=l.args,u=a.url,n=a.callbackAttribute,s=a.callbackFnName,void 0===n&&(n="callback"),void 0===s&&(s="handleRequest"),self[s]=function(){var e;return e=1<=arguments.length?t.call(arguments,0):[],e=e.length>1?e:e[0],postMessage({id:o,resolve:e})},i=n?e(u,n+"="+s):u;try{return importScripts(i)}catch(d){return c=d,postMessage({id:o,reject:{message:c.message,code:c.code,name:c.name}})}})}]); \ No newline at end of file diff --git a/examples/short_lived_workers/app.js b/examples/app.js similarity index 51% rename from examples/short_lived_workers/app.js rename to examples/app.js index 66dbb69..d1df048 100644 --- a/examples/short_lived_workers/app.js +++ b/examples/app.js @@ -13,7 +13,28 @@ architect.jsonp({ // Ajax architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) .then(function(e) { console.log('AJAX:', e) }) - .catch(function(e) { console.log('AJAX ERROR:', e) }) + .catch(function(e) { console.log('AJAX ERROR:', e.response.message) }) + +// Custom +architect.work({ + type: 'foozle', + data: 'foo', + fn: function(data) { + return (data + 'zle').toUpperCase() + }, +}).then(function(e) { console.log('CUSTOM:', e) }) + +architect.work({ + type: 'promise', + data: 'foo', + fn: function(data) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + resolve(data + 'zle') + }, 1000) + }) + }, +}).then(function(e) { console.log('CUSTOM (Promise):', e) }) // $.ajax style architect.ajax({ diff --git a/examples/custom_workers/app.js b/examples/custom_workers/app.js deleted file mode 100644 index e3e0769..0000000 --- a/examples/custom_workers/app.js +++ /dev/null @@ -1,14 +0,0 @@ -var Architect = require('architect') - -architect = new Architect({ - workersPath: '/build/workers', - workersSuffix: '_worker.js', -}) - -architect.custom({ - path: '/build/workers/custom_worker.js', - data: 'foo', - fallback: function(data) { return (data + 'zle (fallback)').toUpperCase() } -}).then(function(data) { - console.log('Custom:', data) -}) diff --git a/examples/custom_workers/index.html b/examples/custom_workers/index.html deleted file mode 100644 index 72badd7..0000000 --- a/examples/custom_workers/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - Architect: Custom Workers - - - - - diff --git a/examples/custom_workers/workers/custom_worker.js b/examples/custom_workers/workers/custom_worker.js deleted file mode 100644 index 77225fc..0000000 --- a/examples/custom_workers/workers/custom_worker.js +++ /dev/null @@ -1,4 +0,0 @@ -addEventListener('message', function(e) { - data = e.data + 'zle' - postMessage(data.toUpperCase()) -}) diff --git a/examples/index.html b/examples/index.html new file mode 100644 index 0000000..e7b54aa --- /dev/null +++ b/examples/index.html @@ -0,0 +1,9 @@ + + + + Architect: Examples + + + + + diff --git a/examples/short_lived_workers/index.html b/examples/short_lived_workers/index.html deleted file mode 100644 index f251881..0000000 --- a/examples/short_lived_workers/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - Architect: Short-lived Workers - - - - - diff --git a/lib/architect.coffee b/lib/architect.coffee index 6bbaca6..b12618b 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -1,30 +1,37 @@ -# Requires -Polyfills = {} -for type in ['ajax', 'jsonp'] - Polyfills[type] = require("./architect/polyfills/workers/#{type}_worker_polyfill") - # Architect class Architect - constructor: ({ workersPath, workersSuffix, threads } = {}) -> + constructor: () -> @jobs = {} @workers = {} - @workersPath = if workersPath then "/#{workersPath.replace(/^\//, '')}" else '/workers' - @workersSuffix = workersSuffix || '_worker.min.js' - spawnWorker: (type) -> - return this.getPolyfillForType(type) unless this.workersAreSupported() - new Worker(this.getWorkerPathForType(type)) + spawnWorker: ({ type, data, fn } = {}) -> + # Known type + try + work = require("./workers/#{type}") + + # Unkown type + catch e + # Custom + if fn + work = require('./workers/custom') - getWorkerPathForType: (type) -> - "#{@workersPath}/#{type}#{@workersSuffix}" + else + throw new Error("Unkown worker type “#{type}” and no fn provided") - getPolyfillForType: (type) -> - klass = Polyfills[type] + # Native worker + if this.workersAreSupported() + fnRaw = if fn then "work = #{fn.toString()};" else '' + workerRaw = "(#{work.toString()})()" - unless klass - throw new Error("#{type} is not a valid type") + blob = new Blob([fnRaw, workerRaw]) + blobURL = window.URL.createObjectURL(blob) - new klass + new Worker(blobURL) + + # Polyfill + else + WorkerPolyfill = require('./workers/polyfill') + new WorkerPolyfill(work, fn) workersAreSupported: (scope = window) -> @workersSupported ?= 'Worker' of scope @@ -51,19 +58,19 @@ class Architect @jobId++ # Workers - work: ({ data, type, path } = {}) -> - this.requireParams('type || path', arguments[0]) + work: ({ type, data, fn } = {}) -> + this.requireParams('type', arguments[0]) new Promise (resolve, reject) => - id = this.getJobId() - @jobs[id] = { id: id, resolve: resolve, reject: reject } + jobId = this.getJobId() + @jobs[jobId] = { id: jobId, resolve: resolve, reject: reject } - unless worker = @workers[type || path] - worker = if type then this.spawnWorker(type) else new Worker(path) + unless worker = @workers[type] + worker = this.spawnWorker({ type, data, fn }) worker.addEventListener('message', this.handleMessage) - @workers[type || path] = worker + @workers[type] = worker - worker.postMessage(id: id, args: data) + worker.postMessage(id: jobId, args: data) handleMessage: (e) => { id, resolve, reject } = e.data @@ -98,16 +105,5 @@ class Architect .then (data) -> resolve(data); success?(data) .catch (err) -> reject(err); error?(err) - custom: ({ path, data, fallback } = {}) -> - this.requireParams('path', arguments[0]) - - new Promise (resolve, reject) => - if this.workersAreSupported() - this.work(data: data, path: path).then(resolve) - else if fallback - resolve(fallback(data)) - else - reject("Workers not supported and fallback not provided for #{path}") - # Export module.exports = Architect diff --git a/lib/architect/polyfills/worker_polyfill.coffee b/lib/architect/polyfills/worker_polyfill.coffee deleted file mode 100644 index 32379aa..0000000 --- a/lib/architect/polyfills/worker_polyfill.coffee +++ /dev/null @@ -1,27 +0,0 @@ -class WorkerPolyfill - constructor: -> - @callbacks = {} - @callbacksQueue = {} - - addEventListener: (type, callback) -> - @callbacks[type] = callback - - return unless data = @callbacksQueue[type] - delete @callbacksQueue[type] - - this.dispatch(type, data) - - dispatch: (type, data) -> - if @callbacks[type] - @callbacks[type]({data: data}) - else - @callbacksQueue[type] = data - - handleRequest: (data) -> - this.dispatch('message', data) - - postMessage: -> # Implemented in child polyfills - terminate: -> # This is meant to be empty - -# Export -module.exports = WorkerPolyfill diff --git a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee b/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee deleted file mode 100644 index 5b091b2..0000000 --- a/lib/architect/polyfills/workers/jsonp_worker_polyfill.coffee +++ /dev/null @@ -1,37 +0,0 @@ -WorkerPolyfill = require('../worker_polyfill') - -class JSONPWorkerPolyfill extends WorkerPolyfill - postMessage: (e) -> - { id, args } = e - { url, callbackAttribute, callbackFnName } = args - - if callbackAttribute is undefined - callbackAttribute = 'callback' - - if callbackFnName is undefined - @jsonpID ||= 0 - callbackFnName = 'architect_jsonp' + (++@jsonpID) - - window[callbackFnName] = (args...) => - delete window[callbackFnName] - this.removeScript() - args = if args.length > 1 then args else args[0] - this.handleRequest(id: id, resolve: args) - - request = if callbackAttribute then this.appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url - this.addScript(request) - - addScript: (request) -> - @tmpScript = document.createElement('script') - @tmpScript.src = request - - document.head.appendChild(@tmpScript) - - removeScript: -> - document.head.removeChild(@tmpScript) - - appendQuery: (url, query) -> - (url + '&' + query).replace(/[&?]{1,2}/, '?') - -# Export -module.exports = JSONPWorkerPolyfill diff --git a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee b/lib/workers/ajax.coffee similarity index 52% rename from lib/architect/polyfills/workers/ajax_worker_polyfill.coffee rename to lib/workers/ajax.coffee index 425f0c4..d062ebc 100644 --- a/lib/architect/polyfills/workers/ajax_worker_polyfill.coffee +++ b/lib/workers/ajax.coffee @@ -1,11 +1,29 @@ -WorkerPolyfill = require('../worker_polyfill') +module.exports = -> + handleSuccess = (id, result) => + this.postMessage(id: id, resolve: result) -class AjaxWorkerPolyfill extends WorkerPolyfill - handleSuccess: (id, result) -> this.handleRequest(id: id, resolve: result) - handleError: (id, xhr) -> this.handleRequest(id: id, reject: xhr) + handleError = (id, xhr, dataType) => + # Returning xhr directly throws DataCloneError + result = {} + result[key] = xhr[key] for key in [ + 'response', 'responseType', 'responseText', 'responseXML', 'responseURL' + 'status', 'statusText' + 'withCredentials' + 'readyState' + 'timeout' + ] - postMessage: (e) -> - { id, args } = e + # Parse response if dataType is json + try + if dataType is 'json' + response = result['response'] + result['response'] = if /^\s*$/.test(response) then null else JSON.parse(response) + catch error + + this.postMessage(id: id, reject: result) + + this.onmessage = (e) -> + { id, args } = e.data { type, url, data, dataType, contentType, headers } = args type ||= 'GET' @@ -21,7 +39,7 @@ class AjaxWorkerPolyfill extends WorkerPolyfill xhr.withCredentials = args.withCredentials if 'withCredentials' of args xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue - xhr.onreadystatechange = (e) => + xhr.onreadystatechange = (e) -> return unless xhr.readyState is 4 # Success @@ -37,14 +55,11 @@ class AjaxWorkerPolyfill extends WorkerPolyfill result = if /^\s*$/.test(result) then null else JSON.parse(result) catch error - return this.handleError(id, xhr) if error - this.handleSuccess(id, result) + return handleError(id, xhr, dataType) if error + handleSuccess(id, result) # Error else - this.handleError(id, xhr) + handleError(id, xhr, dataType) xhr.send(data) - -# Export -module.exports = AjaxWorkerPolyfill diff --git a/lib/workers/ajax_worker.coffee b/lib/workers/ajax_worker.coffee deleted file mode 100644 index 5b593d7..0000000 --- a/lib/workers/ajax_worker.coffee +++ /dev/null @@ -1,62 +0,0 @@ -handleSuccess = (id, result) -> postMessage(id: id, resolve: result) -handleError = (id, xhr, dataType) -> - # Returning xhr directly throws DataCloneError - result = {} - result[key] = xhr[key] for key in [ - 'response', 'responseType', 'responseText', 'responseXML', 'responseURL' - 'status', 'statusText' - 'withCredentials' - 'readyState' - 'timeout' - ] - - # Parse response if dataType is json - try - if dataType is 'json' - response = result['response'] - result['response'] = if /^\s*$/.test(response) then null else JSON.parse(response) - catch error - - postMessage(id: id, reject: result) - -addEventListener 'message', (e) -> - { id, args } = e.data - { type, url, data, dataType, contentType, headers } = args - - type ||= 'GET' - - headers ||= {} - headers['X-Requested-With'] ?= 'XMLHttpRequest' - - if contentType isnt false - headers['Content-Type'] = contentType || 'application/x-www-form-urlencoded' - - xhr = new XMLHttpRequest - xhr.open(type, url) - xhr.withCredentials = args.withCredentials if 'withCredentials' of args - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue - - xhr.onreadystatechange = (e) -> - return unless xhr.readyState is 4 - - # Success - if (xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 - result = xhr.responseText - - try - if dataType is 'script' - `(1,eval)(result)` - else if dataType is 'xml' - result = xhr.responseXML - else if dataType is 'json' - result = if /^\s*$/.test(result) then null else JSON.parse(result) - catch error - - return handleError(id, xhr, dataType) if error - handleSuccess(id, result) - - # Error - else - handleError(id, xhr, dataType) - - xhr.send(data) diff --git a/lib/workers/custom.coffee b/lib/workers/custom.coffee new file mode 100644 index 0000000..4224df8 --- /dev/null +++ b/lib/workers/custom.coffee @@ -0,0 +1,17 @@ +module.exports = -> + this.onmessage = (e) => + { id, args } = e.data + + # `work` function injected by Architect when in WebWorker + # `fn` provided by WorkerPolyfill when in main thread + if this.fn + result = this.fn(args) + else + result = work(args) + + if result instanceof Promise + result + .then (data) => this.postMessage(id: id, resolve: data) + .catch (err) => this.postMessage(id: id, reject: err) + else + this.postMessage(id: id, resolve: result) diff --git a/lib/workers/jsonp.coffee b/lib/workers/jsonp.coffee new file mode 100644 index 0000000..61fe572 --- /dev/null +++ b/lib/workers/jsonp.coffee @@ -0,0 +1,41 @@ +globalScope = self + +module.exports = -> + appendQuery = (url, query) -> + (url + '&' + query).replace(/[&?]{1,2}/, '?') + + this.onmessage = (e) -> + { id, args } = e.data + { url, callbackAttribute, callbackFnName } = args + + if callbackAttribute is undefined + callbackAttribute = 'callback' + + if callbackFnName is undefined + callbackFnName = 'handleRequest' + + request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url + + # globalScope is defined when in main thread + # but undefined in WebWorker + try globalScope + catch e then globalScope = this + + globalScope[callbackFnName] = => + delete globalScope[callbackFnName] + this.removeScripts?(request) + + args = [].slice.call(arguments) + args = if args.length > 1 then args else args[0] + + this.postMessage(id: id, resolve: args) + + try + this.importScripts(request) + catch err + this.postMessage + id: id + reject: + message: err.message + code: err.code + name: err.name diff --git a/lib/workers/jsonp_worker.coffee b/lib/workers/jsonp_worker.coffee deleted file mode 100644 index 7f2082d..0000000 --- a/lib/workers/jsonp_worker.coffee +++ /dev/null @@ -1,28 +0,0 @@ -appendQuery = (url, query) -> - (url + '&' + query).replace(/[&?]{1,2}/, '?') - -addEventListener 'message', (e) -> - { id, args } = e.data - { url, callbackAttribute, callbackFnName } = args - - if callbackAttribute is undefined - callbackAttribute = 'callback' - - if callbackFnName is undefined - callbackFnName = 'handleRequest' - - self[callbackFnName] = (args...) -> - args = if args.length > 1 then args else args[0] - postMessage(id: id, resolve: args) - - request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url - - try - importScripts(request) - catch err - postMessage - id: id - reject: - message: err.message - code: err.code - name: err.name diff --git a/lib/workers/polyfill.coffee b/lib/workers/polyfill.coffee new file mode 100644 index 0000000..75b073f --- /dev/null +++ b/lib/workers/polyfill.coffee @@ -0,0 +1,50 @@ +class WorkerPolyfill + constructor: (work, @fn) -> + @jobs = {} + @scripts = {} + @callbacks = {} + @callbacksQueue = {} + + work.call(this) + + addEventListener: (type, callback) -> + @callbacks[type] = callback + + return unless data = @callbacksQueue[type] + delete @callbacksQueue[type] + + this.dispatch(type, data) + + dispatch: (type, data) -> + if @callbacks[type] + @callbacks[type]({data: data}) + else + @callbacksQueue[type] = data + + handleRequest: (data) -> + this.dispatch('message', data) + + postMessage: (e) -> + if @jobs[e.id] + this.dispatch('message', e) + else + @jobs[e.id] = e + this.onmessage(data: e) + + importScripts: (request) -> + script = document.createElement('script') + script.src = request + + document.head.appendChild(script) + @scripts[request] = script + + removeScripts: (request) -> + return unless script = @scripts[request] + delete @scripts[request] + + document.head.removeChild(script) + + terminate: -> # noop + +# Export +module.exports = WorkerPolyfill diff --git a/package.json b/package.json index 3217681..37fb936 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "url": "https://github.com/EtienneLem/architect.git" }, "scripts": { - "start": "./node_modules/.bin/gulp" + "start": "./node_modules/.bin/gulp", + "dist": "./node_modules/.bin/gulp dist" }, "keywords": [ "architect", diff --git a/webpack.config.js b/webpack.config.js index 65f8655..89328db 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,9 +9,7 @@ var examples_and_specs = { 'specs': ['mocha!./specs'], 'workers/fake_worker': ['./specs/fixtures/workers/fake_worker.coffee'], - 'short_lived_workers_example': ['./examples/short_lived_workers/app.js'], - 'custom_workers_example': ['./examples/custom_workers/app.js'], - 'workers/custom_worker': ['./examples/custom_workers/workers/custom_worker.js'], + 'examples': ['./examples/app.js'], }, output: { @@ -33,41 +31,6 @@ var examples_and_specs = { }, } -// Workers -var workers = function(dist) { - var configs = { - cache: true, - watch: true, - - entry: { - 'workers/ajax_worker': ['./lib/workers/ajax_worker.coffee'], - 'workers/jsonp_worker': ['./lib/workers/jsonp_worker.coffee'], - }, - - output: { - filename: '[name].js' - }, - - module: { - loaders: [ - { test: /\.coffee$/, loader: 'coffee-loader' }, - ] - }, - - resolve: { - extensions: ['', '.js', '.coffee'] - }, - } - - if (dist) { - configs.output.filename = '[name].min.js' - configs.watch = false - configs.plugins = architect.plugins - } - - return configs -} - // Architect var architect = { cache: true, @@ -86,7 +49,7 @@ var architect = { }, resolve: { - extensions: ['', '.js', '.coffee'] + extensions: ['', '.coffee'] }, plugins: [ @@ -98,6 +61,6 @@ var architect = { // Export module.exports = { - build: [workers(false), examples_and_specs], - dist: [workers(true), architect], + build: [examples_and_specs], + dist: [architect], } From 48e8d1f789971c784fc86aa9aad120b16610d059 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 6 Mar 2017 10:08:43 -0500 Subject: [PATCH 36/45] Fix `globalScope` being undefined in minified jsonp worker --- dist/architect.min.js | 2 +- lib/workers/jsonp.coffee | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 9ef30ac..2d53451 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(e,t){e.exports=function(){return this.onmessage=function(e){return function(t){var r,n,s,o;return s=t.data,n=s.id,r=s.args,o=e.fn?e.fn(r):work(r),o instanceof Promise?o.then(function(t){return e.postMessage({id:n,resolve:t})}).catch(function(t){return e.postMessage({id:n,reject:t})}):e.postMessage({id:n,resolve:o})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p;try{}catch(e){t=e,r=this}r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(e,t){e.exports=function(){return this.onmessage=function(e){return function(t){var r,n,s,o;return s=t.data,n=s.id,r=s.args,o=e.fn?e.fn(r):work(r),o instanceof Promise?o.then(function(t){return e.postMessage({id:n,resolve:t})}).catch(function(t){return e.postMessage({id:n,reject:t})}):e.postMessage({id:n,resolve:o})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file diff --git a/lib/workers/jsonp.coffee b/lib/workers/jsonp.coffee index 61fe572..9fb22c0 100644 --- a/lib/workers/jsonp.coffee +++ b/lib/workers/jsonp.coffee @@ -18,8 +18,8 @@ module.exports = -> # globalScope is defined when in main thread # but undefined in WebWorker - try globalScope - catch e then globalScope = this + if typeof globalScope is 'undefined' + globalScope = self globalScope[callbackFnName] = => delete globalScope[callbackFnName] From 477aa1351b1eab8eaa78d6881a423607131c0b10 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 6 Mar 2017 10:50:19 -0500 Subject: [PATCH 37/45] Support passing `fn` as a string in WorkerPolyfill --- dist/architect.min.js | 2 +- examples/app.js | 8 ++++++++ lib/workers/custom.coffee | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 2d53451..d895bbb 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(e,t){e.exports=function(){return this.onmessage=function(e){return function(t){var r,n,s,o;return s=t.data,n=s.id,r=s.args,o=e.fn?e.fn(r):work(r),o instanceof Promise?o.then(function(t){return e.postMessage({id:n,resolve:t})}).catch(function(t){return e.postMessage({id:n,reject:t})}):e.postMessage({id:n,resolve:o})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file diff --git a/examples/app.js b/examples/app.js index d1df048..a1e9ee6 100644 --- a/examples/app.js +++ b/examples/app.js @@ -24,6 +24,14 @@ architect.work({ }, }).then(function(e) { console.log('CUSTOM:', e) }) +architect.work({ + type: 'bar', + data: 'foo', + fn: `function(data) { + return (data + 'bar') + }`, +}).then(function(e) { console.log('CUSTOM (STRING FN):', e) }) + architect.work({ type: 'promise', data: 'foo', diff --git a/lib/workers/custom.coffee b/lib/workers/custom.coffee index 4224df8..6f1511b 100644 --- a/lib/workers/custom.coffee +++ b/lib/workers/custom.coffee @@ -5,6 +5,9 @@ module.exports = -> # `work` function injected by Architect when in WebWorker # `fn` provided by WorkerPolyfill when in main thread if this.fn + if typeof this.fn is 'string' + this.fn = eval("this._fn = #{this.fn}") + result = this.fn(args) else result = work(args) From f586a3bc37f3be65d1f24b0ea8355041fc60590e Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 14:10:15 -0400 Subject: [PATCH 38/45] =?UTF-8?q?Use=20a=20different=20JSONP=20callback=20?= =?UTF-8?q?name=20when=20using=20the=20default=20one=20So=20that=20the=20c?= =?UTF-8?q?allback=20isn=E2=80=99t=20using=20a=20memoized=20job=20ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/workers/jsonp.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/jsonp.coffee b/lib/workers/jsonp.coffee index 9fb22c0..69c07e7 100644 --- a/lib/workers/jsonp.coffee +++ b/lib/workers/jsonp.coffee @@ -12,7 +12,7 @@ module.exports = -> callbackAttribute = 'callback' if callbackFnName is undefined - callbackFnName = 'handleRequest' + callbackFnName = "handleRequest_#{id}" request = if callbackAttribute then appendQuery(url, "#{callbackAttribute}=#{callbackFnName}") else url From b34faed32025eb71ff98d0a082110cff1e256aae Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 14:31:59 -0400 Subject: [PATCH 39/45] Add `usePolyfill` option to default workers --- examples/app.js | 16 +++++++++++++--- lib/architect.coffee | 16 ++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/examples/app.js b/examples/app.js index a1e9ee6..ca035f5 100644 --- a/examples/app.js +++ b/examples/app.js @@ -6,9 +6,19 @@ architect = new Architect({ }) // JSONP -architect.jsonp({ - url: 'https://api.github.com/users/etiennelem' -}).then(function(e) { console.log('JSONP:', e) }) +architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }) + .then(function(e) { console.log('JSONP:', e) }) + +architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }, { usePolyfill: true }) + .then(function(e) { console.log('JSONP (Polyfill):', e) }) + +architect.jsonp({ url: 'nope' }) + .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) + .catch(function(e) { console.log('JSONP Error:', e) }) + +architect.jsonp({ url: 'nope' }, { usePolyfill: true }) + .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) + .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) // Ajax architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) diff --git a/lib/architect.coffee b/lib/architect.coffee index b12618b..d7cf6b4 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -4,7 +4,7 @@ class Architect @jobs = {} @workers = {} - spawnWorker: ({ type, data, fn } = {}) -> + spawnWorker: ({ type, data, fn, usePolyfill } = {}) -> # Known type try work = require("./workers/#{type}") @@ -19,7 +19,7 @@ class Architect throw new Error("Unkown worker type “#{type}” and no fn provided") # Native worker - if this.workersAreSupported() + if !usePolyfill && this.workersAreSupported() fnRaw = if fn then "work = #{fn.toString()};" else '' workerRaw = "(#{work.toString()})()" @@ -58,7 +58,7 @@ class Architect @jobId++ # Workers - work: ({ type, data, fn } = {}) -> + work: ({ type, data, fn, usePolyfill } = {}) -> this.requireParams('type', arguments[0]) new Promise (resolve, reject) => @@ -66,7 +66,7 @@ class Architect @jobs[jobId] = { id: jobId, resolve: resolve, reject: reject } unless worker = @workers[type] - worker = this.spawnWorker({ type, data, fn }) + worker = this.spawnWorker({ type, data, fn, usePolyfill }) worker.addEventListener('message', this.handleMessage) @workers[type] = worker @@ -83,14 +83,14 @@ class Architect else promise.reject(reject) - jsonp: (data = {}) -> + jsonp: (data = {}, { usePolyfill } = {}) -> if typeof data is 'string' data = { url: data } this.requireParams('url', data) - this.work(data: data, type: 'jsonp') + this.work(data: data, type: 'jsonp', usePolyfill: usePolyfill) - ajax: (options = {}) -> + ajax: (options = {}, { usePolyfill } = {}) -> this.requireParams('url', options) { success, error } = options @@ -101,7 +101,7 @@ class Architect # Support both ajax opts.success & promise resolving new Promise (resolve, reject) => - this.work(data: opts, type: 'ajax') + this.work(data: opts, type: 'ajax', usePolyfill: usePolyfill) .then (data) -> resolve(data); success?(data) .catch (err) -> reject(err); error?(err) From a2169976c0b17d53a9d844b4301d5528ceb55d0b Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 14:42:01 -0400 Subject: [PATCH 40/45] [dist] --- dist/architect.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index d895bbb..c7bb47e 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,a,u,c,p,l,f;c=null!=e?e:{},p=c.type,o=c.data,a=c.fn;try{l=r(1)("./"+p)}catch(e){if(i=e,!a)throw new Error("Unkown worker type “"+p+"” and no fn provided");l=r(3)}return this.workersAreSupported()?(u=a?"work = "+a.toString()+";":"",f="("+l.toString()+")()",n=new Blob([u,f]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(l,a)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,a,u,c,p;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(a=[],n=0,o=p.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,o){var i,a;return i=e.getJobId(),e.jobs[i]={id:i,resolve:n,reject:o},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:i,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e){return null==e&&(e={}),"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp"})},e.prototype.ajax=function(e){var t,r,n;return null==e&&(e={}),this.requireParams("url",e),n=e.success,t=e.error,r=JSON.parse(JSON.stringify(e)),delete r.success,delete r.error,new Promise(function(e){return function(s,o){return e.work({data:r,type:"ajax"}).then(function(e){return s(e),"function"==typeof n?n(e):void 0}).catch(function(e){return o(e),"function"==typeof t?t(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,a,u,c,p;for(p={},u=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,a=u.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(p,h,i):t(p,s)}return e(p,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,a,u,c,p;u=t.data,a=u.id,n=u.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest"),c=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:a,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:a,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,h,i):t(l,s)}return e(l,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l;a=t.data,u=a.id,n=a.args,l=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),c=s?e(l,s+"="+o):l,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file From 5fed74fe08a943678e32fe2e25ad4e931392fac6 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 15:57:26 -0400 Subject: [PATCH 41/45] Memoize worker per native/polyfill Now that `usePolyfill` can be forced --- lib/architect.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/architect.coffee b/lib/architect.coffee index d7cf6b4..487f334 100644 --- a/lib/architect.coffee +++ b/lib/architect.coffee @@ -2,7 +2,10 @@ class Architect constructor: () -> @jobs = {} - @workers = {} + @workers = { + native: {} + polyfill: {} + } spawnWorker: ({ type, data, fn, usePolyfill } = {}) -> # Known type @@ -65,10 +68,11 @@ class Architect jobId = this.getJobId() @jobs[jobId] = { id: jobId, resolve: resolve, reject: reject } - unless worker = @workers[type] + nativeOrPolyfill = if usePolyfill || !this.workersAreSupported() then 'polyfill' else 'native' + unless worker = @workers[nativeOrPolyfill][type] worker = this.spawnWorker({ type, data, fn, usePolyfill }) worker.addEventListener('message', this.handleMessage) - @workers[type] = worker + @workers[nativeOrPolyfill][type] = worker worker.postMessage(id: jobId, args: data) From 22cb1eb56d5f17290e90900305048fc355bd67ee Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 15:58:02 -0400 Subject: [PATCH 42/45] Use a Promise in WorkerPolyfill#importScripts Reject in `onerror` --- examples/app.js | 4 ++++ lib/workers/jsonp.coffee | 7 ++++++- lib/workers/polyfill.coffee | 16 +++++++++++----- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/examples/app.js b/examples/app.js index ca035f5..490cb4f 100644 --- a/examples/app.js +++ b/examples/app.js @@ -20,6 +20,10 @@ architect.jsonp({ url: 'nope' }, { usePolyfill: true }) .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) +architect.jsonp({ url: 'http://foo' }, { usePolyfill: true }) + .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) + .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) + // Ajax architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) .then(function(e) { console.log('AJAX:', e) }) diff --git a/lib/workers/jsonp.coffee b/lib/workers/jsonp.coffee index 69c07e7..aa0f4bf 100644 --- a/lib/workers/jsonp.coffee +++ b/lib/workers/jsonp.coffee @@ -31,7 +31,12 @@ module.exports = -> this.postMessage(id: id, resolve: args) try - this.importScripts(request) + # Promise when in main thread + # `undefined` when in WebWorker + this.importScripts(request)?.catch (err) => + this.postMessage + id: id + reject: err catch err this.postMessage id: id diff --git a/lib/workers/polyfill.coffee b/lib/workers/polyfill.coffee index 75b073f..6e15c35 100644 --- a/lib/workers/polyfill.coffee +++ b/lib/workers/polyfill.coffee @@ -32,11 +32,17 @@ class WorkerPolyfill this.onmessage(data: e) importScripts: (request) -> - script = document.createElement('script') - script.src = request - - document.head.appendChild(script) - @scripts[request] = script + # Not resolving a sucessful promise is on purpose + # There’s no use, calling the JSONP callback will + # resolve the worker job. + new Promise (resolve, reject) => + script = document.createElement('script') + script.src = request + script.crossorigin = 'anonymous' + script.onerror = reject + + document.head.appendChild(script) + @scripts[request] = script removeScripts: (request) -> return unless script = @scripts[request] From 0fa08c8610d4fcddfa1761b91c9f8e9834b29763 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Thu, 27 Jul 2017 15:59:03 -0400 Subject: [PATCH 43/45] [dist] --- dist/architect.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index c7bb47e..659ce28 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},(a=e.workers[s])||(a=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),a.addEventListener("message",e.handleMessage),e.workers[s]=a),a.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,h,i):t(l,s)}return e(l,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l;a=t.data,u=a.id,n=a.args,l=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),c=s?e(l,s+"="+o):l,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(c),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return this.importScripts(c)}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){var t;return t=document.createElement("script"),t.src=e,document.head.appendChild(t),this.scripts[e]=t},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={native:{},polyfill:{}}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a,c;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},a=o||!e.workersAreSupported()?"polyfill":"native",(c=e.workers[a][s])||(c=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),c.addEventListener("message",e.handleMessage),e.workers[a][s]=c),c.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,h,i):t(l,s)}return e(l,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l,p;a=t.data,u=a.id,n=a.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),l=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(l),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return null!=(c=this.importScripts(l))?c.catch(function(e){return function(t){return e.postMessage({id:u,reject:t})}}(this)):void 0}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){return new Promise(function(t){return function(r,n){var s;return s=document.createElement("script"),s.src=e,s.crossorigin="anonymous",s.onerror=n,document.head.appendChild(s),t.scripts[e]=s}}(this))},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file From 4b6456d520d157c12e5499b68ee5fd706a880af4 Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Mon, 30 Apr 2018 15:52:15 -0400 Subject: [PATCH 44/45] Add `timeout` option to Architect#ajax --- dist/architect.min.js | 2 +- examples/app.js | 122 +++++++++++++++++++++------------------- lib/workers/ajax.coffee | 3 +- 3 files changed, 68 insertions(+), 59 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 659ce28..6fe52ad 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={native:{},polyfill:{}}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a,c;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},a=o||!e.workersAreSupported()?"polyfill":"native",(c=e.workers[a][s])||(c=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),c.addEventListener("message",e.handleMessage),e.workers[a][s]=c),c.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&h.status<300||304===h.status){s=h.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=h.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,h,i):t(l,s)}return e(l,h,i)}},h.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l,p;a=t.data,u=a.id,n=a.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),l=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(l),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return null!=(c=this.importScripts(l))?c.catch(function(e){return function(t){return e.postMessage({id:u,reject:t})}}(this)):void 0}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){return new Promise(function(t){return function(r,n){var s;return s=document.createElement("script"),s.src=e,s.crossorigin="anonymous",s.onerror=n,document.head.appendChild(s),t.scripts[e]=s}}(this))},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={native:{},polyfill:{}}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a,c;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},a=o||!e.workersAreSupported()?"polyfill":"native",(c=e.workers[a][s])||(c=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),c.addEventListener("message",e.handleMessage),e.workers[a][s]=c),c.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&y.status<300||304===y.status){s=y.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=y.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,y,i):t(l,s)}return e(l,y,i)}},y.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l,p;a=t.data,u=a.id,n=a.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),l=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(l),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return null!=(c=this.importScripts(l))?c.catch(function(e){return function(t){return e.postMessage({id:u,reject:t})}}(this)):void 0}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){return new Promise(function(t){return function(r,n){var s;return s=document.createElement("script"),s.src=e,s.crossorigin="anonymous",s.onerror=n,document.head.appendChild(s),t.scripts[e]=s}}(this))},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file diff --git a/examples/app.js b/examples/app.js index 490cb4f..a112824 100644 --- a/examples/app.js +++ b/examples/app.js @@ -1,66 +1,74 @@ var Architect = require('architect') +architect = new Architect() -architect = new Architect({ - workersPath: '/build/workers', - workersSuffix: '_worker.js', -}) - +// // JSONP -architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }) - .then(function(e) { console.log('JSONP:', e) }) - -architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }, { usePolyfill: true }) - .then(function(e) { console.log('JSONP (Polyfill):', e) }) - -architect.jsonp({ url: 'nope' }) - .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) - .catch(function(e) { console.log('JSONP Error:', e) }) - -architect.jsonp({ url: 'nope' }, { usePolyfill: true }) - .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) - .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) - -architect.jsonp({ url: 'http://foo' }, { usePolyfill: true }) - .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) - .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) +// +// architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }) +// .then(function(e) { console.log('JSONP:', e) }) +// +// architect.jsonp({ url: 'https://api.github.com/users/etiennelem' }, { usePolyfill: true }) +// .then(function(e) { console.log('JSONP (Polyfill):', e) }) +// +// architect.jsonp({ url: 'nope' }) +// .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) +// .catch(function(e) { console.log('JSONP Error:', e) }) +// +// architect.jsonp({ url: 'nope' }, { usePolyfill: true }) +// .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) +// .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) +// +// architect.jsonp({ url: 'http://foo' }, { usePolyfill: true }) +// .then(function(e) { console.log('JSONP (Shouldn’t log):', e) }) +// .catch(function(e) { console.log('JSONP Error (Polyfill):', e) }) +// // Ajax -architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) - .then(function(e) { console.log('AJAX:', e) }) - .catch(function(e) { console.log('AJAX ERROR:', e.response.message) }) - -// Custom -architect.work({ - type: 'foozle', - data: 'foo', - fn: function(data) { - return (data + 'zle').toUpperCase() - }, -}).then(function(e) { console.log('CUSTOM:', e) }) +// +// architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) +// .then(function(e) { console.log('AJAX:', e) }) +// .catch(function(e) { console.log('AJAX ERROR:', e.response.message) }) -architect.work({ - type: 'bar', - data: 'foo', - fn: `function(data) { - return (data + 'bar') - }`, -}).then(function(e) { console.log('CUSTOM (STRING FN):', e) }) +architect.ajax({ url: 'https://httpbin.org/get', dataType: 'json', timeout: 16 }) + .then(console.log) + .catch(console.warn) -architect.work({ - type: 'promise', - data: 'foo', - fn: function(data) { - return new Promise(function(resolve, reject) { - setTimeout(function() { - resolve(data + 'zle') - }, 1000) - }) - }, -}).then(function(e) { console.log('CUSTOM (Promise):', e) }) +// +// Custom +// +// architect.work({ +// type: 'foozle', +// data: 'foo', +// fn: function(data) { +// return (data + 'zle').toUpperCase() +// }, +// }).then(function(e) { console.log('CUSTOM:', e) }) +// +// architect.work({ +// type: 'bar', +// data: 'foo', +// fn: `function(data) { +// return (data + 'bar') +// }`, +// }).then(function(e) { console.log('CUSTOM (STRING FN):', e) }) +// +// architect.work({ +// type: 'promise', +// data: 'foo', +// fn: function(data) { +// return new Promise(function(resolve, reject) { +// setTimeout(function() { +// resolve(data + 'zle') +// }, 1000) +// }) +// }, +// }).then(function(e) { console.log('CUSTOM (Promise):', e) }) +// // $.ajax style -architect.ajax({ - url: 'https://api.github.com/users/etiennelem', - dataType: 'json', - success: function(e) { console.log('AJAX:', e) } -}) +// +// architect.ajax({ +// url: 'https://api.github.com/users/etiennelem', +// dataType: 'json', +// success: function(e) { console.log('AJAX:', e) } +// }) diff --git a/lib/workers/ajax.coffee b/lib/workers/ajax.coffee index d062ebc..128d091 100644 --- a/lib/workers/ajax.coffee +++ b/lib/workers/ajax.coffee @@ -24,7 +24,7 @@ module.exports = -> this.onmessage = (e) -> { id, args } = e.data - { type, url, data, dataType, contentType, headers } = args + { type, url, data, dataType, contentType, headers, timeout } = args type ||= 'GET' @@ -37,6 +37,7 @@ module.exports = -> xhr = new XMLHttpRequest xhr.open(type, url) xhr.withCredentials = args.withCredentials if 'withCredentials' of args + xhr.timeout = timeout || 0 xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.onreadystatechange = (e) -> From 11159887fb150777ac7d24e018d6c5506b949f8a Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Tue, 1 May 2018 14:16:10 -0400 Subject: [PATCH 45/45] =?UTF-8?q?Use=20XHR=E2=80=99s=20specific=20events?= =?UTF-8?q?=20instead=20of=20`onreadystatechange`=20Only=20reject=20w/=20`?= =?UTF-8?q?timeout`=20when=20it=E2=80=99s=20a=20timed=20out=20request,=20t?= =?UTF-8?q?hat=20way=20we=20can=20tell=20the=20different=20between=20an=20?= =?UTF-8?q?error=20and=20a=20timed=20out=20request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/architect.min.js | 2 +- examples/app.js | 16 ++++++++++++---- lib/workers/ajax.coffee | 22 ++++++++++++++++++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/dist/architect.min.js b/dist/architect.min.js index 6fe52ad..f5343b5 100644 --- a/dist/architect.min.js +++ b/dist/architect.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={native:{},polyfill:{}}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a,c;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},a=o||!e.workersAreSupported()?"polyfill":"native",(c=e.workers[a][s])||(c=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),c.addEventListener("message",e.handleMessage),e.workers[a][s]=c),c.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t;return t=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),e=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState","timeout"],o=0,u=a.length;o=200&&y.status<300||304===y.status){s=y.responseText;try{"script"===i?(0,eval)(s):"xml"===i?s=y.responseXML:"json"===i&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){n=e}return n?e(l,y,i):t(l,s)}return e(l,y,i)}},y.send(o)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l,p;a=t.data,u=a.id,n=a.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),l=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(l),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return null!=(c=this.importScripts(l))?c.catch(function(e){return function(t){return e.postMessage({id:u,reject:t})}}(this)):void 0}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){return new Promise(function(t){return function(r,n){var s;return s=document.createElement("script"),s.src=e,s.crossorigin="anonymous",s.onerror=n,document.head.appendChild(s),t.scripts[e]=s}}(this))},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Architect=t():e.Architect=t()}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var s=r[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n,s=function(e,t){return function(){return e.apply(t,arguments)}};n=function(){function e(){this.handleMessage=s(this.handleMessage,this),this.jobs={},this.workers={native:{},polyfill:{}}}return e.prototype.spawnWorker=function(e){var t,n,s,o,i,u,a,c,l,p,f,d;c=null!=e?e:{},l=c.type,o=c.data,u=c.fn,p=c.usePolyfill;try{f=r(1)("./"+l)}catch(e){if(i=e,!u)throw new Error("Unkown worker type “"+l+"” and no fn provided");f=r(3)}return!p&&this.workersAreSupported()?(a=u?"work = "+u.toString()+";":"",d="("+f.toString()+")()",n=new Blob([a,d]),s=window.URL.createObjectURL(n),new Worker(s)):new(t=r(5))(f,u)},e.prototype.workersAreSupported=function(e){return null==e&&(e=window),null!=this.workersSupported?this.workersSupported:this.workersSupported="Worker"in e},e.prototype.requireParams=function(e,t){var r,n,s,o,i,u,a,c,l;for(null==t&&(t={}),i=[],Array.isArray(e)||(e=[e]),r=0,s=e.length;r1){for(u=[],n=0,o=l.length;n1?"s":""))},e.prototype.getJobId=function(){return this.jobId||(this.jobId=1),this.jobId++},e.prototype.work=function(e){var t,r,n,s,o;return n=null!=e?e:{},s=n.type,t=n.data,r=n.fn,o=n.usePolyfill,this.requireParams("type",arguments[0]),new Promise(function(e){return function(n,i){var u,a,c;return u=e.getJobId(),e.jobs[u]={id:u,resolve:n,reject:i},a=o||!e.workersAreSupported()?"polyfill":"native",(c=e.workers[a][s])||(c=e.spawnWorker({type:s,data:t,fn:r,usePolyfill:o}),c.addEventListener("message",e.handleMessage),e.workers[a][s]=c),c.postMessage({id:u,args:t})}}(this))},e.prototype.handleMessage=function(e){var t,r,n,s,o;return n=e.data,t=n.id,o=n.resolve,s=n.reject,r=this.jobs[t],delete this.jobs[t],"resolve"in e.data?r.resolve(o):r.reject(s)},e.prototype.jsonp=function(e,t){var r;return null==e&&(e={}),r=(null!=t?t:{}).usePolyfill,"string"==typeof e&&(e={url:e}),this.requireParams("url",e),this.work({data:e,type:"jsonp",usePolyfill:r})},e.prototype.ajax=function(e,t){var r,n,s,o;return null==e&&(e={}),o=(null!=t?t:{}).usePolyfill,this.requireParams("url",e),s=e.success,r=e.error,n=JSON.parse(JSON.stringify(e)),delete n.success,delete n.error,new Promise(function(e){return function(t,i){return e.work({data:n,type:"ajax",usePolyfill:o}).then(function(e){return t(e),"function"==typeof s?s(e):void 0}).catch(function(e){return i(e),"function"==typeof r?r(e):void 0})}}(this))},e}(),e.exports=n},function(e,t,r){function n(e){return r(s(e))}function s(e){return o[e]||function(){throw new Error("Cannot find module '"+e+"'.")}()}var o={"./ajax":2,"./ajax.coffee":2,"./custom":3,"./custom.coffee":3,"./jsonp":4,"./jsonp.coffee":4,"./polyfill":5,"./polyfill.coffee":5};n.keys=function(){return Object.keys(o)},n.resolve=s,e.exports=n,n.id=1},function(e,t){e.exports=function(){var e,t,r,n;return r=function(e){return function(t,r){return e.postMessage({id:t,resolve:r})}}(this),t=function(e){return function(t,r,n){var s,o,i,u,a,c,l;for(l={},a=["response","responseType","responseText","responseXML","responseURL","status","statusText","withCredentials","readyState"],o=0,u=a.length;o=200&&m.status<300||304===m.status){s=m.responseText;try{"script"===a?(0,eval)(s):"xml"===a?s=m.responseXML:"json"===a&&(s=/^\s*$/.test(s)?null:JSON.parse(s))}catch(e){return n=e,t(f,m,a)}return r(f,s)}return t(f,m,a)}},m.onerror=function(e){return t(f,m,a)},m.ontimeout=function(e){return n(f,m)},m.onabort=function(t){return e(f,m)},m.send(u)}}},function(module,exports){module.exports=function(){return this.onmessage=function(_this){return function(e){var args,id,ref,result;return ref=e.data,id=ref.id,args=ref.args,_this.fn?("string"==typeof _this.fn&&(_this.fn=eval("this._fn = "+_this.fn)),result=_this.fn(args)):result=work(args),result instanceof Promise?result.then(function(e){return _this.postMessage({id:id,resolve:e})}).catch(function(e){return _this.postMessage({id:id,reject:e})}):_this.postMessage({id:id,resolve:result})}}(this)}},function(e,t){var r;r=self,e.exports=function(){var e;return e=function(e,t){return(e+"&"+t).replace(/[&?]{1,2}/,"?")},this.onmessage=function(t){var n,s,o,i,u,a,c,l,p;a=t.data,u=a.id,n=a.args,p=n.url,s=n.callbackAttribute,o=n.callbackFnName,void 0===s&&(s="callback"),void 0===o&&(o="handleRequest_"+u),l=s?e(p,s+"="+o):p,"undefined"==typeof r&&(r=self),r[o]=function(e){return function(){return delete r[o],"function"==typeof e.removeScripts&&e.removeScripts(l),n=[].slice.call(arguments),n=n.length>1?n:n[0],e.postMessage({id:u,resolve:n})}}(this);try{return null!=(c=this.importScripts(l))?c.catch(function(e){return function(t){return e.postMessage({id:u,reject:t})}}(this)):void 0}catch(e){return i=e,this.postMessage({id:u,reject:{message:i.message,code:i.code,name:i.name}})}}}},function(e,t){var r;r=function(){function e(e,t){this.fn=t,this.jobs={},this.scripts={},this.callbacks={},this.callbacksQueue={},e.call(this)}return e.prototype.addEventListener=function(e,t){var r;if(this.callbacks[e]=t,r=this.callbacksQueue[e])return delete this.callbacksQueue[e],this.dispatch(e,r)},e.prototype.dispatch=function(e,t){return this.callbacks[e]?this.callbacks[e]({data:t}):this.callbacksQueue[e]=t},e.prototype.handleRequest=function(e){return this.dispatch("message",e)},e.prototype.postMessage=function(e){return this.jobs[e.id]?this.dispatch("message",e):(this.jobs[e.id]=e,this.onmessage({data:e}))},e.prototype.importScripts=function(e){return new Promise(function(t){return function(r,n){var s;return s=document.createElement("script"),s.src=e,s.crossorigin="anonymous",s.onerror=n,document.head.appendChild(s),t.scripts[e]=s}}(this))},e.prototype.removeScripts=function(e){var t;if(t=this.scripts[e])return delete this.scripts[e],document.head.removeChild(t)},e.prototype.terminate=function(){},e}(),e.exports=r}])}); \ No newline at end of file diff --git a/examples/app.js b/examples/app.js index a112824..e76a2ba 100644 --- a/examples/app.js +++ b/examples/app.js @@ -25,13 +25,21 @@ architect = new Architect() // // Ajax // -// architect.ajax({ url: 'https://api.github.com/users/_etiennelem', dataType: 'json' }) -// .then(function(e) { console.log('AJAX:', e) }) -// .catch(function(e) { console.log('AJAX ERROR:', e.response.message) }) +// Error +architect.ajax({ url: 'https://foo' }) + .then(() => { throw 'Should not throw' }) + .catch(console.warn) // Has no `timeout` + +// Timeout architect.ajax({ url: 'https://httpbin.org/get', dataType: 'json', timeout: 16 }) + .then(() => { throw 'Should not throw' }) + .catch(console.warn) // Has `timeout` + +// Success +architect.ajax({ url: 'https://httpbin.org/get', dataType: 'json' }) .then(console.log) - .catch(console.warn) + .catch(() => { throw 'Should not throw' }) // // Custom diff --git a/lib/workers/ajax.coffee b/lib/workers/ajax.coffee index 128d091..b91a25a 100644 --- a/lib/workers/ajax.coffee +++ b/lib/workers/ajax.coffee @@ -10,7 +10,6 @@ module.exports = -> 'status', 'statusText' 'withCredentials' 'readyState' - 'timeout' ] # Parse response if dataType is json @@ -22,6 +21,12 @@ module.exports = -> this.postMessage(id: id, reject: result) + handleTimeout = (id, xhr) => + this.postMessage(id: id, reject: { status: 0, timeout: xhr.timeout }) + + handleAbort = (id, xhr) => + this.postMessage(id: id, reject: { status: 0, abort: true }) + this.onmessage = (e) -> { id, args } = e.data { type, url, data, dataType, contentType, headers, timeout } = args @@ -36,11 +41,11 @@ module.exports = -> xhr = new XMLHttpRequest xhr.open(type, url) + xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue xhr.withCredentials = args.withCredentials if 'withCredentials' of args xhr.timeout = timeout || 0 - xhr.setRequestHeader(headerName, headerValue) for headerName, headerValue of headers when headerValue - xhr.onreadystatechange = (e) -> + xhr.onload = (e) -> return unless xhr.readyState is 4 # Success @@ -55,12 +60,21 @@ module.exports = -> else if dataType is 'json' result = if /^\s*$/.test(result) then null else JSON.parse(result) catch error + return handleError(id, xhr, dataType) - return handleError(id, xhr, dataType) if error handleSuccess(id, result) # Error else handleError(id, xhr, dataType) + xhr.onerror = (e) -> + handleError(id, xhr, dataType) + + xhr.ontimeout = (e) -> + handleTimeout(id, xhr) + + xhr.onabort = (e) -> + handleAbort(id, xhr) + xhr.send(data)