Skip to content

Instantly share code, notes, and snippets.

@ecto
Created February 12, 2014 05:33
Show Gist options
  • Save ecto/8950511 to your computer and use it in GitHub Desktop.
Save ecto/8950511 to your computer and use it in GitHub Desktop.

Revisions

  1. ecto created this gist Feb 12, 2014.
    166 changes: 166 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,166 @@
    // function
    // Constructor
    // object { function, function }

    var isomerize = function () {
    if (arguments.length == 1) {
    var code = arguments[0];

    if (typeof code == 'function') {
    return new LocalFunctionIsomer(code);
    } else if (typeof code == 'object') {
    return new LocalObjectIsomer(code);
    } else {
    }
    } else {
    }
    }

    isomerize.overrideFunction = function (raw) {
    var local = new LocalFunctionIsomer(code);
    return local;
    }

    isomerize.overrideObject = function (obj) {
    var methods = [];

    for (var i in obj) {
    if (typeof obj[i] == 'object') {
    //isomerize.overrideObject(obj[i]);
    } else if (typeof obj[i] == 'function') {
    obj[i] = isomerize.overrideFunction(obj[i]);
    } else {
    }
    }
    }

    isomerize.externalFunction = function () {
    onmessage = function (e) {
    var data = JSON.parse(e.data);
    var argNames = getParamNames(original);
    var cbCode = data.args.pop();
    var cb = new Function(argNames, cbCode);

    if (~argNames.indexOf('callback')) {
    data.args.push(cb);
    original.apply(original, data.args);
    } else {
    var ret = original.apply(original, data.args);
    cb(ret);
    }
    };

    // https://stackoverflow.com/questions/1007981/how-to-get-function-parameter-names-values-dynamically-from-javascript
    var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
    function getParamNames (func) {
    var fnStr = func.toString().replace(STRIP_COMMENTS, '')
    var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g)
    if(result === null)
    result = []
    return result
    }
    }

    function LocalFunctionIsomer (rawCode) {
    var code = 'var original = ' + rawCode.toString() + ';(' + isomerize.externalFunction.toString() + ')()';
    var blob = new Blob([ code ], { type: 'application/javascript' });
    var worker = new Worker(URL.createObjectURL(blob));
    var listeners = {};

    worker.onmessage = function (e) {
    var data = JSON.parse(e.data);

    if (listeners[data.id]) {
    listeners[data.id].apply(listeners[data.id], data.args);
    delete listeners[data.id];
    }
    };

    return function () {
    var args = [].slice.call(arguments);

    if (typeof args[args.length - 1] != 'function') {
    throw 'Must supply callback';
    }

    var realCallback = args.pop();
    var now = +new Date();

    // replace callback with bridge
    args.push(function () {
    var args = [].slice.call(arguments);
    postMessage(JSON.stringify({
    id: now,
    args: args
    }));
    }.toString()
    .replace('now', now)
    .match(/function[^{]+\{([\s\S]*)\}$/)[1]);

    listeners[now] = realCallback;

    worker.postMessage(JSON.stringify({
    id: now,
    args: args
    }));
    }
    }

    function LocalObjectIsomer (rawObject) {
    console.log('objectisomer', rawObject);
    this.tree = {};
    LocalObjectIsomer.recursivelyOverride(rawObject);

    return function () {
    console.log('YO');
    }
    }

    LocalObjectIsomer.recursivelyOverride = function (obj) {
    for (var i in obj) {
    if (typeof obj[i] == 'object') {
    LocalObjectIsomer.recursivelyOverride(obj[i]);
    } else {
    obj[i].call
    }
    }
    }

    function ExternalIsomer () {

    }


    /*
    * synchronous function example
    */
    function add (a, b) {
    return a + b;
    }
    add = isomerize(add);
    add(1, 2, function (val) {
    console.log(val);
    });

    /*
    * asynchronous function example
    */
    function addAsync (a, b, callback) {
    callback(a + b);
    }
    addAsync = isomerize(addAsync);
    addAsync(1, 2, function (val) {
    console.log(val);
    });

    /*
    * Constructor example
    */

    /*
    * object example
    */

    $(function () {
    sjcl = isomerize(sjcl);
    });