Created
January 13, 2012 23:58
-
-
Save bmeck/1609442 to your computer and use it in GitHub Desktop.
Wrapper for serializing between contexts using native gc.
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
// | |
// 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