forked from pkrumins/dnode
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
socket.io examples work with the new callback stuff now
- Loading branch information
James Halliday
committed
Jul 10, 2010
1 parent
e743e0b
commit 31c9ce9
Showing
9 changed files
with
221 additions
and
111 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// Client code to Connect to DNode proxies from the web browser | ||
function DNode (obj) { | ||
if (!(this instanceof DNode)) return new DNode(obj); | ||
var self = this; | ||
if (obj === undefined) obj = {}; | ||
|
||
function firstTypes (args) { | ||
var types = {}; | ||
[].concat.apply([],args).forEach(function (arg) { | ||
var t = typeof(arg); | ||
if (!(t in types)) types[t] = arg; | ||
}); | ||
return types; | ||
} | ||
|
||
this.connect = function () { | ||
var types = firstTypes(arguments) || {}; | ||
var kwargs = types.object || {}; | ||
var host = kwargs.host || types.string || window.location.hostname; | ||
kwargs.port = kwargs.port || types.number || window.location.port; | ||
var block = types['function'] || kwargs.block || function () {}; | ||
|
||
delete kwargs.port; | ||
delete kwargs.block; | ||
kwargs.rememberTransport = kwargs.rememberTransport || false; | ||
kwargs.transports = kwargs.transports | ||
|| 'websocket htmlfile xhr-multipart xhr-polling'.split(/\s+/); | ||
|
||
var sock = new io.Socket(host, kwargs); | ||
|
||
var remote = {}; | ||
var scrubber = new Scrubber; | ||
|
||
function sendRequest(method, args) { | ||
var scrub = scrubber.scrub(args); | ||
sock.send(JSON.stringify({ | ||
method : method, | ||
arguments : scrub.arguments, | ||
callbacks : scrub.callbacks | ||
})); | ||
} | ||
|
||
sock.addEvent('connect', function () { | ||
sendRequest('methods', Object.keys(obj)); | ||
}); | ||
|
||
sock.addEvent('message', function (strMsg) { | ||
var req = JSON.parse(strMsg); | ||
var args = scrubber.unscrub(req, function (id) { | ||
return function () { | ||
sendRequest(id, [].concat.apply([],arguments)); | ||
}; | ||
}); | ||
|
||
if (req.method == 'methods') { | ||
args.forEach(function (method) { | ||
remote[method] = function () { | ||
var argv = [].concat.apply([],arguments); | ||
sendRequest(method, argv); | ||
}; | ||
}); | ||
block.call(obj, remote, self); | ||
} | ||
else if (typeof(req.method) == 'string') { | ||
obj[req.method].apply(obj,args); | ||
} | ||
else if (typeof(req.method) == 'number') { | ||
scrubber.callbacks[req.method].apply(obj,args); | ||
} | ||
}); | ||
|
||
sock.connect(); | ||
}; | ||
} | ||
|
||
// wrapper to turn synchronous functions into asynchronous ones with the | ||
// result callback inserted as the last argument | ||
DNode.sync = function (f) { | ||
return function () { | ||
var args = [].concat.apply([],arguments); | ||
var argv = args.slice(0,-1); | ||
var cb = args.slice(-1)[0]; | ||
cb(f.apply(this,argv)); | ||
}; | ||
}; | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
function Scrubber () { | ||
this.callbacks = {}; | ||
var cbId = 0; | ||
var self = this; | ||
|
||
// Take the functions out and note them for future use | ||
this.scrub = function (obj) { | ||
var paths = {}; | ||
var args = Traverse(obj).modify(function (node) { | ||
if (typeof(node) == 'function') { | ||
self.callbacks[cbId] = node; | ||
paths[cbId] = this.path; | ||
this.update('[Function]'); | ||
cbId++; | ||
} | ||
}).get(); | ||
return { | ||
arguments : args, | ||
callbacks : paths, | ||
}; | ||
}; | ||
|
||
// Replace callbacks. The supplied function should take a callback id and | ||
// return a callback of its own. | ||
this.unscrub = function (msg, f) { | ||
var args = msg.arguments || []; | ||
Object.keys(msg.callbacks || {}).forEach(function (strId) { | ||
var id = parseInt(strId,10); | ||
var path = msg.callbacks[id]; | ||
var node = args; | ||
path.slice(0,-1).forEach(function (key) { | ||
node = node[key]; | ||
}); | ||
var last = path.slice(-1)[0]; | ||
if (last === undefined) { | ||
args = f(id); | ||
} | ||
else { | ||
node[last] = f(id); | ||
} | ||
}); | ||
return args; | ||
}; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
function Traverse (obj) { | ||
if (!(this instanceof Traverse)) return new Traverse(obj); | ||
|
||
this.get = function () { return obj }; | ||
|
||
this.modify = function (f) { | ||
var path = []; | ||
var parents = []; | ||
walk(obj); | ||
return this; | ||
|
||
function walk (node) { | ||
var state = { | ||
node : node, | ||
path : [].concat(path), | ||
parent : parents.slice(-1)[0], | ||
key : path.slice(-1)[0], | ||
isRoot : node == obj, | ||
notRoot : node != obj, | ||
isLeaf : typeof(node) != 'object' | ||
|| Object.keys(node).length == 0, | ||
notLeaf : typeof(node) == 'object' | ||
&& Object.keys(node).length > 0, | ||
update : function (x) { | ||
if (state.isRoot) { | ||
obj = x; | ||
} | ||
else { | ||
state.parent.node[state.key] = x; | ||
} | ||
state.node = x; | ||
}, | ||
level : path.length, | ||
}; | ||
|
||
f.call(state, node); | ||
if (typeof(state.node) == 'object') { | ||
parents.push(state); | ||
Object.keys(state.node).forEach(function (key) { | ||
path.push(key); | ||
walk(state.node[key]); | ||
path.pop(); | ||
}); | ||
parents.pop(); | ||
} | ||
} | ||
}; | ||
|
||
this.forEach = function (f) { | ||
this.modify(function (node) { | ||
delete this.update; | ||
f.call(this,node); | ||
},null); | ||
return this; | ||
}; | ||
|
||
this.paths = function () { | ||
var acc = []; | ||
this.each(function (x) { | ||
acc.push(this.path); | ||
}); | ||
return acc; | ||
}; | ||
|
||
this.nodes = function () { | ||
var acc = []; | ||
this.each(function (x) { | ||
acc.push(this.node); | ||
}); | ||
return acc; | ||
}; | ||
} |