Last active
September 20, 2015 22:24
-
-
Save sskrla/dddb132b00d39ad4807f to your computer and use it in GitHub Desktop.
Supersonic Background-WebView Proxy Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* Wraps methods in a proxy that effectively makes them singletons where invocation only happens on the background | |
* view's thread. All methods return types become Q promise, method calls on the background proxy will execute synchronously | |
* but still be wrapped in promise. | |
* | |
* Typical usage: | |
* | |
* angular.module('MyModule') | |
* .service('SharedService', function(ProxyService){ | |
* var queue = []; | |
* return ProxyService.singleton('SharedService', { | |
* add: function(item) { | |
* queue.add(item); | |
* }, | |
* | |
* next: function(){ | |
* return queue.pop(); | |
* } | |
* }); | |
* }); | |
*/ | |
angular | |
.module('SteroidsApplication') | |
.service('ProxyService', function($q, backgroundWebView) { | |
function subscribe(name, service) { | |
var proxy = {}; | |
_.each(service, function(body, method) { | |
supersonic.data.channel(name + '#' + method).subscribe(function(rpc){ | |
var success, fail; | |
try { | |
success = service[method].apply(service, rpc.args); | |
} catch(e) { | |
fail = e.message; | |
} | |
postMessage({ | |
receipt: 'rpc.response.' + rpc.messageId, | |
result: success, | |
error: fail | |
}); | |
}); | |
proxy[method] = function() { | |
return $q.when(service[method].apply(service, arguments)); | |
} | |
}); | |
return proxy; | |
}; | |
function publish(name, service) { | |
var proxy = {}; | |
_.each(service, function(body, method) { | |
proxy[method] = function() { | |
var args = Array.prototype.slice.call(arguments); | |
return $q(function(ok, fail){ | |
var id = new Date().getTime(), | |
listener = addEventListener('message', function(e) { | |
if(e.data.receipt == 'rpc.response.' + id) { | |
removeEventListener('message', listener); | |
if(e.data.error) { | |
fail(e.data.error); | |
} else { | |
ok(e.data.result); | |
} | |
} | |
}); | |
supersonic.data.channel(name + '#' + method).publish({ | |
messageId: id, | |
args: args | |
}); | |
}) | |
}; | |
}); | |
return proxy; | |
}; | |
return { | |
singleton: function(name, service) { | |
return backgroundWebView | |
? subscribe(name, service) | |
: publish(name, service); | |
} | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Intent
It may be desirable to provide services, such as a data synchronization queue, that are shared for all webviews in the application. This class allows you to simple wrap the returned service object in a proxy that dispatches method calls and responses over the
message
event channel.Usage
Make sure to bind the
backgroundWebView
constant to true only for the background webview.