Comparing version 0.4.1 to 0.4.3
{ | ||
"name": "operative", | ||
"version": "0.4.1", | ||
"version": "0.4.3", | ||
"main": "dist/operative.js", | ||
@@ -5,0 +5,0 @@ "ignore": [ |
{ | ||
"name": "operative", | ||
"version": "0.4.1", | ||
"version": "0.4.3", | ||
"main": "dist/operative.js", | ||
@@ -5,0 +5,0 @@ "scripts": [ |
@@ -8,3 +8,3 @@ /*! | ||
* @repo http://github.com/padolsey/operative | ||
* @version 0.4.1 | ||
* @version 0.4.3 | ||
* @license MIT | ||
@@ -29,7 +29,7 @@ */ | ||
if (typeof define === 'function' && define.amd) { | ||
define( function () { return operative; }); | ||
} else { | ||
window.operative = operative; | ||
} | ||
// Note: This will work only in the built dist: | ||
// (Otherwise you must explicitly set selfURL to BrowserWorker.js) | ||
var scripts = document.getElementsByTagName('script'); | ||
var opScript = scripts[scripts.length - 1]; | ||
var opScriptURL = /operative/.test(opScript.src) && opScript.src; | ||
@@ -63,3 +63,4 @@ operative.pool = function(size, module, dependencies) { | ||
var getBase = operative.getBaseURL.bind(this); | ||
var getBase = operative.getBaseURL; | ||
var getSelf = operative.getSelfURL; | ||
@@ -70,3 +71,3 @@ var OperativeContext = operative.hasWorkerSupport ? operative.Operative.BrowserWorker : operative.Operative.Iframe; | ||
// Allow a single function to be passed. | ||
var o = new OperativeContext({ main: module }, dependencies, getBase); | ||
var o = new OperativeContext({ main: module }, dependencies, getBase, getSelf); | ||
var singularOperative = function() { | ||
@@ -87,3 +88,3 @@ return o.api.main.apply(o, arguments); | ||
return new OperativeContext(module, dependencies, getBase).api; | ||
return new OperativeContext(module, dependencies, getBase, getSelf).api; | ||
@@ -115,2 +116,7 @@ } | ||
/** | ||
* Set and get Self URL, i.e. the url of the | ||
* operative script itself. | ||
*/ | ||
operative.setSelfURL = function(url) { | ||
@@ -120,2 +126,11 @@ opScriptURL = url; | ||
operative.getSelfURL = function(url) { | ||
return opScriptURL; | ||
}; | ||
/** | ||
* Set and get Base URL, i.e. the path used | ||
* as a base for getting dependencies | ||
*/ | ||
operative.setBaseURL = function(base) { | ||
@@ -156,3 +171,3 @@ baseURL = base; | ||
*/ | ||
function OperativeContext(module, dependencies, getBase) { | ||
function OperativeContext(module, dependencies, getBaseURL, getSelfURL) { | ||
@@ -172,3 +187,4 @@ var _self = this; | ||
this._getBase = getBase; | ||
this._getBaseURL = getBaseURL; | ||
this._getSelfURL = getSelfURL; | ||
@@ -223,3 +239,3 @@ this.isDestroyed = false; | ||
if (!/\/\//.test(dep)) { | ||
deps[i] = dep.replace(/^\/?/, this._getBase().replace(/([^\/])$/, '$1/')); | ||
deps[i] = dep.replace(/^\/?/, this._getBaseURL().replace(/([^\/])$/, '$1/')); | ||
} | ||
@@ -372,6 +388,2 @@ } | ||
var scripts = document.getElementsByTagName('script'); | ||
var opScript = scripts[scripts.length - 1]; | ||
var opScriptURL = /operative/.test(opScript.src) && opScript.src; | ||
var URL = window.URL || window.webkitURL; | ||
@@ -419,3 +431,3 @@ var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; | ||
*/ | ||
Operative.BrowserWorker = function BrowserWorker(module) { | ||
Operative.BrowserWorker = function BrowserWorker() { | ||
Operative.apply(this, arguments); | ||
@@ -472,2 +484,6 @@ }; | ||
WorkerProto._isWorkerViaBlobSupported = function() { | ||
return workerViaBlobSupport; | ||
}; | ||
WorkerProto._setup = function() { | ||
@@ -477,5 +493,7 @@ var self = this; | ||
var worker; | ||
var selfURL = this._getSelfURL(); | ||
var blobSupport = this._isWorkerViaBlobSupported(); | ||
var script = this._buildContextScript( | ||
// The script is not included if we're Eval'ing this file directly: | ||
workerViaBlobSupport ? workerBoilerScript : '' | ||
blobSupport ? workerBoilerScript : '' | ||
); | ||
@@ -487,9 +505,10 @@ | ||
if (workerViaBlobSupport) { | ||
if (blobSupport) { | ||
worker = this.worker = new Worker( makeBlobURI(script) ); | ||
} else { | ||
if (!opScriptURL) { | ||
if (!selfURL) { | ||
throw new Error('Operaritve: No operative.js URL available. Please set via operative.setSelfURL(...)'); | ||
} | ||
worker = this.worker = new Worker( opScriptURL ); | ||
worker = this.worker = new Worker( selfURL ); | ||
// Marshal-agnostic initial message is boiler-code: | ||
@@ -496,0 +515,0 @@ // (We don't yet know if structured-cloning is supported so we send a string) |
@@ -1,2 +0,2 @@ | ||
/** Operative v0.4.1 (c) 2013 James padolsey, MIT-licensed, http://github.com/padolsey/operative **/ | ||
(function(e,r){"undefined"==typeof window&&self.importScripts||("function"==typeof define&&define.amd?define([],r):"object"==typeof exports?module.exports=r():e.operative=r())})(this,function(){function e(t,n){var o=e.getBaseURL.bind(this),i=e.hasWorkerSupport?e.Operative.BrowserWorker:e.Operative.Iframe;if("function"==typeof t){var s=new i({main:t},n,o),a=function(){return s.api.main.apply(s,arguments)};a.transfer=function(){return s.api.main.transfer.apply(s,arguments)};for(var u in s.api)r.call(s.api,u)&&(a[u]=s.api[u]);return a}return new i(t,n,o).api}var r={}.hasOwnProperty;"function"==typeof define&&define.amd?define(function(){return e}):window.operative=e,e.pool=function(r,t,n){r=0|Math.abs(r)||1;for(var o=[],i=0,s=0;r>s;++s)o.push(e(t,n));return{terminate:function(){for(var e=0;r>e;++e)o[e].destroy()},next:function(){return i=i+1===r?0:i+1,o[i]}}},e.hasWorkerSupport=!!window.Worker,e.hasWorkerViaBlobSupport=!1,e.hasTransferSupport=!1;var t=(location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")+location.pathname).replace(/[^\/]+$/,"");return e.objCreate=Object.create||function(e){function r(){}return r.prototype=e,new r},e.setSelfURL=function(e){opScriptURL=e},e.setBaseURL=function(e){t=e},e.getBaseURL=function(){return t},e}),function(){function e(e){this.value=e}function r(e,r,n){var o=this;e.get=e.get||function(e){return this[e]},e.set=e.set||function(e,r){return this[e]=r},this._curToken=0,this._queue=[],this._getBase=n,this.isDestroyed=!1,this.isContextReady=!1,this.module=e,this.dependencies=r||[],this.dataProperties={},this.api={},this.callbacks={},this.deferreds={},this._fixDependencyURLs(),this._setup();for(var i in e)t.call(e,i)&&this._createExposedMethod(i);this.api.__operative__=this,this.api.destroy=this.api.terminate=function(){return o.destroy()}}if("undefined"!=typeof window||!self.importScripts){var t={}.hasOwnProperty,n=[].slice,o={}.toString;operative.Operative=r;var i=r.Promise=window.Promise;r.prototype={_marshal:function(e){return e},_demarshal:function(e){return e},_enqueue:function(e){this._queue.push(e)},_fixDependencyURLs:function(){for(var e=this.dependencies,r=0,t=e.length;t>r;++r){var n=e[r];/\/\//.test(n)||(e[r]=n.replace(/^\/?/,this._getBase().replace(/([^\/])$/,"$1/")))}},_dequeueAll:function(){for(var e=0,r=this._queue.length;r>e;++e)this._queue[e].call(this);this._queue=[]},_buildContextScript:function(e){var r,t=[],n=this.module,o=this.dataProperties;for(var i in n)r=n[i],"function"==typeof r?t.push(' self["'+i.replace(/"/g,'\\"')+'"] = '+(""+r)+";"):o[i]=r;return t.join("\n")+(e?"\n("+(""+e)+"());":"")},_createExposedMethod:function(r){var t=this,s=this.api[r]=function(){function o(){t.isContextReady?t._runMethod(r,s,a,p):t._enqueue(o)}if(t.isDestroyed)throw Error("Operative: Cannot run method. Operative has already been destroyed");var s=++t._curToken,a=n.call(arguments),u="function"==typeof a[a.length-1]&&a.pop(),p=a[a.length-1]instanceof e&&a.pop();if(!u&&!i)throw Error("Operative: No callback has been passed. Assumed that you want a promise. But `operative.Promise` is null. Please provide Promise polyfill/lib.");if(u)t.callbacks[s]=u,setTimeout(function(){o()},1);else if(i)return new i(function(e,r){var n;e.fulfil||e.fulfill?(n=e,n.fulfil=n.fulfill=e.fulfil||e.fulfill):n={fulfil:e,fulfill:e,resolve:e,reject:r,transferResolve:e,transferReject:r},t.deferreds[s]=n,o()})};s.transfer=function(){var r=[].slice.call(arguments),t="function"==typeof r[r.length-1]?r.length-2:r.length-1,n=r[t],i=o.call(n);if("[object Array]"!==i)throw Error("Operative:transfer() must be passed an Array of transfers as its last arguments (Expected: [object Array], Received: "+i+")");return r[t]=new e(n),s.apply(null,r)}},destroy:function(){this.isDestroyed=!0}}}}(),function(){function makeBlobURI(e){var r;try{r=new Blob([e],{type:"text/javascript"})}catch(t){r=new BlobBuilder,r.append(e),r=r.getBlob()}return URL.createObjectURL(r)}function workerBoilerScript(){var postMessage=self.postMessage,structuredCloningSupport=null,toString={}.toString;self.console={},self.isWorker=!0,["log","debug","error","info","warn","time","timeEnd"].forEach(function(e){self.console[e]=function(){postMessage({cmd:"console",method:e,args:[].slice.call(arguments)})}}),self.addEventListener("message",function(e){function callback(){returnResult({args:[].slice.call(arguments)})}function returnResult(e,r){postMessage({cmd:"result",token:data.token,result:e},hasTransferSupport&&r||[])}function extractTransfers(e){var r=e[e.length-1];if("[object Array]"!==toString.call(r))throw Error("Operative: callback.transfer() must be passed an Array of transfers as its last arguments");return r}var data=e.data;if("string"==typeof data&&0===data.indexOf("EVAL|"))return eval(data.substring(5)),void 0;if(null==structuredCloningSupport)return structuredCloningSupport="PING"===e.data[0],self.postMessage(structuredCloningSupport?"pingback:structuredCloningSupport=YES":"pingback:structuredCloningSupport=NO"),structuredCloningSupport||(postMessage=function(e){return self.postMessage(JSON.stringify(e))}),void 0;structuredCloningSupport||(data=JSON.parse(data));var defs=data.definitions,isDeferred=!1,args=data.args;if(defs)for(var i in defs)self[i]=defs[i];else{callback.transfer=function(){var e=[].slice.call(arguments),r=extractTransfers(e);returnResult({args:e},r)},args.push(callback),self.deferred=function(){function e(e,r){return returnResult({isDeferred:!0,action:"resolve",args:[e]},r),t}function r(e,r){returnResult({isDeferred:!0,action:"reject",args:[e]},r)}isDeferred=!0;var t={};return t.fulfil=t.fulfill=t.resolve=function(r){return e(r)},t.reject=function(e){return r(e)},t.transferResolve=function(r){var t=extractTransfers(arguments);return e(r,t)},t.transferReject=function(e){var t=extractTransfers(arguments);return r(e,t)},t};var result=self[data.method].apply(self,args);isDeferred||void 0===result||returnResult({args:[result]}),self.deferred=function(){throw Error("Operative: deferred() called at odd time")}}})}if("undefined"==typeof window&&self.importScripts)return workerBoilerScript(),void 0;var Operative=operative.Operative,scripts=document.getElementsByTagName("script"),opScript=scripts[scripts.length-1],opScriptURL=/operative/.test(opScript.src)&&opScript.src,URL=window.URL||window.webkitURL,BlobBuilder=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,workerViaBlobSupport=function(){try{new Worker(makeBlobURI(";"))}catch(e){return!1}return!0}(),transferrableObjSupport=function(){try{var e=new ArrayBuffer(1);return new Worker(makeBlobURI(";")).postMessage(e,[e]),!e.byteLength}catch(r){return!1}}();operative.hasWorkerViaBlobSupport=workerViaBlobSupport,operative.hasTransferSupport=transferrableObjSupport,Operative.BrowserWorker=function BrowserWorker(){Operative.apply(this,arguments)};var WorkerProto=Operative.BrowserWorker.prototype=operative.objCreate(Operative.prototype);WorkerProto._onWorkerMessage=function(e){var r=e.data;if("string"==typeof r&&0===r.indexOf("pingback"))return"pingback:structuredCloningSupport=NO"===r&&(this._marshal=function(e){return JSON.stringify(e)},this._demarshal=function(e){return JSON.parse(e)}),this.isContextReady=!0,this._postMessage({definitions:this.dataProperties}),this._dequeueAll(),void 0;switch(r=this._demarshal(r),r.cmd){case"console":window.console&&window.console[r.method].apply(window.console,r.args);break;case"result":var t=this.callbacks[r.token],n=this.deferreds[r.token],o=r.result&&r.result.isDeferred&&r.result.action;n&&o?n[o](r.result.args[0]):t?t.apply(this,r.result.args):n&&n.fulfil(r.result.args[0])}},WorkerProto._setup=function(){var e,r=this,t=this._buildContextScript(workerViaBlobSupport?workerBoilerScript:"");if(this.dependencies.length&&(t='importScripts("'+this.dependencies.join('", "')+'");\n'+t),workerViaBlobSupport)e=this.worker=new Worker(makeBlobURI(t));else{if(!opScriptURL)throw Error("Operaritve: No operative.js URL available. Please set via operative.setSelfURL(...)");e=this.worker=new Worker(opScriptURL),e.postMessage("EVAL|"+t)}e.postMessage("EVAL|self.hasTransferSupport="+transferrableObjSupport),e.postMessage(["PING"]),e.addEventListener("message",function(e){r._onWorkerMessage(e)})},WorkerProto._postMessage=function(e){var r=transferrableObjSupport&&e.transfers;return r?this.worker.postMessage(e,r.value):this.worker.postMessage(this._marshal(e))},WorkerProto._runMethod=function(e,r,t,n){this._postMessage({method:e,args:t,token:r,transfers:n})},WorkerProto.destroy=function(){this.worker.terminate(),Operative.prototype.destroy.call(this)}}(),function(){function e(){window.__run__=function(e,r,t,n){function o(){return t.apply(this,arguments)}var i=!1;window.deferred=function(){return i=!0,n},o.transfer=function(){return t.apply(this,[].slice.call(arguments,0,arguments.length-1))},t&&r.push(o);var s=window[e].apply(window,r);window.deferred=function(){throw Error("Operative: deferred() called at odd time")},i||void 0===s||o(s)}}if("undefined"!=typeof window||!self.importScripts){var r=operative.Operative;r.Iframe=function(){r.apply(this,arguments)};var t=r.Iframe.prototype=operative.objCreate(r.prototype),n=0;t._setup=function(){var r=this,t="__operativeIFrameLoaded"+ ++n;this.module.isWorker=!1;var o=this.iframe=document.body.appendChild(document.createElement("iframe"));o.style.display="none";var i=this.iframeWindow=o.contentWindow,s=i.document;window[t]=function(){window[t]=null;var n=s.createElement("script"),o=r._buildContextScript(e);void 0!==n.text?n.text=o:n.innerHTML=o,s.documentElement.appendChild(n);for(var a in r.dataProperties)i[a]=r.dataProperties[a];r.isContextReady=!0,r._dequeueAll()},s.open();var a="";this.dependencies.length&&(a+='\n<script src="'+this.dependencies.join('"></script><script src="')+'"></script>'),s.write(a+"\n<script>setTimeout(window.parent."+t+",0);</script>"),s.close()},t._runMethod=function(e,r,t){var n=this,o=this.callbacks[r],i=this.deferreds[r];this.iframeWindow.__run__(e,t,function(e){var r=o,t=i;r?r.apply(n,arguments):t&&t.fulfil(e)},i)},t.destroy=function(){this.iframe.parentNode.removeChild(this.iframe),r.prototype.destroy.call(this)}}}(); | ||
/** Operative v0.4.3 (c) 2013 James padolsey, MIT-licensed, http://github.com/padolsey/operative **/ | ||
(function(e,r){"undefined"==typeof window&&self.importScripts||("function"==typeof define&&define.amd?define([],r):"object"==typeof exports?module.exports=r():e.operative=r())})(this,function(){function e(t,n){var o=e.getBaseURL,i=e.getSelfURL,s=e.hasWorkerSupport?e.Operative.BrowserWorker:e.Operative.Iframe;if("function"==typeof t){var a=new s({main:t},n,o,i),u=function(){return a.api.main.apply(a,arguments)};u.transfer=function(){return a.api.main.transfer.apply(a,arguments)};for(var l in a.api)r.call(a.api,l)&&(u[l]=a.api[l]);return u}return new s(t,n,o,i).api}var r={}.hasOwnProperty,t=document.getElementsByTagName("script"),n=t[t.length-1],o=/operative/.test(n.src)&&n.src;e.pool=function(r,t,n){r=0|Math.abs(r)||1;for(var o=[],i=0,s=0;r>s;++s)o.push(e(t,n));return{terminate:function(){for(var e=0;r>e;++e)o[e].destroy()},next:function(){return i=i+1===r?0:i+1,o[i]}}},e.hasWorkerSupport=!!window.Worker,e.hasWorkerViaBlobSupport=!1,e.hasTransferSupport=!1;var i=(location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")+location.pathname).replace(/[^\/]+$/,"");return e.objCreate=Object.create||function(e){function r(){}return r.prototype=e,new r},e.setSelfURL=function(e){o=e},e.getSelfURL=function(){return o},e.setBaseURL=function(e){i=e},e.getBaseURL=function(){return i},e}),function(){function e(e){this.value=e}function r(e,r,n,o){var i=this;e.get=e.get||function(e){return this[e]},e.set=e.set||function(e,r){return this[e]=r},this._curToken=0,this._queue=[],this._getBaseURL=n,this._getSelfURL=o,this.isDestroyed=!1,this.isContextReady=!1,this.module=e,this.dependencies=r||[],this.dataProperties={},this.api={},this.callbacks={},this.deferreds={},this._fixDependencyURLs(),this._setup();for(var s in e)t.call(e,s)&&this._createExposedMethod(s);this.api.__operative__=this,this.api.destroy=this.api.terminate=function(){return i.destroy()}}if("undefined"!=typeof window||!self.importScripts){var t={}.hasOwnProperty,n=[].slice,o={}.toString;operative.Operative=r;var i=r.Promise=window.Promise;r.prototype={_marshal:function(e){return e},_demarshal:function(e){return e},_enqueue:function(e){this._queue.push(e)},_fixDependencyURLs:function(){for(var e=this.dependencies,r=0,t=e.length;t>r;++r){var n=e[r];/\/\//.test(n)||(e[r]=n.replace(/^\/?/,this._getBaseURL().replace(/([^\/])$/,"$1/")))}},_dequeueAll:function(){for(var e=0,r=this._queue.length;r>e;++e)this._queue[e].call(this);this._queue=[]},_buildContextScript:function(e){var r,t=[],n=this.module,o=this.dataProperties;for(var i in n)r=n[i],"function"==typeof r?t.push(' self["'+i.replace(/"/g,'\\"')+'"] = '+(""+r)+";"):o[i]=r;return t.join("\n")+(e?"\n("+(""+e)+"());":"")},_createExposedMethod:function(r){var t=this,s=this.api[r]=function(){function o(){t.isContextReady?t._runMethod(r,s,a,l):t._enqueue(o)}if(t.isDestroyed)throw Error("Operative: Cannot run method. Operative has already been destroyed");var s=++t._curToken,a=n.call(arguments),u="function"==typeof a[a.length-1]&&a.pop(),l=a[a.length-1]instanceof e&&a.pop();if(!u&&!i)throw Error("Operative: No callback has been passed. Assumed that you want a promise. But `operative.Promise` is null. Please provide Promise polyfill/lib.");if(u)t.callbacks[s]=u,setTimeout(function(){o()},1);else if(i)return new i(function(e,r){var n;e.fulfil||e.fulfill?(n=e,n.fulfil=n.fulfill=e.fulfil||e.fulfill):n={fulfil:e,fulfill:e,resolve:e,reject:r,transferResolve:e,transferReject:r},t.deferreds[s]=n,o()})};s.transfer=function(){var r=[].slice.call(arguments),t="function"==typeof r[r.length-1]?r.length-2:r.length-1,n=r[t],i=o.call(n);if("[object Array]"!==i)throw Error("Operative:transfer() must be passed an Array of transfers as its last arguments (Expected: [object Array], Received: "+i+")");return r[t]=new e(n),s.apply(null,r)}},destroy:function(){this.isDestroyed=!0}}}}(),function(){function makeBlobURI(e){var r;try{r=new Blob([e],{type:"text/javascript"})}catch(t){r=new BlobBuilder,r.append(e),r=r.getBlob()}return URL.createObjectURL(r)}function workerBoilerScript(){var postMessage=self.postMessage,structuredCloningSupport=null,toString={}.toString;self.console={},self.isWorker=!0,["log","debug","error","info","warn","time","timeEnd"].forEach(function(e){self.console[e]=function(){postMessage({cmd:"console",method:e,args:[].slice.call(arguments)})}}),self.addEventListener("message",function(e){function callback(){returnResult({args:[].slice.call(arguments)})}function returnResult(e,r){postMessage({cmd:"result",token:data.token,result:e},hasTransferSupport&&r||[])}function extractTransfers(e){var r=e[e.length-1];if("[object Array]"!==toString.call(r))throw Error("Operative: callback.transfer() must be passed an Array of transfers as its last arguments");return r}var data=e.data;if("string"==typeof data&&0===data.indexOf("EVAL|"))return eval(data.substring(5)),void 0;if(null==structuredCloningSupport)return structuredCloningSupport="PING"===e.data[0],self.postMessage(structuredCloningSupport?"pingback:structuredCloningSupport=YES":"pingback:structuredCloningSupport=NO"),structuredCloningSupport||(postMessage=function(e){return self.postMessage(JSON.stringify(e))}),void 0;structuredCloningSupport||(data=JSON.parse(data));var defs=data.definitions,isDeferred=!1,args=data.args;if(defs)for(var i in defs)self[i]=defs[i];else{callback.transfer=function(){var e=[].slice.call(arguments),r=extractTransfers(e);returnResult({args:e},r)},args.push(callback),self.deferred=function(){function e(e,r){return returnResult({isDeferred:!0,action:"resolve",args:[e]},r),t}function r(e,r){returnResult({isDeferred:!0,action:"reject",args:[e]},r)}isDeferred=!0;var t={};return t.fulfil=t.fulfill=t.resolve=function(r){return e(r)},t.reject=function(e){return r(e)},t.transferResolve=function(r){var t=extractTransfers(arguments);return e(r,t)},t.transferReject=function(e){var t=extractTransfers(arguments);return r(e,t)},t};var result=self[data.method].apply(self,args);isDeferred||void 0===result||returnResult({args:[result]}),self.deferred=function(){throw Error("Operative: deferred() called at odd time")}}})}if("undefined"==typeof window&&self.importScripts)return workerBoilerScript(),void 0;var Operative=operative.Operative,URL=window.URL||window.webkitURL,BlobBuilder=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,workerViaBlobSupport=function(){try{new Worker(makeBlobURI(";"))}catch(e){return!1}return!0}(),transferrableObjSupport=function(){try{var e=new ArrayBuffer(1);return new Worker(makeBlobURI(";")).postMessage(e,[e]),!e.byteLength}catch(r){return!1}}();operative.hasWorkerViaBlobSupport=workerViaBlobSupport,operative.hasTransferSupport=transferrableObjSupport,Operative.BrowserWorker=function BrowserWorker(){Operative.apply(this,arguments)};var WorkerProto=Operative.BrowserWorker.prototype=operative.objCreate(Operative.prototype);WorkerProto._onWorkerMessage=function(e){var r=e.data;if("string"==typeof r&&0===r.indexOf("pingback"))return"pingback:structuredCloningSupport=NO"===r&&(this._marshal=function(e){return JSON.stringify(e)},this._demarshal=function(e){return JSON.parse(e)}),this.isContextReady=!0,this._postMessage({definitions:this.dataProperties}),this._dequeueAll(),void 0;switch(r=this._demarshal(r),r.cmd){case"console":window.console&&window.console[r.method].apply(window.console,r.args);break;case"result":var t=this.callbacks[r.token],n=this.deferreds[r.token],o=r.result&&r.result.isDeferred&&r.result.action;n&&o?n[o](r.result.args[0]):t?t.apply(this,r.result.args):n&&n.fulfil(r.result.args[0])}},WorkerProto._isWorkerViaBlobSupported=function(){return workerViaBlobSupport},WorkerProto._setup=function(){var e,r=this,t=this._getSelfURL(),n=this._isWorkerViaBlobSupported(),o=this._buildContextScript(n?workerBoilerScript:"");if(this.dependencies.length&&(o='importScripts("'+this.dependencies.join('", "')+'");\n'+o),n)e=this.worker=new Worker(makeBlobURI(o));else{if(!t)throw Error("Operaritve: No operative.js URL available. Please set via operative.setSelfURL(...)");e=this.worker=new Worker(t),e.postMessage("EVAL|"+o)}e.postMessage("EVAL|self.hasTransferSupport="+transferrableObjSupport),e.postMessage(["PING"]),e.addEventListener("message",function(e){r._onWorkerMessage(e)})},WorkerProto._postMessage=function(e){var r=transferrableObjSupport&&e.transfers;return r?this.worker.postMessage(e,r.value):this.worker.postMessage(this._marshal(e))},WorkerProto._runMethod=function(e,r,t,n){this._postMessage({method:e,args:t,token:r,transfers:n})},WorkerProto.destroy=function(){this.worker.terminate(),Operative.prototype.destroy.call(this)}}(),function(){function e(){window.__run__=function(e,r,t,n){function o(){return t.apply(this,arguments)}var i=!1;window.deferred=function(){return i=!0,n},o.transfer=function(){return t.apply(this,[].slice.call(arguments,0,arguments.length-1))},t&&r.push(o);var s=window[e].apply(window,r);window.deferred=function(){throw Error("Operative: deferred() called at odd time")},i||void 0===s||o(s)}}if("undefined"!=typeof window||!self.importScripts){var r=operative.Operative;r.Iframe=function(){r.apply(this,arguments)};var t=r.Iframe.prototype=operative.objCreate(r.prototype),n=0;t._setup=function(){var r=this,t="__operativeIFrameLoaded"+ ++n;this.module.isWorker=!1;var o=this.iframe=document.body.appendChild(document.createElement("iframe"));o.style.display="none";var i=this.iframeWindow=o.contentWindow,s=i.document;window[t]=function(){window[t]=null;var n=s.createElement("script"),o=r._buildContextScript(e);void 0!==n.text?n.text=o:n.innerHTML=o,s.documentElement.appendChild(n);for(var a in r.dataProperties)i[a]=r.dataProperties[a];r.isContextReady=!0,r._dequeueAll()},s.open();var a="";this.dependencies.length&&(a+='\n<script src="'+this.dependencies.join('"></script><script src="')+'"></script>'),s.write(a+"\n<script>setTimeout(window.parent."+t+",0);</script>"),s.close()},t._runMethod=function(e,r,t){var n=this,o=this.callbacks[r],i=this.deferreds[r];this.iframeWindow.__run__(e,t,function(e){var r=o,t=i;r?r.apply(n,arguments):t&&t.fulfil(e)},i)},t.destroy=function(){this.iframe.parentNode.removeChild(this.iframe),r.prototype.destroy.call(this)}}}(); |
@@ -5,3 +5,3 @@ { | ||
"description": "Operative: Inline Web-Worker Helper", | ||
"version": "0.4.1", | ||
"version": "0.4.3", | ||
"author": "James Padolsey (http://git.io/padolsey)", | ||
@@ -8,0 +8,0 @@ "main": "dist/operative.min.js", |
@@ -20,5 +20,36 @@ # Operative | ||
* No DOM/BOM Access | ||
* No synchronous communication with parent page | ||
* No DOM/BOM Access. | ||
* No synchronous communication with parent page. | ||
* An entirely separate execution context (no shared scope/variables). | ||
* Limitations on data transfer depending on browser. | ||
And it won't make things uniformly faster or less burdensome on the UI. Operative will fall-back to using iframes in older browsers, which gives you no non-blocking advantage. | ||
Non-blob worker support (i.e. for IE10) requires that you have a same-origin copy of Operative (this means you can't solely rely on CDNs or elsewhere-hosted scripts if you want to support IE10). | ||
### Browser Support | ||
Operative `0.4.3` has been explicitly tested in: | ||
* Chrome 14, 23, 29, 37, 42 | ||
* Firefox 3, 10, 18, 23, 32 | ||
* IE 8, 9, 10 (Windows 7) | ||
* IE 11 (Windows 10) | ||
* Opera 25 (Mac) | ||
* Opera 10.6 (Windows 7) | ||
* Safari 5.1 (Windows 7) | ||
* Safari 6, 8 (Mac) | ||
* Safari (iPad Air, iOS 8) | ||
* Safari (iPhone 4S, iOS 5.1) | ||
Support for Workers, with varying degrees of support for Transferables and Blobs: | ||
* FF 17+ | ||
* Chrome 7+ | ||
* Safari 4+ | ||
* Opera 11+ | ||
* IE10+ | ||
*Note: Operative has not been tested in non-browser envs* | ||
### Quick install | ||
@@ -33,9 +64,7 @@ | ||
*Note: Operative has not been tested in non-browser envs* | ||
Or just grab the built JS file from `dist/`, also available here (0.4.3): | ||
Or just grab the built JS file from `dist/`, also available here (0.3.0): | ||
* https://raw.github.com/padolsey/operative/0.4.3/dist/operative.js | ||
* https://raw.github.com/padolsey/operative/0.4.3/dist/operative.min.js | ||
* https://raw.github.com/padolsey/operative/0.3.0/dist/operative.js | ||
* https://raw.github.com/padolsey/operative/0.3.0/dist/operative.min.js | ||
### Creating an Operative Module | ||
@@ -47,4 +76,4 @@ | ||
var calculator = operative({ | ||
add: function(a, b, cb) { | ||
cb( a + b ); | ||
add: function(a, b, callback) { | ||
callback( a + b ); | ||
} | ||
@@ -115,10 +144,2 @@ }); | ||
### Browser Support for Workers | ||
* FF 17+ | ||
* Chrome 7+ | ||
* Safari 4+ | ||
* Opera 11+ | ||
* IE10+ | ||
### Degraded Operative | ||
@@ -142,4 +163,6 @@ | ||
Operative supports browsers with no worker-via-blob support (e.g. IE10, Safari 4.0) via eval, and it requires `operative.js` or `operative.min.js` to be its own file and included in the page via a `<script>` tag. Or, alternatively, if its bundled with other JS, you'll have to have an additional `operative.js` and specify it *before creating an operative module* via `operative.setSelfURL('path/to/operative.js')` (this'll only generate a request where the aforementioned support is lacking). Due to the usage of eval in these cases it is recommended to debug your operatives in more capable browsers. | ||
Operative supports browsers with no worker-via-blob support (e.g. IE10, Safari 4.0) via eval, and it requires `operative.js` or `operative.min.js` to be its own file and included in the page via a `<script>` tag. This file must be on the same origin as the parent page. | ||
If you're bundling Operative with other JS, you'll have to have an additional (same-origin!) `operative.js` and specify it *before creating an operative module* via `operative.setSelfURL('path/to/operative.js')` (this'll only generate a request where the aforementioned support is lacking). Due to the usage of eval in these cases it is recommended to debug your operatives in more capable browsers. | ||
### Operative API Documentation | ||
@@ -302,2 +325,7 @@ | ||
* 0.4.3 (26 Apr 2016) | ||
* Fixed self-url setting (see [#36](https://github.com/padolsey/operative/issues/36)) | ||
* Improved readme | ||
* 0.4.2 (25 Apr 2015) | ||
* Added support for CommonJS | ||
* 0.4.0 (10 Apr 2015) | ||
@@ -304,0 +332,0 @@ * Removed deprecated `async()` method in favor of callbacks or promises |
@@ -16,6 +16,2 @@ /** | ||
var scripts = document.getElementsByTagName('script'); | ||
var opScript = scripts[scripts.length - 1]; | ||
var opScriptURL = /operative/.test(opScript.src) && opScript.src; | ||
var URL = window.URL || window.webkitURL; | ||
@@ -63,3 +59,3 @@ var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; | ||
*/ | ||
Operative.BrowserWorker = function BrowserWorker(module) { | ||
Operative.BrowserWorker = function BrowserWorker() { | ||
Operative.apply(this, arguments); | ||
@@ -116,2 +112,6 @@ }; | ||
WorkerProto._isWorkerViaBlobSupported = function() { | ||
return workerViaBlobSupport; | ||
}; | ||
WorkerProto._setup = function() { | ||
@@ -121,5 +121,7 @@ var self = this; | ||
var worker; | ||
var selfURL = this._getSelfURL(); | ||
var blobSupport = this._isWorkerViaBlobSupported(); | ||
var script = this._buildContextScript( | ||
// The script is not included if we're Eval'ing this file directly: | ||
workerViaBlobSupport ? workerBoilerScript : '' | ||
blobSupport ? workerBoilerScript : '' | ||
); | ||
@@ -131,9 +133,10 @@ | ||
if (workerViaBlobSupport) { | ||
if (blobSupport) { | ||
worker = this.worker = new Worker( makeBlobURI(script) ); | ||
} else { | ||
if (!opScriptURL) { | ||
if (!selfURL) { | ||
throw new Error('Operaritve: No operative.js URL available. Please set via operative.setSelfURL(...)'); | ||
} | ||
worker = this.worker = new Worker( opScriptURL ); | ||
worker = this.worker = new Worker( selfURL ); | ||
// Marshal-agnostic initial message is boiler-code: | ||
@@ -140,0 +143,0 @@ // (We don't yet know if structured-cloning is supported so we send a string) |
@@ -28,7 +28,7 @@ /** | ||
if (typeof define === 'function' && define.amd) { | ||
define( function () { return operative; }); | ||
} else { | ||
window.operative = operative; | ||
} | ||
// Note: This will work only in the built dist: | ||
// (Otherwise you must explicitly set selfURL to BrowserWorker.js) | ||
var scripts = document.getElementsByTagName('script'); | ||
var opScript = scripts[scripts.length - 1]; | ||
var opScriptURL = /operative/.test(opScript.src) && opScript.src; | ||
@@ -62,3 +62,4 @@ operative.pool = function(size, module, dependencies) { | ||
var getBase = operative.getBaseURL.bind(this); | ||
var getBase = operative.getBaseURL; | ||
var getSelf = operative.getSelfURL; | ||
@@ -69,3 +70,3 @@ var OperativeContext = operative.hasWorkerSupport ? operative.Operative.BrowserWorker : operative.Operative.Iframe; | ||
// Allow a single function to be passed. | ||
var o = new OperativeContext({ main: module }, dependencies, getBase); | ||
var o = new OperativeContext({ main: module }, dependencies, getBase, getSelf); | ||
var singularOperative = function() { | ||
@@ -86,3 +87,3 @@ return o.api.main.apply(o, arguments); | ||
return new OperativeContext(module, dependencies, getBase).api; | ||
return new OperativeContext(module, dependencies, getBase, getSelf).api; | ||
@@ -114,2 +115,7 @@ } | ||
/** | ||
* Set and get Self URL, i.e. the url of the | ||
* operative script itself. | ||
*/ | ||
operative.setSelfURL = function(url) { | ||
@@ -119,2 +125,11 @@ opScriptURL = url; | ||
operative.getSelfURL = function(url) { | ||
return opScriptURL; | ||
}; | ||
/** | ||
* Set and get Base URL, i.e. the path used | ||
* as a base for getting dependencies | ||
*/ | ||
operative.setBaseURL = function(base) { | ||
@@ -121,0 +136,0 @@ baseURL = base; |
@@ -25,3 +25,3 @@ (function() { | ||
*/ | ||
function OperativeContext(module, dependencies, getBase) { | ||
function OperativeContext(module, dependencies, getBaseURL, getSelfURL) { | ||
@@ -41,3 +41,4 @@ var _self = this; | ||
this._getBase = getBase; | ||
this._getBaseURL = getBaseURL; | ||
this._getSelfURL = getSelfURL; | ||
@@ -92,3 +93,3 @@ this.isDestroyed = false; | ||
if (!/\/\//.test(dep)) { | ||
deps[i] = dep.replace(/^\/?/, this._getBase().replace(/([^\/])$/, '$1/')); | ||
deps[i] = dep.replace(/^\/?/, this._getBaseURL().replace(/([^\/])$/, '$1/')); | ||
} | ||
@@ -95,0 +96,0 @@ } |
@@ -207,2 +207,41 @@ describe('Operative (worker Context)', function() { | ||
describe('No blob-support case', function() { | ||
beforeEach(function() { | ||
operative.Operative.BrowserWorker.prototype._isWorkerViaBlobSupported = function() { | ||
return false; | ||
}; | ||
}); | ||
it('Works correctly', function(done) { | ||
var o = operative(function() { | ||
return 888; | ||
}); | ||
o(function(v) { | ||
expect(v).to.equal(888); | ||
done(); | ||
}); | ||
}); | ||
describe('Explicitly setting the self URL', function() { | ||
beforeEach(function() { | ||
operative.setSelfURL( | ||
'../../src/contexts/BrowserWorker.js?test-explicit' | ||
); | ||
}); | ||
it('Works; a new Worker is created with that URL', function(done) { | ||
var o = operative(function() { | ||
return self.location.href; | ||
}); | ||
o(function(url) { | ||
if (operative.hasWorkerSupport) { | ||
// Worker context | ||
expect(url).to.contain('?test-explicit'); | ||
} else { | ||
// Iframe context (self-url changing does nothing) | ||
expect(url).to.contain('.html'); | ||
} | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('Perpetual callbacks', function() { | ||
@@ -209,0 +248,0 @@ |
Sorry, the diff of this file is not supported yet
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
602595
8050
359