mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
IMPORTANT updates, please upgrade.
This commit is contained in:
parent
b92a91b76a
commit
d687170b90
38
gun.js
38
gun.js
@ -864,28 +864,21 @@
|
||||
}
|
||||
function root(at){
|
||||
//console.log("add to.next(at)"); // TODO: BUG!!!
|
||||
var ev = this, cat = ev.as, coat;
|
||||
var ev = this, cat = ev.as, coat, tmp;
|
||||
if(!at.gun){ at.gun = cat.gun }
|
||||
if(!at['#']){ at['#'] = Gun.text.random() } // TODO: Use what is used other places instead.
|
||||
if(cat.dup.check(at['#'])){ return }
|
||||
if(at['@']){
|
||||
// TODO: BUG! For multi-instances, the "ack" system is globally shared, but it shouldn't be.
|
||||
if(cat.ack(at['@'], at)){ return } // TODO: Consider not returning here, maybe, where this would let the "handshake" on sync occur for Holy Grail?
|
||||
cat.dup.track(at['#']);
|
||||
Gun.on('out', obj_to(at, {gun: cat.gun}));
|
||||
return;
|
||||
}
|
||||
cat.dup.track(at['#']);
|
||||
//if(cat.ack(at['@'], at)){ return }
|
||||
//cat.ack(at['@'], at);
|
||||
if(!(tmp = at['#'])){ tmp = at['#'] = Gun.text.random() } // TODO: Use what is used other places instead.
|
||||
if(cat.dup.check(tmp)){ return }
|
||||
cat.dup.track(tmp);
|
||||
coat = obj_to(at, {gun: cat.gun});
|
||||
if(at.get){
|
||||
//Gun.on.GET(coat);
|
||||
Gun.on('get', coat);
|
||||
}
|
||||
if(at.put){
|
||||
//Gun.on.PUT(coat);
|
||||
Gun.on('put', coat);
|
||||
if(!cat.ack(at['@'], at)){
|
||||
if(at.get){
|
||||
//Gun.on.GET(coat);
|
||||
Gun.on('get', coat);
|
||||
}
|
||||
if(at.put){
|
||||
//Gun.on.PUT(coat);
|
||||
Gun.on('put', coat);
|
||||
}
|
||||
}
|
||||
Gun.on('out', coat);
|
||||
}
|
||||
@ -894,7 +887,7 @@
|
||||
;(function(){
|
||||
Gun.on('put', function(at){
|
||||
//Gun.on.PUT = function(at){
|
||||
if(!at['#']){ return this.to.next(at) } // for tests.
|
||||
if(!at['#']){ return this.to.next(at) } // for tests. // TODO: REMOVE THIS!
|
||||
var ev = this, ctx = {gun: at.gun, graph: at.gun._.graph, put: {}, map: {}, machine: Gun.state()};
|
||||
if(!Gun.graph.is(at.put, null, verify, ctx)){ ctx.err = "Error: Invalid graph!" }
|
||||
if(ctx.err){ return ctx.gun.on('in', {'@': at['#'], err: Gun.log(ctx.err) }) }
|
||||
@ -917,6 +910,7 @@
|
||||
if(HAM.defer){ // pick the lowest
|
||||
ctx.defer = (state < (ctx.defer || Infinity))? state : ctx.defer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ctx.put[soul] = Gun.state.to(node, key, ctx.put[soul]);
|
||||
(ctx.diff || (ctx.diff = {}))[soul] = Gun.state.to(node, key, ctx.diff[soul]);
|
||||
@ -2016,7 +2010,7 @@
|
||||
async[soul] = async[soul] || graph[soul] || node;
|
||||
});
|
||||
count += 1;
|
||||
check[at['#']] = root;
|
||||
if(!at['@']){ check[at['#']] = root; } // only ack non-acks.
|
||||
function save(){
|
||||
clearTimeout(wait);
|
||||
var ack = check;
|
||||
|
2
gun.min.js
vendored
2
gun.min.js
vendored
File diff suppressed because one or more lines are too long
162
lib/radix.js
162
lib/radix.js
@ -1,104 +1,66 @@
|
||||
function radix(r){
|
||||
r = r || {};
|
||||
var u, n = null, c = 0;
|
||||
function get(p){
|
||||
var v = match(p, r);
|
||||
return v;
|
||||
}
|
||||
function match(path, tree, v){
|
||||
if(!Gun.obj.map(tree, function(val, key){
|
||||
if(key[0] !== path[0]){ return }
|
||||
var i = 1;
|
||||
while(key[i] === path[i] && path[i]){ i++ }
|
||||
if(key = key.slice(i)){ // recurse
|
||||
console.log("match", key, i)
|
||||
v = {sub: tree, pre: path.slice(0, i), val: val, post: key, path: path.slice(i) };
|
||||
} else { // replace
|
||||
console.log("matching", path, key, i);
|
||||
v = match(path.slice(i), val);
|
||||
var fs = require('fs');
|
||||
var Gun = require('gun');
|
||||
|
||||
function Radix(){
|
||||
var radix = {};
|
||||
var tree = radix._ = {};
|
||||
var gbm = Gun.obj.map;
|
||||
radix.add = function(key, val, t){
|
||||
t = t || tree;
|
||||
var i = 0, l = key.length-1, k = key[i], at;
|
||||
while(!(at = t[k]) && i < l){
|
||||
k += key[++i];
|
||||
}
|
||||
if(!at){
|
||||
if(!gbm(t, function(r, s){
|
||||
var ii = 0, kk = '';
|
||||
while(s[ii] == key[ii]){
|
||||
kk += s[ii++];
|
||||
}
|
||||
if(kk){
|
||||
var _ = {};
|
||||
_[s.slice(ii)] = r;
|
||||
_[key.slice(ii)] = {$: val};
|
||||
t[kk] = {_: _};
|
||||
delete t[s];
|
||||
return true;
|
||||
}
|
||||
})){
|
||||
(t[k] || (t[k] = {})).$ = val;
|
||||
}
|
||||
return true;
|
||||
})){ console.log("matched", tree, path); v = {sub: tree, path: path} } // insert
|
||||
return v;
|
||||
}
|
||||
function rebalance(ctx, val){
|
||||
console.log("rebalance", ctx, val);
|
||||
if(!ctx.post){ return ctx.sub[ctx.path] = val }
|
||||
ctx.sub[ctx.pre] = ctx.sub[ctx.pre] || (ctx.post? {} : ctx.val || {});
|
||||
ctx.sub[ctx.pre][ctx.path] = val;
|
||||
if(ctx.post){
|
||||
ctx.sub[ctx.pre][ctx.post] = ctx.val;
|
||||
delete ctx.sub[ctx.pre + ctx.post];
|
||||
} else
|
||||
if(i == l){
|
||||
at.$ = val;
|
||||
} else {
|
||||
return radix.add(key.slice(++i), val, at._);
|
||||
}
|
||||
}
|
||||
function set(p, val){
|
||||
rebalance(match(p, r), val);
|
||||
console.log('-------------------------');
|
||||
return r;
|
||||
return radix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
(function(){
|
||||
var radix = Radix();
|
||||
radix.add('user/marknadal', 'asdf');
|
||||
radix.add('user/ambercazzell', 'dafs');
|
||||
radix.add('user/taitforrest', 'sadf');
|
||||
radix.add('user/taitveronika', 'fdsa');
|
||||
radix.add('user/marknadal', 'foo');
|
||||
console.log("__________________");
|
||||
console.log(radix._);
|
||||
fs.writeFileSync('radix-data.json', JSON.stringify(radix._, null, 2));
|
||||
}());
|
||||
(function(){return;
|
||||
var radix = Radix();
|
||||
var gtr = Gun.text.random;
|
||||
var c = 0, l = 10;
|
||||
function bench(){
|
||||
if(c > 1000){ return clearInterval(it), console.log(radix._, Object.keys(radix._).length), fs.writeFileSync('radix-data.json', JSON.stringify(radix._, null, 2)); }
|
||||
for(var i = 0; i < l; i++){
|
||||
radix.add(gtr(7), c++);
|
||||
}
|
||||
//if(c % 1000 === 0){ console.log(radix._) }
|
||||
}
|
||||
return function(p, val){
|
||||
return (1 < arguments.length)? set(p, val) : get(p || '');
|
||||
}
|
||||
} // IT WORKS!!!!!!
|
||||
|
||||
var rad = radix({});
|
||||
|
||||
rad('user/marknadal', {'#': 'asdf'});
|
||||
rad('user/ambercazzell', {'#': 'dafs'});
|
||||
rad('user/taitforrest', {'#': 'sadf'});
|
||||
rad('user/taitveronika', {'#': 'fdsa'});
|
||||
rad('user/marknadal', {'#': 'foo'});
|
||||
|
||||
/*
|
||||
|
||||
function radix(r){
|
||||
var u, n = null, c = 0;
|
||||
r = r || {};
|
||||
function get(){
|
||||
|
||||
}
|
||||
function match(p, l, cb){
|
||||
cb = cb || function(){};
|
||||
console.log("LETS DO THIS", p, l);
|
||||
if(!Gun.obj.map(l, function(v, k){
|
||||
if(k[0] === p[0]){
|
||||
var i = 1;
|
||||
while(k[i] === p[i] && p[i]){ i++ }
|
||||
k = k.slice(i);
|
||||
if(k){
|
||||
cb(p.slice(0, i), v, k, l, p.slice(i));
|
||||
} else {
|
||||
match(p.slice(i), v, cb);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
})){ cb(p, l, null, l) }
|
||||
}
|
||||
function set(p, val){
|
||||
match(p, r, function(pre, data, f, rr, pp){
|
||||
if(f === null){
|
||||
rr[pre] = val;
|
||||
return;
|
||||
}
|
||||
console.log("Match?", c, pre, data, f);
|
||||
rr[pre] = r[pre] || (f? {} : data || {});
|
||||
rr[pre][pp] = val;
|
||||
if(f){
|
||||
rr[pre][f] = data;
|
||||
delete rr[pre + f];
|
||||
}
|
||||
});
|
||||
return r;
|
||||
}
|
||||
return function(p, val){
|
||||
return (1 < arguments.length)? set(p, val) : get(p || '');
|
||||
}
|
||||
} // IT WORKS!!!!!!
|
||||
|
||||
var rad = radix({});
|
||||
|
||||
rad('user/marknadal', {'#': 'asdf'});
|
||||
//rad('user/ambercazzell', {'#': 'dafs'});
|
||||
//rad('user/taitforrest', {'#': 'sadf'});
|
||||
//rad('user/taitveronika', {'#': 'fdsa'});
|
||||
*/
|
||||
var it = setInterval(bench, 1);
|
||||
}());
|
104
lib/radix_.js
Normal file
104
lib/radix_.js
Normal file
@ -0,0 +1,104 @@
|
||||
function radix(r){
|
||||
r = r || {};
|
||||
var u, n = null, c = 0;
|
||||
function get(p){
|
||||
var v = match(p, r);
|
||||
return v;
|
||||
}
|
||||
function match(path, tree, v){
|
||||
if(!Gun.obj.map(tree, function(val, key){
|
||||
if(key[0] !== path[0]){ return }
|
||||
var i = 1;
|
||||
while(key[i] === path[i] && path[i]){ i++ }
|
||||
if(key = key.slice(i)){ // recurse
|
||||
console.log("match", key, i)
|
||||
v = {sub: tree, pre: path.slice(0, i), val: val, post: key, path: path.slice(i) };
|
||||
} else { // replace
|
||||
console.log("matching", path, key, i);
|
||||
v = match(path.slice(i), val);
|
||||
}
|
||||
return true;
|
||||
})){ console.log("matched", tree, path); v = {sub: tree, path: path} } // insert
|
||||
return v;
|
||||
}
|
||||
function rebalance(ctx, val){
|
||||
console.log("rebalance", ctx, val);
|
||||
if(!ctx.post){ return ctx.sub[ctx.path] = val }
|
||||
ctx.sub[ctx.pre] = ctx.sub[ctx.pre] || (ctx.post? {} : ctx.val || {});
|
||||
ctx.sub[ctx.pre][ctx.path] = val;
|
||||
if(ctx.post){
|
||||
ctx.sub[ctx.pre][ctx.post] = ctx.val;
|
||||
delete ctx.sub[ctx.pre + ctx.post];
|
||||
}
|
||||
}
|
||||
function set(p, val){
|
||||
rebalance(match(p, r), val);
|
||||
console.log('-------------------------');
|
||||
return r;
|
||||
}
|
||||
return function(p, val){
|
||||
return (1 < arguments.length)? set(p, val) : get(p || '');
|
||||
}
|
||||
} // IT WORKS!!!!!!
|
||||
|
||||
var rad = radix({});
|
||||
|
||||
rad('user/marknadal', {'#': 'asdf'});
|
||||
rad('user/ambercazzell', {'#': 'dafs'});
|
||||
rad('user/taitforrest', {'#': 'sadf'});
|
||||
rad('user/taitveronika', {'#': 'fdsa'});
|
||||
rad('user/marknadal', {'#': 'foo'});
|
||||
|
||||
/*
|
||||
|
||||
function radix(r){
|
||||
var u, n = null, c = 0;
|
||||
r = r || {};
|
||||
function get(){
|
||||
|
||||
}
|
||||
function match(p, l, cb){
|
||||
cb = cb || function(){};
|
||||
console.log("LETS DO THIS", p, l);
|
||||
if(!Gun.obj.map(l, function(v, k){
|
||||
if(k[0] === p[0]){
|
||||
var i = 1;
|
||||
while(k[i] === p[i] && p[i]){ i++ }
|
||||
k = k.slice(i);
|
||||
if(k){
|
||||
cb(p.slice(0, i), v, k, l, p.slice(i));
|
||||
} else {
|
||||
match(p.slice(i), v, cb);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
})){ cb(p, l, null, l) }
|
||||
}
|
||||
function set(p, val){
|
||||
match(p, r, function(pre, data, f, rr, pp){
|
||||
if(f === null){
|
||||
rr[pre] = val;
|
||||
return;
|
||||
}
|
||||
console.log("Match?", c, pre, data, f);
|
||||
rr[pre] = r[pre] || (f? {} : data || {});
|
||||
rr[pre][pp] = val;
|
||||
if(f){
|
||||
rr[pre][f] = data;
|
||||
delete rr[pre + f];
|
||||
}
|
||||
});
|
||||
return r;
|
||||
}
|
||||
return function(p, val){
|
||||
return (1 < arguments.length)? set(p, val) : get(p || '');
|
||||
}
|
||||
} // IT WORKS!!!!!!
|
||||
|
||||
var rad = radix({});
|
||||
|
||||
rad('user/marknadal', {'#': 'asdf'});
|
||||
//rad('user/ambercazzell', {'#': 'dafs'});
|
||||
//rad('user/taitforrest', {'#': 'sadf'});
|
||||
//rad('user/taitveronika', {'#': 'fdsa'});
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gun",
|
||||
"version": "0.7.8",
|
||||
"version": "0.7.9",
|
||||
"description": "Graph engine",
|
||||
"main": "index.js",
|
||||
"browser": "gun.min.js",
|
||||
|
@ -15,7 +15,7 @@ Gun.on('put', function(at){ var err, id, opt, root = at.gun._.root;
|
||||
async[soul] = async[soul] || graph[soul] || node;
|
||||
});
|
||||
count += 1;
|
||||
check[at['#']] = root;
|
||||
if(!at['@']){ check[at['#']] = root; } // only ack non-acks.
|
||||
function save(){
|
||||
clearTimeout(wait);
|
||||
var ack = check;
|
||||
|
36
src/root.js
36
src/root.js
@ -50,28 +50,21 @@ Gun._ = { // some reserved key words, these are not the only ones.
|
||||
}
|
||||
function root(at){
|
||||
//console.log("add to.next(at)"); // TODO: BUG!!!
|
||||
var ev = this, cat = ev.as, coat;
|
||||
var ev = this, cat = ev.as, coat, tmp;
|
||||
if(!at.gun){ at.gun = cat.gun }
|
||||
if(!at['#']){ at['#'] = Gun.text.random() } // TODO: Use what is used other places instead.
|
||||
if(cat.dup.check(at['#'])){ return }
|
||||
if(at['@']){
|
||||
// TODO: BUG! For multi-instances, the "ack" system is globally shared, but it shouldn't be.
|
||||
if(cat.ack(at['@'], at)){ return } // TODO: Consider not returning here, maybe, where this would let the "handshake" on sync occur for Holy Grail?
|
||||
cat.dup.track(at['#']);
|
||||
Gun.on('out', obj_to(at, {gun: cat.gun}));
|
||||
return;
|
||||
}
|
||||
cat.dup.track(at['#']);
|
||||
//if(cat.ack(at['@'], at)){ return }
|
||||
//cat.ack(at['@'], at);
|
||||
if(!(tmp = at['#'])){ tmp = at['#'] = Gun.text.random() } // TODO: Use what is used other places instead.
|
||||
if(cat.dup.check(tmp)){ return }
|
||||
cat.dup.track(tmp);
|
||||
coat = obj_to(at, {gun: cat.gun});
|
||||
if(at.get){
|
||||
//Gun.on.GET(coat);
|
||||
Gun.on('get', coat);
|
||||
}
|
||||
if(at.put){
|
||||
//Gun.on.PUT(coat);
|
||||
Gun.on('put', coat);
|
||||
if(!cat.ack(at['@'], at)){
|
||||
if(at.get){
|
||||
//Gun.on.GET(coat);
|
||||
Gun.on('get', coat);
|
||||
}
|
||||
if(at.put){
|
||||
//Gun.on.PUT(coat);
|
||||
Gun.on('put', coat);
|
||||
}
|
||||
}
|
||||
Gun.on('out', coat);
|
||||
}
|
||||
@ -80,7 +73,7 @@ Gun._ = { // some reserved key words, these are not the only ones.
|
||||
;(function(){
|
||||
Gun.on('put', function(at){
|
||||
//Gun.on.PUT = function(at){
|
||||
if(!at['#']){ return this.to.next(at) } // for tests.
|
||||
if(!at['#']){ return this.to.next(at) } // for tests. // TODO: REMOVE THIS!
|
||||
var ev = this, ctx = {gun: at.gun, graph: at.gun._.graph, put: {}, map: {}, machine: Gun.state()};
|
||||
if(!Gun.graph.is(at.put, null, verify, ctx)){ ctx.err = "Error: Invalid graph!" }
|
||||
if(ctx.err){ return ctx.gun.on('in', {'@': at['#'], err: Gun.log(ctx.err) }) }
|
||||
@ -103,6 +96,7 @@ Gun._ = { // some reserved key words, these are not the only ones.
|
||||
if(HAM.defer){ // pick the lowest
|
||||
ctx.defer = (state < (ctx.defer || Infinity))? state : ctx.defer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
ctx.put[soul] = Gun.state.to(node, key, ctx.put[soul]);
|
||||
(ctx.diff || (ctx.diff = {}))[soul] = Gun.state.to(node, key, ctx.diff[soul]);
|
||||
|
275
test/panic/holy-grail.js
Normal file
275
test/panic/holy-grail.js
Normal file
@ -0,0 +1,275 @@
|
||||
var config = {
|
||||
IP: require('ip').address(),
|
||||
port: 8080,
|
||||
servers: 2,
|
||||
browsers: 2,
|
||||
route: {
|
||||
'/': __dirname + '/index.html',
|
||||
'/gun.js': __dirname + '/../../gun.js',
|
||||
'/jquery.js': __dirname + '/../../examples/jquery.js'
|
||||
}
|
||||
}
|
||||
|
||||
var panic = require('panic-server');
|
||||
panic.server().on('request', function(req, res){
|
||||
config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res);
|
||||
}).listen(config.port);
|
||||
|
||||
var clients = panic.clients;
|
||||
var manager = require('panic-manager')();
|
||||
|
||||
manager.start({
|
||||
clients: Array(config.servers).fill().map(function(u, i){
|
||||
return {
|
||||
type: 'node',
|
||||
port: config.port + (i + 1)
|
||||
}
|
||||
}),
|
||||
panic: 'http://' + config.IP + ':' + config.port
|
||||
});
|
||||
|
||||
var servers = clients.filter('Node.js');
|
||||
var server = servers.pluck(1);
|
||||
var spawn = servers.excluding(server).pluck(1);
|
||||
var browsers = clients.excluding(servers);
|
||||
var alice = browsers.pluck(1);
|
||||
var bob = browsers.excluding(alice).pluck(1);
|
||||
var again = {};
|
||||
|
||||
describe("The Holy Grail Test!", function(){
|
||||
//this.timeout(5 * 60 * 1000);
|
||||
this.timeout(10 * 60 * 1000);
|
||||
|
||||
it("Servers have joined!", function(){
|
||||
return servers.atLeast(config.servers);
|
||||
});
|
||||
|
||||
it("GUN started!", function(){
|
||||
return server.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
try{ require('fs').unlinkSync(env.i+'data') }catch(e){}
|
||||
try{ require('fs').unlinkSync((env.i+1)+'data') }catch(e){}
|
||||
var port = env.config.port + env.i;
|
||||
var server = require('http').createServer(function(req, res){
|
||||
res.end("I am "+ env.i +"!");
|
||||
});
|
||||
var Gun = require('gun');
|
||||
var gun = Gun({file: env.i+'data', web: server});
|
||||
server.listen(port, function(){
|
||||
test.done();
|
||||
});
|
||||
}, {i: 1, config: config});
|
||||
});
|
||||
|
||||
it(config.browsers +" browser(s) have joined!", function(){
|
||||
console.log("PLEASE OPEN http://"+ config.IP +":"+ config.port +" IN "+ config.browsers +" BROWSER(S)!");
|
||||
return browsers.atLeast(config.browsers);
|
||||
});
|
||||
|
||||
it("Browsers initialized gun!", function(){
|
||||
var tests = [], i = 0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
localStorage.clear();
|
||||
var env = test.props;
|
||||
var gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');
|
||||
window.ref = gun.get('holy').get('grail');
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Write initial value", function(){
|
||||
return alice.run(function(test){
|
||||
console.log("I AM ALICE");
|
||||
ref.put("value");
|
||||
setTimeout(test.async(), 2000);
|
||||
});
|
||||
});
|
||||
|
||||
it("Read initial value", function(){
|
||||
return bob.run(function(test){
|
||||
console.log("I AM BOB");
|
||||
test.async();
|
||||
ref.on(function(data){
|
||||
if("value" === data){
|
||||
return test.done();
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
it("Server has crashed and been wiped!", function(){
|
||||
return server.run(function(test){
|
||||
console.log(3);
|
||||
var env = test.props;
|
||||
try{ require('fs').unlinkSync(env.i+'data'); }catch(e){}
|
||||
process.exit(0);
|
||||
}, {i: 1, config: config})
|
||||
});
|
||||
|
||||
it("Wait...", function(done){
|
||||
console.log(4);
|
||||
setTimeout(done, 2000);
|
||||
});
|
||||
|
||||
it("Alice conflicted.", function(){
|
||||
return alice.run(function(test){
|
||||
var env = test.props;
|
||||
if(window.WebSocket){
|
||||
var err;
|
||||
try{ new WebSocket('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun') }catch(e){ err = e }
|
||||
if(!err){
|
||||
test.fail("Server did not crash.");
|
||||
}
|
||||
}
|
||||
ref.put("Alice");
|
||||
setTimeout(test.async(), 100);
|
||||
}, {config: config});
|
||||
});
|
||||
|
||||
it("Bob conflicted.", function(){
|
||||
return bob.run(function(test){
|
||||
var env = test.props;
|
||||
if(window.WebSocket){
|
||||
var err;
|
||||
try{ new WebSocket('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun') }catch(e){ err = e }
|
||||
if(!err){
|
||||
test.fail("Server did not crash.");
|
||||
}
|
||||
}
|
||||
ref.put("Bob");
|
||||
setTimeout(test.async(), 2000);
|
||||
}, {config: config});
|
||||
});
|
||||
|
||||
it("Alice reloading.", function(){
|
||||
return alice.run(function(test){
|
||||
console.log(localStorage);
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
it("Got Alice.", function(){
|
||||
again.alice = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1);
|
||||
return again.alice.atLeast(1);
|
||||
});
|
||||
|
||||
it("Wait for Bob...", function(done){
|
||||
setTimeout(done, 1000);
|
||||
});
|
||||
|
||||
it("Bob reloading.", function(){
|
||||
return bob.run(function(test){
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
it("Got Bob.", function(){
|
||||
again.bob = browsers.excluding(new panic.ClientList([alice, bob, again.alice])).pluck(1);
|
||||
return again.bob.atLeast(1);
|
||||
});
|
||||
|
||||
it("GUN spawned!", function(){
|
||||
return spawn.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
try{ require('fs').unlinkSync(env.i+'data') }catch(e){}
|
||||
var port = env.config.port + env.i;
|
||||
var server = require('http').createServer(function(req, res){
|
||||
res.end("I am "+ env.i +"!");
|
||||
});
|
||||
var Gun = require('gun');
|
||||
var gun = Gun({file: env.i+'data', web: server});
|
||||
server.listen(port, function(){
|
||||
test.done();
|
||||
});
|
||||
}, {i: 2, config: config});
|
||||
});
|
||||
|
||||
it("Browsers re-initialized gun!", function(){
|
||||
var tests = [], i = 0;
|
||||
new panic.ClientList([again.alice, again.bob]).each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
// NOTE: WE DO NOT CLEAR localStorage!
|
||||
console.log(localStorage['gun/holy']);
|
||||
var env = test.props;
|
||||
var gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun');
|
||||
window.ref = gun.get('holy').get('grail');
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Alice conflict.", function(){
|
||||
return again.alice.run(function(test){
|
||||
test.async();
|
||||
var c = 0;
|
||||
ref.on(function(data){
|
||||
console.log("======", data);
|
||||
window.stay = data;
|
||||
if(!c){
|
||||
c++;
|
||||
if("Alice" == data){
|
||||
setTimeout(function(){
|
||||
window.ALICE = true;
|
||||
test.done();
|
||||
}, 2000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Bob converged.", function(){
|
||||
return again.bob.run(function(test){
|
||||
test.async();
|
||||
var c = 0;
|
||||
ref.on(function(data){
|
||||
console.log("======", data);
|
||||
//return;
|
||||
window.stay = data;
|
||||
if("Bob" != data){
|
||||
test.fail("wrong local value!");
|
||||
return;
|
||||
}
|
||||
setTimeout(function(){
|
||||
if(c){ return }
|
||||
c++;
|
||||
if("Bob" === data){
|
||||
test.done();
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("Alice converged.", function(){
|
||||
return again.alice.run(function(test){
|
||||
//console.log(stay);return;
|
||||
if("Bob" != stay){
|
||||
test.fail("wrong local value!");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("All finished!", function(done){
|
||||
console.log("Done! Cleaning things up...");
|
||||
setTimeout(function(){
|
||||
done();
|
||||
},1000);
|
||||
});
|
||||
|
||||
after("Everything shut down.", function(){
|
||||
browsers.run(function(){
|
||||
//location.reload();
|
||||
//setTimeout(function(){
|
||||
//}, 15 * 1000);
|
||||
});
|
||||
return servers.run(function(){
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user