diff --git a/examples/package.json b/examples/package.json
index 9c2745e3b..59cbda86c 100644
--- a/examples/package.json
+++ b/examples/package.json
@@ -8,7 +8,7 @@
}
, "dependencies": {
"express": "~>4.9.0",
- "gun": "~>0.2.4"
+ "gun": "~>0.3.0"
}
, "scripts": {
"start": "node http.js",
diff --git a/examples/todo/index.html b/examples/todo/index.html
index 92dd811c2..e0a040417 100644
--- a/examples/todo/index.html
+++ b/examples/todo/index.html
@@ -22,7 +22,7 @@
ToDo List
$("#todos").innerHTML = todoHTML;
});
$("#addToDo").onsubmit = function(){
- gun.set(($("#todoItem").value||'').toString().replace(/\", key);
- (function local(key, cb){
- var path = (path = Gun.is.soul(key))? tab.prefix + tab.prenode + path
- : tab.prefix + tab.prekey + key, node = tab.store.get(path), graph, soul;
- if(Gun.is.node(node)){
- (cb.graph = cb.graph || {}
- )[soul = Gun.is.soul.on(node)] = (graph = {})[soul] = cb.node = node;
- cb(null, graph);
- (graph = {})[soul] = Gun.union.pseudo(soul); // end.
- return cb(null, graph);
- } else
- if(Gun.obj.is(node)){
- Gun.obj.map(node, function(rel){ if(Gun.is.soul(rel)){ local(rel, cb) } });
- cb(null, {});
- }
+ (function local(key, cb){return; // TODO: BUG! UNDO!
+ tab.store.get(tab.prefix + key, function(err, data){
+ if(err){ return cb(err) }
+ cb(err, Gun.is.graph.ify(data)); // node
+ cb(err, Gun.is.node.soul.ify({}, Gun.is.node.soul(data))); // end
+ cb(err, {}); // terminate
+ });
}(key, cb));
if(!(cb.local = opt.local)){
Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){ var p = {};
@@ -997,11 +996,6 @@
Gun.log("Stateless handshake sync:", e, r);
}, {peers: tab.peers(url)}); // to the peer. // TODO: This forces local to flush again, not necessary.
}
- if(!Gun.is.soul(key)){
- Gun.is.graph(reply.body || gun.__.key.s[key], function(node, soul){ // make sure for each received node or nodes of our key
- tab.key(key, soul, function(){}); // that the key points to it.
- });
- }
setTimeout(function(){ tab.put(reply.body, function(){}, {local: true}) },1); // and flush the in memory nodes of this graph to localStorage after we've had a chance to union on it.
}), opt);
cb.peers = true;
@@ -1012,9 +1006,8 @@
cb = cb || function(){};
opt = opt || {};
Gun.is.graph(graph, function(node, soul){
- if(!opt.local){ gun.__.on(soul).emit(node) } // TODO: Should this be in core?
if(!gun.__.graph[soul]){ return }
- tab.store.put(tab.prefix + tab.prenode + soul, gun.__.graph[soul]);
+ tab.store.put(tab.prefix + soul, gun.__.graph[soul]);
});
if(!(cb.local = opt.local)){
Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){
@@ -1023,23 +1016,12 @@
});
} tab.peers(cb);
}
- tab.key = tab.key || function(key, soul, cb, opt){
- var meta = {};
- opt = opt || {};
- cb = cb || function(){};
- meta[Gun._.soul] = soul = Gun.is.soul(soul) || soul;
- if(!soul){ return cb({err: Gun.log("No soul!")}) }
- (function(souls){
- (souls = tab.store.get(tab.prefix + tab.prekey + key) || {})[soul] = meta;
- tab.store.put(tab.prefix + tab.prekey + key, souls);
- }());
- if(!(cb.local = opt.local || opt.soul)){
- Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){
- tab.request(url, meta, tab.error(cb, "Error: Key failed to be made on " + url), {url: {pathname: '/' + key }, headers: tab.headers});
- cb.peers = true;
- });
- } tab.peers(cb);
- }
+ tab.com(function(msg, reply){
+
+ });
+ tab.com.to(msg, function(reply){
+
+ }, opt);
tab.error = function(cb, error, fn){
return function(err, reply){
reply.body = reply.body || reply.chunk || reply.end || reply.write;
@@ -1102,18 +1084,18 @@
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);
});
- gun.__.opt.hooks.get = gun.__.opt.hooks.get || tab.get;
- gun.__.opt.hooks.put = gun.__.opt.hooks.put || tab.put;
- gun.__.opt.hooks.key = gun.__.opt.hooks.key || tab.key;
+ gun.__.opt.wire.get = gun.__.opt.wire.get || tab.get;
+ gun.__.opt.wire.put = gun.__.opt.wire.put || tab.put;
+ gun.__.opt.wire.key = gun.__.opt.wire.key || tab.key;
});
- var store = (function(){
- function s(){}
- var store = window.localStorage || {setItem: function(){}, removeItem: function(){}, getItem: function(){}};
- s.put = function(key, val){ return store.setItem(key, Gun.text.ify(val)) }
- s.get = function(key){ return Gun.obj.ify(store.getItem(key) || null) }
- s.del = function(key){ return store.removeItem(key) }
- return s;
- }());
+
+ ;(function(exports){
+ exports.com = function(){
+
+ };
+ com.to = function(){};
+ }(Tab));
+
var request = (function(){
function r(base, body, cb, opt){
opt = opt || (base.length? {base: base} : base);
diff --git a/lib/file.js b/lib/file.js
index edec46ecd..ee17f4133 100644
--- a/lib/file.js
+++ b/lib/file.js
@@ -36,33 +36,23 @@ Gun.on('opt').event(function(gun, opts) {
});
}
- gun.opt({hooks: {
+ gun.opt({wire: {
get: function get(key, cb, o){
- var graph, soul;
- if(soul = Gun.is.soul(key)){
- if(all.nodes[soul]){
- (graph = {})[soul] = all.nodes[soul];
- cb(null, graph);
- (graph = {})[soul] = Gun.union.pseudo(soul);
- cb(null, graph); // end.
- }
- return;
- }
- Gun.obj.map(all.keys[key], function(rel){
- if(Gun.is.soul(rel)){ get(soul = rel, cb, o) }
- });
- return soul? cb(null, {}) : cb(null, null);
+ var graph, soul = key;
+ (graph = {})[soul] = all.nodes[soul];
+ console.log("FILE NODE", graph);
+ if(!graph[soul]){ return cb(null, null) }
+ cb(null, graph);
+ (graph = {})[soul] = Gun.is.node.ify({}, soul);
+ console.log("END NODE", graph);
+ cb(null, graph); // end.
+ console.log("DONE", {});
+ cb(null, {}); // done.
},
put: function(graph, cb, o){
for (key in gun.__.graph) all.nodes[key]=gun.__.graph[key];
writeFile(cb);
- },
- key: function(key, soul, cb, o){
- var meta = {};
- meta[Gun._.soul] = soul = Gun.is.soul(soul) || soul;
- ((all.keys = all.keys || {})[key] = all.keys[key] || {})[soul] = meta;
- writeFile(cb);
- },
+ }/*,
all: function(list, opt, cb) {
opt = opt || {};
opt.from = opt.from || '';
@@ -88,11 +78,11 @@ Gun.on('opt').event(function(gun, opts) {
match[key][Gun._.soul] = soul;
}
return match;
- }
+ }*/
}}, true);
gun.all = gun.all || function(url, cb) {
url = require('url').parse(url, true);
- var r = gun.__.opt.hooks.all(all.keys, {
+ var r = gun.__.opt.wire.all(all.keys, {
from: url.pathname,
upto: url.query['*'],
start: url.query['*>'],
@@ -102,8 +92,4 @@ Gun.on('opt').event(function(gun, opts) {
cb = cb || function() {};
cb(null, r);
}
-<<<<<<< HEAD
}, 100);
-=======
-});
->>>>>>> master
diff --git a/lib/wsp.js b/lib/wsp.js
index 095ac9972..f98111014 100644
--- a/lib/wsp.js
+++ b/lib/wsp.js
@@ -6,6 +6,100 @@
, url = require('url');
Gun.on('opt').event(function(gun, opt){
gun.__.opt.ws = opt.ws = gun.__.opt.ws || opt.ws || {};
+ var wsp = gun.wsp = gun.wsp || function(server){
+ 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(server.address()){
+ start(server, server.address().port);
+ return gun;
+ }
+ }
+ var listen = server.listen;
+ server.listen = function(port){
+ var serve = listen.apply(server, arguments);
+ start(serve, port);
+ return serve;
+ }
+ return gun;
+ }
+ gun.wsp.on = gun.wsp.on || Gun.on.create();
+ gun.wsp.regex = gun.wsp.regex || opt.route || opt.path || /^\/gun/i;
+ gun.wsp.poll = gun.wsp.poll || opt.poll || 1;
+ gun.wsp.pull = gun.wsp.pull || opt.pull || gun.wsp.poll * 1000;
+ gun.wsp.server = gun.wsp.server || function(req, res, next){ // http
+ 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.wsp.regex.test(msg.url.pathname)){ return next(), false } // TODO: BUG! If the option isn't a regex then this will fail!
+ if(msg.url.pathname.replace(gun.wsp.regex,'').slice(0,3).toLowerCase() === '.js'){
+ res.writeHead(200, {'Content-Type': 'text/javascript'});
+ res.end(gun.wsp.js = gun.wsp.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 stream, cb = res = require('./jsonp')(req, res);
+ if(req.headers && (stream = req.headers['gun-sid'])){
+ stream = (gun.wsp.peers = gun.wsp.peers || {})[stream] = gun.wsp.peers[stream] || {sid: stream};
+ stream.sub = stream.sub || gun.wsp.on('network').event(function(req){
+ if(!stream){ return this.off() } // self cleans up after itself!
+ if(!req || (req.headers && req.headers['gun-sid'] === stream.sid)){ return }
+ (stream.queue = stream.queue || []).push(req);
+ stream.drain(stream.reply);
+ });
+ cb = function(r){ (r.headers||{}).poll = gun.wsp.poll; res(r) }
+ stream.drain = stream.drain || function(res){
+ if(!res || !stream || !stream.queue || !stream.queue.length){ return }
+ res({headers: {'gun-sid': stream.sid}, body: stream.queue });
+ stream.off = setTimeout(function(){ stream = null }, gun.wsp.pull);
+ stream.reply = stream.queue = null;
+ return true;
+ }
+ clearTimeout(stream.off);
+ if(req.headers.pull){
+ if(stream.drain(cb)){ return }
+ return stream.reply = cb;
+ }
+ }
+ gun.wsp.EXPLODE(req, cb);
+ }), true;
+ }
+ if((gun.__.opt.maxSockets = opt.maxSockets || gun.__.opt.maxSockets) !== false){
+ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = gun.__.opt.maxSockets || Infinity;
+ }
+ if(opt.server){
+ wsp(opt.server);
+ }
+ return;
+
+
+
+
+
+
+
+ var wsp = gun.wsp = gun.wsp || {};
gun.attach = gun.attach || function(app){
if(app.use){
app.use(gun.server);
@@ -26,7 +120,7 @@
try{ws.send(Gun.text.ify(msg));
}catch(e){} // juuuust in case.
});
- gun.__.opt.hooks.transport(req, res);
+ gun.__.opt.wire.transport(req, res);
});
gun.__.opt.ws.port = port || opt.ws.port || gun.__.opt.ws.port || 80;
return server;
@@ -72,7 +166,7 @@
return tab.reply = cb;
}
}
- gun.__.opt.hooks.transport(req, cb);
+ gun.__.opt.wire.transport(req, cb);
}), true;
}
gun.server.on = gun.server.on || Gun.on.create();
@@ -107,11 +201,13 @@
return cb({headers: reply.headers, body: {time: Gun.time.is() }});
}
/* NTS END! SHOULD HAVE BEEN ITS OWN MODULE */
+ /* ALL HACK! SHOULD BE ITS OWN MODULE OR CORE? */
if(req && req.url && Gun.obj.has(req.url.query, '*')){
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 ) })
});
}
+ /* END ALL HACK! */
if(!key){
if(!Gun.obj.has(req.url.query, Gun._.soul)){
return cb({headers: reply.headers, body: {err: "No key or soul to get."}});
@@ -120,9 +216,9 @@
key[Gun._.soul] = req.url.query[Gun._.soul];
}
console.log("tran.get", key);
- gun.get(key, function(err, graph){
+ gun.__.opt.wire.get(key, function(err, graph){
//tran.sub.scribe(req.tab, graph._[Gun._.soul]);
- //console.log("tran.get", key, "<---", err, graph);
+ console.log("tran.get", key, "<---", err, graph);
if(err || !graph){
return cb({headers: reply.headers, body: (err? (err.err? err : {err: err || "Unknown error."}) : null)});
}
@@ -166,33 +262,25 @@
var reply = {headers: {'Content-Type': tran.json}};
if(!req.body){ return cb({headers: reply.headers, body: {err: "No body"}}) }
gun.server.on('network').emit(Gun.obj.copy(req));
- if(tran.put.key(req, cb)){ return }
+ //if(tran.put.key(req, cb)){ return }
// some NEW code that should get revised.
- if(Gun.is.node(req.body) || Gun.is.graph(req.body)){
- //console.log("tran.put", req.body);
+ console.log("tran.put", 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(err){ return cb({headers: reply.headers, body: {err: err || "Union failed."}}) }
var ctx = ctx || {}; ctx.graph = {};
Gun.is.graph(req.body, function(node, soul){
- ctx.graph[soul] = gun.__.graph[soul]; // TODO: BUG? Probably should be delta fields
+ ctx.graph[soul] = gun.__.graph[soul];
});
- (gun.__.opt.hooks.put || function(g,cb){cb("No save.")})(ctx.graph, function(err, ok){
- if(err){ return cb({headers: reply.headers, body: {err: err || "Failed."}}) }
+ (gun.__.opt.wire.put || function(g,cb){cb("No save.")})(ctx.graph, function(err, ok){
+ if(err){ return cb({headers: reply.headers, body: {err: err || "Failed."}}) } // TODO: err should already be an error object?
cb({headers: reply.headers, body: {ok: ok || "Persisted."}});
});
}).err){ cb({headers: reply.headers, body: {err: req.err || "Union failed."}}) }
+ } else {
+ cb({headers: reply.headers, body: {err: "Not a valid graph!"}});
}
}
- tran.put.key = function(req, cb){ // key hook!
- 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': tran.json}, body: {err: err}}) }
- cb({headers: {'Content-Type': tran.json}, body: reply}); // TODO: Fix so we know what the reply is.
- }, soul);
- return true;
- }
gun.server.on('network').event(function(req){
// TODO: MARK! You should move the networking events to here, not in WSS only.
});
@@ -200,9 +288,9 @@
return tran;
}());
- opt.hooks = opt.hooks || {};
- gun.opt({hooks: {
- transport: opt.hooks.transport || gun.server.transport
+ opt.wire = opt.wire || {};
+ gun.opt({wire: {
+ transport: opt.wire.transport || gun.server.transport
}}, true);
});
}({}));
diff --git a/package.json b/package.json
index 690477bf6..23c7e80a0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gun",
- "version": "0.2.5",
+ "version": "0.3.0",
"description": "Graph engine",
"main": "index.js",
"scripts": {