mirror of
https://github.com/amark/gun.git
synced 2025-06-05 21:56:51 +00:00
temporary push for @Dletta to update stats
This commit is contained in:
parent
d387a4f790
commit
026b278311
69
examples/docs.html
Normal file
69
examples/docs.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- always start with these two lines to set a clean baseline for different devices -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src="jquery.js"></script>
|
||||
|
||||
<title>Docs</title>
|
||||
</head>
|
||||
<body class="black whitet">
|
||||
<style>
|
||||
/*
|
||||
Choose white text on a black background so you can add color in.
|
||||
Pick your favorite font and choose a font size.
|
||||
*/
|
||||
@import url('https://fonts.googleapis.com/css?family=Oxygen');
|
||||
html, body {
|
||||
font-family: "Oxygen", sans-serif;
|
||||
}
|
||||
|
||||
[contenteditable]:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="hold full hue2">
|
||||
<div id="page" class="max focus gap" style="padding-top: 9%;">
|
||||
<p class="loud crack">Docs</p>
|
||||
<p id="p1">The contemporary tendency in our society is to base our distribution on scarcity, which has vanished, and to compress our abundance into the overfed mouths of the middle and upper classes until they gag with superfluity. If democracy is to have breadth of meaning, it is necessary to adjust this inequity. It is not only moral, but it is also intelligent. We are wasting and degrading human life by clinging to archaic thinking.</p>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../../gun/gun.js"></script>
|
||||
<script src="../../gun/lib/meta.js"></script>
|
||||
<script>
|
||||
var gun = Gun('https://guntest.herokuapp.com/gun');
|
||||
|
||||
;(window.onhashchange = function(){
|
||||
var file = (location.hash||'').slice(1);
|
||||
var S = +new Date;
|
||||
gun.get('test/gun/docs/'+file).get('what').once(function(data){
|
||||
console.log(+new Date - S, 'ms load');
|
||||
$('#p1').text(data);
|
||||
});
|
||||
})();
|
||||
|
||||
meta.edit({
|
||||
name: "Edit",
|
||||
combo: ['E'],
|
||||
on: function(eve){
|
||||
console.log("TRIGGERED!!!!");
|
||||
meta.tap.on.attr('contenteditable', 'true');
|
||||
},
|
||||
up: function(){}
|
||||
});
|
||||
meta.edit({
|
||||
name: "Save",
|
||||
combo: ['S'], fake: -1,
|
||||
on: function(eve){
|
||||
meta.tap.on.attr('contenteditable', 'false');
|
||||
var what = $('#p1').text();
|
||||
var file = (location.hash||'').slice(1);
|
||||
gun.get('test/gun/docs/'+file).put({what: what});
|
||||
},
|
||||
up: function(){}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
43
gun.js
43
gun.js
@ -811,20 +811,16 @@
|
||||
// Maybe... in case the in-memory key we have is a local write
|
||||
// we still need to trigger a pull/merge from peers.
|
||||
} else {
|
||||
//var S = +new Date;
|
||||
node = Gun.obj.copy(node);
|
||||
//console.log(+new Date - S, 'copy node');
|
||||
}
|
||||
node = Gun.graph.node(node);
|
||||
tmp = (at||empty).ack;
|
||||
//var S = +new Date;
|
||||
root.on('in', {
|
||||
'@': msg['#'],
|
||||
how: 'mem',
|
||||
put: node,
|
||||
$: gun
|
||||
});
|
||||
//console.log(+new Date - S, 'root got send');
|
||||
//if(0 < tmp){ return }
|
||||
root.on('get', msg);
|
||||
}
|
||||
@ -1317,7 +1313,6 @@
|
||||
function use(msg){
|
||||
var eve = this, as = eve.as, cat = as.at, root = cat.root, gun = msg.$, at = (gun||{})._ || {}, data = msg.put || at.put, tmp;
|
||||
if((tmp = root.now) && eve !== tmp[as.now]){ return eve.to.next(msg) }
|
||||
//console.log("USE:", cat.id, cat.soul, cat.has, cat.get, msg, root.mum);
|
||||
//if(at.async && msg.root){ return }
|
||||
//if(at.async === 1 && cat.async !== true){ return }
|
||||
//if(root.stop && root.stop[at.id]){ return } root.stop && (root.stop[at.id] = true);
|
||||
@ -1545,7 +1540,7 @@
|
||||
as = as.as;
|
||||
if(!msg.$ || !msg.$._){ return } // TODO: Handle
|
||||
if(msg.err){ // TODO: Handle
|
||||
console.log("Please report this as an issue! Put.any.err");
|
||||
Gun.log("Please report this as an issue! Put.any.err");
|
||||
return;
|
||||
}
|
||||
var at = (msg.$._), data = at.put, opt = as.opt||{}, root, tmp;
|
||||
@ -1554,7 +1549,7 @@
|
||||
if(as.ref !== as.$){
|
||||
tmp = (as.$._).get || at.get;
|
||||
if(!tmp){ // TODO: Handle
|
||||
console.log("Please report this as an issue! Put.no.get"); // TODO: BUG!??
|
||||
Gun.log("Please report this as an issue! Put.no.get"); // TODO: BUG!??
|
||||
return;
|
||||
}
|
||||
as.data = obj_put({}, tmp, as.data);
|
||||
@ -1814,7 +1809,7 @@
|
||||
var root, noop = function(){}, store, u;
|
||||
try{store = (Gun.window||noop).localStorage}catch(e){}
|
||||
if(!store){
|
||||
console.log("Warning: No localStorage exists to persist data to!");
|
||||
Gun.log("Warning: No localStorage exists to persist data to!");
|
||||
store = {setItem: function(k,v){this[k]=v}, removeItem: function(k){delete this[k]}, getItem: function(k){return this[k]}};
|
||||
}
|
||||
/*
|
||||
@ -1920,7 +1915,6 @@
|
||||
data = Gun.state.to(data, has);
|
||||
}
|
||||
//if(!data && !Gun.obj.empty(opt.peers)){ return } // if data not found, don't ack if there are peers. // Hmm, what if we have peers but we are disconnected?
|
||||
//console.log("lS get", lex, data);
|
||||
root.on('in', {'@': msg['#'], put: Gun.graph.node(data), how: 'lS', lS: msg.$});// || root.$});
|
||||
};
|
||||
Gun.debug? setTimeout(to,1) : to();
|
||||
@ -1976,15 +1970,14 @@
|
||||
if('[' === tmp){
|
||||
try{msg = JSON.parse(raw);}catch(e){opt.log('DAM JSON parse error', e)}
|
||||
if(!msg){ return }
|
||||
//console.log('hear batch length of', msg.length);
|
||||
LOG && opt.log(+new Date, msg.length, 'in hear batch');
|
||||
(function go(){
|
||||
var S = +new Date; // STATS!
|
||||
var S; LOG && (S = +new Date); // STATS!
|
||||
var m, c = 100; // hardcoded for now?
|
||||
while(c-- && (m = msg.shift())){
|
||||
mesh.hear(m, peer);
|
||||
}
|
||||
//console.log(+new Date - S, 'hear batch');
|
||||
(mesh.hear.long || (mesh.hear.long = [])).push(+new Date - S);
|
||||
LOG && opt.log(S, +new Date - S, 'batch heard');
|
||||
if(!msg.length){ return }
|
||||
puff(go, 0);
|
||||
}());
|
||||
@ -1995,7 +1988,7 @@
|
||||
}catch(e){return opt.log('DAM JSON parse error', e)}
|
||||
if(!msg){ return }
|
||||
if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) }
|
||||
if(msg.DBG_s){ console.log(+new Date - msg.DBG_s, 'to hear', id) }
|
||||
if(msg.DBG_s){ opt.log(+new Date - msg.DBG_s, 'to hear', id) }
|
||||
if(dup.check(id)){ return }
|
||||
dup.track(id, true).it = msg; // GUN core also dedups, so `true` is needed. // Does GUN core need to dedup anymore?
|
||||
if(!(hash = msg['##']) && u !== msg.put){ hash = msg['##'] = Type.obj.hash(msg.put) }
|
||||
@ -2011,9 +2004,9 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
root.on('in', msg);
|
||||
//!msg.nts && console.log(+new Date - S, 'msg', msg['#']);
|
||||
LOG && !msg.nts && opt.log(S, +new Date - S, 'msg', msg['#']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2027,7 +2020,7 @@
|
||||
if(this.to){ this.to.next(msg) } // compatible with middleware adapters.
|
||||
if(!msg){ return false }
|
||||
var id, hash, tmp, raw;
|
||||
//var S = +new Date; //msg.DBG_s = msg.DBG_s || +new Date;
|
||||
var S; LOG && (S = +new Date); //msg.DBG_s = msg.DBG_s || +new Date;
|
||||
var meta = msg._||(msg._=function(){});
|
||||
if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) }
|
||||
if(!(hash = msg['##']) && u !== msg.put){ hash = msg['##'] = Type.obj.hash(msg.put) }
|
||||
@ -2041,15 +2034,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log(+new Date - S, 'mesh say prep');
|
||||
LOG && opt.log(S, +new Date - S, 'say prep');
|
||||
dup.track(id).it = msg; // track for 9 seconds, default. Earth<->Mars would need more!
|
||||
if(!peer){ peer = (tmp = dup.s[msg['@']]) && (tmp = tmp.it) && (tmp = tmp._) && (tmp = tmp.via) }
|
||||
if(!peer && mesh.way){ return mesh.way(msg) }
|
||||
if(!peer || !peer.id){ message = msg;
|
||||
if(!Type.obj.is(peer || opt.peers)){ return false }
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
Type.obj.map(peer || opt.peers, each); // in case peer is a peer list.
|
||||
//console.log(+new Date - S, 'mesh say loop');
|
||||
LOG && opt.log(S, +new Date - S, 'say loop');
|
||||
return;
|
||||
}
|
||||
if(!peer.wire && mesh.wire){ mesh.wire(peer) }
|
||||
@ -2073,10 +2066,10 @@
|
||||
peer.batch = peer.tail = null;
|
||||
if(!tmp){ return }
|
||||
if(!tmp.length){ return } // if(3 > tmp.length){ return } // TODO: ^
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
try{tmp = (1 === tmp.length? tmp[0] : JSON.stringify(tmp));
|
||||
}catch(e){return opt.log('DAM JSON stringify error', e)}
|
||||
//console.log(+new Date - S, 'mesh flush', tmp.length);
|
||||
LOG && opt.log(S, +new Date - S, 'say stringify', tmp.length);
|
||||
if(!tmp){ return }
|
||||
send(tmp, peer);
|
||||
}
|
||||
@ -2086,14 +2079,14 @@
|
||||
// for now - find better place later.
|
||||
function send(raw, peer){ try{
|
||||
var wire = peer.wire;
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
if(peer.say){
|
||||
peer.say(raw);
|
||||
} else
|
||||
if(wire.send){
|
||||
wire.send(raw);
|
||||
}
|
||||
//console.log(+new Date - S, 'wire send', raw.length);
|
||||
LOG && opt.log(S, +new Date - S, 'wire send', raw.length);
|
||||
mesh.say.d += raw.length||0; ++mesh.say.c; // STATS!
|
||||
}catch(e){
|
||||
(peer.queue = peer.queue || []).push(raw);
|
||||
@ -2143,6 +2136,7 @@
|
||||
root.on('bye', peer);
|
||||
var tmp = +(new Date); tmp = (tmp - (peer.met||tmp));
|
||||
mesh.bye.time = ((mesh.bye.time || tmp) + tmp) / 2;
|
||||
LOG = console.LOG; // dirty place to cheaply update LOG settings over time.
|
||||
}
|
||||
mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }
|
||||
mesh.hear['?'] = function(msg, peer){
|
||||
@ -2223,6 +2217,7 @@
|
||||
}());
|
||||
|
||||
var empty = {}, ok = true, u;
|
||||
var LOG = console.LOG;
|
||||
|
||||
try{ module.exports = Mesh }catch(e){}
|
||||
|
||||
|
2
gun.min.js
vendored
2
gun.min.js
vendored
File diff suppressed because one or more lines are too long
@ -149,7 +149,7 @@
|
||||
/* UI */
|
||||
if(meta.css){ return }
|
||||
var $m = $('<div>').attr('id', 'meta');
|
||||
$m.append($('<span>').text('+').addClass('meta-start'));
|
||||
$m.append($('<span>').html('☰').addClass('meta-start'));
|
||||
$m.append($('<div>').addClass('meta-menu meta-none').append('<ul>'));
|
||||
$(document.body).append($m);
|
||||
css({
|
||||
@ -161,7 +161,7 @@
|
||||
background: 'white',
|
||||
'font-size': '18pt',
|
||||
'font-family': 'Tahoma, arial',
|
||||
'box-shadow': '0px 0px 1px #000044',
|
||||
//'box-shadow': '0px 0px 1px #000044',
|
||||
'border-radius': '1em',
|
||||
'text-align': 'center',
|
||||
'z-index': 999999,
|
||||
|
@ -19,7 +19,7 @@
|
||||
function ename(t){ return encodeURIComponent(t).replace(/\*/g, '%2A') }
|
||||
function atomic(v){ return u !== v && (!v || 'object' != typeof v) }
|
||||
var map = Gun.obj.map;
|
||||
var LOG = false;
|
||||
var LOG = console.LOG;
|
||||
|
||||
if(!opt.store){
|
||||
return opt.log("ERROR: Radisk needs `opt.store` interface with `{get: fn, put: fn (, list: fn)}`!");
|
||||
@ -46,7 +46,7 @@
|
||||
cb = val;
|
||||
var S; LOG && (S = +new Date);
|
||||
val = r.batch(key);
|
||||
LOG && console.log(+new Date - S, 'rad mem');
|
||||
LOG && opt.log(S, +new Date - S, 'rad mem');
|
||||
if(u !== val){
|
||||
cb(u, r.range(val, o), o);
|
||||
if(atomic(val)){ return }
|
||||
@ -77,6 +77,7 @@
|
||||
r.thrash = function(){
|
||||
var thrash = r.thrash;
|
||||
if(thrash.ing){ return thrash.more = true }
|
||||
LOG = console.LOG; // dirty place to cheaply update LOG settings over time.
|
||||
thrash.more = false;
|
||||
thrash.ing = true;
|
||||
var batch = thrash.at = r.batch, i = 0;
|
||||
@ -174,9 +175,9 @@
|
||||
}
|
||||
f.write = function(){
|
||||
var tmp = ename(file);
|
||||
var start; LOG && (start = +new Date); // comment this out!
|
||||
var S; LOG && (S = +new Date);
|
||||
opt.store.put(tmp, f.text, function(err){
|
||||
LOG && console.log("wrote to disk in", (+new Date) - start, tmp); // comment this out!
|
||||
LOG && opt.log(S, +new Date - S, "wrote disk", tmp);
|
||||
if(err){ return cb(err) }
|
||||
r.list.add(tmp, cb);
|
||||
});
|
||||
@ -205,10 +206,10 @@
|
||||
|
||||
r.write.jsonify = function(f, file, rad, cb, o){
|
||||
var raw;
|
||||
var start; LOG && (start = +new Date); // comment this out!
|
||||
var S; LOG && (S = +new Date);
|
||||
try{raw = JSON.stringify(rad.$);
|
||||
}catch(e){ return cb("Record too big!") }
|
||||
LOG && console.log("stringified JSON in", +new Date - start); // comment this out!
|
||||
LOG && opt.log(S, +new Date - S, "rad stringified JSON");
|
||||
if(opt.chunk < raw.length && !o.force){
|
||||
if(Radix.map(rad, f.each, true)){ return }
|
||||
}
|
||||
@ -234,7 +235,7 @@
|
||||
if(RAD && !o.next){ // cache
|
||||
var S; LOG && (S = +new Date);
|
||||
var val = RAD(key);
|
||||
LOG && console.log(+new Date - S, 'rad cached');
|
||||
LOG && opt.log(S, +new Date - S, 'rad cached');
|
||||
//if(u !== val){
|
||||
//cb(u, val, o);
|
||||
if(atomic(val)){ cb(u, val, o); return }
|
||||
@ -247,7 +248,7 @@
|
||||
file = (u === file)? u : decodeURIComponent(file);
|
||||
tmp = o.next || key || (o.reverse? o.end || '\uffff' : o.start || '');
|
||||
if(!file || (o.reverse? file < tmp : file > tmp)){
|
||||
LOG && console.log(+new Date - S, 'rad read lex'); S = +new Date;
|
||||
LOG && opt.log(S, +new Date - S, 'rad read lex'); S = +new Date;
|
||||
if(o.next || o.reverse){ g.file = file }
|
||||
if(tmp = Q[g.file]){
|
||||
tmp.push({key: key, ack: cb, file: g.file, opt: o});
|
||||
@ -268,9 +269,9 @@
|
||||
g.info = info;
|
||||
if(disk){ RAD = g.disk = disk }
|
||||
disk = Q[g.file]; delete Q[g.file];
|
||||
LOG && console.log(+new Date - S, 'rad read it in, now ack to:', disk.length); S = +new Date;
|
||||
LOG && opt.log(S, +new Date - S, 'rad read in, ack', disk.length); S = +new Date;
|
||||
map(disk, g.ack);
|
||||
LOG && console.log(+new Date - S, 'rad read acked');
|
||||
LOG && opt.log(S, +new Date - S, 'rad read acked');
|
||||
}
|
||||
g.ack = function(as){
|
||||
if(!as.ack){ return }
|
||||
@ -315,7 +316,7 @@
|
||||
var p = function Parse(){}, info = {};
|
||||
p.disk = Radix();
|
||||
p.read = function(err, data){ var tmp;
|
||||
LOG && console.log('read disk in', +new Date - S, ename(file)); // keep this commented out in
|
||||
LOG && opt.log(S, +new Date - S, 'read disk', ename(file));
|
||||
delete Q[file];
|
||||
if((p.err = err) || (p.not = !data)){
|
||||
return map(q, p.ack);
|
||||
@ -332,12 +333,12 @@
|
||||
}
|
||||
info.parsed = data.length;
|
||||
|
||||
LOG && (S = +new Date); // keep this commented out in production!
|
||||
LOG && (S = +new Date);
|
||||
if(opt.jsonify || '{' === data[0]){ // temporary testing idea
|
||||
try{
|
||||
var json = JSON.parse(data);
|
||||
p.disk.$ = json;
|
||||
LOG && console.log('parsed JSON in', +new Date - S); // keep this commented out in production!
|
||||
LOG && opt.log(S, +new Date - S, 'rad parsed JSON');
|
||||
map(q, p.ack);
|
||||
return;
|
||||
}catch(e){ tmp = e }
|
||||
@ -346,7 +347,7 @@
|
||||
return map(q, p.ack);
|
||||
}
|
||||
}
|
||||
LOG && (S = +new Date); // keep this commented out in production!
|
||||
LOG && (S = +new Date);
|
||||
var tmp = p.split(data), pre = [], i, k, v;
|
||||
if(!tmp || 0 !== tmp[1]){
|
||||
p.err = "File '"+file+"' does not have root radix! ";
|
||||
@ -369,7 +370,7 @@
|
||||
if(u !== k && u !== v){ p.disk(pre.join(''), v) }
|
||||
tmp = p.split(tmp[2]);
|
||||
}
|
||||
LOG && console.log('parsed RAD in', +new Date - S); // keep this commented out in production!
|
||||
LOG && opt.log(S, +new Date - S, 'parsed RAD');
|
||||
//cb(err, p.disk);
|
||||
map(q, p.ack);
|
||||
};
|
||||
@ -389,7 +390,7 @@
|
||||
if(p.err || p.not){ return cb(p.err, u, info) }
|
||||
cb(u, p.disk, info);
|
||||
}
|
||||
var S; LOG && (S = +new Date); // keep this commented out in production!
|
||||
var S; LOG && (S = +new Date);
|
||||
if(raw){ return p.read(null, raw) }
|
||||
opt.store.get(ename(file), p.read);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
if(u === root.opt.super){
|
||||
root.opt.super = true;
|
||||
}
|
||||
root.opt.log = root.opt.log || Gun.log;
|
||||
this.to.next(root);
|
||||
})
|
||||
require('../nts');
|
||||
|
12
lib/stats.js
12
lib/stats.js
@ -39,6 +39,7 @@ Gun.on('opt', function(root){
|
||||
stats.peers.count = Object.keys(root.opt.peers||{}).length;
|
||||
stats.node = {};
|
||||
stats.node.count = Object.keys(root.graph||{}).length;
|
||||
stats.all = all;
|
||||
var dam = root.opt.mesh;
|
||||
if(dam){
|
||||
stats.dam = {'in': {count: dam.hear.c, done: dam.hear.d, long: dam.hear.long}, 'out': {count: dam.say.c, done: dam.say.d}};
|
||||
@ -57,3 +58,14 @@ Gun.on('opt', function(root){
|
||||
}, 1000 * 15);
|
||||
Object.keys = Object.keys || function(o){ return Gun.obj.map(o, function(v,k,t){t(k)}) }
|
||||
});
|
||||
|
||||
|
||||
var log = Gun.log, all = {}, max = 1000;
|
||||
Gun.log = function(a,b,c,d){
|
||||
if('number' == typeof a && 'number' == typeof b && 'string' == typeof c){
|
||||
var tmp = (all[c] || (all[c] = []));
|
||||
if(max < tmp.push([a,b])){ all[c] = [] } // reset
|
||||
return;
|
||||
}
|
||||
return log.apply(Gun, arguments);
|
||||
}
|
13
lib/store.js
13
lib/store.js
@ -30,12 +30,12 @@ Gun.on('create', function(root){
|
||||
val = Radisk.encode(val, null, esc)+'>'+Radisk.encode(Gun.state.is(node, key), null, esc);
|
||||
rad(soul+esc+key, val, (track? ack : u));
|
||||
});
|
||||
//console.log(+new Date - S, 'put loop');
|
||||
Gun.log(S, +new Date - S, 'put loop');
|
||||
function ack(err, ok){
|
||||
acks--;
|
||||
if(ack.err){ return }
|
||||
if(ack.err = err){
|
||||
try{opt.store.stats.put.err = err}catch(e){} // STATS!
|
||||
//Gun.log(); //try{opt.store.stats.put.err = err}catch(e){} // STATS!
|
||||
root.on('in', {'@': id, err: err});
|
||||
return;
|
||||
}
|
||||
@ -45,7 +45,7 @@ Gun.on('create', function(root){
|
||||
}catch(e){} // STATS!
|
||||
//console.log(+new Date - S, 'put'); S = +new Date;
|
||||
root.on('in', {'@': id, ok: 1});
|
||||
//console.log(+new Date - S, 'put sent');
|
||||
//console.log(S, +new Date - S, 'put sent');
|
||||
}
|
||||
});
|
||||
|
||||
@ -89,7 +89,7 @@ Gun.on('create', function(root){
|
||||
if(err){ opt.store.stats.get.err = err }
|
||||
}catch(e){} // STATS!
|
||||
//if(u === data && o.chunks > 1){ return } // if we already sent a chunk, ignore ending empty responses. // this causes tests to fail.
|
||||
//console.log(+new Date - S, 'got'); S = +new Date;
|
||||
Gun.log(S, +new Date - S, 'got'); S = +new Date; // MARK RETURN HERE!!!! Gun.log will always log unless off :/ switch to something like LOG && whatever?
|
||||
if(data){
|
||||
if(typeof data !== 'string'){
|
||||
if(o.atom){
|
||||
@ -100,11 +100,10 @@ Gun.on('create', function(root){
|
||||
}
|
||||
if(!graph && data){ each(data, '') }
|
||||
}
|
||||
//console.log(+new Date - S, 'got prep'); S = +new Date;
|
||||
Gun.log(S, +new Date - S, 'got prep');
|
||||
root.on('in', {'@': id, put: graph, '%': o.more? 1 : u, err: err? err : u, _: each});
|
||||
//console.log(+new Date - S, 'got sent');
|
||||
}, o);
|
||||
//console.log(+new Date - S, 'get call');
|
||||
Gun.log(S, +new Date - S, 'get call');
|
||||
function each(val, has, a,b){
|
||||
if(!val){ return }
|
||||
has = (key+has).split(esc);
|
||||
|
@ -4,7 +4,7 @@ if(typeof Gun === 'undefined'){ return } // TODO: localStorage is Browser only.
|
||||
var root, noop = function(){}, store, u;
|
||||
try{store = (Gun.window||noop).localStorage}catch(e){}
|
||||
if(!store){
|
||||
console.log("Warning: No localStorage exists to persist data to!");
|
||||
Gun.log("Warning: No localStorage exists to persist data to!");
|
||||
store = {setItem: function(k,v){this[k]=v}, removeItem: function(k){delete this[k]}, getItem: function(k){return this[k]}};
|
||||
}
|
||||
/*
|
||||
@ -110,7 +110,6 @@ Gun.on('create', function(root){
|
||||
data = Gun.state.to(data, has);
|
||||
}
|
||||
//if(!data && !Gun.obj.empty(opt.peers)){ return } // if data not found, don't ack if there are peers. // Hmm, what if we have peers but we are disconnected?
|
||||
//console.log("lS get", lex, data);
|
||||
root.on('in', {'@': msg['#'], put: Gun.graph.node(data), how: 'lS', lS: msg.$});// || root.$});
|
||||
};
|
||||
Gun.debug? setTimeout(to,1) : to();
|
||||
|
@ -19,15 +19,14 @@ function Mesh(root){
|
||||
if('[' === tmp){
|
||||
try{msg = JSON.parse(raw);}catch(e){opt.log('DAM JSON parse error', e)}
|
||||
if(!msg){ return }
|
||||
//console.log('hear batch length of', msg.length);
|
||||
LOG && opt.log(msg.length, 'in hear batch');
|
||||
(function go(){
|
||||
var S = +new Date; // STATS!
|
||||
var S; LOG && (S = +new Date); // STATS!
|
||||
var m, c = 100; // hardcoded for now?
|
||||
while(c-- && (m = msg.shift())){
|
||||
mesh.hear(m, peer);
|
||||
}
|
||||
//console.log(+new Date - S, 'hear batch');
|
||||
(mesh.hear.long || (mesh.hear.long = [])).push(+new Date - S);
|
||||
LOG && opt.log(+new Date - S, 'batch heard');
|
||||
if(!msg.length){ return }
|
||||
puff(go, 0);
|
||||
}());
|
||||
@ -38,7 +37,7 @@ function Mesh(root){
|
||||
}catch(e){return opt.log('DAM JSON parse error', e)}
|
||||
if(!msg){ return }
|
||||
if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) }
|
||||
if(msg.DBG_s){ console.log(+new Date - msg.DBG_s, 'to hear', id) }
|
||||
if(msg.DBG_s){ opt.log(+new Date - msg.DBG_s, 'to hear', id) }
|
||||
if(dup.check(id)){ return }
|
||||
dup.track(id, true).it = msg; // GUN core also dedups, so `true` is needed. // Does GUN core need to dedup anymore?
|
||||
if(!(hash = msg['##']) && u !== msg.put){ hash = msg['##'] = Type.obj.hash(msg.put) }
|
||||
@ -54,9 +53,9 @@ function Mesh(root){
|
||||
}
|
||||
return;
|
||||
}
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
root.on('in', msg);
|
||||
//!msg.nts && console.log(+new Date - S, 'msg', msg['#']);
|
||||
LOG && !msg.nts && opt.log(+new Date - S, 'msg', msg['#']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -70,7 +69,7 @@ function Mesh(root){
|
||||
if(this.to){ this.to.next(msg) } // compatible with middleware adapters.
|
||||
if(!msg){ return false }
|
||||
var id, hash, tmp, raw;
|
||||
//var S = +new Date; //msg.DBG_s = msg.DBG_s || +new Date;
|
||||
var S; LOG && (S = +new Date); //msg.DBG_s = msg.DBG_s || +new Date;
|
||||
var meta = msg._||(msg._=function(){});
|
||||
if(!(id = msg['#'])){ id = msg['#'] = Type.text.random(9) }
|
||||
if(!(hash = msg['##']) && u !== msg.put){ hash = msg['##'] = Type.obj.hash(msg.put) }
|
||||
@ -84,15 +83,15 @@ function Mesh(root){
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log(+new Date - S, 'mesh say prep');
|
||||
LOG && opt.log(+new Date - S, 'say prep');
|
||||
dup.track(id).it = msg; // track for 9 seconds, default. Earth<->Mars would need more!
|
||||
if(!peer){ peer = (tmp = dup.s[msg['@']]) && (tmp = tmp.it) && (tmp = tmp._) && (tmp = tmp.via) }
|
||||
if(!peer && mesh.way){ return mesh.way(msg) }
|
||||
if(!peer || !peer.id){ message = msg;
|
||||
if(!Type.obj.is(peer || opt.peers)){ return false }
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
Type.obj.map(peer || opt.peers, each); // in case peer is a peer list.
|
||||
//console.log(+new Date - S, 'mesh say loop');
|
||||
LOG && opt.log(+new Date - S, 'say loop');
|
||||
return;
|
||||
}
|
||||
if(!peer.wire && mesh.wire){ mesh.wire(peer) }
|
||||
@ -116,10 +115,10 @@ function Mesh(root){
|
||||
peer.batch = peer.tail = null;
|
||||
if(!tmp){ return }
|
||||
if(!tmp.length){ return } // if(3 > tmp.length){ return } // TODO: ^
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
try{tmp = (1 === tmp.length? tmp[0] : JSON.stringify(tmp));
|
||||
}catch(e){return opt.log('DAM JSON stringify error', e)}
|
||||
//console.log(+new Date - S, 'mesh flush', tmp.length);
|
||||
LOG && opt.log(+new Date - S, 'say stringify', tmp.length);
|
||||
if(!tmp){ return }
|
||||
send(tmp, peer);
|
||||
}
|
||||
@ -129,14 +128,14 @@ function Mesh(root){
|
||||
// for now - find better place later.
|
||||
function send(raw, peer){ try{
|
||||
var wire = peer.wire;
|
||||
//var S = +new Date;
|
||||
var S; LOG && (S = +new Date);
|
||||
if(peer.say){
|
||||
peer.say(raw);
|
||||
} else
|
||||
if(wire.send){
|
||||
wire.send(raw);
|
||||
}
|
||||
//console.log(+new Date - S, 'wire send', raw.length);
|
||||
LOG && opt.log(+new Date - S, 'wire send', raw.length);
|
||||
mesh.say.d += raw.length||0; ++mesh.say.c; // STATS!
|
||||
}catch(e){
|
||||
(peer.queue = peer.queue || []).push(raw);
|
||||
@ -186,6 +185,7 @@ function Mesh(root){
|
||||
root.on('bye', peer);
|
||||
var tmp = +(new Date); tmp = (tmp - (peer.met||tmp));
|
||||
mesh.bye.time = ((mesh.bye.time || tmp) + tmp) / 2;
|
||||
LOG = console.LOG; // dirty place to cheaply update LOG settings over time.
|
||||
}
|
||||
mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }
|
||||
mesh.hear['?'] = function(msg, peer){
|
||||
@ -266,6 +266,7 @@ function Mesh(root){
|
||||
}());
|
||||
|
||||
var empty = {}, ok = true, u;
|
||||
var LOG = console.LOG;
|
||||
|
||||
try{ module.exports = Mesh }catch(e){}
|
||||
|
||||
|
@ -89,7 +89,6 @@ function soul(gun, cb, opt, as){
|
||||
function use(msg){
|
||||
var eve = this, as = eve.as, cat = as.at, root = cat.root, gun = msg.$, at = (gun||{})._ || {}, data = msg.put || at.put, tmp;
|
||||
if((tmp = root.now) && eve !== tmp[as.now]){ return eve.to.next(msg) }
|
||||
//console.log("USE:", cat.id, cat.soul, cat.has, cat.get, msg, root.mum);
|
||||
//if(at.async && msg.root){ return }
|
||||
//if(at.async === 1 && cat.async !== true){ return }
|
||||
//if(root.stop && root.stop[at.id]){ return } root.stop && (root.stop[at.id] = true);
|
||||
|
@ -177,7 +177,7 @@ function any(soul, as, msg, eve){
|
||||
as = as.as;
|
||||
if(!msg.$ || !msg.$._){ return } // TODO: Handle
|
||||
if(msg.err){ // TODO: Handle
|
||||
console.log("Please report this as an issue! Put.any.err");
|
||||
Gun.log("Please report this as an issue! Put.any.err");
|
||||
return;
|
||||
}
|
||||
var at = (msg.$._), data = at.put, opt = as.opt||{}, root, tmp;
|
||||
@ -186,7 +186,7 @@ function any(soul, as, msg, eve){
|
||||
if(as.ref !== as.$){
|
||||
tmp = (as.$._).get || at.get;
|
||||
if(!tmp){ // TODO: Handle
|
||||
console.log("Please report this as an issue! Put.no.get"); // TODO: BUG!??
|
||||
Gun.log("Please report this as an issue! Put.no.get"); // TODO: BUG!??
|
||||
return;
|
||||
}
|
||||
as.data = obj_put({}, tmp, as.data);
|
||||
|
@ -162,20 +162,16 @@ Gun.dup = require('./dup');
|
||||
// Maybe... in case the in-memory key we have is a local write
|
||||
// we still need to trigger a pull/merge from peers.
|
||||
} else {
|
||||
//var S = +new Date;
|
||||
node = Gun.obj.copy(node);
|
||||
//console.log(+new Date - S, 'copy node');
|
||||
}
|
||||
node = Gun.graph.node(node);
|
||||
tmp = (at||empty).ack;
|
||||
//var S = +new Date;
|
||||
root.on('in', {
|
||||
'@': msg['#'],
|
||||
how: 'mem',
|
||||
put: node,
|
||||
$: gun
|
||||
});
|
||||
//console.log(+new Date - S, 'root got send');
|
||||
//if(0 < tmp){ return }
|
||||
root.on('get', msg);
|
||||
}
|
||||
|
171
test/panic/livestream.js
Normal file
171
test/panic/livestream.js
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
This is the first in a series of basic networking correctness tests.
|
||||
Each test itself might be dumb and simple, but built up together,
|
||||
they prove desired end goals for behavior at scale.
|
||||
1. (this file) Is a browser write is confirmed as save by multiple peers even if by daisy chain.
|
||||
2.
|
||||
*/
|
||||
|
||||
var config = {
|
||||
IP: require('ip').address(),
|
||||
port: 8765,
|
||||
servers: 1,
|
||||
browsers: 2,
|
||||
route: {
|
||||
'/': __dirname + '/index.html',
|
||||
'/gun.js': __dirname + '/../../gun.js',
|
||||
'/jquery.js': __dirname + '/../../examples/jquery.js',
|
||||
'/livestream.html': __dirname + '/livestream.html',
|
||||
}
|
||||
}
|
||||
|
||||
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 bob = servers.pluck(1);
|
||||
var browsers = clients.excluding(servers);
|
||||
var alice = browsers.pluck(1);
|
||||
var others = clients.excluding(alice);
|
||||
|
||||
describe("Broadcast Video", 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(){
|
||||
var tests = [], i = 0;
|
||||
servers.each(function(client){
|
||||
tests.push(client.run(function(test){
|
||||
var env = test.props;
|
||||
test.async();
|
||||
try{ require('fs').unlinkSync(env.i+'data') }catch(e){}
|
||||
try{ require('gun/lib/fsrm')(env.i+'data') }catch(e){}
|
||||
var server = require('http').createServer(function(req, res){
|
||||
res.end("I am "+ env.i +"!");
|
||||
});
|
||||
var port = env.config.port + env.i;
|
||||
var Gun = require('gun');
|
||||
var peers = [], i = env.config.servers;
|
||||
while(i--){
|
||||
var tmp = (env.config.port + (i + 1));
|
||||
if(port != tmp){ // ignore ourselves
|
||||
peers.push('http://'+ env.config.IP + ':' + tmp + '/gun');
|
||||
}
|
||||
}
|
||||
console.log(port, " connect to ", peers);
|
||||
var gun = Gun({file: env.i+'data', peers: peers, web: server});
|
||||
server.listen(port, function(){
|
||||
test.done();
|
||||
});
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
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 load QVDev's streaming!", function(){
|
||||
var tests = [], i = 0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
test.async();
|
||||
console.log("load?");
|
||||
function load(src, cb){
|
||||
var script = document.createElement('script');
|
||||
script.onload = cb; script.src = src;
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
load('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/GunRecorder.js', function(){
|
||||
load('https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/GunStreamer.js', function(){
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
$('body').append('<video id="video" width="100%" autoplay></video>');
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Browsers initialized gun!", function(){
|
||||
var tests = [], i = 0;
|
||||
browsers.each(function(client, id){
|
||||
tests.push(client.run(function(test){
|
||||
try{ localStorage.clear() }catch(e){}
|
||||
try{ indexedDB.deleteDatabase('radata') }catch(e){}
|
||||
var env = test.props;
|
||||
var gun = Gun('http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun');
|
||||
window.gun = gun;
|
||||
}, {i: i += 1, config: config}));
|
||||
});
|
||||
return Promise.all(tests);
|
||||
});
|
||||
|
||||
it("Stream", function(){
|
||||
return alice.run(function(test){
|
||||
console.log("I AM ALICE");
|
||||
test.async();
|
||||
var stream = window.stream = new GunStreamer({
|
||||
url: "https://cdn.jsdelivr.net/gh/QVDev/GunStreamer/js/parser_worker.js",
|
||||
gun: gun,
|
||||
streamId: 'livestream',
|
||||
dbRecord: 'streams'
|
||||
});
|
||||
var record = window.record = new GunRecorder({
|
||||
mimeType: 'video/webm; codecs="opus,vp8"',
|
||||
//audioBitsPerSecond: 6000,//Audio bits per second this is the lowest quality
|
||||
//videoBitsPerSecond: 100000,//Video bits per second this is the lowest quality
|
||||
cameraOptions: {video:{width: 1280, height: 720, facingMode: "environment", frameRate: 60}, audio: true},
|
||||
video_id: "video",
|
||||
recordInterval: 1000, // how long each chunk?
|
||||
onRecordStateChange: function(state){ /* change play/pause buttons */ },
|
||||
onDataAvailable: function(data){ console.log('r -> s', data); stream.onDataAvailable(data) } // pass recorded data to streamer
|
||||
});
|
||||
record.startCamera();
|
||||
$('#video').on('playing', function(eve){
|
||||
console.log("YES!!!");
|
||||
record.record();
|
||||
});
|
||||
console.log("start recording!");
|
||||
}, {acks: config.servers});
|
||||
});
|
||||
|
||||
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