From b99202f0ec7e4d25eb12e2c2fb9802cad47376e2 Mon Sep 17 00:00:00 2001 From: Adriano Rogowski Date: Sat, 20 Apr 2019 21:28:04 -0300 Subject: [PATCH 01/18] AXE - change necessary to work webrtc. --- gun.js | 3 ++- src/adapters/mesh.js | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/gun.js b/gun.js index a9439655..cfb73384 100644 --- a/gun.js +++ b/gun.js @@ -2062,7 +2062,8 @@ peer.say(raw); } else if(wire.send){ - if(wire.readyState && 1 != wire.readyState){ throw "socket not ready yet!" } + if(wire.readyState && 1 != wire.readyState && wire instanceof opt.WebSocket){ throw "socket not ready yet!" } + // if(wire.readyState && 'open' != wire.readyState && wire instanceof RTCDataChannel){ throw "rtc not ready yet!" } wire.send(raw); } }catch(e){ diff --git a/src/adapters/mesh.js b/src/adapters/mesh.js index 0f984bf0..cfe32e87 100644 --- a/src/adapters/mesh.js +++ b/src/adapters/mesh.js @@ -20,7 +20,7 @@ function Mesh(ctx){ return; } // add hook for AXE? - if (Gun.AXE && opt && opt.super) { Gun.AXE.say(msg, mesh.say, this); return; } // rogowski + if (Gun.AXE) { Gun.AXE.say(msg, mesh.say, this); return; } mesh.say(msg); } @@ -125,7 +125,8 @@ function Mesh(ctx){ peer.say(raw); } else if(wire.send){ - if(wire.readyState && 1 != wire.readyState){ throw "socket not ready yet!" } + if(wire.readyState && 1 != wire.readyState && wire instanceof opt.WebSocket){ throw "socket not ready yet!" } + // if(wire.readyState && 'open' != wire.readyState && wire instanceof RTCDataChannel){ throw "rtc not ready yet!" } wire.send(raw); } }catch(e){ @@ -193,26 +194,30 @@ function Mesh(ctx){ tmp = tmp.id = tmp.id || Type.text.random(9); mesh.say({dam: '?'}, opt.peers[tmp] = peer); } - if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) } - tmp = peer.queue; peer.queue = []; - Type.obj.map(tmp, function(msg){ - mesh.say(msg, peer); - }); + if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer); } + // tmp = peer.queue; peer.queue = []; + // Type.obj.map(tmp, function(msg){ + // mesh.say(msg, peer); + // }); } mesh.bye = function(peer){ Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect ctx.on('bye', peer); } - mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) } mesh.hear['?'] = function(msg, peer){ if(!msg.pid){ - return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); + //return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); + mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); + var tmp = peer.queue; peer.queue = []; + Type.obj.map(tmp, function(msg){ + mesh.say(msg, peer); + }); + return; } peer.id = peer.id || msg.pid; mesh.hi(peer); } - return mesh; } @@ -231,6 +236,4 @@ Mesh.hash = function(s){ // via SO var empty = {}, u; Object.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) } - try{ module.exports = Mesh }catch(e){} - - + try{ module.exports = Mesh }catch(e){} \ No newline at end of file From f7d9089ba74ed3dbf3496dbb45ee1b01cbcdda23 Mon Sep 17 00:00:00 2001 From: Yusuke Sano Date: Sun, 21 Apr 2019 17:45:39 +0900 Subject: [PATCH 02/18] bye.js fix (support new mesh) I am using gundb 0.8.1 0.2019.331 and noticed not working bye method when programming web application on this version. Maybe this is happened because bye() access to outdated mesh structure. --- lib/bye.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/bye.js b/lib/bye.js index 776e6d4f..a7fa5c0d 100644 --- a/lib/bye.js +++ b/lib/bye.js @@ -5,8 +5,8 @@ Gun.on('opt', function(root){ if(root.once){ return } root.on('in', function(msg){ //Msg did not have a peer property saved before, so nothing ever went further - if(!msg.mesh || !msg.BYE){ return this.to.next(msg) } - var peer = msg.mesh.via; + if(!msg._ || !msg.BYE){ return this.to.next(msg) } + var peer = msg._.via; (peer.bye = peer.bye || []).push(msg.BYE); }) root.on('bye', function(peer){ From 4085a4053cdfb57d059fc7ba5e4a47881c2fcf21 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Mon, 22 Apr 2019 17:44:38 -0700 Subject: [PATCH 03/18] Reverse RAD! --- lib/radisk.js | 15 ++++++++------- lib/radix.js | 1 + lib/rindexed.js | 3 +++ lib/store.js | 1 + package.json | 2 +- src/adapters/mesh.js | 25 +++++++++++++++---------- src/map.js | 2 +- src/type.js | 36 +++++++++++++++--------------------- test/rad/rad.js | 34 ++++++++++++++++++++++++++++++++++ 9 files changed, 79 insertions(+), 40 deletions(-) diff --git a/lib/radisk.js b/lib/radisk.js index 47c0984c..376b07ea 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -236,10 +236,11 @@ // if a node is requested and some of it is cached... the other parts might not be. //} } - var g = function Get(){}, tmp; - g.lex = function(file){ + var g = function Get(){}; + g.lex = function(file){ var tmp; file = (u === file)? u : decodeURIComponent(file); - if(!file || file > (o.next || key || o.start || o.end || '')){ + tmp = o.next || key || (o.reverse? o.end || '\uffff' : o.start || ''); + if(!file || (o.reverse? file < tmp : file > tmp)){ if(o.next){ g.file = file } if(tmp = Q[g.file]){ tmp.push({key: key, ack: cb, file: g.file, opt: o}); @@ -272,6 +273,7 @@ o.next = as.file; r.read(tmp, as.ack, o); } + if(o.reverse){ g.lex.reverse = true } r.list(g.lex); } }()); @@ -373,9 +375,10 @@ var dir, q, f = String.fromCharCode(28), ef = ename(f); r.list = function(cb){ if(dir){ + var tmp = {reverse: (cb.reverse)? 1 : 0}; Radix.map(dir, function(val, key){ return cb(key); - }) || cb(); + }, tmp) || cb(); return; } if(q){ return q.push(cb) } q = [cb]; @@ -420,9 +423,7 @@ r.list.dir = dir = rad; tmp = q; q = null; Gun.list.map(tmp, function(cb){ - Radix.map(dir, function(val, key){ - return cb(key); - }) || cb(); + r.list(cb); }); } }()); diff --git a/lib/radix.js b/lib/radix.js index b9d4c4c7..2eb7b311 100644 --- a/lib/radix.js +++ b/lib/radix.js @@ -57,6 +57,7 @@ var keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort; //var keys = Object.keys(t).sort(); opt = (true === opt)? {branch: true} : (opt || {}); + if(opt.reverse){ keys = keys.slice().reverse() } var start = opt.start, end = opt.end; var i = 0, l = keys.length; for(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt; diff --git a/lib/rindexed.js b/lib/rindexed.js index 005e2977..fcccd9a1 100644 --- a/lib/rindexed.js +++ b/lib/rindexed.js @@ -16,6 +16,9 @@ }}catch(e){} var store = function Store(){}; + if(Store[opt.file]){ return Store[opt.file] } + Store[opt.file] = store; + store.start = function(){ var o = indexedDB.open(opt.file, 1); o.onupgradeneeded = function(eve){ (eve.target.result).createObjectStore(opt.file) } diff --git a/lib/store.js b/lib/store.js index 4613cc26..471867bf 100644 --- a/lib/store.js +++ b/lib/store.js @@ -61,6 +61,7 @@ Gun.on('create', function(root){ if((tmp = get['%']) || opt.limit){ opt.limit = (tmp <= (opt.pack || (1000 * 100)))? tmp : 1; } + if(has['-'] || (soul||{})['-']){ opt.reverse = true } //console.log("RAD get:", key, opt); //var start = (+new Date); // console.log("GET!", id, JSON.stringify(key)); rad(key||'', function(err, data, o){ diff --git a/package.json b/package.json index ef840765..3aa3fbbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.416", + "version": "0.2019.422", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", diff --git a/src/adapters/mesh.js b/src/adapters/mesh.js index 0f984bf0..df4f2dcc 100644 --- a/src/adapters/mesh.js +++ b/src/adapters/mesh.js @@ -1,3 +1,4 @@ + var Gun = require('../index'); var Type = require('../type'); @@ -20,7 +21,7 @@ function Mesh(ctx){ return; } // add hook for AXE? - if (Gun.AXE && opt && opt.super) { Gun.AXE.say(msg, mesh.say, this); return; } // rogowski + if (Gun.AXE) { Gun.AXE.say(msg, mesh.say, this); return; } mesh.say(msg); } @@ -193,26 +194,30 @@ function Mesh(ctx){ tmp = tmp.id = tmp.id || Type.text.random(9); mesh.say({dam: '?'}, opt.peers[tmp] = peer); } - if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) } - tmp = peer.queue; peer.queue = []; - Type.obj.map(tmp, function(msg){ - mesh.say(msg, peer); - }); + if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer); } + // tmp = peer.queue; peer.queue = []; + // Type.obj.map(tmp, function(msg){ + // mesh.say(msg, peer); + // }); } mesh.bye = function(peer){ Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect ctx.on('bye', peer); } - mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) } mesh.hear['?'] = function(msg, peer){ if(!msg.pid){ - return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); +// return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); + mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); + var tmp = peer.queue; peer.queue = []; + Type.obj.map(tmp, function(msg){ + mesh.say(msg, peer); + }); + return; } peer.id = peer.id || msg.pid; mesh.hi(peer); } - return mesh; } @@ -233,4 +238,4 @@ Mesh.hash = function(s){ // via SO try{ module.exports = Mesh }catch(e){} - + \ No newline at end of file diff --git a/src/map.js b/src/map.js index cb60a711..4ffada80 100644 --- a/src/map.js +++ b/src/map.js @@ -29,7 +29,7 @@ function map(msg){ function each(v,k){ if(n_ === k){ return } var msg = this.msg, gun = msg.$, at = gun._, cat = this.at, tmp = at.lex; - if(tmp && !Gun.text.match(k, tmp['.'] || tmp['#'] || tmp)){ return } // TODO: Ugly hack! + if(tmp && !Gun.text.match(k, tmp['.'] || tmp['#'] || tmp)){ return } // review? ((tmp = gun.get(k)._).echo || (tmp.echo = {}))[cat.id] = tmp.echo[cat.id] || cat; } var obj_map = Gun.obj.map, noop = function(){}, event = {stun: noop, off: noop}, n_ = Gun.node._, u; diff --git a/src/type.js b/src/type.js index bab8fd65..82be63d4 100644 --- a/src/type.js +++ b/src/type.js @@ -18,28 +18,22 @@ Type.text.random = function(l, c){ while(l > 0){ s += c.charAt(Math.floor(Math.random() * c.length)); l-- } return s; } -Type.text.match = function(t, o){ var r = false; - t = t || ''; - o = Type.text.is(o)? {'=': o} : o || {}; // {'~', '=', '*', '<', '>', '+', '-', '?', '!'} // ignore case, exactly equal, anything after, lexically larger, lexically lesser, added in, subtacted from, questionable fuzzy match, and ends with. - if(Type.obj.has(o,'~')){ t = t.toLowerCase(); o['='] = (o['='] || o['~']).toLowerCase() } - if(Type.obj.has(o,'=')){ return t === o['='] } - if(Type.obj.has(o,'*')){ if(t.slice(0, o['*'].length) === o['*']){ r = true; t = t.slice(o['*'].length) } else { return false }} - if(Type.obj.has(o,'!')){ if(t.slice(-o['!'].length) === o['!']){ r = true } else { return false }} - if(Type.obj.has(o,'+')){ - if(Type.list.map(Type.list.is(o['+'])? o['+'] : [o['+']], function(m){ - if(t.indexOf(m) >= 0){ r = true } else { return true } - })){ return false } +Type.text.match = function(t, o){ var tmp, u; + if('string' !== typeof t){ return false } + if('string' == typeof o){ o = {'=': o} } + o = o || {}; + tmp = (o['='] || o['*'] || o['>'] || o['<']); + if(t === tmp){ return true } + if(u !== o['=']){ return false } + tmp = (o['*'] || o['>'] || o['<']); + if(t.slice(0, (tmp||'').length) === tmp){ return true } + if(u !== o['*']){ return false } + if(u !== o['>'] && u !== o['<']){ + return (t > o['>'] && t < o['<'])? true : false; } - if(Type.obj.has(o,'-')){ - if(Type.list.map(Type.list.is(o['-'])? o['-'] : [o['-']], function(m){ - if(t.indexOf(m) < 0){ r = true } else { return true } - })){ return false } - } - if(Type.obj.has(o,'>')){ if(t > o['>']){ r = true } else { return false }} - if(Type.obj.has(o,'<')){ if(t < o['<']){ r = true } else { return false }} - function fuzzy(t,f){ var n = -1, i = 0, c; for(;c = f[i++];){ if(!~(n = t.indexOf(c, n+1))){ return false }} return true } // via http://stackoverflow.com/questions/9206013/javascript-fuzzy-search - if(Type.obj.has(o,'?')){ if(fuzzy(t, o['?'])){ r = true } else { return false }} // change name! - return r; + if(u !== o['>'] && t > o['>']){ return true } + if(u !== o['<'] && t < o['<']){ return true } + return false; } Type.list = {is: function(l){ return (l instanceof Array) }} Type.list.slit = Array.prototype.slice; diff --git a/test/rad/rad.js b/test/rad/rad.js index ee46a444..da72c2d4 100644 --- a/test/rad/rad.js +++ b/test/rad/rad.js @@ -31,6 +31,7 @@ Gun = root.Gun if(Gun.window && !Gun.window.RindexedDB){ return } var opt = {}; +opt.file = 'radatatest'; var Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk'); opt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt); opt.chunk = 1000; @@ -110,6 +111,20 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam expect(Gun.obj.empty(all)).to.be.ok(); done(); }); + + it('radix reverse', function(done){ + var r = Radix(), tmp; + r('alice', 1);r('bob', 2);r('carl', 3);r('dave', 4); + Radix.map(r, function(v,k, a,b){ + tmp = v; + }, {reverse: 1}); + expect(tmp).to.be(1); + Radix.map(r, function(v,k, a,b){ + tmp = v; + }); + expect(tmp).to.be(4); + done(); + }); }); describe('Radisk', function(){ @@ -138,6 +153,25 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam }) }) }); + + /*it('read contacts reverse', function(done){ + var opt = {}; + opt.reverse = true; + opt.end = 'nothing'; + opt.start = 'marcy'; + var first, last; + rad('', function(err, data){ + console.log("???", err, data); + return; + Radix.map(data, function(v,k){ + console.log(k, v); + //delete all[find+k]; + }); + //if(!Gun.obj.empty(all)){ return } + //done(); + }, opt); + }); + console.log("UNDO THIS RETURN!!!");return;*/ it('read contacts start end', function(done){ var opt = {}; From 1abcfe0c8353bac0334e30ebd9b23afb3c965d1e Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Mon, 22 Apr 2019 18:14:02 -0700 Subject: [PATCH 04/18] radix empty end should be infinite --- lib/radix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/radix.js b/lib/radix.js index 2eb7b311..8a5b59a0 100644 --- a/lib/radix.js +++ b/lib/radix.js @@ -65,7 +65,7 @@ p = pre.slice(); p.push(key); pt = p.join(''); if(u !== start && pt < (start||'').slice(0,pt.length)){ continue } - if(u !== end && end < pt){ continue } + if(u !== end && (end || '\uffff') < pt){ continue } if(u !== (tmp = tree[''])){ tmp = cb(tmp, pt, key, pre); if(u !== tmp){ return tmp } From 32a68c2d4d858d36fd53871f2871512e7d9f2386 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Tue, 23 Apr 2019 13:28:05 -0700 Subject: [PATCH 05/18] fix Reverse RAD! --- lib/radisk.js | 14 ++++++++++---- package.json | 2 +- test/common.js | 2 ++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/radisk.js b/lib/radisk.js index 376b07ea..2e0b6a24 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -236,17 +236,22 @@ // if a node is requested and some of it is cached... the other parts might not be. //} } + o.span = (u !== o.start) || (u !== o.end); var g = function Get(){}; g.lex = function(file){ var tmp; 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)){ - if(o.next){ g.file = file } + if(o.next || o.reverse){ g.file = file } if(tmp = Q[g.file]){ tmp.push({key: key, ack: cb, file: g.file, opt: o}); return true; } Q[g.file] = [{key: key, ack: cb, file: g.file, opt: o}]; + if(!g.file){ + g.it(null, u, {}); + return true; + } r.parse(g.file, g.it); return true; } @@ -267,8 +272,10 @@ if(!o.some){ o.some = (u !== data) } if(u !== data){ as.ack(g.err, data, o) } else if(!as.file){ !o.some && as.ack(g.err, u, o); return } - if(/*!last || */last === tmp){ !o.some && as.ack(g.err, u, o); return } - if(last && last > tmp && 0 != last.indexOf(tmp)){ !o.some && as.ack(g.err, u, o); return } + if(!o.span){ + if(/*!last || */last === tmp){ !o.some && as.ack(g.err, u, o); return } + if(last && last > tmp && 0 != last.indexOf(tmp)){ !o.some && as.ack(g.err, u, o); return } + } if(o.some && o.parsed >= o.limit){ return } o.next = as.file; r.read(tmp, as.ack, o); @@ -322,7 +329,6 @@ return map(q, p.ack); } } - var start; LOG && (start = (+new Date)); // keep this commented out in production! var tmp = p.split(data), pre = [], i, k, v; if(!tmp || 0 !== tmp[1]){ diff --git a/package.json b/package.json index 3aa3fbbf..3f3b34e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.422", + "version": "0.2019.423", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", diff --git a/test/common.js b/test/common.js index d0d23c17..0c2de5b8 100644 --- a/test/common.js +++ b/test/common.js @@ -6,6 +6,8 @@ describe('Gun', function(){ if(typeof window !== 'undefined'){ env = window } root = env.window? env.window : global; try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){} + try{ localStorage.clear() }catch(e){} + try{ indexedDB.deleteDatabase('radatatest') }catch(e){} try{ require('fs').unlinkSync('data.json') }catch(e){} try{ require('../lib/fsrm')('radatatest') }catch(e){} //root.Gun = root.Gun || require('../gun'); From 2c8abba79c6e1cd1bbe67ed63774c7f45714a9a4 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Thu, 25 Apr 2019 13:22:23 -0700 Subject: [PATCH 06/18] call next in put --- lib/les.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/les.js b/lib/les.js index 75a44ece..45d78578 100644 --- a/lib/les.js +++ b/lib/les.js @@ -127,6 +127,7 @@ //Executed every time a node gets modified root.on("put", function(e) { + this.to.next(e); var ctime = Date.now(); var souls = Object.keys(e.put || empty); // get all of the nodes in the update for (var i = 0; i < souls.length; i++) { // iterate over them and add them @@ -219,4 +220,4 @@ return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals); } }); -}()); \ No newline at end of file +}()); From 33893e40b8a12d8fa95c991e20e9d03307fda908 Mon Sep 17 00:00:00 2001 From: go1dfish Date: Thu, 25 Apr 2019 13:48:50 -0700 Subject: [PATCH 07/18] Fix for gc_info_enable --- lib/les.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/les.js b/lib/les.js index 45d78578..8ffddfa2 100644 --- a/lib/les.js +++ b/lib/les.js @@ -71,7 +71,7 @@ const gc_enable = root.opt.gc_enable ? root.opt.gc_enable : true; const gc_delay = root.opt.gc_delay ? root.opt.gc_delay : 1000; - const gc_info_enable = root.opt.gc_info_enable ? root.opt.gc_info_enable : true; + const gc_info_enable = ("gc_info_enable" in root.opt) ? root.opt.gc_info_enable : true; const gc_info = root.opt.gc_info ? root.opt.gc_info : 5000; const gc_info_mini = root.opt.gc_info_mini ? root.opt.gc_info_mini : false; From ecffdce786b6f813c634f5479194f685e7a05dcf Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Thu, 25 Apr 2019 18:34:25 -0700 Subject: [PATCH 08/18] same process instances should share RAD plugins for same file options to prevent corruption --- lib/rfs.js | 6 ++++++ lib/rindexed.js | 5 ++++- lib/rs3.js | 8 +++++++- package.json | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/rfs.js b/lib/rfs.js index 7473f258..6ed7d131 100644 --- a/lib/rfs.js +++ b/lib/rfs.js @@ -3,7 +3,13 @@ function Store(opt){ opt.log = opt.log || console.log; opt.file = String(opt.file || 'radata'); var fs = require('fs'), u; + var store = function Store(){}; + if(Store[opt.file]){ + console.log("Warning: reusing same fs store and options as 1st."); + return Store[opt.file]; + } + Store[opt.file] = store; store.put = function(file, data, cb){ var random = Math.random().toString(36).slice(-3); diff --git a/lib/rindexed.js b/lib/rindexed.js index fcccd9a1..281120ba 100644 --- a/lib/rindexed.js +++ b/lib/rindexed.js @@ -16,7 +16,10 @@ }}catch(e){} var store = function Store(){}; - if(Store[opt.file]){ return Store[opt.file] } + if(Store[opt.file]){ + console.log("Warning: reusing same IndexedDB store and options as 1st."); + return Store[opt.file]; + } Store[opt.file] = store; store.start = function(){ diff --git a/lib/rs3.js b/lib/rs3.js index 3c6c1630..5b56c2e9 100644 --- a/lib/rs3.js +++ b/lib/rs3.js @@ -41,8 +41,14 @@ function Store(opt){ opt.file = String(opt.file || 'radata'); var opts = opt.s3, s3 = opts.s3; var c = {p: {}, g: {}, l: {}}; - + var store = function Store(){}; + if(Store[opt.file]){ + console.log("Warning: reusing same S3 store and options as 1st."); + return Store[opt.file]; + } + Store[opt.file] = store; + store.put = function(file, data, cb){ var params = {Bucket: opts.bucket, Key: file, Body: data}; //console.log("RS3 PUT ---->", (data||"").slice(0,20)); diff --git a/package.json b/package.json index 3f3b34e5..47487569 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.423", + "version": "0.2019.425", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", From da431c06bcf0f409679ecbe2c2800d1a7ea656e7 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Thu, 25 Apr 2019 20:10:04 -0700 Subject: [PATCH 09/18] fix tests to not delete folder while running --- test/rad/rad.js | 5 ++--- test/sea/sea.js | 16 +++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/test/rad/rad.js b/test/rad/rad.js index da72c2d4..bd97283d 100644 --- a/test/rad/rad.js +++ b/test/rad/rad.js @@ -7,13 +7,12 @@ var Gun; root = env.window? env.window : global; try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){} try{ indexedDB.deleteDatabase('radatatest') }catch(e){} - try{ require('fs').unlinkSync('data.json') }catch(e){} - try{ require('../../lib/fsrm')('radatatest') }catch(e){} - //root.Gun = root.Gun || require('../gun'); if(root.Gun){ root.Gun = root.Gun; root.Gun.TESTING = true; } else { + try{ require('fs').unlinkSync('data.json') }catch(e){} + try{ require('../../lib/fsrm')('radatatest') }catch(e){} root.Gun = require('../../gun'); root.Gun.TESTING = true; //require('../lib/file'); diff --git a/test/sea/sea.js b/test/sea/sea.js index ec7d0828..e4e5f70e 100644 --- a/test/sea/sea.js +++ b/test/sea/sea.js @@ -7,24 +7,22 @@ var Gun; root = env.window? env.window : global; try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){} try{ indexedDB.deleteDatabase('radatatest') }catch(e){} - try{ require('fs').unlinkSync('data.json') }catch(e){} - try{ require('../../lib/fsrm')('radatatest') }catch(e){} - //root.Gun = root.Gun || require('../gun'); if(root.Gun){ root.Gun = root.Gun; root.Gun.TESTING = true; } else { + try{ require('fs').unlinkSync('data.json') }catch(e){} + try{ require('../../lib/fsrm')('radatatest') }catch(e){} root.Gun = require('../../gun'); root.Gun.TESTING = true; //require('../lib/file'); - require('../lib/store'); - require('../lib/rfs'); + require('../../lib/store'); + require('../../lib/rfs'); } - if(root.Gun.SEA){ - //Gun = root.Gun = root.Gun; - } else { - var expect = global.expect = require("../expect"); + try{ var expect = global.expect = require("../expect") }catch(e){} + + if(!root.Gun.SEA){ require('../../sea.js'); } }(this)); From 2d541f9529fe4552bf102a264d30fe55da3e5719 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Fri, 26 Apr 2019 16:03:33 -0700 Subject: [PATCH 10/18] fix queue issue --- gun.js | 21 +++++++++++---------- src/adapters/mesh.js | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/gun.js b/gun.js index e357005b..9c710b97 100644 --- a/gun.js +++ b/gun.js @@ -2129,11 +2129,12 @@ tmp = tmp.id = tmp.id || Type.text.random(9); mesh.say({dam: '?'}, opt.peers[tmp] = peer); } - if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer); } - // tmp = peer.queue; peer.queue = []; - // Type.obj.map(tmp, function(msg){ - // mesh.say(msg, peer); - // }); + if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) } + // @rogowski I need this here by default for now to fix go1dfish's bug + tmp = peer.queue; peer.queue = []; + Type.obj.map(tmp, function(msg){ + mesh.say(msg, peer); + }); } mesh.bye = function(peer){ Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect @@ -2142,12 +2143,12 @@ mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) } mesh.hear['?'] = function(msg, peer){ if(!msg.pid){ -// return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); - var tmp = peer.queue; peer.queue = []; - Type.obj.map(tmp, function(msg){ - mesh.say(msg, peer); - }); + // @rogowski I want to re-enable this AXE logic with some fix/merge later. + // var tmp = peer.queue; peer.queue = []; + // Type.obj.map(tmp, function(msg){ + // mesh.say(msg, peer); + // }); return; } peer.id = peer.id || msg.pid; diff --git a/src/adapters/mesh.js b/src/adapters/mesh.js index df4f2dcc..d198f766 100644 --- a/src/adapters/mesh.js +++ b/src/adapters/mesh.js @@ -126,7 +126,6 @@ function Mesh(ctx){ peer.say(raw); } else if(wire.send){ - if(wire.readyState && 1 != wire.readyState){ throw "socket not ready yet!" } wire.send(raw); } }catch(e){ @@ -194,11 +193,12 @@ function Mesh(ctx){ tmp = tmp.id = tmp.id || Type.text.random(9); mesh.say({dam: '?'}, opt.peers[tmp] = peer); } - if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer); } - // tmp = peer.queue; peer.queue = []; - // Type.obj.map(tmp, function(msg){ - // mesh.say(msg, peer); - // }); + if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) } + // @rogowski I need this here by default for now to fix go1dfish's bug + tmp = peer.queue; peer.queue = []; + Type.obj.map(tmp, function(msg){ + mesh.say(msg, peer); + }); } mesh.bye = function(peer){ Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect @@ -207,12 +207,12 @@ function Mesh(ctx){ mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) } mesh.hear['?'] = function(msg, peer){ if(!msg.pid){ -// return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer); - var tmp = peer.queue; peer.queue = []; - Type.obj.map(tmp, function(msg){ - mesh.say(msg, peer); - }); + // @rogowski I want to re-enable this AXE logic with some fix/merge later. + // var tmp = peer.queue; peer.queue = []; + // Type.obj.map(tmp, function(msg){ + // mesh.say(msg, peer); + // }); return; } peer.id = peer.id || msg.pid; From 16634cf02388e81f6c6920a212905896bb03816b Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Fri, 26 Apr 2019 16:03:57 -0700 Subject: [PATCH 11/18] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47487569..a650c95b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.425", + "version": "0.2019.426", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", From e9fc38ddd19caef05884580b67ba6eb05d9a448b Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Fri, 26 Apr 2019 16:10:56 -0700 Subject: [PATCH 12/18] disable multicast by default :( --- lib/multicast.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/multicast.js b/lib/multicast.js index a49ca9dc..34bbe97d 100644 --- a/lib/multicast.js +++ b/lib/multicast.js @@ -3,7 +3,8 @@ var Gun = (typeof window !== "undefined")? window.Gun : require('../gun'); Gun.on('create', function(root){ this.to.next(root); var opt = root.opt; - if(false === opt.multicast){ return } + if(false === opt.multicast){ return } + if(true !== opt.multicast){ return } // disable multicast by default for now. var udp = opt.multicast = opt.multicast || {}; udp.address = udp.address || '233.255.255.255'; From 2071512b202887c8ea28b77ca9c3c24c246dcb8c Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Sat, 27 Apr 2019 00:16:12 -0700 Subject: [PATCH 13/18] add health stats --- lib/server.js | 1 + lib/stats.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 lib/stats.js diff --git a/lib/server.js b/lib/server.js index 509af9e5..90159bd0 100644 --- a/lib/server.js +++ b/lib/server.js @@ -17,6 +17,7 @@ require('./file'); require('./evict'); require('./multicast'); + require('./stats'); if('debug' === process.env.GUN_ENV){ require('./debug') } module.exports = Gun; }()); diff --git a/lib/stats.js b/lib/stats.js new file mode 100644 index 00000000..40c9be4f --- /dev/null +++ b/lib/stats.js @@ -0,0 +1,43 @@ +var Gun = (typeof window !== "undefined")? window.Gun : require('../gun'); + +Gun.on('opt', function(root){ + this.to.next(root); + if(root.once){ return } + if(typeof process === 'undefined'){ return } + if(typeof require === 'undefined'){ return } + var noop = function(){}; + var os = require('os') || {}; + var fs = require('fs') || {}; + fs.existsSync = fs.existsSync || require('path').existsSync; + if(!fs.existsSync){ return } + if(!process){ return } + process.uptime = process.uptime || noop; + process.cpuUsage = process.cpuUsage || noop; + process.memoryUsage = process.memoryUsage || noop; + os.totalmem = os.totalmem || noop; + os.freemem = os.freemem || noop; + os.loadavg = os.loadavg || noop; + os.cpus = os.cpus || noop; + setTimeout(function(){ + root.stats = Gun.obj.ify((fs.existsSync(__dirname+'/../stats.'+root.opt.file) && fs.readFileSync(__dirname+'/../stats.'+root.opt.file).toString())) || {}; + root.stats.up = root.stats.up || {}; + root.stats.up.start = root.stats.up.start || +(new Date); + root.stats.up.count = (root.stats.up.count || 0) + 1; + },1); + setInterval(function(){ + if(!root.stats){ return } + var stats = root.stats, tmp; + (stats.up||{}).time = process.uptime(); + stats.memory = process.memoryUsage() || {}; + stats.memory.totalmem = os.totalmem(); + stats.memory.freemem = os.freemem(); + stats.cpu = process.cpuUsage() || {}; + stats.cpu.loadavg = os.loadavg(); + stats.peers = {}; + stats.peers.count = Object.keys(root.opt.peers||{}).length; + stats.node = {}; + stats.node.count = Object.keys(root.graph||{}).length; + fs.writeFile(__dirname+'/../stats.'+root.opt.file, JSON.stringify(stats, null, 2), function(err){}); + }, 1000 * 15); + Object.keys = Object.keys || function(o){ return Gun.obj.map(o, function(v,k,t){t(k)}) } +}); \ No newline at end of file From bf40e7e15208091f810140105bf43fc42b1b8281 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Sat, 27 Apr 2019 11:54:25 -0700 Subject: [PATCH 14/18] tomap + stats --- gun.js | 3 ++- lib/stats.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gun.js b/gun.js index 9c710b97..99a0fe27 100644 --- a/gun.js +++ b/gun.js @@ -1985,7 +1985,7 @@ } (msg._ = function(){}).via = peer; if((tmp = msg['><'])){ - (msg._).to = Type.obj.map(tmp.split(','), function(k,i,m){m(k,true)}); + (msg._).to = Type.obj.map(tmp.split(','), tomap); } if(msg.dam){ if(tmp = mesh.hear[msg.dam]){ @@ -2008,6 +2008,7 @@ return; } } + var tomap = function(k,i,m){m(k,true)}; ;(function(){ mesh.say = function(msg, peer, o){ diff --git a/lib/stats.js b/lib/stats.js index 40c9be4f..8b29367e 100644 --- a/lib/stats.js +++ b/lib/stats.js @@ -25,7 +25,7 @@ Gun.on('opt', function(root){ root.stats.up.count = (root.stats.up.count || 0) + 1; },1); setInterval(function(){ - if(!root.stats){ return } + if(!root.stats){ root.stats = {} } var stats = root.stats, tmp; (stats.up||{}).time = process.uptime(); stats.memory = process.memoryUsage() || {}; From b78e73a32bd13d60b04b371a42e363b56fb5c6d4 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Sat, 27 Apr 2019 11:55:08 -0700 Subject: [PATCH 15/18] stats! version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a650c95b..ce42e859 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.426", + "version": "0.2019.427", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", From a111e20f271c011b4c0c739b8c4f41d0605fb8ca Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Sat, 27 Apr 2019 15:06:00 -0700 Subject: [PATCH 16/18] fix Lex lookups --- gun.js | 18 ++++++++++-------- package.json | 2 +- src/adapters/mesh.js | 3 ++- src/chain.js | 12 +++++++----- src/type.js | 6 +++--- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/gun.js b/gun.js index 99a0fe27..0be1772f 100644 --- a/gun.js +++ b/gun.js @@ -49,10 +49,10 @@ if(t.slice(0, (tmp||'').length) === tmp){ return true } if(u !== o['*']){ return false } if(u !== o['>'] && u !== o['<']){ - return (t > o['>'] && t < o['<'])? true : false; + return (t >= o['>'] && t <= o['<'])? true : false; } - if(u !== o['>'] && t > o['>']){ return true } - if(u !== o['<'] && t < o['<']){ return true } + if(u !== o['>'] && t >= o['>']){ return true } + if(u !== o['<'] && t <= o['<']){ return true } return false; } Type.list = {is: function(l){ return (l instanceof Array) }} @@ -958,7 +958,7 @@ if(tmp){ return } msg.$ = back.$; } else - if(obj_has(back.put, get)){ + if(obj_has(back.put, get)){ // TODO: support #LEX ! put = (back.$.get(get)._); if(!(tmp = put.ack)){ put.ack = -1 } back.on('in', { @@ -1178,14 +1178,16 @@ }); } function ask(at, soul){ - var tmp = (at.root.$.get(soul)._); - if(at.ack){ - tmp.on('out', {get: {'#': soul}}); + var tmp = (at.root.$.get(soul)._), lex = at.lex; + if(at.ack || lex){ + (lex = lex||{})['#'] = soul; + tmp.on('out', {get: lex}); if(!at.ask){ return } // TODO: PERFORMANCE? More elegant way? } tmp = at.ask; Gun.obj.del(at, 'ask'); obj_map(tmp || at.next, function(neat, key){ - neat.on('out', {get: {'#': soul, '.': key}}); + var lex = neat.lex || {}; lex['#'] = soul; lex['.'] = lex['.'] || key; + neat.on('out', {get: lex}); }); Gun.obj.del(at, 'ask'); // TODO: PERFORMANCE? More elegant way? } diff --git a/package.json b/package.json index ce42e859..54c3faa7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.2019.427", + "version": "0.2019.428", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.js", diff --git a/src/adapters/mesh.js b/src/adapters/mesh.js index d198f766..3904cd72 100644 --- a/src/adapters/mesh.js +++ b/src/adapters/mesh.js @@ -49,7 +49,7 @@ function Mesh(ctx){ } (msg._ = function(){}).via = peer; if((tmp = msg['><'])){ - (msg._).to = Type.obj.map(tmp.split(','), function(k,i,m){m(k,true)}); + (msg._).to = Type.obj.map(tmp.split(','), tomap); } if(msg.dam){ if(tmp = mesh.hear[msg.dam]){ @@ -72,6 +72,7 @@ function Mesh(ctx){ return; } } + var tomap = function(k,i,m){m(k,true)}; ;(function(){ mesh.say = function(msg, peer, o){ diff --git a/src/chain.js b/src/chain.js index 18104481..1864ac1f 100644 --- a/src/chain.js +++ b/src/chain.js @@ -37,7 +37,7 @@ function output(msg){ if(tmp){ return } msg.$ = back.$; } else - if(obj_has(back.put, get)){ + if(obj_has(back.put, get)){ // TODO: support #LEX ! put = (back.$.get(get)._); if(!(tmp = put.ack)){ put.ack = -1 } back.on('in', { @@ -257,14 +257,16 @@ function not(at, msg){ }); } function ask(at, soul){ - var tmp = (at.root.$.get(soul)._); - if(at.ack){ - tmp.on('out', {get: {'#': soul}}); + var tmp = (at.root.$.get(soul)._), lex = at.lex; + if(at.ack || lex){ + (lex = lex||{})['#'] = soul; + tmp.on('out', {get: lex}); if(!at.ask){ return } // TODO: PERFORMANCE? More elegant way? } tmp = at.ask; Gun.obj.del(at, 'ask'); obj_map(tmp || at.next, function(neat, key){ - neat.on('out', {get: {'#': soul, '.': key}}); + var lex = neat.lex || {}; lex['#'] = soul; lex['.'] = lex['.'] || key; + neat.on('out', {get: lex}); }); Gun.obj.del(at, 'ask'); // TODO: PERFORMANCE? More elegant way? } diff --git a/src/type.js b/src/type.js index 82be63d4..caf5ab37 100644 --- a/src/type.js +++ b/src/type.js @@ -29,10 +29,10 @@ Type.text.match = function(t, o){ var tmp, u; if(t.slice(0, (tmp||'').length) === tmp){ return true } if(u !== o['*']){ return false } if(u !== o['>'] && u !== o['<']){ - return (t > o['>'] && t < o['<'])? true : false; + return (t >= o['>'] && t <= o['<'])? true : false; } - if(u !== o['>'] && t > o['>']){ return true } - if(u !== o['<'] && t < o['<']){ return true } + if(u !== o['>'] && t >= o['>']){ return true } + if(u !== o['<'] && t <= o['<']){ return true } return false; } Type.list = {is: function(l){ return (l instanceof Array) }} From 4c8eb2c112f04a298d1a644d23934fff7e4cf153 Mon Sep 17 00:00:00 2001 From: Andrea Puddu Date: Fri, 3 May 2019 12:21:27 +0200 Subject: [PATCH 17/18] Update nts.html Change font family to monospace to prevent the text moving --- examples/game/nts.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/game/nts.html b/examples/game/nts.html index c8397f26..c52427e4 100644 --- a/examples/game/nts.html +++ b/examples/game/nts.html @@ -3,7 +3,7 @@ -

+

@@ -16,4 +16,4 @@ when.innerHTML = print; }); - \ No newline at end of file + From ed9b234c213321642a4f41b284c0f3a4f69c69fd Mon Sep 17 00:00:00 2001 From: sirpy Date: Mon, 6 May 2019 23:46:35 +0300 Subject: [PATCH 18/18] fix: settings can be from opts or from process.env --- lib/rs3.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rs3.js b/lib/rs3.js index 5b56c2e9..339582a0 100644 --- a/lib/rs3.js +++ b/lib/rs3.js @@ -7,7 +7,7 @@ var u, AWS; Gun.on('create', function(root){ this.to.next(root); var opt = root.opt; - if(!process.env.AWS_S3_BUCKET){ return } + if(!opt.s3 && !process.env.AWS_S3_BUCKET){ return } opt.batch = opt.batch || (1000 * 10); opt.until = opt.until || (1000 * 3); opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB @@ -101,4 +101,4 @@ function Store(opt){ return store; } -module.exports = Store; \ No newline at end of file +module.exports = Store;