From 944194b299a0668b40fafefacd2022a3b40a2357 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Mon, 18 Jun 2018 21:33:05 -0700 Subject: [PATCH] a clean link and map --- examples/contact/index.html | 2 +- gun.js | 145 +++++++------- lib/open.js | 2 +- lib/radisk.js | 4 +- lib/time.js | 2 +- lib/unset.js | 2 +- package.json | 2 +- sea.js | 12 +- test/common.js | 387 ++++++++++++------------------------ test/mocha.html | 24 ++- test/old/performance.js | 138 +++++++++++++ test/panic/speak.js | 2 +- test/say.html | 2 +- 13 files changed, 378 insertions(+), 346 deletions(-) create mode 100644 test/old/performance.js diff --git a/examples/contact/index.html b/examples/contact/index.html index 38679545..1d76c900 100644 --- a/examples/contact/index.html +++ b/examples/contact/index.html @@ -169,7 +169,7 @@ Gun.node.is(at.put.users, function(val, key){ Gun.SEA.verify(val, false, function(val){ //Gun.SEA.read(val, false, function(val){ - if('~@'+key === Gun.val.rel.is(val)){ return } + if('~@'+key === Gun.val.link.is(val)){ return } no = true; }) if(no){ return no } diff --git a/gun.js b/gun.js index 5dcac8b2..2f892388 100644 --- a/gun.js +++ b/gun.js @@ -22,7 +22,7 @@ // Generic javascript utilities. var Type = {}; //Type.fns = Type.fn = {is: function(fn){ return (!!fn && fn instanceof Function) }} - Type.fns = Type.fn = {is: function(fn){ return (!!fn && 'function' == typeof fn) }} + Type.fn = {is: function(fn){ return (!!fn && 'function' == typeof fn) }} Type.bi = {is: function(b){ return (b instanceof Boolean || typeof b == 'boolean') }} Type.num = {is: function(n){ return !list_is(n) && ((n - parseFloat(n) + 1) >= 0 || Infinity === n || -Infinity === n) }} Type.text = {is: function(t){ return (typeof t == 'string') }} @@ -266,7 +266,7 @@ } return Val.rel.is(v) || false; // is the value a soul relation? Then it is valid and return it. If not, everything else remaining is an invalid data type. Custom extensions can be built on top of these primitives to support other types. } - Val.rel = {_: '#'}; + Val.link = Val.rel = {_: '#'}; ;(function(){ Val.rel.is = function(v){ // this defines whether an object is a soul relation or not, they look like this: {'#': 'UUID'} if(v && v[rel_] && !v._ && obj_is(v)){ // must be an object. @@ -289,7 +289,7 @@ }()); Val.rel.ify = function(t){ return obj_put({}, rel_, t) } // convert a soul into a relation and return it. Type.obj.has._ = '.'; - var rel_ = Val.rel._, u; + var rel_ = Val.link._, u; var bi_is = Type.bi.is; var num_is = Type.num.is; var text_is = Type.text.is; @@ -309,7 +309,7 @@ n._[soul_] = o.soul || n._[soul_] || text_random(); // put the soul on it. return n; } - Node.soul._ = Val.rel._; + Node.soul._ = Val.link._; ;(function(){ Node.is = function(n, cb, as){ var s; // checks to see if an object is a valid node. if(!obj_is(n)){ return false } // must be an object. @@ -685,7 +685,7 @@ var gun = at.gun.opt(at.opt); if(!at.once){ at.on('in', root, at); - at.on('out', root, obj_to(at, {out: root})); + at.on('out', root, {at: at, out: root}); Gun.on('create', at); at.on('create', at); } @@ -694,11 +694,11 @@ } function root(msg){ //console.log("add to.next(at)"); // TODO: MISSING FEATURE!!! - var ev = this, at = ev.as, gun = at.gun, dup, tmp; + var ev = this, as = ev.as, at = as.at || as, gun = at.gun, dup, tmp; //if(!msg.gun){ msg.gun = at.gun } if(!(tmp = msg['#'])){ tmp = msg['#'] = text_rand(9) } if((dup = at.dup).check(tmp)){ - if(at.out === msg.out){ + if(as.out === msg.out){ msg.out = u; ev.to.next(msg); } @@ -717,7 +717,7 @@ } } ev.to.next(msg); - if(!at.out){ + if(!as.out){ msg.out = root; at.on('out', msg); } @@ -726,14 +726,11 @@ ;(function(){ Gun.on.put = function(msg, gun){ - var at = gun._, ctx = {gun: gun, graph: at.graph, put: {}, map: {}, souls: {}, machine: Gun.state(), ack: msg['@']}; + var at = gun._, ctx = {gun: gun, graph: at.graph, put: {}, map: {}, souls: {}, machine: Gun.state(), ack: msg['@'], cat: at, stop: {}}; if(!Gun.graph.is(msg.put, null, verify, ctx)){ ctx.err = "Error: Invalid graph!" } if(ctx.err){ return at.on('in', {'@': msg['#'], err: Gun.log(ctx.err) }) } obj_map(ctx.put, merge, ctx); - if(!ctx.async){ - at.stop = {}; // temporary fix till a better solution? - obj_map(ctx.map, map, ctx) - } + if(!ctx.async){ obj_map(ctx.map, map, ctx) } if(u !== ctx.defer){ setTimeout(function(){ Gun.on.put(msg, gun); @@ -776,16 +773,15 @@ obj_map(node, each, as); if(!ctx.async){ return } if(!ctx.and){ - // If it is async, we only need to setup on listener per context (ctx) + // If it is async, we only need to setup one listener per context (ctx) cat.on('node', function(m){ this.to.next(m); // make sure to call other context's listeners. if(m !== ctx.map[m.get]){ return } // filter out events not from this context! ctx.souls[m.get] = false; // set our many-async flag - obj_map(m.put, aeach, m); // merge into view + obj_map(m.put, patch, m); // merge into view if(obj_map(ctx.souls, function(v){ if(v){ return v } })){ return } // if flag still outstanding, keep waiting. if(ctx.c){ return } ctx.c = 1; // failsafe for only being called once per context. this.off(); - cat.stop = {}; // temporary fix till a better solution? obj_map(ctx.map, map, ctx); // all done, trigger chains. }); } @@ -798,14 +794,16 @@ if(ctx.async){ return } at.put = Gun.state.to(node, key, at.put); } - function aeach(val, key){ + function patch(val, key){ var msg = this, node = msg.put, at = (msg.gun._); at.put = Gun.state.to(node, key, at.put); } function map(msg, soul){ if(!msg.gun){ return } - //console.log('map ->', soul, msg.put); + this.cat.stop = this.stop; // temporary fix till a better solution? + //console.log("MAP |||-->", soul); (msg.gun._).on('in', msg); + this.cat.stop = null; // temporary fix till a better solution? } Gun.on.get = function(msg, gun){ @@ -861,7 +859,7 @@ var list_is = Gun.list.is; var text = Gun.text, text_is = text.is, text_rand = text.random; var obj = Gun.obj, obj_is = obj.is, obj_has = obj.has, obj_to = obj.to, obj_map = obj.map, obj_copy = obj.copy; - var state_lex = Gun.state.lex, _soul = Gun.val.rel._, _has = '.', node_ = Gun.node._, rel_is = Gun.val.rel.is; + var state_lex = Gun.state.lex, _soul = Gun.val.rel._, _has = '.', node_ = Gun.node._, rel_is = Gun.val.link.is; var empty = {}, u; console.debug = function(i, s){ return (console.debug.i && i === console.debug.i && console.debug.i++) && (console.log.apply(console, arguments) || s) }; @@ -983,9 +981,7 @@ root.ask(ack, msg); return root.on('in', msg); } - if(root.now){ - root.now[at.id] = root.now[at.id] || true; - } + if(root.now){ root.now[at.id] = root.now[at.id] || true; at.pass = {} } if(get['.']){ if(at.get){ msg = {get: {'.': at.get}, gun: at.gun}; @@ -1007,7 +1003,7 @@ } function input(msg){ - var ev = this, cat = this.as, gun = msg.gun, at = gun._, change = msg.put, rel, tmp; + var ev = this, cat = ev.as, gun = msg.gun, at = (gun||empty)._ || empty, change = msg.put, rel, tmp; if(cat.get && msg.get !== cat.get){ msg = obj_to(msg, {get: cat.get}); } @@ -1036,10 +1032,10 @@ if(cat.soul){ ev.to.next(msg); echo(cat, msg, ev); - obj_map(change, map, {at: msg, cat: cat}); + if(cat.next){ obj_map(change, map, {msg: msg, cat: cat}) } return; } - if(!(rel = Gun.val.rel.is(change))){ + if(!(rel = Gun.val.link.is(change))){ if(Gun.val.is(change)){ if(cat.has || cat.soul){ not(cat, msg); @@ -1062,11 +1058,10 @@ ev.to.next(msg); echo(cat, msg, ev); relate(cat, msg, at, rel); - obj_map(change, map, {at: msg, cat: cat}); + if(cat.next){ obj_map(change, map, {msg: msg, cat: cat}) } return; } relate(cat, msg, at, rel); - ev.to.next(msg); echo(cat, msg, ev); } @@ -1080,31 +1075,43 @@ relate(from, msg, from, rel); } if(from === at){ return } + if(!from.gun){ from = {} } (from.echo || (from.echo = {}))[at.id] = at; if(at.has && !(at.map||empty)[from.id]){ // if we haven't seen this before. not(at, msg); } - tmp = (at.map || (at.map = {}))[from.id] = at.map[from.id] || {at: from}; - var now = at.root.now; - //now = now || at.root.stop; - if(rel === tmp.rel){ + tmp = from.id? ((at.map || (at.map = {}))[from.id] = at.map[from.id] || {at: from}) : {}; + //console.log("!!!", at.id, at.get, at.ask, rel, tmp, 'pass?', at.pass, tmp.pass); + if(rel === tmp.link){ + if(!(tmp.pass || at.pass)){ + return; + } + /*if(from.ack){ return } //return; // if at.has // NOW is a hack to get synchronous replies to correctly call. // and STOP is a hack to get async behavior to correctly call. // neither of these are ideal, need to be fixed without hacks, // but for now, this works for current tests. :/ if(!now){ return; - /*var stop = at.root.stop; + var stop = at.root.stop; if(!stop){ return } if(stop[at.id] === rel){ return } - stop[at.id] = rel;*/ + stop[at.id] = rel; } else { + // move back to here to get rid of bugs if(u === now[at.id]){ return } if((now._ || (now._ = {}))[at.id] === rel){ return } now._[at.id] = rel; } + //return; // delete this*/ } - ask(at, tmp.rel = rel); + if(at.pass){ + Gun.obj.map(at.map, function(tmp){ tmp.pass = true }) + obj_del(at, 'pass'); + } + if(tmp.pass){ obj_del(tmp, 'pass') } + if(at.has){ at.link = rel } + ask(at, tmp.link = rel); } function echo(at, msg, ev){ if(!at.echo){ return } // || node_ === at.get ? @@ -1115,7 +1122,7 @@ to.on('in', this); } function map(data, key){ // Map over only the changes on every update. - var cat = this.cat, next = cat.next || empty, via = this.at, chain, at, tmp; + var cat = this.cat, next = cat.next || empty, via = this.msg, chain, at, tmp; if(node_ === key && !next[key]){ return } if(!(at = next[key])){ return; @@ -1128,9 +1135,8 @@ at.put = data; } chain = at.gun; - } else { - chain = via.gun.get(key); - } + } else + if(via.gun){ chain = via.gun.get(key) } at.on('in', { put: data, get: key, @@ -1142,10 +1148,12 @@ if(!(at.has || at.soul)){ return } var tmp = at.map, root = at.root; at.map = null; - if(!root.now || !root.now[at.id]){ + if(at.has){ at.link = null } + //if(!root.now || !root.now[at.id]){ + if(!at.pass){ if((!msg['@']) && null === tmp){ return } } - if(u === tmp && Gun.val.rel.is(at.put)){ return } // TODO: Bug? Threw second condition in for a particular test, not sure if a counter example is tested though. + if(u === tmp && Gun.val.link.is(at.put)){ return } // This prevents the very first call of a thing from triggering a "clean up" call. // TODO: link.is(at.put) || !val.is(at.put) ? obj_map(tmp, function(proxy){ if(!(proxy = proxy.at)){ return } obj_del(proxy.echo, at.id); @@ -1169,10 +1177,7 @@ if(!at.ask){ return } // TODO: PERFORMANCE? More elegant way? } obj_map(at.ask || at.next, function(neat, key){ - //(tmp.gun.get(key)._).on('out', {get: {'#': soul, '.': key}}); - //tmp.on('out', {get: {'#': soul, '.': key}}); neat.on('out', {get: {'#': soul, '.': key}}); - //at.on('out', {get: {'#': soul, '.': key}}); }); Gun.obj.del(at, 'ask'); // TODO: PERFORMANCE? More elegant way? } @@ -1191,7 +1196,7 @@ return; } if(node_ == get['.']){ // is this a security concern? - at.on('in', {get: at.get, put: tmp[at.get], gun: at.gun, '@': msg['@']}); + at.on('in', {get: at.get, put: Gun.val.link.ify(get['#']), gun: at.gun, '@': msg['@']}); return; } //if(/*!msg.gun &&*/ !get['.'] && get['#']){ at.ack = (at.ack + 1) || 1 } @@ -1265,15 +1270,16 @@ return at; } function use(msg){ - var ev = this, as = ev.as, gun = msg.gun, at = gun._, root = at.root, data = msg.put, tmp; - if((tmp = root.now) && ev !== tmp[as.now]){ + var ev = this, as = ev.as, gun = msg.gun, at = (gun||{})._ || {}, root = at.root, data = msg.put, tmp; + if(root && (tmp = root.stop)){ if(tmp[at.id]){ return } tmp[at.id] = msg.root; } // temporary fix till a better solution? + if(root && (tmp = root.now) && ev !== tmp[as.now]){ return ev.to.next(msg); } if(u === data){ data = at.put; } - if((tmp = data) && tmp[rel._] && (tmp = rel.is(tmp))){ - tmp = (at.root.gun.get(tmp)._); + if((tmp = data) && tmp[rel._] && (tmp = rel.is(tmp)) && root){ + tmp = (root.gun.get(tmp)._); if(u !== tmp.put){ msg = obj_to(msg, {put: tmp.put}); } @@ -1392,7 +1398,6 @@ // neither of these are ideal, need to be fixed without hacks, // but for now, this works for current tests. :/ var tmp = cat.root.now; obj.del(cat.root, 'now'); cat.root.PUT = true; - var tmp2 = cat.root.stop; (as.ref._).now = true; (as.ref._).on('out', { gun: as.ref, put: as.out = as.env.graph, opt: as.opt, '#': ask @@ -1400,7 +1405,6 @@ obj.del((as.ref._), 'now'); obj.del((cat.root), 'PUT'); cat.root.now = tmp; - cat.root.stop = tmp2; }, as); if(as.res){ as.res() } } function no(v,k){ if(v){ return true } } @@ -1553,31 +1557,31 @@ return gun; } - function ok(at, ev){ var opt = this; - var gun = at.gun, cat = gun._, data = cat.put || at.put, tmp = opt.last, id = cat.id+at.get, tmp; + function ok(msg, ev){ var opt = this; + var gun = msg.gun, at = (gun||{})._ || {}, data = at.put || msg.put, tmp = opt.last, id = (at.id||'')+msg.get, tmp; if(u === data){ return; } - if(data && data[rel._] && (tmp = rel.is(data))){ - tmp = (cat.root.gun.get(tmp)._); + if(data && data[rel._] && (tmp = rel.is(data)) && at.root){ + tmp = (at.root.gun.get(tmp)._); if(u === tmp.put){ return; } data = tmp.put; } if(opt.change){ // TODO: BUG? Move above the undef checks? - data = at.put; + data = msg.put; } // DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE if(tmp.put === data && tmp.get === id && !Gun.node.soul(data)){ return } tmp.put = data; tmp.get = id; // DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE - cat.last = data; + at.last = data; if(opt.as){ - opt.ok.call(opt.as, at, ev); + opt.ok.call(opt.as, msg, ev); } else { - opt.ok.call(gun, data, at.get, at, ev); + opt.ok.call(gun, data, msg.get, msg, ev); } } @@ -1600,7 +1604,7 @@ } else { Gun.log.once("valonce", "Chainable val is experimental, its behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it."); var chain = gun.chain(); - chain._.val = gun.once(function(){ + chain._.nix = gun.once(function(){ chain._.on('in', gun._); }); return chain; @@ -1662,8 +1666,8 @@ } if(tmp = at.map){ obj_map(tmp, function(at){ - if(at.rel){ - cat.root.gun.get(at.rel).off(); + if(at.link){ + cat.root.gun.get(at.link).off(); } }); } @@ -1685,10 +1689,9 @@ Gun.chain.map = function(cb, opt, t){ var gun = this, cat = gun._, chain; if(!cb){ - if(chain = cat.fields){ return chain } - chain = cat.fields = gun.chain(); - chain._.val = gun.back('val'); - chain._.MAPOF = cat.soul; + if(chain = cat.each){ return chain } + chain = cat.each = gun.chain(); + chain._.nix = gun.back('nix'); gun.on('in', map, chain._); return chain; } @@ -1697,17 +1700,17 @@ gun.map().on(function(data, key, at, ev){ var next = (cb||noop).call(this, data, key, at, ev); if(u === next){ return } - if(Gun.is(next)){ + if(data === next || Gun.is(next)){ chain._.on('in', next._); return; } - chain._.on('in', {get: key, put: next, gun: chain}); + chain._.on('in', {get: key, put: next}); }); return chain; } function map(msg){ if(!msg.put || Gun.val.is(msg.put)){ return } - if(this.as.val){ this.off() } // TODO: Ugly hack! + if(this.as.nix){ this.off() } // TODO: Ugly hack! obj_map(msg.put, each, {at: this.as, msg: msg}); this.to.next(msg); } @@ -1850,7 +1853,7 @@ root.on('get', function(msg){ this.to.next(msg); var lex = msg.get, soul, data, u; - //setTimeout(function(){ + function to(){ if(!lex || !(soul = lex['#'])){ return } //if(0 >= msg.cap){ return } var has = lex['.']; @@ -1861,8 +1864,10 @@ if(!data && !Gun.obj.empty(opt.peers)){ // if data not found, don't ack if there are peers. return; // Hmm, what if we have peers but we are disconnected? } + //console.log("lS get", id, data); root.on('in', {'@': msg['#'], put: Gun.graph.node(data), how: 'lS', lS: msg.I}); - //},1); + }; + Gun.debug? setTimeout(to,1) : to(); }); var map = function(val, key, node, soul){ diff --git a/lib/open.js b/lib/open.js index 1df4f64f..13aa3acc 100644 --- a/lib/open.js +++ b/lib/open.js @@ -39,7 +39,7 @@ Gun.chain.open = function(cb, opt, at){ } var tmp = this, id; Gun.obj.map(data, function(val, key){ - if(!(id = Gun.val.rel.is(val))){ + if(!(id = Gun.val.link.is(val))){ (at || opt.doc)[key] = val; return; } diff --git a/lib/radisk.js b/lib/radisk.js index 48426375..187c9393 100644 --- a/lib/radisk.js +++ b/lib/radisk.js @@ -277,7 +277,7 @@ function Radisk(opt){ } return t + '"' + d + s; } else - if(d && d['#'] && (tmp = Gun.val.rel.is(d))){ + if(d && d['#'] && (tmp = Gun.val.link.is(d))){ return t + '#' + tmp + t; } else if(Gun.num.is(d)){ @@ -317,7 +317,7 @@ function Radisk(opt){ return d; } else if('#' === p){ - return Gun.val.rel.ify(d); + return Gun.val.link.ify(d); } else if('+' === p){ if(0 === d.length){ diff --git a/lib/time.js b/lib/time.js index 8fb429ce..8f0cb6b9 100644 --- a/lib/time.js +++ b/lib/time.js @@ -21,7 +21,7 @@ if(typeof window === "undefined"){ //Not in the browser, Include from node cb && cb({err: "Only root level node references supported currently, hopefully will change this in the future."}); return gun; } - data = Gun.val.rel.ify(data); + data = Gun.val.link.ify(data); } opt = (cb === a)? b : a; opt = Gun.text.is(opt)? {key: opt} : opt || {}; diff --git a/lib/unset.js b/lib/unset.js index 93ac47fb..65ae287c 100644 --- a/lib/unset.js +++ b/lib/unset.js @@ -4,7 +4,7 @@ if(typeof window !== "undefined"){ var Gun = require('gun/gun'); } -const rel_ = Gun.val.rel._; // '#' +const rel_ = Gun.val.link._; // '#' const node_ = Gun.node._; // '_' Gun.chain.unset = function(node){ diff --git a/package.json b/package.json index 22d4096c..8ff146e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.9.9991", + "version": "0.9.9992", "description": "A realtime, decentralized, offline-first, graph data synchronization engine.", "main": "index.js", "browser": "gun.min.js", diff --git a/sea.js b/sea.js index e1e6282f..4e554583 100644 --- a/sea.js +++ b/sea.js @@ -1164,7 +1164,7 @@ gunRoot.get(tmp).put(user) }catch(e){console.log(e)} // next up, we want to associate the alias with the public key. So we add it to the alias list. - gunRoot.get('~@'+username).put(Gun.obj.put({}, tmp, Gun.val.rel.ify(tmp))) + gunRoot.get('~@'+username).put(Gun.obj.put({}, tmp, Gun.val.link.ify(tmp))) // callback that the user has been created. (Note: ok = 0 because we didn't wait for disk to ack) setTimeout(() => { cat.ing = false; resolve({ ok: 0, pub: pairs.pub}) }, 10) // TODO: BUG! If `.auth` happens synchronously after `create` finishes, auth won't work. This setTimeout is a temporary hack until we can properly fix it. } catch (e) { @@ -1496,12 +1496,12 @@ }; each.alias = function(val, key, node, soul){ // Example: {_:#~@, ~@alice: {#~@alice}} if(!val){ return each.end({err: "Data must exist!"}) } // data MUST exist - if('~@'+key === Gun.val.rel.is(val)){ return check['alias'+key] = 0 } // in fact, it must be EXACTLY equal to itself + if('~@'+key === Gun.val.link.is(val)){ return check['alias'+key] = 0 } // in fact, it must be EXACTLY equal to itself each.end({err: "Mismatching alias."}); // if it isn't, reject. }; each.pubs = function(val, key, node, soul){ // Example: {_:#~@alice, ~asdf: {#~asdf}} if(!val){ return each.end({err: "Alias must exist!"}) } // data MUST exist - if(key === Gun.val.rel.is(val)){ return check['pubs'+soul+key] = 0 } // and the ID must be EXACTLY equal to its property + if(key === Gun.val.link.is(val)){ return check['pubs'+soul+key] = 0 } // and the ID must be EXACTLY equal to its property each.end({err: "Alias must match!"}); // that way nobody can tamper with the list of public keys. }; each.pub = function(val, key, node, soul, pub, user){ // Example: {_:#~asdf, hello:SEA{'world',fdsa}} @@ -1514,7 +1514,7 @@ //var id = Gun.text.random(3); SEA.sign(val, user.sea, function(data){ var rel; if(u === data){ return each.end({err: SEA.err || 'Pub signature fail.'}) } - if(rel = Gun.val.rel.is(val)){ + if(rel = Gun.val.link.is(val)){ (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true; } node[key] = data; @@ -1528,7 +1528,7 @@ if(u === data){ // make sure the signature matches the account it claims to be on. return each.end({err: "Unverified data."}); // reject any updates that are signed with a mismatched account. } - if((rel = Gun.val.rel.is(data)) && pub === relpub(rel)){ + if((rel = Gun.val.link.is(data)) && pub === relpub(rel)){ (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true; } check['user'+soul+key] = 0; @@ -1550,7 +1550,7 @@ check['any'+soul+key] = 1; SEA.verify(val, pub = tmp, function(data){ var rel; if(!data){ return each.end({err: "Mismatched owner on '" + key + "'."}) } - if((rel = Gun.val.rel.is(data)) && pub === relpub(rel)){ + if((rel = Gun.val.link.is(data)) && pub === relpub(rel)){ (at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true; } check['any'+soul+key] = 0; diff --git a/test/common.js b/test/common.js index 96578284..d142abaf 100644 --- a/test/common.js +++ b/test/common.js @@ -1,170 +1,35 @@ -var root; -(function(env){ - root = env.window? env.window : global; - env.window && root.localStorage && root.localStorage.clear(); - try{ require('fs').unlinkSync('data.json') }catch(e){} - //root.Gun = root.Gun || require('../gun'); - if(root.Gun){ - root.Gun = root.Gun; - } else { - root.Gun = require('../gun'); - Gun.serve = require('../lib/serve'); - //require('./s3'); - //require('./uws'); - //require('./wsp/server'); - require('../lib/file'); - } -}(this)); -//Gun.log.squelch = true; -var gleak = {globals: {}, check: function(){ // via tobyho - var leaked = [] - for (var key in gleak.globe){ if (!(key in gleak.globals)){ leaked.push(key)} } - if (leaked.length > 0){ console.log("GLOBAL LEAK!", leaked); return leaked } -}}; -(function(env){ - for (var key in (gleak.globe = env)){ gleak.globals[key] = true } -}(this)); - -describe('Performance', function(){ return; // performance tests - var console = root.console || {log: function(){}}; - function perf(fn, i){ - i = i || 1000; - while(--i){ - fn(i); - } - } - perf.now = this.performance? function(){ return performance.now() } : function(){ return Gun.time.now()/1000 }; - (function(){ - var t1 = perf.now(); - var obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'}; - Object.keys && perf(function(){ - var l = Object.keys(obj), ll = l.length, i = 0, s = ''; - for(; i < ll; i++){ - var v = l[i]; - s += v; - } - }); - console.log('map: native', (t1 = (perf.now() - t1)/1000) + 's'); - - var t2 = perf.now(); - var obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'}; - perf(function(){ - var s = ''; - Gun.obj.map(obj, function(v){ - s += v; - }) - }); - console.log('map: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); - }()); - (function(){ - if(!Gun.store){ - var tab = Gun().tab; - if(!tab){ return } - Gun.store = tab.store; - } - root.localStorage && root.localStorage.clear(); - var it = 1000; - var t1 = perf.now(); - perf(function(i){ - var obj = {'i': i, 'v': Gun.text.random(100)}; - Gun.store.put('test/native/' + i, obj); - }, it); - console.log('store: native', (t1 = (perf.now() - t1)/1000) + 's'); - - root.localStorage && root.localStorage.clear(); - var gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){ - Gun.is.graph(g, function(node, soul){ - Gun.store.put(soul, node); - }); - cb(null); - }}}); - var t2 = perf.now(); - perf(function(i){ - var obj = {'i': i, 'v': Gun.text.random(100)}; - gun.put(obj); - }, it); - console.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); - root.localStorage && root.localStorage.clear(); - }()); - (function(){ // setTimeout - if(!Gun.store){ - var tab = Gun().tab; - if(!tab){ return } - Gun.store = tab.store; - } - root.localStorage && root.localStorage.clear(); - var t1 = perf.now(); - i = i || 1000; - while(--i){ - var obj = {'i': i, 'v': Gun.text.random(100)}; - Gun.store.put('test/native/' + i, obj); - } - console.log('store: native', (t1 = (perf.now() - t1)/1000) + 's'); - - root.localStorage && root.localStorage.clear(); - var gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){ - Gun.is.graph(g, function(node, soul){ - Gun.store.put(soul, node); - }); - cb(null); - }}}); - var t2 = perf.now(); - perf(function(i){ - var obj = {'i': i, 'v': Gun.text.random(100)}; - gun.put(obj); - }, it); - console.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); - root.localStorage && root.localStorage.clear(); - }()); - (function(){ - var t1 = perf.now(); - var on = Gun.on.create(), c = 0, o = []; - perf(function(i){ - o.push(function(n){ - c += 1; - }); - var ii = 0, l = o.length; - for(; ii < l; ii++){ - o[ii](i); - } - }); - console.log('on: native', (t1 = (perf.now() - t1)/1000) + 's'); - - var on = Gun.on.create(), c = 0; - var t2 = perf.now(); - perf(function(i){ - on('change').event(function(n){ - c += 1; - }); - on('change').emit(i); - }); - console.log('on: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); - }());return; - (function(){ // always do this last! - var t1 = perf.now(); - perf(function(i){ - setTimeout(function(){ - if(i === 1){ - cb1(); - } - },0); - }); var cb1 = function(){ - console.log('setTimeout: native', (t1 = (perf.now() - t1)/1000) + 's', (t1 / t2).toFixed(1)+'x', 'slower.'); - } - var t2 = perf.now(); - perf(function(i){ - setImmediate(function(){ - if(i === 1){ - cb2(); - } - }); - }); var cb2 = function(){ - console.log('setImmediate: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); - } - }()); -}); - describe('Gun', function(){ + + var root; + (function(){ + var env; + if(typeof global !== 'undefined'){ env = global } + if(typeof window !== 'undefined'){ env = window } + root = env.window? env.window : global; + env.window && root.localStorage && root.localStorage.clear(); + try{ require('fs').unlinkSync('data.json') }catch(e){} + //root.Gun = root.Gun || require('../gun'); + if(root.Gun){ + root.Gun = root.Gun; + } else { + root.Gun = require('../gun'); + Gun.serve = require('../lib/serve'); + //require('./s3'); + //require('./uws'); + //require('./wsp/server'); + require('../lib/file'); + } + }(this)); + //Gun.log.squelch = true; + var gleak = {globals: {}, check: function(){ // via tobyho + var leaked = [] + for (var key in gleak.globe){ if (!(key in gleak.globals)){ leaked.push(key)} } + if (leaked.length > 0){ console.log("GLOBAL LEAK!", leaked); return leaked } + }}; + (function(env){ + for (var key in (gleak.globe = env)){ gleak.globals[key] = true } + }(this)); + var t = {}; describe('Utility', function(){ @@ -278,20 +143,20 @@ describe('Gun', function(){ this.document && expect(Gun.obj.is(document.createElement('div'))).to.be(false); expect(Gun.obj.is(new (function Class(){ this.x = 1; this.y = 2 })())).to.be(true); }); - it('fns',function(){ - expect(Gun.fns.is(function(){})).to.be(true); - expect(Gun.fns.is(u)).to.be(false); - expect(Gun.fns.is(null)).to.be(false); - expect(Gun.fns.is('')).to.be(false); - expect(Gun.fns.is('a')).to.be(false); - expect(Gun.fns.is(0)).to.be(false); - expect(Gun.fns.is(1)).to.be(false); - expect(Gun.fns.is([])).to.be(false); - expect(Gun.fns.is([1])).to.be(false); - expect(Gun.fns.is({})).to.be(false); - expect(Gun.fns.is({a:1})).to.be(false); - expect(Gun.fns.is(false)).to.be(false); - expect(Gun.fns.is(true)).to.be(false); + it('fn',function(){ + expect(Gun.fn.is(function(){})).to.be(true); + expect(Gun.fn.is(u)).to.be(false); + expect(Gun.fn.is(null)).to.be(false); + expect(Gun.fn.is('')).to.be(false); + expect(Gun.fn.is('a')).to.be(false); + expect(Gun.fn.is(0)).to.be(false); + expect(Gun.fn.is(1)).to.be(false); + expect(Gun.fn.is([])).to.be(false); + expect(Gun.fn.is([1])).to.be(false); + expect(Gun.fn.is({})).to.be(false); + expect(Gun.fn.is({a:1})).to.be(false); + expect(Gun.fn.is(false)).to.be(false); + expect(Gun.fn.is(true)).to.be(false); }); it('time',function(){ t.ts = Gun.time.is(); @@ -402,7 +267,7 @@ describe('Gun', function(){ setTimeout(this.add(function(){ this.done(null, num * num); }, key), parseInt((""+Math.random()).substring(2,5))); - }, Gun.fns.sum(function(err, val){ + }, Gun.fn.sum(function(err, val){ expect(val.a).to.eql(4); expect(val.b).to.eql(4); expect(val.c).to.eql(9); @@ -780,24 +645,24 @@ describe('Gun', function(){ expect(Gun.val.is({a:1})).to.be(false); expect(Gun.val.is(function(){})).to.be(false); }); - it('is rel',function(){ - expect(Gun.val.rel.is({'#':'somesoulidhere'})).to.be('somesoulidhere'); - expect(Gun.val.rel.is({'#':'somethingelsehere'})).to.be('somethingelsehere'); - expect(Gun.val.rel.is({'#':'somesoulidhere', and: 'nope'})).to.be(false); - expect(Gun.val.rel.is({or: 'nope', '#':'somesoulidhere'})).to.be(false); - expect(Gun.val.rel.is(false)).to.be(false); - expect(Gun.val.rel.is(true)).to.be(false); - expect(Gun.val.rel.is('')).to.be(false); - expect(Gun.val.rel.is('a')).to.be(false); - expect(Gun.val.rel.is(0)).to.be(false); - expect(Gun.val.rel.is(1)).to.be(false); - expect(Gun.val.rel.is(Infinity)).to.be(false); // boohoo :( - expect(Gun.val.rel.is(NaN)).to.be(false); - expect(Gun.val.rel.is([])).to.be(false); - expect(Gun.val.rel.is([1])).to.be(false); - expect(Gun.val.rel.is({})).to.be(false); - expect(Gun.val.rel.is({a:1})).to.be(false); - expect(Gun.val.rel.is(function(){})).to.be(false); + it('is link',function(){ + expect(Gun.val.link.is({'#':'somesoulidhere'})).to.be('somesoulidhere'); + expect(Gun.val.link.is({'#':'somethingelsehere'})).to.be('somethingelsehere'); + expect(Gun.val.link.is({'#':'somesoulidhere', and: 'nope'})).to.be(false); + expect(Gun.val.link.is({or: 'nope', '#':'somesoulidhere'})).to.be(false); + expect(Gun.val.link.is(false)).to.be(false); + expect(Gun.val.link.is(true)).to.be(false); + expect(Gun.val.link.is('')).to.be(false); + expect(Gun.val.link.is('a')).to.be(false); + expect(Gun.val.link.is(0)).to.be(false); + expect(Gun.val.link.is(1)).to.be(false); + expect(Gun.val.link.is(Infinity)).to.be(false); // boohoo :( + expect(Gun.val.link.is(NaN)).to.be(false); + expect(Gun.val.link.is([])).to.be(false); + expect(Gun.val.link.is([1])).to.be(false); + expect(Gun.val.link.is({})).to.be(false); + expect(Gun.val.link.is({a:1})).to.be(false); + expect(Gun.val.link.is(function(){})).to.be(false); }); it.skip('is lex',function(){ expect(Gun.is.lex({'#': 'soul'})).to.eql({soul: 'soul'}); @@ -1021,11 +886,11 @@ describe('Gun', function(){ var data = {users: {1: {where: {lat: Math.random(), lng: Math.random(), i: 1}}}}; Gun.ify(data, function(err, ctx){ var soul, node; - expect(soul = Gun.val.rel.is(ctx.root.users)).to.be.ok(); + expect(soul = Gun.val.link.is(ctx.root.users)).to.be.ok(); node = ctx.graph[soul]; - expect(soul = Gun.val.rel.is(node[1])).to.be.ok(); + expect(soul = Gun.val.link.is(node[1])).to.be.ok(); node = ctx.graph[soul]; - expect(soul = Gun.val.rel.is(node.where)).to.be.ok(); + expect(soul = Gun.val.link.is(node.where)).to.be.ok(); node = ctx.graph[soul]; expect(node.lat).to.be.ok(); expect(node.lng).to.be.ok(); @@ -1538,11 +1403,11 @@ describe('Gun', function(){ done.to = setTimeout(function(){ expect(check.alice.age).to.be(26); expect(check.alice.name).to.be('Alice'); - expect(Gun.val.rel.is(check.alice.pet)).to.be.ok(); + expect(Gun.val.link.is(check.alice.pet)).to.be.ok(); //expect(count.alice).to.be(1); expect(check.bob.age).to.be(29); expect(check.bob.name).to.be('Bob!'); - expect(Gun.val.rel.is(check.bob.pet)).to.be.ok(); + expect(Gun.val.link.is(check.bob.pet)).to.be.ok(); //expect(count.bob).to.be(1); done(); },10); @@ -1756,9 +1621,9 @@ describe('Gun', function(){ gun.get('u/m/mutate/n/u').map().on(function(v,f){ check[v.name] = f; count[v.name] = (count[v.name] || 0) + 1; - //console.log("*****************", f,v); if(check.Alice && check.Bob && check['Alice Zzxyz']){ clearTimeout(done.to); + //console.log("****", f, v) done.to = setTimeout(function(){ expect(done.last).to.be.ok(); //expect(check['Alice Aabca']).to.not.be.ok(); @@ -2187,10 +2052,10 @@ describe('Gun', function(){ done.to = setTimeout(function(){ expect(check.alice.name).to.be('alice'); expect(check.alice.age).to.be(24); - expect(Gun.val.rel.is(check.alice.spouse)).to.be.ok(); + expect(Gun.val.link.is(check.alice.spouse)).to.be.ok(); expect(check.bob.name).to.be('bob'); expect(check.bob.age).to.be(26); - expect(Gun.val.rel.is(check.bob.spouse)).to.be.ok(); + expect(Gun.val.link.is(check.bob.spouse)).to.be.ok(); expect(check.GUN.name).to.be('GUN'); expect(check.ACME.name).to.be('ACME'); expect(check.ACME.corp).to.be('C'); @@ -2274,10 +2139,10 @@ describe('Gun', function(){ done.to = setTimeout(function(){ expect(check.alice.name).to.be('alice'); expect(check.alice.age).to.be(24); - expect(Gun.val.rel.is(check.alice.spouse)).to.be.ok(); + expect(Gun.val.link.is(check.alice.spouse)).to.be.ok(); expect(check.bob.name).to.be('bob'); expect(check.bob.age).to.be(26); - expect(Gun.val.rel.is(check.bob.spouse)).to.be.ok(); + expect(Gun.val.link.is(check.bob.spouse)).to.be.ok(); expect(check.GUN.name).to.be('GUN'); expect(check.ACME.name).to.be('ACME'); expect(check.ACME.corp).to.be('C'); @@ -2970,7 +2835,7 @@ describe('Gun', function(){ //console.log("*****************", data); expect(data.age).to.be(29); expect(data.name).to.be("Bob!"); - expect(Gun.val.rel.is(data.pet)).to.ok(); + expect(Gun.val.link.is(data.pet)).to.ok(); done(); //},300); }); @@ -3146,11 +3011,12 @@ describe('Gun', function(){ //console.log("***", at.put); done.alias = done.alias || at.put.mark; //!console.debug.i&&(console.debug.i=1)&&console.log("---------------------"); - }).get('mark').get(function(at){ + }).get('mark').on(function(data){ //console.log("************", at.put);//return; - setTimeout(function(){ - done.mark = done.mark || at.put.pub; - expect(Gun.val.rel.is(done.mark)).to.be('pub'); + clearTimeout(done.to); + done.to = setTimeout(function(){ + done.mark = done.mark || data.pub; + expect(Gun.val.link.is(done.mark)).to.be('pub'); expect(done.app).to.be.ok(); expect(done.pub).to.be.ok(); expect(done.alias).to.be.ok(); @@ -3498,9 +3364,10 @@ describe('Gun', function(){ list.set(gun.get('dave').put({name: 'dave', age: 25})); var check = {}; - list.val().map().on(function(data, key){ + list.once().map().on(function(data, key){ check[key] = data; clearTimeout(done.to); + //console.log("*****", key, data); done.to = setTimeout(function(){ if(check.alice && check.bob && check.carl && check.dave && done.last){ expect(check.alice.age).to.be(27); @@ -4157,7 +4024,7 @@ describe('Gun', function(){ done.e = 2; return; } - expect(Gun.val.rel.is(data.bob)).to.be.ok(); + expect(Gun.val.link.is(data.bob)).to.be.ok(); done.e = 1; }); }); @@ -4194,7 +4061,7 @@ describe('Gun', function(){ }, s)}); gun.get('only/p/soul').path('bob').any(function(err, data){ //console.log("*********", err, data); - expect(Gun.val.rel.is(data)).to.be.ok(); + expect(Gun.val.link.is(data)).to.be.ok(); //expect(Gun.obj.empty(data, '_')).to.be.ok(); done(); }, {'.': null}); @@ -4216,7 +4083,7 @@ describe('Gun', function(){ if(done.c){ expect(data.age).to.be(30); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); expect(done.c).to.be(1); done(); done.c = 2; @@ -4224,7 +4091,7 @@ describe('Gun', function(){ } expect(data.age).to.be(29); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); done.c=1; }); setTimeout(function(){ @@ -4248,13 +4115,13 @@ describe('Gun', function(){ if(done.c){ expect(data.age).to.be(30); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); done(); return; } expect(data.age).to.be(29); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); done.c=1; }); setTimeout(function(){ @@ -4287,7 +4154,7 @@ describe('Gun', function(){ } expect(data.age).to.be(29); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); }); setTimeout(function(){ gun.get('change/pointer/to/prime').path('bob').put(3); @@ -4362,7 +4229,7 @@ describe('Gun', function(){ expect(done.soul = Gun.node.soul(data)).to.be('dafssfad'); expect(data.age).to.be(29); expect(data.name).to.be('Bob!'); - expect(Gun.val.rel.is(data.pet)).to.be.ok(); + expect(Gun.val.link.is(data.pet)).to.be.ok(); }); return; setTimeout(function(){ @@ -4437,7 +4304,7 @@ describe('Gun', function(){ get.put({foo: 'bar'}); get.any(function(err,data){ //console.log("data", data); - expect(Gun.val.rel.is(data.all)).to.be.ok(); + expect(Gun.val.link.is(data.all)).to.be.ok(); expect(data.foo).to.be('bar'); }); }); @@ -4642,7 +4509,7 @@ describe('Gun', function(){ kn = Gun.obj.copy(kn); delete kn._; expect(Gun.obj.empty(kn, '##')).to.be.ok(); - kn = gun.back(-1)._.graph[Gun.val.rel.is(kn['##'])]; + kn = gun.back(-1)._.graph[Gun.val.link.is(kn['##'])]; Gun.node.is(kn, function(node, s){ var n = gun.back(-1)._.graph[s]; if(Gun.obj.has(n, '##')){ @@ -4842,12 +4709,12 @@ describe('Gun', function(){ var root = gun.back(-1)._.graph[soul]; expect(root.hello).to.be('key'); expect(root.yay).to.not.be.ok(); - expect(Gun.val.rel.is(root.hi)).to.be.ok(); - expect(Gun.val.rel.is(root.hi)).to.not.be(soul); - var node = gun.back(-1)._.graph[Gun.val.rel.is(root.hi)]; + expect(Gun.val.link.is(root.hi)).to.be.ok(); + expect(Gun.val.link.is(root.hi)).to.not.be(soul); + var node = gun.back(-1)._.graph[Gun.val.link.is(root.hi)]; expect(node.yay).to.be('value'); - if(done.sub){ expect(done.sub).to.be(Gun.val.rel.is(root.hi)) } - else { done.sub = Gun.val.rel.is(root.hi) } + if(done.sub){ expect(done.sub).to.be(Gun.val.link.is(root.hi)) } + else { done.sub = Gun.val.link.is(root.hi) } done.w = 1; if(done.r){ done(); done.c = 1 }; }).on(function(node, field){ if(done.c){ return } @@ -4984,7 +4851,7 @@ describe('Gun', function(){ get.val(function(data){ // TODO: API CHANGE! Empty objects should react. //console.log("...1", data); expect(Gun.obj.empty(data, '_')).to.be.ok(); // API CHANGED, - //expect(Gun.val.rel.is(data.very)).to.be.ok(); + //expect(Gun.val.link.is(data.very)).to.be.ok(); });//, {wait: 10000}); setTimeout(function(){ var put = get.put({ @@ -4998,12 +4865,12 @@ describe('Gun', function(){ }); get.val(function(data){ //console.log("...2", data); - expect(Gun.val.rel.is(data.very)).to.be.ok(); + expect(Gun.val.link.is(data.very)).to.be.ok(); }); setTimeout(function(){ put.val(function(data){ //console.log("...3", data); - expect(Gun.val.rel.is(data.very)).to.be.ok(); + expect(Gun.val.link.is(data.very)).to.be.ok(); done.val = true; }); var p = put.path('very'); @@ -5012,7 +4879,7 @@ describe('Gun', function(){ p.val(function(data){ //console.log("...4", data); expect(data.we).to.be('have gone!'); - expect(Gun.val.rel.is(data.deep)).to.be.ok(); + expect(Gun.val.link.is(data.deep)).to.be.ok(); }); p.put('EXPLODE'); setTimeout(function(){ @@ -5104,7 +4971,7 @@ describe('Gun', function(){ var g = gun.get('hello/key', function(err, node){ if(done.soul){ return } expect(err).to.not.be.ok(); - expect(done.ref = Gun.val.rel.is(node.hi)).to.be.ok(); + expect(done.ref = Gun.val.link.is(node.hi)).to.be.ok(); done.soul = Gun.node.soul(node); }); g.path('hi').put({happy: "faces"}, function(err, ok){ @@ -5138,7 +5005,7 @@ describe('Gun', function(){ gun.get('hello/key', function(err, node){ if(done.soul){ return } expect(err).to.not.be.ok(); - expect(done.ref = Gun.val.rel.is(node.hi)).to.be.ok(); + expect(done.ref = Gun.val.link.is(node.hi)).to.be.ok(); done.soul = Gun.node.soul(node); }).path('hi').put('crushed', function(err, ok){ if(done.c){ return } @@ -5472,12 +5339,12 @@ describe('Gun', function(){ expect(err).to.not.be.ok(); }).val(function(val){ setTimeout(function(){ // TODO: Is this cheating? I don't think so cause we are using things outside of the API! - var a = gun.back(-1)._.graph[Gun.val.rel.is(val.a)]; - var b = gun.back(-1)._.graph[Gun.val.rel.is(val.b)]; - expect(Gun.val.rel.is(val.a)).to.be(Gun.node.soul(a)); - expect(Gun.val.rel.is(val.b)).to.be(Gun.node.soul(b)); - expect(Gun.val.rel.is(a.kid)).to.be(Gun.node.soul(b)); - expect(Gun.val.rel.is(b.parent)).to.be(Gun.node.soul(a)); + var a = gun.back(-1)._.graph[Gun.val.link.is(val.a)]; + var b = gun.back(-1)._.graph[Gun.val.link.is(val.b)]; + expect(Gun.val.link.is(val.a)).to.be(Gun.node.soul(a)); + expect(Gun.val.link.is(val.b)).to.be(Gun.node.soul(b)); + expect(Gun.val.link.is(a.kid)).to.be(Gun.node.soul(b)); + expect(Gun.val.link.is(b.parent)).to.be(Gun.node.soul(a)); done(); },10); }); @@ -5579,8 +5446,8 @@ describe('Gun', function(){ }).val(function(val){ expect(val.age).to.be(23); expect(val.name).to.be("Mark Nadal"); - expect(Gun.val.rel.is(val.wife)).to.be.ok(); - expect(Gun.val.rel.is(val.pet)).to.be.ok(); + expect(Gun.val.link.is(val.wife)).to.be.ok(); + expect(Gun.val.link.is(val.pet)).to.be.ok(); }).path('wife.pet.name').val(function(val){ //console.debug(1, "*****************", val); expect(val).to.be('Hobbes'); @@ -5589,7 +5456,7 @@ describe('Gun', function(){ expect(val.name).to.be("Amber Nadal"); expect(val.phd).to.be.ok(); expect(val.age).to.be(23); - expect(Gun.val.rel.is(val.pet)).to.be.ok(); + expect(Gun.val.link.is(val.pet)).to.be.ok(); done(); }); }); @@ -5686,7 +5553,7 @@ describe('Gun', function(){ foo.put({bar: {zoo: 'who'}}).val(function(obj, field){ //console.log("terribly terrilby unpleasant", field, obj); expect(obj.foo).to.be('bar'); - expect(Gun.val.rel.is(obj.bar)).to.ok(); + expect(Gun.val.link.is(obj.bar)).to.ok(); done(); //setTimeout(function(){ done() },1); }); }); @@ -5718,8 +5585,8 @@ describe('Gun', function(){ expect(obj.another).to.be('node'); // double .vals here also RELATED to the #"context no double emit" but because of a faulty .not or .init system. bar.val(function(node){ - expect(Gun.val.rel.is(node.combo)).to.be.ok(); - expect(Gun.val.rel.is(node.combo)).to.be(Gun.node.soul(obj)); + expect(Gun.val.link.is(node.combo)).to.be.ok(); + expect(Gun.val.link.is(node.combo)).to.be(Gun.node.soul(obj)); done(); //setTimeout(function(){ done() },1); }); }); @@ -6253,7 +6120,7 @@ describe('Gun', function(){ users.path(Gun.text.random()).put('sam'); setTimeout(function(){ users.val(function(v){ - expect(Gun.val.rel.is(v)).to.not.be.ok(); + expect(Gun.val.link.is(v)).to.not.be.ok(); expect(Object.keys(v).length).to.be(3); done(); }); @@ -7343,11 +7210,11 @@ describe('Gun', function(){ //console.log("chain.put PUT <----", ify.graph, '\n'); if(err || ify.err){ return cb.call(gun, err || ify.err) } if(err = Gun.union(gun, ify.graph).err){ return cb.call(gun, err) } - if($.from = Gun.val.rel.is(ify.root[$.field])){ $.soul = $.from; $.field = null } + if($.from = Gun.val.link.is(ify.root[$.field])){ $.soul = $.from; $.field = null } Gun.obj.map(ify.graph, function(node, soul){ Gun.union(gun, Gun.union.pseudo(soul)) }); gun._.at('soul').emit({soul: $.soul, field: $.field, key: $.key, PUT: 'SOUL', WAS: 'ON'}); // WAS ON //return cb(null, true); - if(Gun.fns.is(ctx.hook = gun.__.opt.hooks.put)){ + if(Gun.fn.is(ctx.hook = gun.__.opt.hooks.put)){ ctx.hook(ify.graph, function(err, data){ // now iterate through those nodes to a persistence layer and get a callback once all are saved if(err){ return cb.call(gun, err) } return cb.call(gun, null, data); @@ -7506,11 +7373,11 @@ describe('Gun', function(){ expect(done.c++).to.be(0); }).val(function(p){ done.p = Gun.node.soul(p); - done.m = Gun.val.rel.is(p[0]); - expect(Gun.val.rel.is(p[0])).to.be.ok(); - expect(Gun.val.rel.is(p[1])).to.be.ok(); - expect(Gun.val.rel.is(p[2])).to.be.ok(); - expect(Gun.val.rel.is(p[3])).to.be.ok(); + done.m = Gun.val.link.is(p[0]); + expect(Gun.val.link.is(p[0])).to.be.ok(); + expect(Gun.val.link.is(p[1])).to.be.ok(); + expect(Gun.val.link.is(p[2])).to.be.ok(); + expect(Gun.val.link.is(p[3])).to.be.ok(); }) var players = [], me; @@ -8023,19 +7890,19 @@ describe('Gun', function(){ test.val(function(node,b){ delete node._; expect(Gun.obj.empty(node, 'try')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.val.rel.is(node.try)]); + node = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.try)]); delete node._; expect(Gun.obj.empty(node, 'this')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.val.rel.is(node.this)]); + node = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.this)]); delete node._; expect(Gun.obj.empty(node, 'at')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.val.rel.is(node.at)]); + node = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.at)]); delete node._; expect(Gun.obj.empty(node, 'lvl4')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.val.rel.is(node.lvl4)]); + node = Gun.obj.copy(gun.__.graph[Gun.val.link.is(node.lvl4)]); delete node._; expect(Gun.obj.empty(node, 'msg')).to.be.ok(); diff --git a/test/mocha.html b/test/mocha.html index cc6088d6..0ee65c5f 100644 --- a/test/mocha.html +++ b/test/mocha.html @@ -18,6 +18,28 @@ - + \ No newline at end of file diff --git a/test/old/performance.js b/test/old/performance.js new file mode 100644 index 00000000..3243db11 --- /dev/null +++ b/test/old/performance.js @@ -0,0 +1,138 @@ +describe('Performance', function(){ return; // performance tests + var console = root.console || {log: function(){}}; + function perf(fn, i){ + i = i || 1000; + while(--i){ + fn(i); + } + } + perf.now = this.performance? function(){ return performance.now() } : function(){ return Gun.time.now()/1000 }; + (function(){ + var t1 = perf.now(); + var obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'}; + Object.keys && perf(function(){ + var l = Object.keys(obj), ll = l.length, i = 0, s = ''; + for(; i < ll; i++){ + var v = l[i]; + s += v; + } + }); + console.log('map: native', (t1 = (perf.now() - t1)/1000) + 's'); + + var t2 = perf.now(); + var obj = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i'}; + perf(function(){ + var s = ''; + Gun.obj.map(obj, function(v){ + s += v; + }) + }); + console.log('map: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); + }()); + (function(){ + if(!Gun.store){ + var tab = Gun().tab; + if(!tab){ return } + Gun.store = tab.store; + } + root.localStorage && root.localStorage.clear(); + var it = 1000; + var t1 = perf.now(); + perf(function(i){ + var obj = {'i': i, 'v': Gun.text.random(100)}; + Gun.store.put('test/native/' + i, obj); + }, it); + console.log('store: native', (t1 = (perf.now() - t1)/1000) + 's'); + + root.localStorage && root.localStorage.clear(); + var gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){ + Gun.is.graph(g, function(node, soul){ + Gun.store.put(soul, node); + }); + cb(null); + }}}); + var t2 = perf.now(); + perf(function(i){ + var obj = {'i': i, 'v': Gun.text.random(100)}; + gun.put(obj); + }, it); + console.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); + root.localStorage && root.localStorage.clear(); + }()); + (function(){ // setTimeout + if(!Gun.store){ + var tab = Gun().tab; + if(!tab){ return } + Gun.store = tab.store; + } + root.localStorage && root.localStorage.clear(); + var t1 = perf.now(); + i = i || 1000; + while(--i){ + var obj = {'i': i, 'v': Gun.text.random(100)}; + Gun.store.put('test/native/' + i, obj); + } + console.log('store: native', (t1 = (perf.now() - t1)/1000) + 's'); + + root.localStorage && root.localStorage.clear(); + var gun = Gun({wire: {get:function(l,cb){cb()},put:function(g,cb){ + Gun.is.graph(g, function(node, soul){ + Gun.store.put(soul, node); + }); + cb(null); + }}}); + var t2 = perf.now(); + perf(function(i){ + var obj = {'i': i, 'v': Gun.text.random(100)}; + gun.put(obj); + }, it); + console.log('store: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); + root.localStorage && root.localStorage.clear(); + }()); + (function(){ + var t1 = perf.now(); + var on = Gun.on.create(), c = 0, o = []; + perf(function(i){ + o.push(function(n){ + c += 1; + }); + var ii = 0, l = o.length; + for(; ii < l; ii++){ + o[ii](i); + } + }); + console.log('on: native', (t1 = (perf.now() - t1)/1000) + 's'); + + var on = Gun.on.create(), c = 0; + var t2 = perf.now(); + perf(function(i){ + on('change').event(function(n){ + c += 1; + }); + on('change').emit(i); + }); + console.log('on: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); + }());return; + (function(){ // always do this last! + var t1 = perf.now(); + perf(function(i){ + setTimeout(function(){ + if(i === 1){ + cb1(); + } + },0); + }); var cb1 = function(){ + console.log('setTimeout: native', (t1 = (perf.now() - t1)/1000) + 's', (t1 / t2).toFixed(1)+'x', 'slower.'); + } + var t2 = perf.now(); + perf(function(i){ + setImmediate(function(){ + if(i === 1){ + cb2(); + } + }); + }); var cb2 = function(){ + console.log('setImmediate: gun', (t2 = (perf.now() - t2)/1000) + 's', (t2 / t1).toFixed(1)+'x', 'slower.'); + } + }()); +}); \ No newline at end of file diff --git a/test/panic/speak.js b/test/panic/speak.js index 7af18e66..130e7c38 100644 --- a/test/panic/speak.js +++ b/test/panic/speak.js @@ -172,7 +172,7 @@ describe("Stress test GUN with SEA users causing PANIC!", function(){ var no; Gun.node.is(at.put.users, function(val, key){ Gun.SEA.read(val, false, function(val){ - if('alias/'+key === Gun.val.rel.is(val)){ return } + if('alias/'+key === Gun.val.link.is(val)){ return } no = true; }) if(no){ return no } diff --git a/test/say.html b/test/say.html index 316e6fb6..27d1ccb8 100644 --- a/test/say.html +++ b/test/say.html @@ -15,7 +15,7 @@ var no; Gun.node.is(at.put.users, function(val, key){ Gun.SEA.read(val, false, function(val){ - if('alias/'+key === Gun.val.rel.is(val)){ return } + if('alias/'+key === Gun.val.link.is(val)){ return } no = true; }) if(no){ return no }