Skip to content

Instantly share code, notes, and snippets.

@bmeck
Created January 13, 2012 23:58
Show Gist options
  • Save bmeck/1609442 to your computer and use it in GitHub Desktop.
Save bmeck/1609442 to your computer and use it in GitHub Desktop.
Wrapper for serializing between contexts using native gc.
//
// Wrap an object for another context...
// Will not wrap functions given to parent from sandbox
// Will not crawl prototypes, be explicit
// Result is not a "live" representation, if you need to sync objects you should rewrap
// DO NOT ADD/UPDATE PROPERTIES ON RESULT ONLY READ AND INVOKE
//
function wrapper() {
var stringify = JSON.stringify,
parse = JSON.parse,
isArray = Array.isArrray,
indexOf = function (arr, item) {
"use strict";
for (var i = 0; i < arr.length; i++) {
if (arr[i] === item) return i;
}
return -1;
}
var comm;
comm = {
unwrap: function ( ) { },
wrap: function wrap(o, visited) {
"use strict";
visited = visited || {};
visited.source = visited.source || [];
visited.callbacks = visited.callbacks || [];
visited.result = visited.result || {};
if (typeof o === 'function') {
var result = function fn() {
"use strict";
var args = [];
for (var i = 0; i < arguments.length; i++) {
args[i] = comm.unwrap(arguments[i]);
}
//
// this apply is outside sandbox, we are ok
//
return comm.unwrap(o.apply(null, args));
}
return result;
}
if (typeof o === 'object') {
if (!o) {
return null;
}
var result = {};//stringify(o)[0] === '[' ? [] : {};
for(var key in o) {
;(function (key) {
var item = o[key],
index = indexOf(visited.source, item);
if (index !== -1) {
if (index in visited.result) {
result[key] = visited.result[index];
}
else {
var cbs = visited.callbacks[index] || (visited.callbacks[index] = []);
cbs[cbs.length] = (function () {
if(typeof console != 'undefined') console.log(index)
result[key] = visited.result[index];
});
}
}
else {
var index = visited.source.length;
visited.source[index] = o[key];
result[key] = wrap(o[key], visited);
visited.result[index] = result[key];
var callbacks = visited.callbacks[index];
if (callbacks) {
for (var i = 0; i < callbacks.length; i++) {
callbacks[i]();
}
}
}
})(key);
};
return result;
}
if (typeof o === 'number') {
return parse(stringify(o));
}
if (typeof o === 'boolean') {
return parse(stringify(o));
}
if (typeof o === 'string') {
return parse(stringify(o));
}
return undefined;
}
}
return comm;
};
//
// Utility to combine a duplex wrapper
//
function getWrapper(runner) {
var runnerFn = runner('('+wrapper.toString()+')');
var outer_wrap = wrapper();
var runner_wrap = runnerFn();
outer_wrap.unwrap = runner_wrap.wrap;
runner_wrap.unwrap = outer_wrap.wrap;
return runner_wrap.wrap;
}
module.exports = getWrapper;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment