Skip to content

Instantly share code, notes, and snippets.

@sskrla
Last active September 20, 2015 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sskrla/dddb132b00d39ad4807f to your computer and use it in GitHub Desktop.
Save sskrla/dddb132b00d39ad4807f to your computer and use it in GitHub Desktop.
Supersonic Background-WebView Proxy Service
'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);
}
};
});
@sskrla
Copy link
Author

sskrla commented Sep 20, 2015

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.

angular.module('MyModule')
  .service('SharedService', function(ProxyService){
    var queue = [];
    return ProxyService.singleton('SharedService', {
      add: function(item) {
        queue.add(item);
      },

      next: function(){
        return queue.pop();
      }
    });
  });
SharedService.add("Test")
  .then(function(){ 
    console.log("Queued");

    SharedService.next()
      .then(function(item){ 
        console.log("Got " + item); 
      });
  });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment