mirror of
https://github.com/amark/gun.git
synced 2025-06-23 22:42:32 +00:00
server updated
This commit is contained in:
parent
ab138b5350
commit
8c0dae0176
@ -24,8 +24,8 @@
|
|||||||
<button>send</button>
|
<button>send</button>
|
||||||
</form>
|
</form>
|
||||||
<script>
|
<script>
|
||||||
var chat = Gun(location.origin + '/gun').get('example/chat/data').not(function(){
|
var chat = Gun(location.origin + '/gun').get('example/chat/data').not(function(key){
|
||||||
return this.put({1: {who: 'Welcome', what: "to the chat app!", when: 1}}).key('example/chat/data');
|
return this.put({1: {who: 'Welcome', what: "to the chat app!", when: 1}}).key(key);
|
||||||
});
|
});
|
||||||
chat.map().val(function(msg, field){
|
chat.map().val(function(msg, field){
|
||||||
var $ul = $('ul'), $last = $.sort(field, $ul.lastChild), $msg;
|
var $ul = $('ul'), $last = $.sort(field, $ul.lastChild), $msg;
|
||||||
|
@ -11,7 +11,7 @@ var gun = Gun({
|
|||||||
});
|
});
|
||||||
|
|
||||||
var server = require('http').createServer(function(req, res){
|
var server = require('http').createServer(function(req, res){
|
||||||
if(gun.server(req, res)){
|
if(gun.wsp.server(req, res)){
|
||||||
return; // filters gun requests!
|
return; // filters gun requests!
|
||||||
}
|
}
|
||||||
require('fs').createReadStream(require('path').join(__dirname, req.url)).on('error',function(){ // static files!
|
require('fs').createReadStream(require('path').join(__dirname, req.url)).on('error',function(){ // static files!
|
||||||
@ -19,7 +19,7 @@ var server = require('http').createServer(function(req, res){
|
|||||||
res.end(require('fs').readFileSync(require('path').join(__dirname, 'index.html'))); // or default to index
|
res.end(require('fs').readFileSync(require('path').join(__dirname, 'index.html'))); // or default to index
|
||||||
}).pipe(res); // stream
|
}).pipe(res); // stream
|
||||||
});
|
});
|
||||||
gun.attach(server);
|
gun.wsp(server);
|
||||||
server.listen(port);
|
server.listen(port);
|
||||||
|
|
||||||
console.log('Server started on port ' + port + ' with /gun');
|
console.log('Server started on port ' + port + ' with /gun');
|
90
gun.js
90
gun.js
@ -562,6 +562,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gun.is.node.HAM = function(n, f){ return (f && n && n._ && n._[Gun._.HAM] && n._[Gun._.HAM][f]) || false }
|
||||||
|
|
||||||
Gun.HAM = function(machineState, incomingState, currentState, incomingValue, currentValue){ // TODO: Lester's comments on roll backs could be vulnerable to divergence, investigate!
|
Gun.HAM = function(machineState, incomingState, currentState, incomingValue, currentValue){ // TODO: Lester's comments on roll backs could be vulnerable to divergence, investigate!
|
||||||
if(machineState < incomingState){
|
if(machineState < incomingState){
|
||||||
// the incoming value is outside the boundary of the machine's state, it must be reprocessed in another state.
|
// the incoming value is outside the boundary of the machine's state, it must be reprocessed in another state.
|
||||||
@ -930,6 +932,35 @@
|
|||||||
if(at.obj === has.obj){ return has }
|
if(at.obj === has.obj){ return has }
|
||||||
}) || (ctx.seen.push(at) && false);
|
}) || (ctx.seen.push(at) && false);
|
||||||
}
|
}
|
||||||
|
ify.wire = function(n, cb, opt){ return Gun.text.is(n)? ify.wire.from(n, cb, opt) : ify.wire.to(n, cb, opt) }
|
||||||
|
ify.wire.to = function(n, cb, opt){ var t, b;
|
||||||
|
if(!n || !(t = Gun.is.node.soul(n))){ return null }
|
||||||
|
cb = cb || function(){};
|
||||||
|
t = (b = "#'" + JSON.stringify(t) + "'");
|
||||||
|
Gun.obj.map(n, function(v,f){
|
||||||
|
if(Gun._.meta === f){ return }
|
||||||
|
var w = '', s = Gun.is.node.HAM(n,f);
|
||||||
|
if(!s){ return }
|
||||||
|
w += ".'" + JSON.stringify(f) + "'";
|
||||||
|
w += "='" + JSON.stringify(v) + "'";
|
||||||
|
w += ">'" + JSON.stringify(s) + "'";
|
||||||
|
t += w;
|
||||||
|
w = b + w;
|
||||||
|
cb(null, w);
|
||||||
|
});
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
ify.wire.from = function(n, cb, opt){
|
||||||
|
if(!n){ return null }
|
||||||
|
var a = [], s = -1, e = 0, end = 1;
|
||||||
|
while((e = n.indexOf("'", s + 1)) >= 0){
|
||||||
|
if(s === e || '\\' === n.charAt(e-1)){}else{
|
||||||
|
a.push(n.slice(s + 1,e));
|
||||||
|
s = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
Gun.ify = ify;
|
Gun.ify = ify;
|
||||||
}(Gun));
|
}(Gun));
|
||||||
|
|
||||||
@ -951,7 +982,7 @@
|
|||||||
|
|
||||||
|
|
||||||
;(function(Tab){
|
;(function(Tab){
|
||||||
return;
|
|
||||||
if(!this.Gun){ return }
|
if(!this.Gun){ return }
|
||||||
if(!window.JSON){ throw new Error("Include JSON first: ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js") } // for old IE use
|
if(!window.JSON){ throw new Error("Include JSON first: ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js") } // for old IE use
|
||||||
|
|
||||||
@ -1016,12 +1047,6 @@
|
|||||||
});
|
});
|
||||||
} tab.peers(cb);
|
} tab.peers(cb);
|
||||||
}
|
}
|
||||||
tab.com(function(msg, reply){
|
|
||||||
|
|
||||||
});
|
|
||||||
tab.com.to(msg, function(reply){
|
|
||||||
|
|
||||||
}, opt);
|
|
||||||
tab.error = function(cb, error, fn){
|
tab.error = function(cb, error, fn){
|
||||||
return function(err, reply){
|
return function(err, reply){
|
||||||
reply.body = reply.body || reply.chunk || reply.end || reply.write;
|
reply.body = reply.body || reply.chunk || reply.end || reply.write;
|
||||||
@ -1055,31 +1080,15 @@
|
|||||||
var reply = {headers: {'Content-Type': tab.server.json}};
|
var reply = {headers: {'Content-Type': tab.server.json}};
|
||||||
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
|
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
|
||||||
// TODO: Re-emit message to other peers if we have any non-overlaping ones.
|
// TODO: Re-emit message to other peers if we have any non-overlaping ones.
|
||||||
if(tab.server.put.key(req, cb)){ return }
|
if(req.err = Gun.union(gun, req.body, function(err, ctx){
|
||||||
if(Gun.is.node(req.body) || Gun.is.graph(req.body, function(node, soul){
|
if(err){ return cb({headers: reply.headers, body: {err: err || "Union failed."}}) }
|
||||||
gun.__.flag.end[soul] = true; // TODO: Put this in CORE not in TAB driver?
|
var ctx = ctx || {}; ctx.graph = {};
|
||||||
})){
|
Gun.is.graph(req.body, function(node, soul){ ctx.graph[soul] = gun.__.graph[soul] });
|
||||||
//console.log("tran.put", req.body);
|
gun.__.opt.wire.put(ctx.graph, function(err, ok){
|
||||||
if(req.err = Gun.union(gun, req.body, function(err, ctx){
|
if(err){ return cb({headers: reply.headers, body: {err: err || "Failed."}}) }
|
||||||
if(err){ return cb({headers: reply.headers, body: {err: err || "Union failed."}}) }
|
cb({headers: reply.headers, body: {ok: ok || "Persisted."}});
|
||||||
var ctx = ctx || {}; ctx.graph = {};
|
}, {local: true});
|
||||||
Gun.is.graph(req.body, function(node, soul){ ctx.graph[soul] = gun.__.graph[soul] });
|
}).err){ cb({headers: reply.headers, body: {err: req.err || "Union failed."}}) }
|
||||||
gun.__.opt.hooks.put(ctx.graph, function(err, ok){
|
|
||||||
if(err){ return cb({headers: reply.headers, body: {err: err || "Failed."}}) }
|
|
||||||
cb({headers: reply.headers, body: {ok: ok || "Persisted."}});
|
|
||||||
}, {local: true});
|
|
||||||
}).err){ cb({headers: reply.headers, body: {err: req.err || "Union failed."}}) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tab.server.put.key = function(req, cb){
|
|
||||||
if(!req || !req.url || !req.url.key || !Gun.obj.has(req.body, Gun._.soul)){ return }
|
|
||||||
var index = req.url.key, soul = Gun.is.soul(req.body);
|
|
||||||
//console.log("tran.key", index, req.body);
|
|
||||||
gun.key(index, function(err, reply){
|
|
||||||
if(err){ return cb({headers: {'Content-Type': tab.server.json}, body: {err: err}}) }
|
|
||||||
cb({headers: {'Content-Type': tab.server.json}, body: reply}); // TODO: Fix so we know what the reply is.
|
|
||||||
}, soul);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
Gun.obj.map(gun.__.opt.peers, function(){ // only create server if peers and do it once by returning immediately.
|
Gun.obj.map(gun.__.opt.peers, function(){ // only create server if peers and do it once by returning immediately.
|
||||||
return (tab.server.able = tab.server.able || tab.request.createServer(tab.server) || true);
|
return (tab.server.able = tab.server.able || tab.request.createServer(tab.server) || true);
|
||||||
@ -1089,13 +1098,6 @@
|
|||||||
gun.__.opt.wire.key = gun.__.opt.wire.key || tab.key;
|
gun.__.opt.wire.key = gun.__.opt.wire.key || tab.key;
|
||||||
});
|
});
|
||||||
|
|
||||||
;(function(exports){
|
|
||||||
exports.com = function(){
|
|
||||||
|
|
||||||
};
|
|
||||||
com.to = function(){};
|
|
||||||
}(Tab));
|
|
||||||
|
|
||||||
var request = (function(){
|
var request = (function(){
|
||||||
function r(base, body, cb, opt){
|
function r(base, body, cb, opt){
|
||||||
opt = opt || (base.length? {base: base} : base);
|
opt = opt || (base.length? {base: base} : base);
|
||||||
@ -1110,6 +1112,7 @@
|
|||||||
while(i--){ (r.createServer.s[i] || function(){})(req, cb) }
|
while(i--){ (r.createServer.s[i] || function(){})(req, cb) }
|
||||||
}
|
}
|
||||||
r.createServer.s = [];
|
r.createServer.s = [];
|
||||||
|
r.back = 2; r.backoff = 2;
|
||||||
r.transport = function(opt, cb){
|
r.transport = function(opt, cb){
|
||||||
//Gun.log("TRANSPORT:", opt);
|
//Gun.log("TRANSPORT:", opt);
|
||||||
if(r.ws(opt, cb)){ return }
|
if(r.ws(opt, cb)){ return }
|
||||||
@ -1134,7 +1137,7 @@
|
|||||||
}
|
}
|
||||||
if(ws === false){ return }
|
if(ws === false){ return }
|
||||||
ws = r.ws.peers[opt.base] = new WS(opt.base.replace('http','ws'));
|
ws = r.ws.peers[opt.base] = new WS(opt.base.replace('http','ws'));
|
||||||
ws.onopen = function(o){ r.ws(opt, cb) };
|
ws.onopen = function(o){ r.back = 2; r.ws(opt, cb) };
|
||||||
ws.onclose = window.onbeforeunload = function(c){
|
ws.onclose = window.onbeforeunload = function(c){
|
||||||
if(!c){ return }
|
if(!c){ return }
|
||||||
if(ws && ws.close instanceof Function){ ws.close() }
|
if(ws && ws.close instanceof Function){ ws.close() }
|
||||||
@ -1145,9 +1148,8 @@
|
|||||||
}
|
}
|
||||||
ws = r.ws.peers[opt.base] = null; // this will make the next request try to reconnect
|
ws = r.ws.peers[opt.base] = null; // this will make the next request try to reconnect
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
console.log("!!!!! WEBSOCKET DICONNECTED !!!!!! ATTEMPTING INFINITE RETRY WITH NO BACKOFF !!!!!!!");
|
|
||||||
r.ws(opt, function(){}); // opt here is a race condition, is it not? Does this matter?
|
r.ws(opt, function(){}); // opt here is a race condition, is it not? Does this matter?
|
||||||
}, 50) // make this an exponential backoff.
|
}, r.back *= r.backoff);
|
||||||
};
|
};
|
||||||
ws.onmessage = function(m){
|
ws.onmessage = function(m){
|
||||||
if(!m || !m.data){ return }
|
if(!m || !m.data){ return }
|
||||||
@ -1157,10 +1159,10 @@
|
|||||||
if(!res){ return }
|
if(!res){ return }
|
||||||
res.headers = res.headers || {};
|
res.headers = res.headers || {};
|
||||||
if(res.headers['ws-rid']){ return (r.ws.cbs[res.headers['ws-rid']]||function(){})(null, res) }
|
if(res.headers['ws-rid']){ return (r.ws.cbs[res.headers['ws-rid']]||function(){})(null, res) }
|
||||||
Gun.log("We have a pushed message!", res);
|
//Gun.log("We have a pushed message!", res);
|
||||||
if(res.body){ r.createServer.ing(res, function(){}) } // emit extra events.
|
if(res.body){ r.createServer.ing(res, function(){}) } // emit extra events.
|
||||||
};
|
};
|
||||||
ws.onerror = function(e){ console.log("!!!! WEBSOCKET ERROR !!!!", e); Gun.log(e); };
|
ws.onerror = function(e){ Gun.log(e); };
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
r.ws.peers = {};
|
r.ws.peers = {};
|
||||||
|
17
lib/file.js
17
lib/file.js
@ -38,19 +38,16 @@ Gun.on('opt').event(function(gun, opts) {
|
|||||||
|
|
||||||
gun.opt({wire: {
|
gun.opt({wire: {
|
||||||
get: function get(key, cb, o){
|
get: function get(key, cb, o){
|
||||||
var graph, soul = key;
|
var node, soul = key;
|
||||||
(graph = {})[soul] = all.nodes[soul];
|
node = all.nodes[soul];
|
||||||
console.log("FILE NODE", graph);
|
if(!node){ return cb(null, null) }
|
||||||
if(!graph[soul]){ return cb(null, null) }
|
cb(null, node);
|
||||||
cb(null, graph);
|
node = Gun.is.node.ify({}, soul);
|
||||||
(graph = {})[soul] = Gun.is.node.ify({}, soul);
|
cb(null, node); // end.
|
||||||
console.log("END NODE", graph);
|
|
||||||
cb(null, graph); // end.
|
|
||||||
console.log("DONE", {});
|
|
||||||
cb(null, {}); // done.
|
cb(null, {}); // done.
|
||||||
},
|
},
|
||||||
put: function(graph, cb, o){
|
put: function(graph, cb, o){
|
||||||
for (key in gun.__.graph) all.nodes[key]=gun.__.graph[key];
|
for (key in gun.__.graph) all.nodes[key]=gun.__.graph[key]||graph[key];
|
||||||
writeFile(cb);
|
writeFile(cb);
|
||||||
}/*,
|
}/*,
|
||||||
all: function(list, opt, cb) {
|
all: function(list, opt, cb) {
|
||||||
|
169
lib/wsp.js
169
lib/wsp.js
@ -6,26 +6,26 @@
|
|||||||
, url = require('url');
|
, url = require('url');
|
||||||
Gun.on('opt').event(function(gun, opt){
|
Gun.on('opt').event(function(gun, opt){
|
||||||
gun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};
|
gun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};
|
||||||
|
function start(server, port){
|
||||||
|
gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;
|
||||||
|
if(server.use){ server.use(gun.__.opt.ws.server) }
|
||||||
|
require('./ws')(gun.wsp.ws = gun.wsp.ws || new ws(gun.__.opt.ws), function(req, res){
|
||||||
|
var ws = this;
|
||||||
|
req.headers['gun-sid'] = ws.sid = ws.sid? ws.sid : req.headers['gun-sid'];
|
||||||
|
ws.sub = ws.sub || gun.wsp.on('network').event(function(msg){
|
||||||
|
if(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return this.off() }
|
||||||
|
if(!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)){ return }
|
||||||
|
if(msg && msg.headers){ delete msg.headers['ws-rid'] }
|
||||||
|
// TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id?
|
||||||
|
try{ws.send(Gun.text.ify(msg));
|
||||||
|
}catch(e){} // juuuust in case.
|
||||||
|
});
|
||||||
|
gun.wsp.wire(req, res);
|
||||||
|
});
|
||||||
|
gun.__.opt.ws.port = gun.__.opt.ws.port || opt.ws.port || port || 80;
|
||||||
|
}
|
||||||
var wsp = gun.wsp = gun.wsp || function(server){
|
var wsp = gun.wsp = gun.wsp || function(server){
|
||||||
if(!server){ return gun }
|
if(!server){ return gun }
|
||||||
function start(port, server){
|
|
||||||
gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;
|
|
||||||
gun.__.opt.ws.port = gun.__.opt.ws.port || opt.ws.port || port || 80;
|
|
||||||
if(server.use){ server.use(gun.__.opt.ws.server) }
|
|
||||||
require('./ws')(gun.wsp.ws = gun.wsp.ws || new ws(gun.__.opt.ws), function(req, res){
|
|
||||||
var ws = this;
|
|
||||||
req.headers['gun-sid'] = ws.sid = ws.sid? ws.sid : req.headers['gun-sid'];
|
|
||||||
ws.sub = ws.sub || gun.wsp.on('network').event(function(msg){
|
|
||||||
if(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return this.off() }
|
|
||||||
if(!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)){ return }
|
|
||||||
if(msg && msg.headers){ delete msg.headers['ws-rid'] }
|
|
||||||
// TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id?
|
|
||||||
try{ws.send(Gun.text.ify(msg));
|
|
||||||
}catch(e){} // juuuust in case.
|
|
||||||
});
|
|
||||||
gun.wsp.EXPLODE(req, res);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if(Gun.fns.is(server.address)){
|
if(Gun.fns.is(server.address)){
|
||||||
if(server.address()){
|
if(server.address()){
|
||||||
start(server, server.address().port);
|
start(server, server.address().port);
|
||||||
@ -82,112 +82,19 @@
|
|||||||
return stream.reply = cb;
|
return stream.reply = cb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gun.wsp.EXPLODE(req, cb);
|
gun.wsp.wire(req, cb);
|
||||||
}), true;
|
}), true;
|
||||||
}
|
}
|
||||||
if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
|
if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
|
||||||
require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity;
|
require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity;
|
||||||
}
|
}
|
||||||
if(opt.server){
|
gun.wsp.wire = gun.wsp.wire || (function(){
|
||||||
wsp(opt.server);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var wsp = gun.wsp = gun.wsp || {};
|
|
||||||
gun.attach = gun.attach || function(app){
|
|
||||||
if(app.use){
|
|
||||||
app.use(gun.server);
|
|
||||||
}
|
|
||||||
var listen = app.listen;
|
|
||||||
app.listen = function(port){
|
|
||||||
var server = listen.apply(app, arguments);
|
|
||||||
gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server;
|
|
||||||
gun.__.opt.ws.path = gun.__.opt.ws.path || opt.ws.path || '/gun';
|
|
||||||
require('./ws')(gun.server.websocket = gun.server.websocket || new ws(gun.__.opt.ws), function(req, res){
|
|
||||||
var ws = this;
|
|
||||||
req.headers['gun-sid'] = ws.sid = ws.sid? ws.sid : req.headers['gun-sid'];
|
|
||||||
ws.sub = ws.sub || gun.server.on('network').event(function(msg){
|
|
||||||
if(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return this.off() }
|
|
||||||
if(!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)){ return }
|
|
||||||
if(msg && msg.headers){ delete msg.headers['ws-rid'] }
|
|
||||||
// TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id?
|
|
||||||
try{ws.send(Gun.text.ify(msg));
|
|
||||||
}catch(e){} // juuuust in case.
|
|
||||||
});
|
|
||||||
gun.__.opt.wire.transport(req, res);
|
|
||||||
});
|
|
||||||
gun.__.opt.ws.port = port || opt.ws.port || gun.__.opt.ws.port || 80;
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
return gun;
|
|
||||||
}
|
|
||||||
gun.server = gun.server || function(req, res, next){ // http
|
|
||||||
//Gun.log("\n\n GUN SERVER!", req);
|
|
||||||
next = next || function(){};
|
|
||||||
if(!req || !res){ return next(), false }
|
|
||||||
if(!req.url){ return next(), false }
|
|
||||||
if(!req.method){ return next(), false }
|
|
||||||
var msg = {};
|
|
||||||
msg.url = url.parse(req.url, true);
|
|
||||||
if(!gun.server.regex.test(msg.url.pathname)){ return next(), false }
|
|
||||||
if(msg.url.pathname.replace(gun.server.regex,'').slice(0,3).toLowerCase() === '.js'){
|
|
||||||
res.writeHead(200, {'Content-Type': 'text/javascript'});
|
|
||||||
res.end(gun.server.js = gun.server.js || require('fs').readFileSync(__dirname + '/../gun.js')); // gun server is caching the gun library for the client
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return http(req, res, function(req, res){
|
|
||||||
if(!req){ return next() }
|
|
||||||
var tab, cb = res = require('./jsonp')(req, res);
|
|
||||||
if(req.headers && (tab = req.headers['gun-sid'])){
|
|
||||||
tab = (gun.server.peers = gun.server.peers || {})[tab] = gun.server.peers[tab] || {sid: tab};
|
|
||||||
tab.sub = tab.sub || gun.server.on('network').event(function(req){
|
|
||||||
if(!tab){ return this.off() } // self cleans up after itself!
|
|
||||||
if(!req || (req.headers && req.headers['gun-sid'] === tab.sid)){ return }
|
|
||||||
(tab.queue = tab.queue || []).push(req);
|
|
||||||
tab.drain(tab.reply);
|
|
||||||
});
|
|
||||||
cb = function(r){ (r.headers||{}).poll = gun.__.opt.poll; res(r) }
|
|
||||||
tab.drain = tab.drain || function(res){
|
|
||||||
if(!res || !tab || !tab.queue || !tab.queue.length){ return }
|
|
||||||
res({headers: {'gun-sid': tab.sid}, body: tab.queue });
|
|
||||||
tab.off = setTimeout(function(){ tab = null }, gun.__.opt.pull);
|
|
||||||
tab.reply = tab.queue = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
clearTimeout(tab.off);
|
|
||||||
if(req.headers.pull){
|
|
||||||
if(tab.drain(cb)){ return }
|
|
||||||
return tab.reply = cb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gun.__.opt.wire.transport(req, cb);
|
|
||||||
}), true;
|
|
||||||
}
|
|
||||||
gun.server.on = gun.server.on || Gun.on.create();
|
|
||||||
gun.__.opt.poll = gun.__.opt.poll || opt.poll || 1;
|
|
||||||
gun.__.opt.pull = gun.__.opt.pull || opt.pull || gun.__.opt.poll * 1000;
|
|
||||||
gun.server.regex = gun.__.opt.route = gun.__.opt.route || opt.route || /^\/gun/i;
|
|
||||||
if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
|
|
||||||
require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity; // WARNING: Document this!
|
|
||||||
}
|
|
||||||
/* gun.server.xff = function(r){
|
|
||||||
if(!r){ return '' }
|
|
||||||
var req = {headers: r.headers || {}, connection: r.connection || {}, socket: r.socket || {}};
|
|
||||||
return req.headers['x-forwarded-for'] || req.connection.remoteAddress || req.socket.remoteAddress || (req.connection.socket || {}).remoteAddress || '';
|
|
||||||
} */
|
|
||||||
gun.server.transport = gun.server.transport || (function(){
|
|
||||||
// all streams, technically PATCH but implemented as PUT or POST, are forwarded to other trusted peers
|
// all streams, technically PATCH but implemented as PUT or POST, are forwarded to other trusted peers
|
||||||
// except for the ones that are listed in the message as having already been sending to.
|
// except for the ones that are listed in the message as having already been sending to.
|
||||||
// all states, implemented with GET, are replied to the source that asked for it.
|
// all states, implemented with GET, are replied to the source that asked for it.
|
||||||
function tran(req, cb){
|
function tran(req, cb){
|
||||||
req.method = req.body? 'put' : 'get'; // put or get is based on whether there is a body or not
|
req.method = req.body? 'put' : 'get'; // put or get is based on whether there is a body or not
|
||||||
req.url.key = req.url.pathname.replace(gun.server.regex,'').replace(/^\//i,'') || '';
|
req.url.key = req.url.pathname.replace(gun.wsp.regex,'').replace(/^\//i,'') || '';
|
||||||
if('get' == req.method){ return tran.get(req, cb) }
|
if('get' == req.method){ return tran.get(req, cb) }
|
||||||
if('put' == req.method || 'post' == req.method){ return tran.put(req, cb) }
|
if('put' == req.method || 'post' == req.method){ return tran.put(req, cb) }
|
||||||
cb({body: {hello: 'world'}});
|
cb({body: {hello: 'world'}});
|
||||||
@ -196,18 +103,18 @@
|
|||||||
var key = req.url.key
|
var key = req.url.key
|
||||||
, reply = {headers: {'Content-Type': tran.json}};
|
, reply = {headers: {'Content-Type': tran.json}};
|
||||||
//console.log(req);
|
//console.log(req);
|
||||||
/* NTS HACK! SHOULD BE ITS OWN ISOLATED MODULE! */
|
// NTS HACK! SHOULD BE ITS OWN ISOLATED MODULE! //
|
||||||
if(req && req.url && req.url.pathname && req.url.pathname.indexOf('gun.nts') >= 0){
|
if(req && req.url && req.url.pathname && req.url.pathname.indexOf('gun.nts') >= 0){
|
||||||
return cb({headers: reply.headers, body: {time: Gun.time.is() }});
|
return cb({headers: reply.headers, body: {time: Gun.time.is() }});
|
||||||
}
|
}
|
||||||
/* NTS END! SHOULD HAVE BEEN ITS OWN MODULE */
|
// NTS END! SHOULD HAVE BEEN ITS OWN MODULE //
|
||||||
/* ALL HACK! SHOULD BE ITS OWN MODULE OR CORE? */
|
// ALL HACK! SHOULD BE ITS OWN MODULE OR CORE? //
|
||||||
if(req && req.url && Gun.obj.has(req.url.query, '*')){
|
if(req && req.url && Gun.obj.has(req.url.query, '*')){
|
||||||
return gun.all(req.url.key + req.url.search, function(err, list){
|
return gun.all(req.url.key + req.url.search, function(err, list){
|
||||||
cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : list || null ) })
|
cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : list || null ) })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
/* END ALL HACK! */
|
// END ALL HACK! //
|
||||||
if(!key){
|
if(!key){
|
||||||
if(!Gun.obj.has(req.url.query, Gun._.soul)){
|
if(!Gun.obj.has(req.url.query, Gun._.soul)){
|
||||||
return cb({headers: reply.headers, body: {err: "No key or soul to get."}});
|
return cb({headers: reply.headers, body: {err: "No key or soul to get."}});
|
||||||
@ -216,13 +123,13 @@
|
|||||||
key[Gun._.soul] = req.url.query[Gun._.soul];
|
key[Gun._.soul] = req.url.query[Gun._.soul];
|
||||||
}
|
}
|
||||||
console.log("tran.get", key);
|
console.log("tran.get", key);
|
||||||
gun.__.opt.wire.get(key, function(err, graph){
|
gun.__.opt.wire.get(key, function(err, node){
|
||||||
//tran.sub.scribe(req.tab, graph._[Gun._.soul]);
|
//tran.sub.scribe(req.tab, graph._[Gun._.soul]);
|
||||||
console.log("tran.get", key, "<---", err, graph);
|
console.log("tran.get", key, "<---", err, node);
|
||||||
if(err || !graph){
|
if(err || !node){
|
||||||
return cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : null)});
|
return cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : null)});
|
||||||
}
|
}
|
||||||
if(Gun.obj.empty(graph)){ return cb({headers: reply.headers, body: graph}) } // we're out of stuff!
|
if(Gun.obj.empty(node)){ return cb({headers: reply.headers, body: node}) } // we're out of stuff!
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(function(chunks){// FEATURE! Stream chunks if the nodes are large!
|
(function(chunks){// FEATURE! Stream chunks if the nodes are large!
|
||||||
@ -253,7 +160,7 @@
|
|||||||
});
|
});
|
||||||
}([]));
|
}([]));
|
||||||
*/
|
*/
|
||||||
cb({headers: reply.headers, chunk: graph }); // Use this if you don't want streaming chunks feature.
|
cb({headers: reply.headers, chunk: node }); // Use this if you don't want streaming chunks feature.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
tran.put = function(req, cb){
|
tran.put = function(req, cb){
|
||||||
@ -261,9 +168,7 @@
|
|||||||
// This will give you much more fine-grain control over security, transactions, and what not.
|
// This will give you much more fine-grain control over security, transactions, and what not.
|
||||||
var reply = {headers: {'Content-Type': tran.json}};
|
var reply = {headers: {'Content-Type': tran.json}};
|
||||||
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
|
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
|
||||||
gun.server.on('network').emit(Gun.obj.copy(req));
|
gun.wsp.on('network').emit(Gun.obj.copy(req));
|
||||||
//if(tran.put.key(req, cb)){ return }
|
|
||||||
// some NEW code that should get revised.
|
|
||||||
console.log("tran.put", req.body);
|
console.log("tran.put", req.body);
|
||||||
if(Gun.is.graph(req.body)){
|
if(Gun.is.graph(req.body)){
|
||||||
if(req.err = Gun.union(gun, req.body, function(err, ctx){ // TODO: BUG? Probably should give me ctx.graph
|
if(req.err = Gun.union(gun, req.body, function(err, ctx){ // TODO: BUG? Probably should give me ctx.graph
|
||||||
@ -281,16 +186,14 @@
|
|||||||
cb({headers: reply.headers, body: {err: "Not a valid graph!"}});
|
cb({headers: reply.headers, body: {err: "Not a valid graph!"}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gun.server.on('network').event(function(req){
|
gun.wsp.on('network').event(function(req){
|
||||||
// TODO: MARK! You should move the networking events to here, not in WSS only.
|
// TODO: MARK! You should move the networking events to here, not in WSS only.
|
||||||
});
|
});
|
||||||
tran.json = 'application/json';
|
tran.json = 'application/json';
|
||||||
return tran;
|
return tran;
|
||||||
}());
|
}());
|
||||||
|
if(opt.server){
|
||||||
opt.wire = opt.wire || {};
|
wsp(opt.server);
|
||||||
gun.opt({wire: {
|
}
|
||||||
transport: opt.wire.transport || gun.server.transport
|
|
||||||
}}, true);
|
|
||||||
});
|
});
|
||||||
}({}));
|
}({}));
|
@ -968,7 +968,8 @@ describe('Gun', function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('API', function(){
|
describe('API', function(){
|
||||||
var gun = Gun();
|
var gopt = {wire:{put:function(n,cb){cb()},get:function(k,cb){cb()}}};
|
||||||
|
var gun = Gun(gopt);
|
||||||
|
|
||||||
it('gun chain separation', function(done){
|
it('gun chain separation', function(done){
|
||||||
var gun = Gun();
|
var gun = Gun();
|
||||||
@ -1139,12 +1140,13 @@ describe('Gun', function(){
|
|||||||
|
|
||||||
it('put node key get', function(done){
|
it('put node key get', function(done){
|
||||||
done.keycb = false;
|
done.keycb = false;
|
||||||
gun.put({hello: "key"}).key('yes/key', function(err, ok){ // DEBUG FROM HERE!
|
gun.put({hello: "key"}).key('yes/key', function(err, ok){
|
||||||
done.keycb = true;
|
done.keycb = true;
|
||||||
expect(err).to.not.be.ok();
|
expect(err).to.not.be.ok();
|
||||||
}).get('yes/key', function(err, node){ // CHANGELOG: API 0.3 BREAKING CHANGE FROM err, graph
|
}).get('yes/key', function(err, node){ // CHANGELOG: API 0.3 BREAKING CHANGE FROM err, graph
|
||||||
expect(err).to.not.be.ok();
|
expect(err).to.not.be.ok();
|
||||||
expect(Gun.is.node.soul(node)).to.be('yes/key');
|
expect(Gun.is.node.soul(node)).to.be('yes/key');
|
||||||
|
console.log("wait what?", done.keycb);
|
||||||
expect(done.keycb).to.be.ok();
|
expect(done.keycb).to.be.ok();
|
||||||
expect(node.hello).to.be('key');
|
expect(node.hello).to.be('key');
|
||||||
if(done.c){ return }
|
if(done.c){ return }
|
||||||
@ -1282,7 +1284,7 @@ describe('Gun', function(){
|
|||||||
done();
|
done();
|
||||||
}, 500);
|
}, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get node put node merge conflict', function(done){
|
it('get node put node merge conflict', function(done){
|
||||||
gun.get('hello/key', function(err, node){
|
gun.get('hello/key', function(err, node){
|
||||||
if(done.soul){ return }
|
if(done.soul){ return }
|
||||||
@ -1441,7 +1443,7 @@ describe('Gun', function(){
|
|||||||
done(); done.c = 1;
|
done(); done.c = 1;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/* // TODO: Future feature!
|
/* // TODO: Future feature!
|
||||||
it('put gun node', function(done){
|
it('put gun node', function(done){
|
||||||
var mark = gun.put({age: 23, name: "Mark Nadal"});
|
var mark = gun.put({age: 23, name: "Mark Nadal"});
|
||||||
@ -1957,7 +1959,7 @@ describe('Gun', function(){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('map', function(done){
|
it('map', function(done){
|
||||||
var c = 0, set = gun.put({a: {here: 'you'}, b: {go: 'dear'}, c: {sir: '!'} });
|
var c = 0, set = gun.put({a: {here: 'you'}, b: {go: 'dear'}, c: {sir: '!'} });
|
||||||
set.map(function(obj, field){
|
set.map(function(obj, field){
|
||||||
@ -2082,7 +2084,7 @@ describe('Gun', function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('double not', function(done){ // from the thought tutorial
|
it('double not', function(done){ // from the thought tutorial
|
||||||
var gun = Gun().get('thoughts').not(function(key){
|
var gun = Gun(gopt).get('thoughts').not(function(key){
|
||||||
return this.put({}).key(key);
|
return this.put({}).key(key);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2095,7 +2097,7 @@ describe('Gun', function(){
|
|||||||
})
|
})
|
||||||
}, 10);
|
}, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('node path node path node path', function(done){
|
it('node path node path node path', function(done){
|
||||||
var gun = Gun();
|
var gun = Gun();
|
||||||
var data = gun.get('data');
|
var data = gun.get('data');
|
||||||
@ -2368,7 +2370,7 @@ describe('Gun', function(){
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get pseudo merge across peers', function(done){
|
it('get pseudo merge across peers', function(done){
|
||||||
Gun.on('opt').event(function(gun, o){
|
Gun.on('opt').event(function(gun, o){
|
||||||
if(connect){ return }
|
if(connect){ return }
|
||||||
@ -2564,7 +2566,7 @@ describe('Gun', function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('gun get put, sub path put, original val', function(done){ // bug from Jesse working on Trace
|
it('gun get put, sub path put, original val', function(done){ // bug from Jesse working on Trace
|
||||||
var gun = Gun().get('players');
|
var gun = Gun(gopt).get('players');
|
||||||
|
|
||||||
gun.put({
|
gun.put({
|
||||||
taken: true,
|
taken: true,
|
||||||
@ -2937,10 +2939,10 @@ describe('Gun', function(){
|
|||||||
game.put({board: {11: ' ', 22: ' ', 33: 'A'}});
|
game.put({board: {11: ' ', 22: ' ', 33: 'A'}});
|
||||||
},100);
|
},100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("get init put map -> put, foreach gun path map", function(done){ // replicate Jesse's Trace game bug
|
it("get init put map -> put, foreach gun path map", function(done){ // replicate Jesse's Trace game bug
|
||||||
done.c = 0;
|
done.c = 0;
|
||||||
gun = Gun({init: true})
|
gun = Gun(gopt).opt({init: true})
|
||||||
.get('players').init()
|
.get('players').init()
|
||||||
.put({
|
.put({
|
||||||
0: {
|
0: {
|
||||||
@ -3001,7 +3003,7 @@ describe('Gun', function(){
|
|||||||
it("gun get path empty val", function(done){ // flip flop bug
|
it("gun get path empty val", function(done){ // flip flop bug
|
||||||
done.c = 0;
|
done.c = 0;
|
||||||
var u;
|
var u;
|
||||||
var gun = Gun();
|
var gun = Gun(gopt);
|
||||||
var game = gun.get('game1/players');
|
var game = gun.get('game1/players');
|
||||||
var me = game.path('player1').val(function(val){
|
var me = game.path('player1').val(function(val){
|
||||||
if(!done.c){ done.fail = true }
|
if(!done.c){ done.fail = true }
|
||||||
@ -3021,7 +3023,7 @@ describe('Gun', function(){
|
|||||||
it("gun get path empty on", function(done){
|
it("gun get path empty on", function(done){
|
||||||
done.c = 0;
|
done.c = 0;
|
||||||
var u;
|
var u;
|
||||||
var gun = Gun();
|
var gun = Gun(gopt);
|
||||||
var game = gun.get('game2/players');
|
var game = gun.get('game2/players');
|
||||||
var me = game.path('player2').on(function(val){
|
var me = game.path('player2').on(function(val){
|
||||||
if(!done.c){ done.fail = true }
|
if(!done.c){ done.fail = true }
|
||||||
@ -3043,7 +3045,7 @@ describe('Gun', function(){
|
|||||||
|
|
||||||
it("gun get path empty not", function(done){
|
it("gun get path empty not", function(done){
|
||||||
var u;
|
var u;
|
||||||
var gun = Gun({init: true});
|
var gun = Gun(gopt).opt({init: true})
|
||||||
var game = gun.get('game3/players').init();
|
var game = gun.get('game3/players').init();
|
||||||
var me = game.path('player3').not(function(field){
|
var me = game.path('player3').not(function(field){
|
||||||
expect(field).to.be('player3');
|
expect(field).to.be('player3');
|
||||||
@ -3053,7 +3055,7 @@ describe('Gun', function(){
|
|||||||
|
|
||||||
it("gun get path empty init", function(done){
|
it("gun get path empty init", function(done){
|
||||||
var u;
|
var u;
|
||||||
var gun = Gun({init: true});
|
var gun = Gun(gopt).opt({init: true});
|
||||||
var game = gun.get('game4/players').init();
|
var game = gun.get('game4/players').init();
|
||||||
var me = game.path('player4').init().path('alias').init().put({oh: 'awesome'}).val(function(val, field){
|
var me = game.path('player4').init().path('alias').init().put({oh: 'awesome'}).val(function(val, field){
|
||||||
expect(val.oh).to.be('awesome');
|
expect(val.oh).to.be('awesome');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user