Comparing version 3.0.0-alpha.3 to 3.0.0-alpha.4
@@ -178,3 +178,14 @@ // Derived from https://github.com/umdjs/umd/blob/master/templates/amdWebGlobal.js | ||
local.removeEventListener(MESSAGE, handleMessageEvent); | ||
(event.data.resolution === FULFILLED ? resolve : reject)(event.data.returnValue); | ||
var returnValue = event.data.returnValue; | ||
if (event.data.returnValueIsError) { | ||
var deserializedError = new Error(); | ||
Object.keys(returnValue).forEach(function (key) { | ||
return deserializedError[key] = returnValue[key]; | ||
}); | ||
returnValue = deserializedError; | ||
} | ||
(event.data.resolution === FULFILLED ? resolve : reject)(returnValue); | ||
} | ||
@@ -238,8 +249,3 @@ }; | ||
if (destroyed) { | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw new Error('Unable to send ' + methodName + '() reply due to destroyed connection'); | ||
}); | ||
throw new Error('Unable to send ' + methodName + '() reply due to destroyed connection'); | ||
return; | ||
@@ -250,9 +256,21 @@ } | ||
var message = { | ||
penpal: REPLY, | ||
id: id, | ||
resolution: resolution, | ||
returnValue: returnValue | ||
}; | ||
if (resolution === REJECTED && returnValue instanceof Error) { | ||
message.returnValue = { | ||
name: returnValue.name, | ||
message: returnValue.message, | ||
stack: returnValue.stack | ||
}; | ||
message.returnValueIsError = true; | ||
} | ||
try { | ||
remote.postMessage({ | ||
penpal: REPLY, | ||
id: id, | ||
resolution: resolution, | ||
returnValue: returnValue | ||
}, remoteOrigin); | ||
remote.postMessage(message, remoteOrigin); | ||
} catch (err) { | ||
@@ -270,8 +288,3 @@ // If a consumer attempts to send an object that's not cloneable (e.g., window), | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw err; | ||
}); | ||
throw err; | ||
} | ||
@@ -281,18 +294,4 @@ }; | ||
new Penpal.Promise(function (resolve, reject) { | ||
try { | ||
// The consumer's function may throw an error, return a raw return value, return | ||
// a promise that resolves, or return a promise that gets rejected. | ||
// In the case that it throws an error, we'll send the error stack as a reply | ||
resolve(methods[methodName].apply(methods, _toConsumableArray(args))); | ||
} catch (err) { | ||
reject(err.toString()); | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw err; | ||
}); | ||
} | ||
new Penpal.Promise(function (resolve) { | ||
return resolve(methods[methodName].apply(methods, _toConsumableArray(args))); | ||
}).then(createPromiseHandler(FULFILLED), createPromiseHandler(REJECTED)); | ||
@@ -299,0 +298,0 @@ } |
@@ -1,1 +0,1 @@ | ||
!function(e,n){var t={};!function(e){"use strict";function n(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var t={"http:":"80","https:":"443"},r=/^(https?:)?\/\/([^\/:]+)(:(\d+))?/,o={Promise:function(){try{return window?window.Promise:null}catch(e){return null}}(),debug:!1},i=function(){var e=0;return function(){return++e}}(),a=function(){for(var e=arguments.length,n=Array(e),t=0;t<e;t++)n[t]=arguments[t];if(o.debug){var r;(r=console).log.apply(r,["[Penpal]"].concat(n))}},d=function(e){var n=document.location,o=r.exec(e),i=void 0,a=void 0,d=void 0;return o?(i=o[1]?o[1]:n.protocol,a=o[2],d=o[4]):(i=n.protocol,a=n.hostname,d=n.port),i+"//"+a+(d&&d!==t[i]?":"+d:"")},c=function(e){var n=[];return e(function(){n.forEach(function(e){e()})}),{then:function(e){n.push(e)}}},u=function(e,n,t,r){var d=n.localName,c=n.local,u=n.remote,s=n.remoteOrigin,l=!1;a(d+": Connecting call sender");var f=function(e){return function(){for(var n=arguments.length,t=Array(n),r=0;r<n;r++)t[r]=arguments[r];return a(d+": Sending "+e+"() call"),new o.Promise(function(n,r){if(l)return void r(new Error("Unable to send "+e+"() call due to destroyed connection"));var o=i(),f=function t(i){i.source===u&&i.origin===s&&"reply"===i.data.penpal&&i.data.id===o&&(a(d+": Received "+e+"() reply"),c.removeEventListener("message",t),("fulfilled"===i.data.resolution?n:r)(i.data.returnValue))};c.addEventListener("message",f),u.postMessage({penpal:"call",id:o,methodName:e,args:t},s)})}};r.then(function(){l=!0}),t.reduce(function(e,n){return e[n]=f(n),e},e)},s=function(e,t,r){var i=e.localName,d=e.local,c=e.remote,u=e.remoteOrigin,s=!1;a(i+": Connecting call receiver");var l=function(e){if(e.source===c&&e.origin===u&&"call"===e.data.penpal){var r=e.data,d=r.methodName,l=r.args,f=r.id;if(a(i+": Received "+d+"() call"),d in t){var m=function(e){return function(n){if(s)return void setTimeout(function(){throw new Error("Unable to send "+d+"() reply due to destroyed connection")});a(i+": Sending "+d+"() reply");try{c.postMessage({penpal:"reply",id:f,resolution:e,returnValue:n},u)}catch(e){"DataCloneError"===e.name&&c.postMessage({penpal:"reply",id:f,resolution:"rejected",returnValue:e.toString()},u),setTimeout(function(){throw e})}}};new o.Promise(function(e,r){try{e(t[d].apply(t,n(l)))}catch(e){r(e.toString()),setTimeout(function(){throw e})}}).then(m("fulfilled"),m("rejected"))}}};d.addEventListener("message",l),r.then(function(){s=!0,d.removeEventListener("message",l)})};o.connectToChild=function(e){var n=e.url,t=e.appendTo,r=e.methods,i=void 0===r?{}:r,l=e.timeout,f=void 0,m=new c(function(e){return f=e}),p=window,h=document.createElement("iframe");(t||document.body).appendChild(h),m.then(function(){h.parentNode&&h.parentNode.removeChild(h)});var v=h.contentWindow||h.contentDocument.parentWindow,g=d(n);return{promise:new o.Promise(function(e,t){void 0!==l&&setTimeout(function(){t(new Error("Connection to child timed out after "+l+"ms")),f()},l);var r={},o=void 0,d=function(n){if(n.source===v&&n.origin===g&&"handshake"===n.data.penpal){a("Parent: Received handshake"),a("Parent: Sending handshake reply"),n.source.postMessage({penpal:"handshake-reply",methodNames:Object.keys(i)},n.origin);var t={localName:"Parent",local:p,remote:v,remoteOrigin:n.origin};s(t,i,m),o&&o.forEach(function(e){delete r[e]}),o=n.data.methodNames,u(r,t,o,m),e(r)}};p.addEventListener("message",d),m.then(function(){p.removeEventListener("message",d),t("Parent: Connection destroyed")}),a("Parent: Loading iframe"),h.src=n}),iframe:h,destroy:f}},o.connectToParent=function(e){var n=e.parentOrigin,t=void 0===n?"*":n,r=e.methods,i=void 0===r?{}:r,d=e.timeout;if(window===window.top)throw new Error("connectToParent() must be called within an iframe");var l=void 0,f=new c(function(e){return l=e}),m=window,p=m.parent;return{promise:new o.Promise(function(e,n){void 0!==d&&setTimeout(function(){n(new Error("Connection to parent timed out after "+d+"ms")),l()},d);var r=function n(r){if(("*"===t||t===r.origin)&&r.source===p&&"handshake-reply"===r.data.penpal){a("Child: Received handshake reply"),m.removeEventListener("message",n);var o={localName:"Child",local:m,remote:p,remoteOrigin:r.origin},d={};s(o,i,f),u(d,o,r.data.methodNames,f),e(d)}};m.addEventListener("message",r),f.then(function(){m.removeEventListener("message",r),n(new Error("Child: Connection destroyed"))}),a("Child: Sending handshake"),p.postMessage({penpal:"handshake",methodNames:Object.keys(i)},t)}),destroy:l}},e.default=o}(t),"function"==typeof define&&define.amd?define("Penpal",t.default):e.Penpal=t.default}(this); | ||
!function(e,n){var r={};!function(e){"use strict";function n(e){if(Array.isArray(e)){for(var n=0,r=Array(e.length);n<e.length;n++)r[n]=e[n];return r}return Array.from(e)}Object.defineProperty(e,"__esModule",{value:!0});var r={"http:":"80","https:":"443"},t=/^(https?:)?\/\/([^\/:]+)(:(\d+))?/,o={Promise:function(){try{return window?window.Promise:null}catch(e){return null}}(),debug:!1},a=function(){var e=0;return function(){return++e}}(),i=function(){for(var e=arguments.length,n=Array(e),r=0;r<e;r++)n[r]=arguments[r];if(o.debug){var t;(t=console).log.apply(t,["[Penpal]"].concat(n))}},d=function(e){var n=document.location,o=t.exec(e),a=void 0,i=void 0,d=void 0;return o?(a=o[1]?o[1]:n.protocol,i=o[2],d=o[4]):(a=n.protocol,i=n.hostname,d=n.port),a+"//"+i+(d&&d!==r[a]?":"+d:"")},c=function(e){var n=[];return e(function(){n.forEach(function(e){e()})}),{then:function(e){n.push(e)}}},s=function(e,n,r,t){var d=n.localName,c=n.local,s=n.remote,u=n.remoteOrigin,l=!1;i(d+": Connecting call sender");var f=function(e){return function(){for(var n=arguments.length,r=Array(n),t=0;t<n;t++)r[t]=arguments[t];return i(d+": Sending "+e+"() call"),new o.Promise(function(n,t){if(l)return void t(new Error("Unable to send "+e+"() call due to destroyed connection"));var o=a(),f=function r(a){if(a.source===s&&a.origin===u&&"reply"===a.data.penpal&&a.data.id===o){i(d+": Received "+e+"() reply"),c.removeEventListener("message",r);var l=a.data.returnValue;if(a.data.returnValueIsError){var f=new Error;Object.keys(l).forEach(function(e){return f[e]=l[e]}),l=f}("fulfilled"===a.data.resolution?n:t)(l)}};c.addEventListener("message",f),s.postMessage({penpal:"call",id:o,methodName:e,args:r},u)})}};t.then(function(){l=!0}),r.reduce(function(e,n){return e[n]=f(n),e},e)},u=function(e,r,t){var a=e.localName,d=e.local,c=e.remote,s=e.remoteOrigin,u=!1;i(a+": Connecting call receiver");var l=function(e){if(e.source===c&&e.origin===s&&"call"===e.data.penpal){var t=e.data,d=t.methodName,l=t.args,f=t.id;if(i(a+": Received "+d+"() call"),d in r){var m=function(e){return function(n){if(u)throw new Error("Unable to send "+d+"() reply due to destroyed connection");i(a+": Sending "+d+"() reply");var r={penpal:"reply",id:f,resolution:e,returnValue:n};"rejected"===e&&n instanceof Error&&(r.returnValue={name:n.name,message:n.message,stack:n.stack},r.returnValueIsError=!0);try{c.postMessage(r,s)}catch(e){throw"DataCloneError"===e.name&&c.postMessage({penpal:"reply",id:f,resolution:"rejected",returnValue:e.toString()},s),e}}};new o.Promise(function(e){return e(r[d].apply(r,n(l)))}).then(m("fulfilled"),m("rejected"))}}};d.addEventListener("message",l),t.then(function(){u=!0,d.removeEventListener("message",l)})};o.connectToChild=function(e){var n=e.url,r=e.appendTo,t=e.methods,a=void 0===t?{}:t,l=e.timeout,f=void 0,m=new c(function(e){return f=e}),p=window,v=document.createElement("iframe");(r||document.body).appendChild(v),m.then(function(){v.parentNode&&v.parentNode.removeChild(v)});var h=v.contentWindow||v.contentDocument.parentWindow,g=d(n);return{promise:new o.Promise(function(e,r){void 0!==l&&setTimeout(function(){r(new Error("Connection to child timed out after "+l+"ms")),f()},l);var t={},o=void 0,d=function(n){if(n.source===h&&n.origin===g&&"handshake"===n.data.penpal){i("Parent: Received handshake"),i("Parent: Sending handshake reply"),n.source.postMessage({penpal:"handshake-reply",methodNames:Object.keys(a)},n.origin);var r={localName:"Parent",local:p,remote:h,remoteOrigin:n.origin};u(r,a,m),o&&o.forEach(function(e){delete t[e]}),o=n.data.methodNames,s(t,r,o,m),e(t)}};p.addEventListener("message",d),m.then(function(){p.removeEventListener("message",d),r("Parent: Connection destroyed")}),i("Parent: Loading iframe"),v.src=n}),iframe:v,destroy:f}},o.connectToParent=function(e){var n=e.parentOrigin,r=void 0===n?"*":n,t=e.methods,a=void 0===t?{}:t,d=e.timeout;if(window===window.top)throw new Error("connectToParent() must be called within an iframe");var l=void 0,f=new c(function(e){return l=e}),m=window,p=m.parent;return{promise:new o.Promise(function(e,n){void 0!==d&&setTimeout(function(){n(new Error("Connection to parent timed out after "+d+"ms")),l()},d);var t=function n(t){if(("*"===r||r===t.origin)&&t.source===p&&"handshake-reply"===t.data.penpal){i("Child: Received handshake reply"),m.removeEventListener("message",n);var o={localName:"Child",local:m,remote:p,remoteOrigin:t.origin},d={};u(o,a,f),s(d,o,t.data.methodNames,f),e(d)}};m.addEventListener("message",t),f.then(function(){m.removeEventListener("message",t),n(new Error("Child: Connection destroyed"))}),i("Child: Sending handshake"),p.postMessage({penpal:"handshake",methodNames:Object.keys(a)},r)}),destroy:l}},e.default=o}(r),"function"==typeof define&&define.amd?define("Penpal",r.default):e.Penpal=r.default}(this); |
@@ -164,3 +164,14 @@ 'use strict'; | ||
local.removeEventListener(MESSAGE, handleMessageEvent); | ||
(event.data.resolution === FULFILLED ? resolve : reject)(event.data.returnValue); | ||
var returnValue = event.data.returnValue; | ||
if (event.data.returnValueIsError) { | ||
var deserializedError = new Error(); | ||
Object.keys(returnValue).forEach(function (key) { | ||
return deserializedError[key] = returnValue[key]; | ||
}); | ||
returnValue = deserializedError; | ||
} | ||
(event.data.resolution === FULFILLED ? resolve : reject)(returnValue); | ||
} | ||
@@ -224,8 +235,3 @@ }; | ||
if (destroyed) { | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw new Error('Unable to send ' + methodName + '() reply due to destroyed connection'); | ||
}); | ||
throw new Error('Unable to send ' + methodName + '() reply due to destroyed connection'); | ||
return; | ||
@@ -236,9 +242,21 @@ } | ||
var message = { | ||
penpal: REPLY, | ||
id: id, | ||
resolution: resolution, | ||
returnValue: returnValue | ||
}; | ||
if (resolution === REJECTED && returnValue instanceof Error) { | ||
message.returnValue = { | ||
name: returnValue.name, | ||
message: returnValue.message, | ||
stack: returnValue.stack | ||
}; | ||
message.returnValueIsError = true; | ||
} | ||
try { | ||
remote.postMessage({ | ||
penpal: REPLY, | ||
id: id, | ||
resolution: resolution, | ||
returnValue: returnValue | ||
}, remoteOrigin); | ||
remote.postMessage(message, remoteOrigin); | ||
} catch (err) { | ||
@@ -256,8 +274,3 @@ // If a consumer attempts to send an object that's not cloneable (e.g., window), | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw err; | ||
}); | ||
throw err; | ||
} | ||
@@ -267,18 +280,4 @@ }; | ||
new Penpal.Promise(function (resolve, reject) { | ||
try { | ||
// The consumer's function may throw an error, return a raw return value, return | ||
// a promise that resolves, or return a promise that gets rejected. | ||
// In the case that it throws an error, we'll send the error stack as a reply | ||
resolve(methods[methodName].apply(methods, _toConsumableArray(args))); | ||
} catch (err) { | ||
reject(err.toString()); | ||
// Some promise libraries, like RSVP, don't report uncaught errors without special | ||
// handlers being added by the consumer. By throwing them asynchronously, they're | ||
// guaranteed to hit the console. We may choose to change this behavior later. | ||
setTimeout(function () { | ||
throw err; | ||
}); | ||
} | ||
new Penpal.Promise(function (resolve) { | ||
return resolve(methods[methodName].apply(methods, _toConsumableArray(args))); | ||
}).then(createPromiseHandler(FULFILLED), createPromiseHandler(REJECTED)); | ||
@@ -285,0 +284,0 @@ } |
{ | ||
"name": "penpal", | ||
"version": "3.0.0-alpha.3", | ||
"version": "3.0.0-alpha.4", | ||
"description": "A promise-based library for communicating with iframes via postMessage.", | ||
@@ -5,0 +5,0 @@ "author": "Aaron Hardy <aaron@aaronhardy.com>", |
47196
7
853