From 6cb7261ac26b5b010ca13c00207629410a3b7d44 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Mon, 23 Aug 2021 00:59:58 -0700 Subject: [PATCH] unbuild fixes & shim temporary deprecations for publication --- gun.js | 453 ++++++++++++++++++++++++++++++++++++++++++++ gun.min.js | 2 +- src/ask.js | 3 +- src/get.js | 1 + src/localStorage.js | 1 + src/put.js | 9 +- src/root.js | 28 +-- src/shim.js | 2 +- src/websocket.js | 3 + 9 files changed, 482 insertions(+), 20 deletions(-) diff --git a/gun.js b/gun.js index ef8a46bb..f28f7559 100644 --- a/gun.js +++ b/gun.js @@ -1758,4 +1758,457 @@ }); })(USE, './localStorage'); +}()); + +/* BELOW IS TEMPORARY FOR OLD INTERNAL COMPATIBILITY, THEY ARE IMMEDIATELY DEPRECATED AND WILL BE REMOVED IN NEXT VERSION */ +;(function(){ + var u; + if(''+u == typeof Gun){ return } + var DEP = function(n){ console.log("Warning! Deprecated internal utility will break in next version:", n) } + // Generic javascript utilities. + var Type = Gun; + //Type.fns = Type.fn = {is: function(fn){ return (!!fn && fn instanceof Function) }} + Type.fn = Type.fn || {is: function(fn){ DEP('fn'); return (!!fn && 'function' == typeof fn) }} + Type.bi = Type.bi || {is: function(b){ DEP('bi');return (b instanceof Boolean || typeof b == 'boolean') }} + Type.num = Type.num || {is: function(n){ DEP('num'); return !list_is(n) && ((n - parseFloat(n) + 1) >= 0 || Infinity === n || -Infinity === n) }} + Type.text = Type.text || {is: function(t){ DEP('text'); return (typeof t == 'string') }} + Type.text.ify = Type.text.ify || function(t){ DEP('text.ify'); + if(Type.text.is(t)){ return t } + if(typeof JSON !== "undefined"){ return JSON.stringify(t) } + return (t && t.toString)? t.toString() : t; + } + Type.text.random = Type.text.random || function(l, c){ DEP('text.random'); + var s = ''; + l = l || 24; // you are not going to make a 0 length random number, so no need to check type + c = c || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz'; + while(l > 0){ s += c.charAt(Math.floor(Math.random() * c.length)); l-- } + return s; + } + Type.text.match = Type.text.match || function(t, o){ var tmp, u; DEP('text.match'); + 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(u !== o['>'] && t >= o['>']){ return true } + if(u !== o['<'] && t <= o['<']){ return true } + return false; + } + Type.text.hash = Type.text.hash || function(s, c){ // via SO + DEP('text.hash'); + if(typeof s !== 'string'){ return } + c = c || 0; + if(!s.length){ return c } + for(var i=0,l=s.length,n; i B){ return 1 } + else { return 0 } + } + } + Type.list.map = Type.list.map || function(l, c, _){ DEP('list.map'); return obj_map(l, c, _) } + Type.list.index = 1; // change this to 0 if you want non-logical, non-mathematical, non-matrix, non-convenient array notation + Type.obj = Type.boj || {is: function(o){ DEP('obj'); return o? (o instanceof Object && o.constructor === Object) || Object.prototype.toString.call(o).match(/^\[object (\w+)\]$/)[1] === 'Object' : false }} + Type.obj.put = Type.obj.put || function(o, k, v){ DEP('obj.put'); return (o||{})[k] = v, o } + Type.obj.has = Type.obj.has || function(o, k){ DEP('obj.has'); return o && Object.prototype.hasOwnProperty.call(o, k) } + Type.obj.del = Type.obj.del || function(o, k){ DEP('obj.del'); + if(!o){ return } + o[k] = null; + delete o[k]; + return o; + } + Type.obj.as = Type.obj.as || function(o, k, v, u){ DEP('obj.as'); return o[k] = o[k] || (u === v? {} : v) } + Type.obj.ify = Type.obj.ify || function(o){ DEP('obj.ify'); + if(obj_is(o)){ return o } + try{o = JSON.parse(o); + }catch(e){o={}}; + return o; + } + ;(function(){ var u; + function map(v,k){ + if(obj_has(this,k) && u !== this[k]){ return } + this[k] = v; + } + Type.obj.to = Type.obj.to || function(from, to){ DEP('obj.to'); + to = to || {}; + obj_map(from, map, to); + return to; + } + }()); + Type.obj.copy = Type.obj.copy || function(o){ DEP('obj.copy'); // because http://web.archive.org/web/20140328224025/http://jsperf.com/cloning-an-object/2 + return !o? o : JSON.parse(JSON.stringify(o)); // is shockingly faster than anything else, and our data has to be a subset of JSON anyways! + } + ;(function(){ + function empty(v,i){ var n = this.n, u; + if(n && (i === n || (obj_is(n) && obj_has(n, i)))){ return } + if(u !== i){ return true } + } + Type.obj.empty = Type.obj.empty || function(o, n){ DEP('obj.empty'); + if(!o){ return true } + return obj_map(o,empty,{n:n})? false : true; + } + }()); + ;(function(){ + function t(k,v){ + if(2 === arguments.length){ + t.r = t.r || {}; + t.r[k] = v; + return; + } t.r = t.r || []; + t.r.push(k); + }; + var keys = Object.keys, map, u; + Object.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) } + Type.obj.map = map = Type.obj.map || function(l, c, _){ DEP('obj.map'); + var u, i = 0, x, r, ll, lle, f = 'function' == typeof c; + t.r = u; + if(keys && obj_is(l)){ + ll = keys(l); lle = true; + } + _ = _ || {}; + if(list_is(l) || ll){ + x = (ll || l).length; + for(;i < x; i++){ + var ii = (i + Type.list.index); + if(f){ + r = lle? c.call(_, l[ll[i]], ll[i], t) : c.call(_, l[i], ii, t); + if(r !== u){ return r } + } else { + //if(Type.test.is(c,l[i])){ return ii } // should implement deep equality testing! + if(c === l[lle? ll[i] : i]){ return ll? ll[i] : ii } // use this for now + } + } + } else { + for(i in l){ + if(f){ + if(obj_has(l,i)){ + r = _? c.call(_, l[i], i, t) : c(l[i], i, t); + if(r !== u){ return r } + } + } else { + //if(a.test.is(c,l[i])){ return i } // should implement deep equality testing! + if(c === l[i]){ return i } // use this for now + } + } + } + return f? t.r : Type.list.index? 0 : -1; + } + }()); + Type.time = Type.time || {}; + Type.time.is = Type.time.is || function(t){ DEP('time'); return t? t instanceof Date : (+new Date().getTime()) } + + var fn_is = Type.fn.is; + var list_is = Type.list.is; + var obj = Type.obj, obj_is = obj.is, obj_has = obj.has, obj_map = obj.map; + + var Val = {}; + Val.is = function(v){ DEP('val.is'); // Valid values are a subset of JSON: null, binary, number (!Infinity), text, or a soul relation. Arrays need special algorithms to handle concurrency, so they are not supported directly. Use an extension that supports them if needed but research their problems first. + if(v === u){ return false } + if(v === null){ return true } // "deletes", nulling out keys. + if(v === Infinity){ return false } // we want this to be, but JSON does not support it, sad face. + if(text_is(v) // by "text" we mean strings. + || bi_is(v) // by "binary" we mean boolean. + || num_is(v)){ // by "number" we mean integers or decimals. + return true; // simple values are valid. + } + return Val.link.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.link = Val.rel = {_: '#'}; + ;(function(){ + Val.link.is = function(v){ DEP('val.link.is'); // 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. + var o = {}; + obj_map(v, map, o); + if(o.id){ // a valid id was found. + return o.id; // yay! Return it. + } + } + return false; // the value was not a valid soul relation. + } + function map(s, k){ var o = this; // map over the object... + if(o.id){ return o.id = false } // if ID is already defined AND we're still looping through the object, it is considered invalid. + if(k == rel_ && text_is(s)){ // the key should be '#' and have a text value. + o.id = s; // we found the soul! + } else { + return o.id = false; // if there exists anything else on the object that isn't the soul, then it is considered invalid. + } + } + }()); + Val.link.ify = function(t){ DEP('val.link.ify'); return obj_put({}, rel_, t) } // convert a soul into a relation and return it. + Type.obj.has._ = '.'; + var rel_ = Val.link._, u; + var bi_is = Type.bi.is; + var num_is = Type.num.is; + var text_is = Type.text.is; + var obj = Type.obj, obj_is = obj.is, obj_put = obj.put, obj_map = obj.map; + + Type.val = Type.val || Val; + + var Node = {_: '_'}; + Node.soul = function(n, o){ DEP('node.soul'); return (n && n._ && n._[o || soul_]) } // convenience function to check to see if there is a soul on a node and return it. + Node.soul.ify = function(n, o){ DEP('node.soul.ify'); // put a soul on an object. + o = (typeof o === 'string')? {soul: o} : o || {}; + n = n || {}; // make sure it exists. + n._ = n._ || {}; // make sure meta exists. + n._[soul_] = o.soul || n._[soul_] || text_random(); // put the soul on it. + return n; + } + Node.soul._ = Val.link._; + ;(function(){ + Node.is = function(n, cb, as){ DEP('node.is'); var s; // checks to see if an object is a valid node. + if(!obj_is(n)){ return false } // must be an object. + if(s = Node.soul(n)){ // must have a soul on it. + return !obj_map(n, map, {as:as,cb:cb,s:s,n:n}); + } + return false; // nope! This was not a valid node. + } + function map(v, k){ // we invert this because the way we check for this is via a negation. + if(k === Node._){ return } // skip over the metadata. + if(!Val.is(v)){ return true } // it is true that this is an invalid node. + if(this.cb){ this.cb.call(this.as, v, k, this.n, this.s) } // optionally callback each key/value. + } + }()); + ;(function(){ + Node.ify = function(obj, o, as){ DEP('node.ify'); // returns a node from a shallow object. + if(!o){ o = {} } + else if(typeof o === 'string'){ o = {soul: o} } + else if('function' == typeof o){ o = {map: o} } + if(o.map){ o.node = o.map.call(as, obj, u, o.node || {}) } + if(o.node = Node.soul.ify(o.node || {}, o)){ + obj_map(obj, map, {o:o,as:as}); + } + return o.node; // This will only be a valid node if the object wasn't already deep! + } + function map(v, k){ var o = this.o, tmp, u; // iterate over each key/value. + if(o.map){ + tmp = o.map.call(this.as, v, ''+k, o.node); + if(u === tmp){ + obj_del(o.node, k); + } else + if(o.node){ o.node[k] = tmp } + return; + } + if(Val.is(v)){ + o.node[k] = v; + } + } + }()); + var obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_map = obj.map; + var text = Type.text, text_random = text.random; + var soul_ = Node.soul._; + var u; + Type.node = Type.node || Node; + + var State = Type.state; + State.lex = function(){ DEP('state.lex'); return State().toString(36).replace('.','') } + State.to = function(from, k, to){ DEP('state.to'); + var val = (from||{})[k]; + if(obj_is(val)){ + val = obj_copy(val); + } + return State.ify(to, k, State.is(from, k), val, Node.soul(from)); + } + ;(function(){ + State.map = function(cb, s, as){ DEP('state.map'); var u; // for use with Node.ify + var o = obj_is(o = cb || s)? o : null; + cb = fn_is(cb = cb || s)? cb : null; + if(o && !cb){ + s = num_is(s)? s : State(); + o[N_] = o[N_] || {}; + obj_map(o, map, {o:o,s:s}); + return o; + } + as = as || obj_is(s)? s : u; + s = num_is(s)? s : State(); + return function(v, k, o, opt){ + if(!cb){ + map.call({o: o, s: s}, v,k); + return v; + } + cb.call(as || this || {}, v, k, o, opt); + if(obj_has(o,k) && u === o[k]){ return } + map.call({o: o, s: s}, v,k); + } + } + function map(v,k){ + if(N_ === k){ return } + State.ify(this.o, k, this.s) ; + } + }()); + var obj = Type.obj, obj_as = obj.as, obj_has = obj.has, obj_is = obj.is, obj_map = obj.map, obj_copy = obj.copy; + var num = Type.num, num_is = num.is; + var fn = Type.fn, fn_is = fn.is; + var N_ = Node._, u; + + var Graph = {}; + ;(function(){ + Graph.is = function(g, cb, fn, as){ DEP('graph.is'); // checks to see if an object is a valid graph. + if(!g || !obj_is(g) || obj_empty(g)){ return false } // must be an object. + return !obj_map(g, map, {cb:cb,fn:fn,as:as}); // makes sure it wasn't an empty object. + } + function map(n, s){ // we invert this because the way'? we check for this is via a negation. + if(!n || s !== Node.soul(n) || !Node.is(n, this.fn, this.as)){ return true } // it is true that this is an invalid graph. + if(!this.cb){ return } + nf.n = n; nf.as = this.as; // sequential race conditions aren't races. + this.cb.call(nf.as, n, s, nf); + } + function nf(fn){ // optional callback for each node. + if(fn){ Node.is(nf.n, fn, nf.as) } // where we then have an optional callback for each key/value. + } + }()); + ;(function(){ + Graph.ify = function(obj, env, as){ DEP('graph.ify'); + var at = {path: [], obj: obj}; + if(!env){ + env = {}; + } else + if(typeof env === 'string'){ + env = {soul: env}; + } else + if('function' == typeof env){ + env.map = env; + } + if(typeof as === 'string'){ + env.soul = env.soul || as; + as = u; + } + if(env.soul){ + at.link = Val.link.ify(env.soul); + } + env.shell = (as||{}).shell; + env.graph = env.graph || {}; + env.seen = env.seen || []; + env.as = env.as || as; + node(env, at); + env.root = at.node; + return env.graph; + } + function node(env, at){ var tmp; + if(tmp = seen(env, at)){ return tmp } + at.env = env; + at.soul = soul; + if(Node.ify(at.obj, map, at)){ + at.link = at.link || Val.link.ify(Node.soul(at.node)); + if(at.obj !== env.shell){ + env.graph[Val.link.is(at.link)] = at.node; + } + } + return at; + } + function map(v,k,n){ + var at = this, env = at.env, is, tmp; + if(Node._ === k && obj_has(v,Val.link._)){ + return n._; // TODO: Bug? + } + if(!(is = valid(v,k,n, at,env))){ return } + if(!k){ + at.node = at.node || n || {}; + if(obj_has(v, Node._) && Node.soul(v)){ // ? for safety ? + at.node._ = obj_copy(v._); + } + at.node = Node.soul.ify(at.node, Val.link.is(at.link)); + at.link = at.link || Val.link.ify(Node.soul(at.node)); + } + if(tmp = env.map){ + tmp.call(env.as || {}, v,k,n, at); + if(obj_has(n,k)){ + v = n[k]; + if(u === v){ + obj_del(n, k); + return; + } + if(!(is = valid(v,k,n, at,env))){ return } + } + } + if(!k){ return at.node } + if(true === is){ + return v; + } + tmp = node(env, {obj: v, path: at.path.concat(k)}); + if(!tmp.node){ return } + return tmp.link; //{'#': Node.soul(tmp.node)}; + } + function soul(id){ var at = this; + var prev = Val.link.is(at.link), graph = at.env.graph; + at.link = at.link || Val.link.ify(id); + at.link[Val.link._] = id; + if(at.node && at.node[Node._]){ + at.node[Node._][Val.link._] = id; + } + if(obj_has(graph, prev)){ + graph[id] = graph[prev]; + obj_del(graph, prev); + } + } + function valid(v,k,n, at,env){ var tmp; + if(Val.is(v)){ return true } + if(obj_is(v)){ return 1 } + if(tmp = env.invalid){ + v = tmp.call(env.as || {}, v,k,n); + return valid(v,k,n, at,env); + } + env.err = "Invalid value at '" + at.path.concat(k).join('.') + "'!"; + if(Type.list.is(v)){ env.err += " Use `.set(item)` instead of an Array." } + } + function seen(env, at){ + var arr = env.seen, i = arr.length, has; + while(i--){ has = arr[i]; + if(at.obj === has.obj){ return has } + } + arr.push(at); + } + }()); + Graph.node = function(node){ DEP('graph.node'); + var soul = Node.soul(node); + if(!soul){ return } + return obj_put({}, soul, node); + } + ;(function(){ + Graph.to = function(graph, root, opt){ DEP('graph.to'); + if(!graph){ return } + var obj = {}; + opt = opt || {seen: {}}; + obj_map(graph[root], map, {obj:obj, graph: graph, opt: opt}); + return obj; + } + function map(v,k){ var tmp, obj; + if(Node._ === k){ + if(obj_empty(v, Val.link._)){ + return; + } + this.obj[k] = obj_copy(v); + return; + } + if(!(tmp = Val.link.is(v))){ + this.obj[k] = v; + return; + } + if(obj = this.opt.seen[tmp]){ + this.obj[k] = obj; + return; + } + this.obj[k] = this.opt.seen[tmp] = Graph.to(this.graph, tmp, this.opt); + } + }()); + var fn_is = Type.fn.is; + var obj = Type.obj, obj_is = obj.is, obj_del = obj.del, obj_has = obj.has, obj_empty = obj.empty, obj_put = obj.put, obj_map = obj.map, obj_copy = obj.copy; + var u; + Type.graph = Type.graph || Graph; }()); \ No newline at end of file diff --git a/gun.min.js b/gun.min.js index bf55fd98..9aa10246 100644 --- a/gun.min.js +++ b/gun.min.js @@ -1 +1 @@ -!function(){function f(n,t){return t?require(n):n.slice?f[o(n)]:function(t,e){n(t={exports:{}}),f[o(e)]=t.exports};function o(t){return t.split("/").slice(-1).toString().replace(".js","")}}if("undefined"!=typeof module)var e=module;f(function(t){String.random=function(t,e){var n="";for(t=t||24,e=e||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0"]||e["<"])||o===e["="]&&(n=e["*"]||e[">"],t.slice(0,(n||"").length)===n||o===e["*"]&&(o!==e[">"]&&o!==e["<"]?t>=e[">"]&&t<=e["<"]:o!==e[">"]&&t>=e[">"]||o!==e["<"]&&t<=e["<"])))},String.hash=function(t,e){if("string"==typeof t){if(e=e||0,!t.length)return e;for(var n=0,o=t.length;n"]||n;if(o)return"number"==typeof(o=o[e])?o:-1/0},e.ify=function(t,e,n,o,i){(t=t||{})._=t._||{},i&&(t._["#"]=i);var r=t._[">"]||(t._[">"]={});return void 0!==e&&"_"!==e&&("number"==typeof n&&(r[e]=n),void 0!==o&&(t[e]=o)),t},t.exports=e})(f,"./state"),f(function(t){f("./shim"),t.exports=function(o){var i={s:{}},r=i.s;o=o||{max:999,age:9e3},i.check=function(t){return!!r[t]&&e(t)};var e=i.track=function(t){var e=r[t]||(r[t]={});return e.was=i.now=+new Date,i.to||(i.to=setTimeout(i.drop,o.age+9)),e};return i.drop=function(n){i.to=null,i.now=+new Date;var t=Object.keys(r);console.STAT&&console.STAT(i.now,+new Date-i.now,"dup drop keys"),setTimeout.each(t,function(t){var e=r[t];e&&(n||o.age)>i.now-e.was||delete r[t]},0,99)},i}})(f,"./dup"),f(function(t){f("./onto"),t.exports=function(t,e){if(this.on){var n=(this.opt||{}).lack||9e3;if("function"!=typeof t){if(!t)return;var o=t["#"]||t,i=(this.tag||"")[o];if(!i)return;return e&&(i=this.on(o,e),clearTimeout(i.err),i.err=setTimeout(function(){i.off()},n)),!0}o=e&&e["#"]||Math.random().toString(36).slice(2);if(!t)return o;var r=this.on(o,t,e);return r.err=r.err||setTimeout(function(){r.off(),r.next({err:"Error: No ACK yet.",lack:!0})},n),o}}})(f,"./ask"),f(function(t){function s(t){return t instanceof s?(this._={$:this}).$:this instanceof s?s.create(this._={$:this,opt:t}):new s(t)}function c(t,a){var u=+new Date,e=t._||{},s=e.DBG=t.DBG,c=t["#"],f=g(9),l=Object.keys(a||"").sort(),h=((a||"")._||"")["#"],p=(l.length,t.$._.root),d=a===p.graph[h];console.STAT&&console.STAT(u,((s||e).gk=+new Date)-u,"got keys"),a&&function t(){u=+new Date;for(var e,n,o,i=0,r={};i<9&&(e=l[i++]);)O(r,e,m(a,e),a[e],h);l=l.slice(i),(n={})[h]=r,r=n,d&&((o=function(){}).ram=o.faith=!0),n=l.length,console.STAT&&console.STAT(u,-(u-(u=+new Date)),"got copied some"),s&&(s.ga=+new Date),p.on("in",{"@":c,"#":f,put:r,"%":n?f=g(9):S,$:p.$,_:o,DBG:s}),console.STAT&&console.STAT(u,+new Date-u,"got in"),n&&setTimeout.turn(t)}(),a||p.on("in",{"@":t["#"]})}s.is=function(t){return t instanceof s||t&&t._&&t===t._.$||!1},s.version=.202,(s.chain=s.prototype).toJSON=function(){},f("./shim"),s.valid=f("./valid"),s.state=f("./state"),s.on=f("./onto"),s.dup=f("./dup"),s.ask=f("./ask"),function(){function $(t){if(t)if(t.out!==$){var e,n=this.as,o=n.at||n,i=o.$,r=o.dup,a=t.DBG;if((e=t["#"])||(e=t["#"]=g(9)),!r.check(e)){if(r.track(e),e=t._,t._="function"==typeof e?e:function(){},t.$&&t.$===(t.$._||"").$||(t.$=i),t["@"]&&!t.put&&function(t){var e,n=t["@"]||"",o=(t.$._||"").root;if(!(e=n._))return;e.acks=(e.acks||0)+1,(e.err=t.err)&&(t["@"]=e["#"],--e.stun);if(0==e.stun&&e.acks==e.all)o&&o.on("in",{"@":e["#"],err:t.err,ok:t.err?S:"shard"}),t.err&&b(e)}(t),!o.ask(t["@"],t)){if(a&&(a.u=+new Date),t.put)return void u(t);t.get&&s.on.get(t,i)}a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.nts||t.NTS||(t.out=$,o.on("out",t),a&&(a.ue=+new Date))}}else this.to.next(t)}function u(a){if(a){var u=a._||"",t=u.root=((u.$=a.$||"")._||"").root;if(a["@"]&&u.faith&&!u.miss)return a.out=$,void t.on("out",a);u.latch=t.hatch,u.match=t.hatch=[];var s=a.put,c=u.DBG=a.DBG,f=+new Date;if(!s["#"]||!s["."]){c&&(c.p=f),u["#"]=a["#"],u.msg=a,u.all=0,u.stun=1;var l=Object.keys(s);console.STAT&&console.STAT(f,((c||u).pk=+new Date)-f,"put sort");var h,p,d,g,v,y,k,m=0;!function t(e){if(h!=m){if(!(d=l[h=m]))return console.STAT&&console.STAT(f,((c||u).pd=+new Date)-f,"put"),void b(u);(g=s[d])?(k=g._)?d!==k["#"]?y=_+T(d)+"soul not same.":(v=k[">"])||(y=_+T(d)+"no state."):y=_+T(d)+"no meta.":y=_+T(d)+"no node.",p=Object.keys(g||{})}if(y)return a.err=u.err=y,void b(u);var n,o=0;for(e=e||0;e++<9&&(n=p[o++]);)if("_"!==n){var i=g[n],r=v[n];if(S===r){y=_+T(n)+"on"+T(d)+"no state.";break}if(!D(i)){y=_+T(n)+"on"+T(d)+"bad "+typeof i+T(i);break}w(i,n,d,r,a)}(p=p.slice(o)).length?x(t):(++m,p=null,t(e))}()}}}function w(t,e,n,o,i){var r,a=i._||"",u=a.root,s=u.graph,c=s[n]||j,f=m(c,e,1),l=c[e],h=a.DBG;(r=console.STAT)&&(s[n]&&l||(r.has=(r.has||0)+1));var p=k();if(py?y:r),void(console.STAT&&console.STAT((h||a).Hf=+new Date,r,"future"));if((!(o":o},_:a})}}function n(t){var e;(e=(t._||"").DBG)&&(e.pa=+new Date,e.pm=e.pm||+new Date);var n,o=this.as,i=o.graph,r=t._,a=t.put,u=a["#"],s=a["."],c=a[":"],f=a[">"];t["#"];(n=r.msg)&&(n=n.put)&&(n=n[u])&&O(n,s,f,c,u),i[u]=O(i[u],s,f,c,u),(n=(o.next||"")[u])&&n.on("in",t),this.to.next(t),b(r)}function b(t,e){var n;if(!t.stop&&(t.err||!(0<--t.stun))&&(t.stop=1,n=t.root)){var o=t.match;o.end=1,o===n.hatch&&(!(o=t.latch)||o.end?delete n.hatch:n.hatch=o),t.hatch&&t.hatch(),setTimeout.each(t.match,function(t){t&&t()}),!(e=t.msg)||t.err||e.err||(e.out=$,t.root.on("out",e))}}s.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||s.on,t.ask=t.ask||s.ask,t.dup=t.dup||s.dup();var e=t.$.opt(t.opt);return t.once||(t.on("in",$,t),t.on("out",$,t),t.on("put",n,t),s.on("create",t),t.on("create",t)),t.once=1,e},s.on.put=u,console.log("BEWARE: BETA VERSION OF NEW GUN! NOT ALL FEATURES FINISHED!");var _="Error: Invalid graph!",T=function(t){return" '"+(""+t).slice(0,9)+"...' "},v=JSON.stringify,y=2147483647,k=s.state}(),s.on.get=function(t,e){var n=e._,o=t.get,i=o["#"],r=n.graph[i],a=o["."],u=((n.next||(n.next={}))[i],(t._||{}).DBG=t.DBG);if(u&&(u.g=+new Date),!r)return n.on("get",t);if(a){if("string"!=typeof a||S===r[a])return n.on("get",t);r=O({},a,m(r,a),r[a],i)}r&&c(t,r),n.on("get",t)},s.on.get.ack=c,s.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return Object.plain(t)||(t={}),Object.plain(n.opt)||(n.opt=t),"string"==typeof e&&(e=[e]),e instanceof Array&&(Object.plain(n.opt.peers)||(n.opt.peers={}),e.forEach(function(t){var e={};e.id=e.url=t,n.opt.peers[t]=n.opt.peers[t]||e})),n.opt.peers=n.opt.peers||{},o(t,function t(e){var n=this[e];this&&this.hasOwnProperty(e)||"string"==typeof n||Object.empty(n)?this[e]=n:(!n||n.constructor===Object||n instanceof Array)&&o(n,t)}),s.on("opt",n),n.opt.uuid=n.opt.uuid||function(t){return s.state().toString(36).replace(".","")+String.random(t||12)},this};var S,n,o=function(t,e){Object.keys(t).forEach(e,t)},g=String.random,x=setTimeout.turn,D=s.valid,m=s.state.is,O=s.state.ify,j={};(s.log=function(){return s.log.off||n.log.apply(n,arguments),[].slice.call(arguments).join(" ")}).once=function(t,e,n){return(n=s.log.once)[t]=n[t]||0,n[t]++||s.log(e)},"undefined"!=typeof window&&((window.GUN=window.Gun=s).window=window);try{void 0!==e&&(e.exports=s)}catch(t){}((t.exports=s).window||{}).console=(s.window||{}).console||{log:function(){}},(n=console).only=function(t,e){return n.only.i&&t===n.only.i&&n.only.i++&&(n.log.apply(n,arguments)||e)},s.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco if anything takes you longer than 5min to figure out!")})(f,"./root"),f(function(t){f("./root").chain.back=function(t,e){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var n=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=n;o":v(r.graph[i.soul],e)}}),n))return}else{if(n=i.ask&&i.ask[""],(i.ask||(i.ask={}))[""]=i,p!==i.put&&(i.on("in",i),n))return;t.$=i.$}return r.ask(a,t),r.on("in",t)}if(e["."])return o.get?(t={get:{".":o.get},$:o.$},(i.ask||(i.ask={}))[o.get]=t.$._):t={get:o.lex?t.get:{},$:o.$},i.on("out",t);if(((o.ask||(o.ask={}))[""]=o).get)return e["."]=o.get,(i.ask||(i.ask={}))[o.get]=t.$._,i.on("out",t)}return i.on("out",t)}o.on("in",{put:o.put=p,$:o.$})},s.on.in=function(e,n){var t,o=(n=n||this.as).root,i=e.$||(e.$=n.$),r=(i||"")._||d,a=e.put||"",u=a["#"],s=a["."],c=p!==a["="]?a["="]:a[":"],f=a[">"]||-1/0;if(p!==e.put&&(p===a["#"]||p===a["."]||p===a[":"]&&p===a["="]||p===a[">"]))return g(a)?void n.on("in",{$:r.back.$,put:{"#":u=r.back.soul,".":s=r.has||r.get,"=":a,">":v(r.back.put,s)},via:e}):(u=((a||"")._||"")["#"])?(i=n.root.$.get(u),setTimeout.each(Object.keys(a).sort(),function(t){"_"!=t&&p!==(f=v(a,t))&&n.on("in",{$:i,put:{"#":u,".":t,"=":a[t],">":f},VIA:e})})):void console.log("chain not yet supported for",a,"...",e,n);(e.seen||"")[n.id]||(((e.seen||(e.seen=function(){}))[n.id]=n)!==r&&(Object.keys(e).forEach(function(t){a[t]=e[t]},a={}),a.get=n.get||a.get,n.soul||n.has?r.soul&&(a.$=n.$,a.$$=a.$$||r.$):a.$$$=a.$$$||n.$,e=a),h(e,n),(n.soul||e.$$)&&f>=v(o.graph[u],s)&&((a=o.$.get(u)._).put=y(a.put,s,f,c,u)),!r.soul&&f>=v(o.graph[u],s)&&(t=(o.$.get(u)._.next||"")[s])&&(t.put=c,"string"==typeof(a=g(c))&&(t.put=o.$.get(a)._.put||c)),this.to&&this.to.next(e),n.any&&setTimeout.each(Object.keys(n.any),function(t){(t=n.any[t])&&t(e)},0,99),n.echo&&setTimeout.each(Object.keys(n.echo),function(t){(t=n.echo[t])&&t.on("in",e)},0,99),((e.$$||"")._||r).soul&&(t=n.next)&&(t=t[s])&&(a={},Object.keys(e).forEach(function(t){a[t]=e[t]}),a.$=(e.$$||e.$).get(a.get=s),delete a.$$,delete a.$$$,t.on("in",a)),l(e,n))},s.on.link=l,s.on.unlink=h;var p,d={},u=String.random,g=s.valid,c=function(t,e){return t&&Object.prototype.hasOwnProperty.call(t,e)},e=s.state,v=e.is,y=e.ify})(f,"./chain"),f(function(t){var g=f("./root");function r(t){var e=this.at||this.on;if(!t||e.soul||e.has)return this.off();if(t=(t=(t=t.$||t)._||t).id){var n;e.map;if((n=this.seen||(this.seen={}))[t])return!0;n[t]=!0}}g.chain.get=function(t,e,n){var o,i;if("string"==typeof t){if(0==t.length)return(o=this.chain())._.err={err:g.log("0 length key!",t)},e&&e.call(o,o._.err),o;(o=((f=this._).next||a)[t])||(o=t&&function(t,e){var n=e._,o=n.next,i=e.chain()._;o=o||(n.next={});o[i.get=t]=i,e===n.root.$?i.soul=t:(n.soul||n.has)&&(i.has=t);return i}(t,this)),o=o&&o.$}else{if("function"==typeof t){if(!0===e)return function(t,e,n,o){var a,u=t._,s=0;if(a=u.soul||u.link)return e(a,o,u);if(u.jam)return u.jam.push([e,o]);u.jam=[[e,o]],t.get(function(t,e){if(!(v===t.put&&!u.root.opt.super&&(a=Object.keys(u.root.opt.peers).length)&&++s<=a)){e.rid(t);var n,o=(o=t.$)&&o._||{},i=0;for(a=u.jam,delete u.jam;n=a[i++];){var r=n[0];n=n[1],r&&r(o.link||o.soul||g.valid(t.put)||((t.put||{})._||{})["#"],n,t,e)}}},{out:{get:{".":!0}}})}(this,t,0,n),this;var c,f=(o=this)._,l=e||{},h=f.root;l.at=f,l.ok=t;var p={};function d(e,t,n){if(!d.stun&&(!(o=h.pass)||o[c])){var o,i=e.$._,r=(e.$$||"")._,a=(r||i).put,u=!i.has&&!i.soul,s={};if(!u&&v!==a||(a=v===((o=e.put)||"")["="]?v===(o||"")[":"]?o:o[":"]:o["="]),"string"==typeof(o=g.valid(a))&&(a=v===(o=h.$.get(o)._.put)?l.not?v:a:o),!l.not||v!==a){if(v===l.stun){if((o=h.stun)&&o.on&&(f.$.back(function(t){if(o.on(""+t.id,s={}),(s.run||0)s.run&&(s.stun&&!s.stun.end||(s.stun=o.on("stun"),s.stun=s.stun&&s.stun.last),s.stun&&!s.stun.end)))return void((s.stun.add||(s.stun.add={}))[c]=function(){d(e,t,1)});if(v===a&&(n=0),(o=h.hatch)&&!o.end&&v===l.hatch&&!n){if(p[i.$._.id])return;return p[i.$._.id]=1,void o.push(function(){d(e,t,1)})}p={}}l.on?l.ok.call(i.$,a,i.get,e,t||d):l.v2020?l.ok(e,t||d):(Object.keys(e).forEach(function(t){o[t]=e[t]},o={}),(e=o).put=a,l.ok.call(l.as,e,t||d))}}}return(((d.at=f).any||(f.any={}))[c=String.random(7)]=d).off=function(){d.stun=1,f.any&&delete f.any[c]},d.rid=r,d.id=l.run||++h.once,i=h.pass,(h.pass={})[c]=1,l.out=l.out||{get:{}},f.on("out",l.out),h.pass=i,o}if("number"==typeof t)return this.get(""+t,e,n);if("string"==typeof(i=u(t)))return this.get(i,e,n);(i=this.get.next)&&(o=i(this,t))}return o?e&&"function"==typeof e&&o.get(e,n):((o=this.chain())._.err={err:g.log("Invalid get request!",t)},e&&e.call(o,o._.err)),o};var v,a={},u=g.valid})(f,"./get"),f(function(t){var g=f("./root");function v(e,t){if(t){t=(t._||"").id||t;var n,o=e.root.stun||(e.root.stun={on:g.on}),i={};e.stun||(e.stun=o.on("stun",function(){})),(n=o.on(""+t))&&n.the.last.next(i),i.run>=e.run||o.on(""+t,function(t){if(e.stun.end)return this.off(),void this.to.next(t);t.run=t.run||e.run,t.stun=t.stun||e.stun})}}function u(e){if(e.err)u.end(e.stun,e.root);else if(!e.todo.length&&!e.end&&Object.empty(e.wait)){e.end=1;var t,n=e.$.back(-1)._,o=n.root,i=n.ask(function(t){o.on("ack",t),t.err&&g.log(t),++r>(e.acks||0)&&this.off(),e.ack&&e.ack(t,this)},e.opt),r=0,a=e.stun;(t=function(){a&&(u.end(a,o),setTimeout.each(Object.keys(a=a.add||""),function(t){(t=a[t])&&t()}))}).hatch=t,e.via._.on("out",{put:e.out=e.graph,opt:e.opt,"#":i,_:t})}}g.chain.put=function(t,e,p){var n=this,o=n._,i=o.root;(p=p||{}).root=o.root,p.run||(p.run=i.once),v(p,o.id),p.ack=p.ack||e,p.via=p.via||n,p.data=p.data||t,p.soul||(p.soul=o.soul||"string"==typeof e&&e);var d=p.state=p.state||g.state();return"function"==typeof t?t(function(t){p.data=t,n.put(void 0,void 0,p)}):p.soul?(p.$=i.$.get(p.soul),p.todo=[{it:p.data,ref:p.$}],p.turn=p.turn||r,p.ran=p.ran||u,function t(){var e,n,o,i,r,a=p.todo,u=a.pop(),s=u.it;u.ref&&u.ref._.id;if(v(p,u.ref),(i=u.todo)&&(s=s[n=i.pop()],i.length&&a.push(u)),n&&(a.path||(a.path=[])).push(n),!(e=k(s))&&!(r=g.is(s))){if(!Object.plain(s))return(p.ack||y).call(p,p.out={err:p.err=g.log("Invalid data: "+(s&&(i=s.constructor)&&i.name||typeof s)+" at "+(p.via.back(function(t){t.get&&i.push(t.get)},i=[])||i.join("."))+"."+(a.path||[]).join("."))}),void p.ran(p);for(var c=p.seen||(p.seen=[]),f=c.length;f--;)if(s===(i=c[f]).it){e=s=i.link;break}}if(n&&e)u.node=m(u.node,n,d,s);else{p.seen.push(o={it:s,link:{},todo:r?[]:Object.keys(s).sort().reverse(),path:(a.path||[]).slice(),up:u}),u.node=m(u.node,n,d,o.link),!r&&o.todo.length&&a.push(o);var l=p.seen.length;function h(t,e){if(o.link["#"])return p.ran(p);e&&(e.off(),e.rid(t));var n=t.soul||(i=(t.$$||t.$)._||"").soul||i.link||((i=i.put||"")._||"")["#"]||i["#"]||((i=t.put||"")&&t.$$?i["#"]:(i["="]||i[":"]||"")["#"]);v(p,t.$),n||u.link["#"]?(n||(n=[],(t.$$||t.$).back(function(t){if(i=t.soul||t.link)return n.push(i);n.push(t.get)}),n=n.reverse().join("/")),o.link["#"]=n,r||(((p.graph||(p.graph={}))[n]=o.node||(o.node={_:{}}))._["#"]=n),delete p.wait[l],o.wait&&setTimeout.each(o.wait,function(t){t&&t()}),p.ran(p)):(u.wait||(u.wait=[])).push(function(){h(t,e)})}(p.wait||(p.wait={}))[l]="",i=(o.ref=r?s:n?u.ref.get(n):u.ref)._,(i=s&&(s._||"")["#"]||i.soul||i.link)?h({soul:i}):o.ref.get(h,{run:p.run,v2020:1,out:{get:{".":" "}}})}if(!a.length)return p.ran(p);p.turn(t)}()):function(e){var n,t=e.via._;e.via=e.via.back(function(t){if(t.soul||!t.get)return t.$;n=e.data,(e.data={})[t.get]=n}),e.via&&e.via._.soul||(e.via=t.root.$.get(((e.data||"")._||"")["#"]||t.$.back("opt.uuid")()));e.via.put(e.data,e.ack,e)}(p),n},u.end=function(t,e){t.end=y,t.the.to===t&&t===t.the.last&&delete e.stun,t.off()};var y=function(){},r=setTimeout.turn,k=g.valid,m=g.state.ify})(f,"./put"),f(function(t){var e=f("./root");f("./chain"),f("./back"),f("./put"),f("./get"),t.exports=e})(f,"./index"),f(function(t){var d=f("./index");d.chain.on=function(t,e,n,o){var i,r=this._;r.root;if("string"==typeof t)return e?(i=r.on(t,e,n||r,o),n&&n.$&&(n.subs||(n.subs=[])).push(i),this):r.on(t);var a=e;(a=!0===a?{change:!0}:a||{}).not=1,a.on=1;return this.get(t,a),this},d.chain.once=function(s,c){if(c=c||{},!s)return function(t,e,n){return d.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."),(n=t.chain())._.nix=t.once(function(t,e){n._.on("in",this._)}),n._.lex=t._.lex,n}(this);var f,l=this._,h=l.root,p=(l.put,String.random(7));return this.get(function(t,e,n,o){var i=this,r=i._,a=r.one||(r.one={});function u(){r.has||r.soul||(r={put:t,get:e}),void 0===(f=r.put)&&(f=((n.$$||"")._||"").put),"string"==typeof d.valid(f)&&void 0===(f=h.$.get(f)._.put)||o.stun||""!==a[p]&&(a[p]="",(l.soul||l.has)&&o.off(),s.call(i,f,r.get))}o.stun||""!==a[p]&&(!0!==(f=d.valid(t))?"string"!=typeof f&&(clearTimeout(a[p]),a[p]=setTimeout(u,c.wait||99)):u())},{on:1}),this},d.chain.off=function(){var n,t=this._,o=t.back;if(o)return t.ack=0,(n=o.next)&&n[t.get]&&delete n[t.get],(n=o.ask)&&delete n[t.get],(n=o.put)&&delete n[t.get],(n=t.soul)&&delete o.root.graph[n],(n=t.map)&&Object.keys(n).forEach(function(t,e){(e=n[t]).link&&o.root.$.get(e.link).off()}),(n=t.next)&&Object.keys(n).forEach(function(t,e){n[t].$.off()}),t.on("off",{}),this}})(f,"./on"),f(function(t){var s=f("./index"),o=s.chain.get.next;function r(t){this.to.next(t);var e,n=this.as,o=t.$._,i=t.put;(o.soul||t.$$)&&((e=n.lex)&&!String.match(t.get||(i||"")["."],e["."]||e["#"]||e)||s.on.link(t,n))}s.chain.get.next=function(t,e){var n;return Object.plain(e)?(n=((n=e["#"])||"")["="]||n)?t.get(n):((n=t.chain()._).lex=e,t.on("in",function(t){String.match(t.get||(t.put||"")["."],e["."]||e["#"]||e)&&n.on("in",t),this.to.next(t)}),n.$):(o||c)(t,e)},s.chain.map=function(a,t,e){var n,u,o=this,i=o._;return Object.plain(a)&&(n=a["."]?a:{".":a},a=void 0),a?(s.log.once("mapfn","Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it."),u=o.chain(),o.map().on(function(t,e,n,o){var i=(a||c).call(this,t,e,n,o);if(void 0!==i){if(t===i)return u._.on("in",n);if(s.is(i))return u._.on("in",i._);var r={};Object.keys(n.put).forEach(function(t){r[t]=n.put[t]},r),r["="]=i,u._.on("in",{get:e,put:r})}})):(u=i.each)||((i.each=u=o.chain())._.lex=n||u._.lex||i.lex,u._.nix=o.back("nix"),o.on("in",r,u._)),u};var c=function(){}})(f,"./map"),f(function(t){var u=f("./index");u.chain.set=function(t,i,e){var n,r,a=this,o=a.back(-1);return i=i||function(){},(e=e||{}).item=e.item||t,(n=((t||"")._||"")["#"])&&((t={})["#"]=n),"string"==typeof(r=u.valid(t))?a.get(n=r).put(t,i,e):u.is(t)?(a.put(function(o){t.get(function(t,e,n){if(!t)return i.call(a,{err:u.log('Only a node can be linked! Not "'+n.put+'"!')});(r={})[t]={"#":t},o(r)},!0)}),t):(Object.plain(t)&&(t=o.get(n=a.back("opt.uuid")()).put(t)),a.get(n||o.back("opt.uuid")(7)).put(t,i,e))}})(f,"./set"),f(function(t){f("./shim");var T;try{t.exports=function(s){var g=function(){},v=s.opt||{};v.log=v.log||console.log,v.gap=v.gap||v.wait||0,v.max=v.max||.3*(v.memory?999*v.memory*999:3e8),v.pack=v.pack||.01*v.max*.01,v.puff=v.puff||9;var y=setTimeout.turn||setTimeout,i=JSON.parseAsync||function(t,e,n){try{e(void 0,JSON.parse(t,n))}catch(t){e(t)}},k=JSON.stringifyAsync||function(t,e,n,o){try{e(void 0,JSON.stringify(t,n,o))}catch(t){e(t)}},m=s.dup,$=m.check,w=m.track,u=(new Date,g.hear=function(t,a){if(t){if(v.max<=t.length)return g.say({dam:"!",err:"Message too big!"},a);g===this&&(u.d+=t.length||0,++u.c);var e,n=a.SH=+new Date,o=t[0];return"["===o?(i(t,function(t,i){if(t||!i)return g.say({dam:"!",err:"DAM JSON parse error."},a);console.STAT&&console.STAT(+new Date,i.length,"# on hear batch");var r=v.puff;!function t(){for(var e,n=+new Date,o=0;o<"])&&"string"==typeof r&&r.slice(0,99).split(",").forEach(function(t){this[t]=1},t._.yo={}),r=t.dam)return(r=g.hear[r])&&r(t,e,s),void w(o);n=+new Date;u&&(u.is=n),e.SI=o,s.on("in",g.last=t),u&&(u.hd=+new Date),console.STAT&&console.STAT(n,+new Date-n,t.get?"msg get":t.put?"msg put":"msg"),(r=w(o)).via=e,t.get&&(r.it=t),a&&w(a),g.leap=g.last=null}},u.c=u.d=0,function(){var h,p=0;function t(t,e){var n;return e instanceof Object?(Object.keys(e).sort().forEach(o,{to:n={},on:e}),n):e}function o(t){this.to[t]=this.on[t]}g.hash=function(i,r){var a,u,s,c=+new Date;k(i.put,function t(e,n){var o=(u=u||(s=n||"")).slice(0,32768);a=String.hash(o,a),(u=u.slice(32768))?y(t,0):(console.STAT&&console.STAT(c,+new Date-c,"say json+hash"),i._.$put=s,i["##"]=a,d(i,r),delete i._.$put)},t)};var d=g.say=function(r,t){var e;if((e=this)&&(e=e.to)&&e.next&&e.next(r),!r)return!1;var n,a,u=r["@"],s=r._||(r._=function(){}),o=r.DBG,i=+new Date;if(s.y=s.y||i,t||o&&(o.y=i),(n=r["#"])||(n=r["#"]=String.random(9)),h||w(n),r.put&&(r.err||(m.s[n]||"").err))return!1;if(r["##"]||T===r.put||s.via||!u){if(!t&&u&&(t=(e=m.s[u])&&(e.via||(e=e.it)&&(e=e._)&&e.via)||(e=g.last)&&u===e["#"]&&g.leap),!t&&u){if(m.s[u])return;return console.STAT&&console.STAT(+new Date,++p,"total no peer to ack to"),!1}if(!t&&g.way)return g.way(r);if(o&&(o.yh=+new Date),a=s.raw){if(o&&(o.yr=+new Date),!t||!t.id){if(!Object.plain(t||v.peers))return!1;i=+new Date,v.puff;var c=v.peers,f=Object.keys(t||v.peers||{});return console.STAT&&console.STAT(i,+new Date-i,"peer keys"),void function t(){var e=+new Date;h=1;var n=s.raw;s.raw=a;for(var o,i=0;i<9&&(o=(f||"")[i++]);)(o=c[o])&&d(r,o);s.raw=n,h=0,f=f.slice(i),console.STAT&&console.STAT(e,+new Date-e,"say loop"),f.length&&(y(t,0),u&&w(u))}()}if(!t.wire&&g.wire&&g.wire(t),n!==t.last){if(t.last=n,t===s.via)return!1;if((e=s.yo)&&(e[t.url]||e[t.pid]||e[t.id]))return!1;if(console.STAT&&console.STAT(i,((o||s).yp=+new Date)-(s.y||i),"say prep"),!h&&u&&w(u),t.batch){if(t.tail=(e=t.tail||0)+a.length,t.tail<=v.pack)return void(t.batch+=(e?",":"")+a);b(t)}t.batch="[";var l=+new Date;setTimeout(function(){console.STAT&&console.STAT(l,+new Date-l,"0ms TO"),b(t)},v.gap),_(a,t),console.STAT&&u===t.SI&&console.STAT(i,+new Date-t.SH,"say ack")}}else g.raw(r,t)}else g.hash(r,t)};g.say.c=g.say.d=0,g.raw=function(n,o){if(!n)return"";var i,r,a=n._||{};if(r=a.raw)return r;if("string"==typeof n)return n;var t=n["##"],e=n["@"];if(t&&e){if(!a.via&&$(e+t))return!1;if((r=(m.s[e]||"").it)||(r=g.last)&&e===r["#"]){if(t===r["##"])return!1;r["##"]||(r["##"]=t)}}if(!n.dam){var u=0,s=[];for(var c in r=v.peers){var f=r[c];if(s.push(f.url||f.pid||f.id),6<++u)break}1<"]=s.join())}if(i=a.$put)return r={},Object.keys(n).forEach(function(t){r[t]=n[t]}),r.put=":])([:",void k(r,function(t,e){if(!t){var n=+new Date;r=e.indexOf('"put":":])([:"'),l(T,e=e.slice(0,r+6)+i+e.slice(r+14)),console.STAT&&console.STAT(n,+new Date-n,"say slice")}});function l(t,e){t||(a.raw=e,d(n,o))}k(n,l)}}(),g.hi=function(e){var t=e.wire||{};e.id?v.peers[e.url||e.id]=e:(t=e.id=e.id||String.random(9),g.say({dam:"?",pid:s.opt.pid},v.peers[t]=e),delete m.s[e.last]),e.met=e.met||+new Date,t.hied||s.on(t.hied="hi",e),t=e.queue,e.queue=[],setTimeout.each(t||[],function(t){_(t,e)},0,9)},g.bye=function(t){s.on("bye",t);var e=+new Date;e-=t.met||e,g.bye.time=((g.bye.time||e)+e)/2},g.hear["!"]=function(t,e){v.log("Error:",t.err)},g.hear["?"]=function(t,e){t.pid&&(e.pid||(e.pid=t.pid),t["@"])||(g.say({dam:"?",pid:v.pid,"@":t["#"]},e),delete m.s[e.last])},s.on("create",function(t){t.opt.pid=t.opt.pid||String.random(9),this.to.next(t),t.on("out",g.say)}),s.on("bye",function(t,e){t=v.peers[t.id||t]||t,this.to.next(t),t.bye?t.bye():(e=t.wire)&&e.close&&e.close(),delete v.peers[t.id],t.wire=null});var o={};return s.on("bye",function(t,e){this.to.next(t),(e=console.STAT)&&(e.peers=(e.peers||0)-1),(e=t.url)&&(o[e]=!0,setTimeout(function(){delete o[e]},v.lack||9e3))}),s.on("hi",function(e,n){this.to.next(e),(n=console.STAT)&&(n.peers=(n.peers||0)+1),(n=e.url)&&o[n]&&(delete o[n],v.super||setTimeout.each(Object.keys(s.next),function(t){s.next[t];(n={})[t]=s.graph[t],n=String.hash(n),g.say({"##":n,get:{"#":t}},e)}))}),g}}catch(t){}})(f,"./mesh"),f(function(t){var c=f("../index");c.Mesh=f("./mesh"),c.on("opt",function(t){if(this.to.next(t),!t.once){var o=t.opt;if(!1!==o.WebSocket){var e=c.window||{},n=o.WebSocket||e.WebSocket||e.webkitWebSocket||e.mozWebSocket;if(n){o.WebSocket=n;var i=o.mesh=o.mesh||c.Mesh(t);i.wire||o.wire;i.wire=o.wire=u,setTimeout(function(){o.super||t.on("out",{dam:"hi"})},1);var r=1998,a=""+void 0!=typeof document&&document}}}function u(e){try{if(!e||!e.url)return n&&n(e);var t=e.url.replace(/^http/,"ws"),n=e.wire=new o.WebSocket(t);return n.onclose=function(){o.mesh.bye(e),s(e)},n.onerror=function(t){s(e)},n.onopen=function(){o.mesh.hi(e)},n.onmessage=function(t){t&&o.mesh.hear(t.data||t,e)},n}catch(t){}}function s(e){clearTimeout(e.defer),a&&e.retry<=0||(e.retry=(e.retry||o.retry+1||60)-(-e.tried+(e.tried=+new Date)<4*r?1:0),e.defer=setTimeout(function t(){if(a&&a.hidden)return setTimeout(t,r);u(e)},r))}})})(f,"./websocket"),f(function(t){if("undefined"!=typeof Gun){var o;try{o=(Gun.window||function(){}).localStorage}catch(t){}o||(Gun.log("Warning: No localStorage exists to persist data to!"),o={setItem:function(t,e){this[t]=e},removeItem:function(t){delete this[t]},getItem:function(t){return this[t]}}),Gun.on("create",function e(n){this.to.next(n);var r,i,a=n.opt,u=(n.graph,[]);if(!1!==a.localStorage){a.prefix=a.file||"gun/";try{r=e[a.prefix]=e[a.prefix]||JSON.parse(o.getItem(a.prefix))||{}}catch(t){r=e[a.prefix]={}}n.on("get",function(t){this.to.next(t);var e,n,o,i=t.get;i&&(e=i["#"])&&((n=r[e]||void 0)&&(o=i["."])&&!Object.plain(o)&&(n=Gun.state.ify({},o,Gun.state.is(n,o),n[o],e)),Gun.on.get.ack(t,n))}),n.on("put",function(t){this.to.next(t);var e=t.put,n=e["#"],o=e["."];r[n]=Gun.state.ify(r[n],o,e[">"],e[":"],n),t["@"]||u.push(t["#"]),i=i||setTimeout(s,a.wait||1)})}function s(){var e,t=u;clearTimeout(i),i=!1,u=[];try{o.setItem(a.prefix,JSON.stringify(r))}catch(t){Gun.log((e=t||"localStorage failure")+" Consider using GUN's IndexedDB plugin for RAD for more storage space, https://gun.eco/docs/RAD#install"),n.on("localStorage:error",{err:e,get:a.prefix,put:r})}(e||Object.empty(a.peers))&&setTimeout.each(t,function(t){n.on("in",{"@":t,err:e,ok:0})})}})}})(f,"./localStorage")}(); \ No newline at end of file +!function(){function f(n,t){return t?require(n):n.slice?f[o(n)]:function(t,e){n(t={exports:{}}),f[o(e)]=t.exports};function o(t){return t.split("/").slice(-1).toString().replace(".js","")}}if("undefined"!=typeof module)var e=module;f(function(t){String.random=function(t,e){var n="";for(t=t||24,e=e||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0"]||e["<"])||o===e["="]&&(n=e["*"]||e[">"],t.slice(0,(n||"").length)===n||o===e["*"]&&(o!==e[">"]&&o!==e["<"]?t>=e[">"]&&t<=e["<"]:o!==e[">"]&&t>=e[">"]||o!==e["<"]&&t<=e["<"])))},String.hash=function(t,e){if("string"==typeof t){if(e=e||0,!t.length)return e;for(var n=0,o=t.length;n"]||n;if(o)return"number"==typeof(o=o[e])?o:-1/0},e.ify=function(t,e,n,o,i){(t=t||{})._=t._||{},i&&(t._["#"]=i);var r=t._[">"]||(t._[">"]={});return void 0!==e&&"_"!==e&&("number"==typeof n&&(r[e]=n),void 0!==o&&(t[e]=o)),t},t.exports=e})(f,"./state"),f(function(t){f("./shim"),t.exports=function(o){var i={s:{}},r=i.s;o=o||{max:999,age:9e3},i.check=function(t){return!!r[t]&&e(t)};var e=i.track=function(t){var e=r[t]||(r[t]={});return e.was=i.now=+new Date,i.to||(i.to=setTimeout(i.drop,o.age+9)),e};return i.drop=function(n){i.to=null,i.now=+new Date;var t=Object.keys(r);console.STAT&&console.STAT(i.now,+new Date-i.now,"dup drop keys"),setTimeout.each(t,function(t){var e=r[t];e&&(n||o.age)>i.now-e.was||delete r[t]},0,99)},i}})(f,"./dup"),f(function(t){f("./onto"),t.exports=function(t,e){if(this.on){var n=(this.opt||{}).lack||9e3;if("function"!=typeof t){if(!t)return;var o=t["#"]||t,i=(this.tag||"")[o];if(!i)return;return e&&(i=this.on(o,e),clearTimeout(i.err),i.err=setTimeout(function(){i.off()},n)),!0}o=e&&e["#"]||a(9);if(!t)return o;var r=this.on(o,t,e);return r.err=r.err||setTimeout(function(){r.off(),r.next({err:"Error: No ACK yet.",lack:!0})},n),o}};var a=String.random||function(){return Math.random().toString(36).slice(2)}})(f,"./ask"),f(function(t){function c(t){return t instanceof c?(this._={$:this}).$:this instanceof c?c.create(this._={$:this,opt:t}):new c(t)}function s(t,a){var u=+new Date,e=t._||{},s=e.DBG=t.DBG,c=t["#"],f=g(9),h=Object.keys(a||"").sort(),l=((a||"")._||"")["#"],p=(h.length,t.$._.root),d=a===p.graph[l];console.STAT&&console.STAT(u,((s||e).gk=+new Date)-u,"got keys"),a&&function t(){u=+new Date;for(var e,n,o,i=0,r={};i<9&&(e=h[i++]);)O(r,e,m(a,e),a[e],l);h=h.slice(i),(n={})[l]=r,r=n,d&&((o=function(){}).ram=o.faith=!0),n=h.length,console.STAT&&console.STAT(u,-(u-(u=+new Date)),"got copied some"),s&&(s.ga=+new Date),p.on("in",{"@":c,"#":f,put:r,"%":n?f=g(9):S,$:p.$,_:o,DBG:s}),console.STAT&&console.STAT(u,+new Date-u,"got in"),n&&setTimeout.turn(t)}(),a||p.on("in",{"@":t["#"]})}c.is=function(t){return t instanceof c||t&&t._&&t===t._.$||!1},c.version=.202,(c.chain=c.prototype).toJSON=function(){},f("./shim"),c.valid=f("./valid"),c.state=f("./state"),c.on=f("./onto"),c.dup=f("./dup"),c.ask=f("./ask"),function(){function $(t){if(t)if(t.out!==$){var e,n=this.as,o=n.at||n,i=o.$,r=o.dup,a=t.DBG;if((e=t["#"])||(e=t["#"]=g(9)),!r.check(e)){if(r.track(e),e=t._,t._="function"==typeof e?e:function(){},t.$&&t.$===(t.$._||"").$||(t.$=i),t["@"]&&!t.put&&function(t){var e,n=t["@"]||"";if(!(e=n._))return;e.acks=(e.acks||0)+1,(e.err=t.err)&&(t["@"]=e["#"],b(e));e.stop||e.crack||(e.crack=e.match&&e.match.push(function(){s(e)}));s(e)}(t),!o.ask(t["@"],t)){if(a&&(a.u=+new Date),t.put)return void u(t);t.get&&c.on.get(t,i)}a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.nts||t.NTS||(t.out=$,o.on("out",t),a&&(a.ue=+new Date))}}else this.to.next(t)}function u(a){if(a){var u=a._||"",t=u.root=((u.$=a.$||"")._||"").root;if(a["@"]&&u.faith&&!u.miss)return a.out=$,void t.on("out",a);u.latch=t.hatch,u.match=t.hatch=[];var s=a.put,c=u.DBG=a.DBG,f=+new Date;if(!s["#"]||!s["."]){c&&(c.p=f),u["#"]=a["#"],u.msg=a,u.all=0,u.stun=1;var h=Object.keys(s);console.STAT&&console.STAT(f,((c||u).pk=+new Date)-f,"put sort");var l,p,d,g,v,y,k,m=0;!function t(e){if(l!=m){if(!(d=h[l=m]))return console.STAT&&console.STAT(f,((c||u).pd=+new Date)-f,"put"),void b(u);(g=s[d])?(k=g._)?d!==k["#"]?y=_+T(d)+"soul not same.":(v=k[">"])||(y=_+T(d)+"no state."):y=_+T(d)+"no meta.":y=_+T(d)+"no node.",p=Object.keys(g||{})}if(y)return a.err=u.err=y,void b(u);var n,o=0;for(e=e||0;e++<9&&(n=p[o++]);)if("_"!==n){var i=g[n],r=v[n];if(S===r){y=_+T(n)+"on"+T(d)+"no state.";break}if(!D(i)){y=_+T(n)+"on"+T(d)+"bad "+typeof i+T(i);break}w(i,n,d,r,a)}(p=p.slice(o)).length?x(t):(++m,p=null,t(e))}()}}}function w(t,e,n,o,i){var r,a=i._||"",u=a.root,s=u.graph,c=s[n]||j,f=m(c,e,1),h=c[e],l=a.DBG;(r=console.STAT)&&(s[n]&&h||(r.has=(r.has||0)+1));var p=k();if(py?y:r),void(console.STAT&&console.STAT((l||a).Hf=+new Date,r,"future"));if((!(o":o},_:a})}}function n(t){var e;(e=(t._||"").DBG)&&(e.pa=+new Date,e.pm=e.pm||+new Date);var n,o=this.as,i=o.graph,r=t._,a=t.put,u=a["#"],s=a["."],c=a[":"],f=a[">"];t["#"];(n=r.msg)&&(n=n.put)&&(n=n[u])&&O(n,s,f,c,u),i[u]=O(i[u],s,f,c,u),(n=(o.next||"")[u])&&n.on("in",t),b(r),this.to.next(t)}function b(t,e){var n;if(!t.stop&&(t.err||!(0<--t.stun))&&(t.stop=1,n=t.root)){var o=t.match;o.end=1,o===n.hatch&&(!(o=t.latch)||o.end?delete n.hatch:n.hatch=o),t.hatch&&t.hatch(),setTimeout.each(t.match,function(t){t&&t()}),!(e=t.msg)||t.err||e.err||(e.out=$,t.root.on("out",e))}}function s(t){t&&t.root&&(t.stun||t.acks!==t.all||t.root.on("in",{"@":t["#"],err:t.err,ok:t.err?S:{"":1}}))}c.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||c.on,t.ask=t.ask||c.ask,t.dup=t.dup||c.dup();var e=t.$.opt(t.opt);return t.once||(t.on("in",$,t),t.on("out",$,t),t.on("put",n,t),c.on("create",t),t.on("create",t)),t.once=1,e},c.on.put=u,console.log("BEWARE: BETA VERSION OF NEW GUN! NOT ALL FEATURES FINISHED!");var _="Error: Invalid graph!",T=function(t){return" '"+(""+t).slice(0,9)+"...' "},v=JSON.stringify,y=2147483647,k=c.state}(),c.on.get=function(t,e){var n=e._,o=t.get,i=o["#"],r=n.graph[i],a=o["."],u=((n.next||(n.next={}))[i],(t._||{}).DBG=t.DBG);if(u&&(u.g=+new Date),!r)return n.on("get",t);if(a){if("string"!=typeof a||S===r[a])return n.on("get",t);r=O({},a,m(r,a),r[a],i)}r&&s(t,r),n.on("get",t)},c.on.get.ack=s,c.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return Object.plain(t)||(t={}),Object.plain(n.opt)||(n.opt=t),"string"==typeof e&&(e=[e]),e instanceof Array&&(Object.plain(n.opt.peers)||(n.opt.peers={}),e.forEach(function(t){var e={};e.id=e.url=t,n.opt.peers[t]=n.opt.peers[t]||e})),n.opt.peers=n.opt.peers||{},o(t,function t(e){var n=this[e];this&&this.hasOwnProperty(e)||"string"==typeof n||Object.empty(n)?this[e]=n:(!n||n.constructor===Object||n instanceof Array)&&o(n,t)}),c.on("opt",n),n.opt.uuid=n.opt.uuid||function(t){return c.state().toString(36).replace(".","")+String.random(t||12)},this};var S,n,o=function(t,e){Object.keys(t).forEach(e,t)},g=String.random,x=setTimeout.turn,D=c.valid,m=c.state.is,O=c.state.ify,j={};(c.log=function(){return c.log.off||n.log.apply(n,arguments),[].slice.call(arguments).join(" ")}).once=function(t,e,n){return(n=c.log.once)[t]=n[t]||0,n[t]++||c.log(e)},"undefined"!=typeof window&&((window.GUN=window.Gun=c).window=window);try{void 0!==e&&(e.exports=c)}catch(t){}((t.exports=c).window||{}).console=(c.window||{}).console||{log:function(){}},(n=console).only=function(t,e){return n.only.i&&t===n.only.i&&n.only.i++&&(n.log.apply(n,arguments)||e)},c.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, please ask for help on http://chat.gun.eco if anything takes you longer than 5min to figure out!")})(f,"./root"),f(function(t){f("./root").chain.back=function(t,e){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var n=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=n;o":v(r.graph[i.soul],e)}}),n))return}else{if(n=i.ask&&i.ask[""],(i.ask||(i.ask={}))[""]=i,p!==i.put&&(i.on("in",i),n))return;t.$=i.$}return r.ask(a,t),r.on("in",t)}if(e["."])return o.get?(t={get:{".":o.get},$:o.$},(i.ask||(i.ask={}))[o.get]=t.$._):t={get:o.lex?t.get:{},$:o.$},i.on("out",t);if(((o.ask||(o.ask={}))[""]=o).get)return e["."]=o.get,(i.ask||(i.ask={}))[o.get]=t.$._,i.on("out",t)}return i.on("out",t)}o.on("in",{put:o.put=p,$:o.$})},s.on.in=function(e,n){var t,o=(n=n||this.as).root,i=e.$||(e.$=n.$),r=(i||"")._||d,a=e.put||"",u=a["#"],s=a["."],c=p!==a["="]?a["="]:a[":"],f=a[">"]||-1/0;if(p!==e.put&&(p===a["#"]||p===a["."]||p===a[":"]&&p===a["="]||p===a[">"]))return g(a)?void n.on("in",{$:r.back.$,put:{"#":u=r.back.soul,".":s=r.has||r.get,"=":a,">":v(r.back.put,s)},via:e}):(u=((a||"")._||"")["#"])?(i=n.root.$.get(u),setTimeout.each(Object.keys(a).sort(),function(t){"_"!=t&&p!==(f=v(a,t))&&n.on("in",{$:i,put:{"#":u,".":t,"=":a[t],">":f},VIA:e})})):void console.log("chain not yet supported for",a,"...",e,n);(e.seen||"")[n.id]||(((e.seen||(e.seen=function(){}))[n.id]=n)!==r&&(Object.keys(e).forEach(function(t){a[t]=e[t]},a={}),a.get=n.get||a.get,n.soul||n.has?r.soul&&(a.$=n.$,a.$$=a.$$||r.$):a.$$$=a.$$$||n.$,e=a),l(e,n),(n.soul||e.$$)&&f>=v(o.graph[u],s)&&((a=o.$.get(u)._).put=y(a.put,s,f,c,u)),!r.soul&&f>=v(o.graph[u],s)&&(t=(o.$.get(u)._.next||"")[s])&&(t.put=c,"string"==typeof(a=g(c))&&(t.put=o.$.get(a)._.put||c)),this.to&&this.to.next(e),n.any&&setTimeout.each(Object.keys(n.any),function(t){(t=n.any[t])&&t(e)},0,99),n.echo&&setTimeout.each(Object.keys(n.echo),function(t){(t=n.echo[t])&&t.on("in",e)},0,99),((e.$$||"")._||r).soul&&(t=n.next)&&(t=t[s])&&(a={},Object.keys(e).forEach(function(t){a[t]=e[t]}),a.$=(e.$$||e.$).get(a.get=s),delete a.$$,delete a.$$$,t.on("in",a)),h(e,n))},s.on.link=h,s.on.unlink=l;var p,d={},u=String.random,g=s.valid,c=function(t,e){return t&&Object.prototype.hasOwnProperty.call(t,e)},e=s.state,v=e.is,y=e.ify})(f,"./chain"),f(function(t){var g=f("./root");function r(t){var e=this.at||this.on;if(!t||e.soul||e.has)return this.off();if(t=(t=(t=t.$||t)._||t).id){var n;e.map;if((n=this.seen||(this.seen={}))[t])return!0;n[t]=!0}}g.chain.get=function(t,e,n){var o,i;if("string"==typeof t){if(0==t.length)return(o=this.chain())._.err={err:g.log("0 length key!",t)},e&&e.call(o,o._.err),o;(o=((f=this._).next||a)[t])||(o=t&&function(t,e){var n=e._,o=n.next,i=e.chain()._;o=o||(n.next={});o[i.get=t]=i,e===n.root.$?i.soul=t:(n.soul||n.has)&&(i.has=t);return i}(t,this)),o=o&&o.$}else{if("function"==typeof t){if(!0===e)return function(t,e,n,o){var a,u=t._,s=0;if(a=u.soul||u.link)return e(a,o,u);if(u.jam)return u.jam.push([e,o]);u.jam=[[e,o]],t.get(function(t,e){if(!(v===t.put&&!u.root.opt.super&&(a=Object.keys(u.root.opt.peers).length)&&++s<=a)){e.rid(t);var n,o=(o=t.$)&&o._||{},i=0;for(a=u.jam,delete u.jam;n=a[i++];){var r=n[0];n=n[1],r&&r(o.link||o.soul||g.valid(t.put)||((t.put||{})._||{})["#"],n,t,e)}}},{out:{get:{".":!0}}})}(this,t,0,n),this;var c,f=(o=this)._,h=e||{},l=f.root;h.at=f,h.ok=t;var p={};function d(e,t,n){if(!d.stun&&(!(o=l.pass)||o[c])){var o,i=e.$._,r=(e.$$||"")._,a=(r||i).put,u=!i.has&&!i.soul,s={};if(!u&&v!==a||(a=v===((o=e.put)||"")["="]?v===(o||"")[":"]?o:o[":"]:o["="]),"string"==typeof(o=g.valid(a))&&(a=v===(o=l.$.get(o)._.put)?h.not?v:a:o),!h.not||v!==a){if(v===h.stun){if((o=l.stun)&&o.on&&(f.$.back(function(t){if(o.on(""+t.id,s={}),(s.run||0)s.run&&(s.stun&&!s.stun.end||(s.stun=o.on("stun"),s.stun=s.stun&&s.stun.last),s.stun&&!s.stun.end)))return void((s.stun.add||(s.stun.add={}))[c]=function(){d(e,t,1)});if(v===a&&(n=0),(o=l.hatch)&&!o.end&&v===h.hatch&&!n){if(p[i.$._.id])return;return p[i.$._.id]=1,void o.push(function(){d(e,t,1)})}p={}}if(l.pass){if(l.pass[c+i.id])return;l.pass[c+i.id]=1}h.on?h.ok.call(i.$,a,i.get,e,t||d):h.v2020?h.ok(e,t||d):(Object.keys(e).forEach(function(t){o[t]=e[t]},o={}),(e=o).put=a,h.ok.call(h.as,e,t||d))}}}return(((d.at=f).any||(f.any={}))[c=String.random(7)]=d).off=function(){d.stun=1,f.any&&delete f.any[c]},d.rid=r,d.id=h.run||++l.once,i=l.pass,(l.pass={})[c]=1,h.out=h.out||{get:{}},f.on("out",h.out),l.pass=i,o}if("number"==typeof t)return this.get(""+t,e,n);if("string"==typeof(i=u(t)))return this.get(i,e,n);(i=this.get.next)&&(o=i(this,t))}return o?e&&"function"==typeof e&&o.get(e,n):((o=this.chain())._.err={err:g.log("Invalid get request!",t)},e&&e.call(o,o._.err)),o};var v,a={},u=g.valid})(f,"./get"),f(function(t){var g=f("./root");function v(e,t){if(t){t=(t._||"").id||t;var n,o=e.root.stun||(e.root.stun={on:g.on}),i={};e.stun||(e.stun=o.on("stun",function(){})),(n=o.on(""+t))&&n.the.last.next(i),i.run>=e.run||o.on(""+t,function(t){if(e.stun.end)return this.off(),void this.to.next(t);t.run=t.run||e.run,t.stun=t.stun||e.stun})}}function u(e){if(e.err)u.end(e.stun,e.root);else if(!e.todo.length&&!e.end&&Object.empty(e.wait)){e.end=1;var t,n=e.$.back(-1)._,o=n.root,i=n.ask(function(t){o.on("ack",t),t.err&&g.log(t),++r>(e.acks||0)&&this.off(),e.ack&&e.ack(t,this)},e.opt),r=0,a=e.stun;(t=function(){a&&(u.end(a,o),setTimeout.each(Object.keys(a=a.add||""),function(t){(t=a[t])&&t()}))}).hatch=t,e.via._.on("out",{put:e.out=e.graph,opt:e.opt,"#":i,_:t})}}g.chain.put=function(t,e,p){var n=this,o=n._,i=o.root;(p=p||{}).root=o.root,p.run||(p.run=i.once),v(p,o.id),p.ack=p.ack||e,p.via=p.via||n,p.data=p.data||t,p.soul||(p.soul=o.soul||"string"==typeof e&&e);var d=p.state=p.state||g.state();return"function"==typeof t?t(function(t){p.data=t,n.put(void 0,void 0,p)}):p.soul?(p.$=i.$.get(p.soul),p.todo=[{it:p.data,ref:p.$}],p.turn=p.turn||r,p.ran=p.ran||u,function t(){var e,n,i,r,a,o=p.todo,u=o.pop(),s=u.it;u.ref&&u.ref._.id;if(v(p,u.ref),(r=u.todo)&&(s=s[n=r.pop()],r.length&&o.push(u)),n&&(o.path||(o.path=[])).push(n),!(e=k(s))&&!(a=g.is(s))){if(!Object.plain(s))return(p.ack||y).call(p,p.out={err:p.err=g.log("Invalid data: "+(s&&(r=s.constructor)&&r.name||typeof s)+" at "+(p.via.back(function(t){t.get&&r.push(t.get)},r=[])||r.join("."))+"."+(o.path||[]).join("."))}),void p.ran(p);for(var c=p.seen||(p.seen=[]),f=c.length;f--;)if(s===(r=c[f]).it){e=s=r.link;break}}if(n&&e)u.node=m(u.node,n,d,s);else{p.seen.push(i={it:s,link:{},todo:a?[]:Object.keys(s).sort().reverse(),path:(o.path||[]).slice(),up:u}),u.node=m(u.node,n,d,i.link),!a&&i.todo.length&&o.push(i);var h=p.seen.length;function l(t,e){var n=i.link["#"];e&&(e.off(),e.rid(t));var o=n||t.soul||(r=(t.$$||t.$)._||"").soul||r.link||((r=r.put||"")._||"")["#"]||r["#"]||((r=t.put||"")&&t.$$?r["#"]:(r["="]||r[":"]||"")["#"]);n||v(p,t.$),o||u.link["#"]?(o||(o=[],(t.$$||t.$).back(function(t){if(r=t.soul||t.link)return o.push(r);o.push(t.get)}),o=o.reverse().join("/")),i.link["#"]=o,a||(((p.graph||(p.graph={}))[o]=i.node||(i.node={_:{}}))._["#"]=o),delete p.wait[h],i.wait&&setTimeout.each(i.wait,function(t){t&&t()}),p.ran(p)):(u.wait||(u.wait=[])).push(function(){l(t,e)})}(p.wait||(p.wait={}))[h]="",r=(i.ref=a?s:n?u.ref.get(n):u.ref)._,(r=s&&(s._||"")["#"]||r.soul||r.link)?l({soul:r}):i.ref.get(l,{run:p.run,v2020:1,out:{get:{".":" "}}})}if(!o.length)return p.ran(p);p.turn(t)}()):function(e){var n,t=e.via._;e.via=e.via.back(function(t){if(t.soul||!t.get)return t.$;n=e.data,(e.data={})[t.get]=n}),e.via&&e.via._.soul||(e.via=t.root.$.get(((e.data||"")._||"")["#"]||t.$.back("opt.uuid")()));e.via.put(e.data,e.ack,e)}(p),n},u.end=function(t,e){t.end=y,t.the.to===t&&t===t.the.last&&delete e.stun,t.off()};var y=function(){},r=setTimeout.turn,k=g.valid,m=g.state.ify})(f,"./put"),f(function(t){var e=f("./root");f("./chain"),f("./back"),f("./put"),f("./get"),t.exports=e})(f,"./index"),f(function(t){var d=f("./index");d.chain.on=function(t,e,n,o){var i,r=this._;r.root;if("string"==typeof t)return e?(i=r.on(t,e,n||r,o),n&&n.$&&(n.subs||(n.subs=[])).push(i),this):r.on(t);var a=e;(a=!0===a?{change:!0}:a||{}).not=1,a.on=1;return this.get(t,a),this},d.chain.once=function(s,c){if(c=c||{},!s)return function(t,e,n){return d.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."),(n=t.chain())._.nix=t.once(function(t,e){n._.on("in",this._)}),n._.lex=t._.lex,n}(this);var f,h=this._,l=h.root,p=(h.put,String.random(7));return this.get(function(t,e,n,o){var i=this,r=i._,a=r.one||(r.one={});function u(){r.has||r.soul||(r={put:t,get:e}),void 0===(f=r.put)&&(f=((n.$$||"")._||"").put),"string"==typeof d.valid(f)&&void 0===(f=l.$.get(f)._.put)||o.stun||""!==a[p]&&(a[p]="",(h.soul||h.has)&&o.off(),s.call(i,f,r.get))}o.stun||""!==a[p]&&(!0!==(f=d.valid(t))?"string"!=typeof f&&(clearTimeout(a[p]),a[p]=setTimeout(u,c.wait||99)):u())},{on:1}),this},d.chain.off=function(){var n,t=this._,o=t.back;if(o)return t.ack=0,(n=o.next)&&n[t.get]&&delete n[t.get],(n=o.ask)&&delete n[t.get],(n=o.put)&&delete n[t.get],(n=t.soul)&&delete o.root.graph[n],(n=t.map)&&Object.keys(n).forEach(function(t,e){(e=n[t]).link&&o.root.$.get(e.link).off()}),(n=t.next)&&Object.keys(n).forEach(function(t,e){n[t].$.off()}),t.on("off",{}),this}})(f,"./on"),f(function(t){var s=f("./index"),o=s.chain.get.next;function r(t){this.to.next(t);var e,n=this.as,o=t.$._,i=t.put;(o.soul||t.$$)&&((e=n.lex)&&!String.match(t.get||(i||"")["."],e["."]||e["#"]||e)||s.on.link(t,n))}s.chain.get.next=function(t,e){var n;return Object.plain(e)?(n=((n=e["#"])||"")["="]||n)?t.get(n):((n=t.chain()._).lex=e,t.on("in",function(t){String.match(t.get||(t.put||"")["."],e["."]||e["#"]||e)&&n.on("in",t),this.to.next(t)}),n.$):(o||c)(t,e)},s.chain.map=function(a,t,e){var n,u,o=this,i=o._;return Object.plain(a)&&(n=a["."]?a:{".":a},a=void 0),a?(s.log.once("mapfn","Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it."),u=o.chain(),o.map().on(function(t,e,n,o){var i=(a||c).call(this,t,e,n,o);if(void 0!==i){if(t===i)return u._.on("in",n);if(s.is(i))return u._.on("in",i._);var r={};Object.keys(n.put).forEach(function(t){r[t]=n.put[t]},r),r["="]=i,u._.on("in",{get:e,put:r})}})):(u=i.each)||((i.each=u=o.chain())._.lex=n||u._.lex||i.lex,u._.nix=o.back("nix"),o.on("in",r,u._)),u};var c=function(){}})(f,"./map"),f(function(t){var u=f("./index");u.chain.set=function(t,i,e){var n,r,a=this,o=a.back(-1);return i=i||function(){},(e=e||{}).item=e.item||t,(n=((t||"")._||"")["#"])&&((t={})["#"]=n),"string"==typeof(r=u.valid(t))?a.get(n=r).put(t,i,e):u.is(t)?(a.put(function(o){t.get(function(t,e,n){if(!t)return i.call(a,{err:u.log('Only a node can be linked! Not "'+n.put+'"!')});(r={})[t]={"#":t},o(r)},!0)}),t):(Object.plain(t)&&(t=o.get(n=a.back("opt.uuid")()).put(t)),a.get(n||o.back("opt.uuid")(7)).put(t,i,e))}})(f,"./set"),f(function(t){f("./shim");var T;try{t.exports=function(s){var g=function(){},v=s.opt||{};v.log=v.log||console.log,v.gap=v.gap||v.wait||0,v.max=v.max||.3*(v.memory?999*v.memory*999:3e8),v.pack=v.pack||.01*v.max*.01,v.puff=v.puff||9;var y=setTimeout.turn||setTimeout,i=JSON.parseAsync||function(t,e,n){try{e(void 0,JSON.parse(t,n))}catch(t){e(t)}},k=JSON.stringifyAsync||function(t,e,n,o){try{e(void 0,JSON.stringify(t,n,o))}catch(t){e(t)}},m=s.dup,$=m.check,w=m.track,u=(new Date,g.hear=function(t,a){if(t){if(v.max<=t.length)return g.say({dam:"!",err:"Message too big!"},a);g===this&&(u.d+=t.length||0,++u.c);var e,n=a.SH=+new Date,o=t[0];return"["===o?(i(t,function(t,i){if(t||!i)return g.say({dam:"!",err:"DAM JSON parse error."},a);console.STAT&&console.STAT(+new Date,i.length,"# on hear batch");var r=v.puff;!function t(){for(var e,n=+new Date,o=0;o<"])&&"string"==typeof r&&r.slice(0,99).split(",").forEach(function(t){this[t]=1},t._.yo={}),r=t.dam)return(r=g.hear[r])&&r(t,e,s),void w(o);n=+new Date;u&&(u.is=n),e.SI=o,s.on("in",g.last=t),u&&(u.hd=+new Date),console.STAT&&console.STAT(n,+new Date-n,t.get?"msg get":t.put?"msg put":"msg"),(r=w(o)).via=e,t.get&&(r.it=t),a&&w(a),g.leap=g.last=null}},u.c=u.d=0,function(){var l,p=0;function t(t,e){var n;return e instanceof Object?(Object.keys(e).sort().forEach(o,{to:n={},on:e}),n):e}function o(t){this.to[t]=this.on[t]}g.hash=function(i,r){var a,u,s,c=+new Date;k(i.put,function t(e,n){var o=(u=u||(s=n||"")).slice(0,32768);a=String.hash(o,a),(u=u.slice(32768))?y(t,0):(console.STAT&&console.STAT(c,+new Date-c,"say json+hash"),i._.$put=s,i["##"]=a,d(i,r),delete i._.$put)},t)};var d=g.say=function(r,t){var e;if((e=this)&&(e=e.to)&&e.next&&e.next(r),!r)return!1;var n,a,u=r["@"],s=r._||(r._=function(){}),o=r.DBG,i=+new Date;if(s.y=s.y||i,t||o&&(o.y=i),(n=r["#"])||(n=r["#"]=String.random(9)),l||w(n),r.put&&(r.err||(m.s[n]||"").err))return!1;if(r["##"]||T===r.put||s.via||!u){if(!t&&u&&(t=(e=m.s[u])&&(e.via||(e=e.it)&&(e=e._)&&e.via)||(e=g.last)&&u===e["#"]&&g.leap),!t&&u){if(m.s[u])return;return console.STAT&&console.STAT(+new Date,++p,"total no peer to ack to"),!1}if(!t&&g.way)return g.way(r);if(o&&(o.yh=+new Date),a=s.raw){if(o&&(o.yr=+new Date),!t||!t.id){if(!Object.plain(t||v.peers))return!1;i=+new Date,v.puff;var c=v.peers,f=Object.keys(t||v.peers||{});return console.STAT&&console.STAT(i,+new Date-i,"peer keys"),void function t(){var e=+new Date;l=1;var n=s.raw;s.raw=a;for(var o,i=0;i<9&&(o=(f||"")[i++]);)(o=c[o])&&d(r,o);s.raw=n,l=0,f=f.slice(i),console.STAT&&console.STAT(e,+new Date-e,"say loop"),f.length&&(y(t,0),u&&w(u))}()}if(!t.wire&&g.wire&&g.wire(t),n!==t.last){if(t.last=n,t===s.via)return!1;if((e=s.yo)&&(e[t.url]||e[t.pid]||e[t.id]))return!1;if(console.STAT&&console.STAT(i,((o||s).yp=+new Date)-(s.y||i),"say prep"),!l&&u&&w(u),t.batch){if(t.tail=(e=t.tail||0)+a.length,t.tail<=v.pack)return void(t.batch+=(e?",":"")+a);b(t)}t.batch="[";var h=+new Date;setTimeout(function(){console.STAT&&console.STAT(h,+new Date-h,"0ms TO"),b(t)},v.gap),_(a,t),console.STAT&&u===t.SI&&console.STAT(i,+new Date-t.SH,"say ack")}}else g.raw(r,t)}else g.hash(r,t)};g.say.c=g.say.d=0,g.raw=function(n,o){if(!n)return"";var i,r,a=n._||{};if(r=a.raw)return r;if("string"==typeof n)return n;var t=n["##"],e=n["@"];if(t&&e){if(!a.via&&$(e+t))return!1;if((r=(m.s[e]||"").it)||(r=g.last)&&e===r["#"]){if(t===r["##"])return!1;r["##"]||(r["##"]=t)}}if(!n.dam){var u=0,s=[];for(var c in r=v.peers){var f=r[c];if(s.push(f.url||f.pid||f.id),6<++u)break}1<"]=s.join())}if(i=a.$put)return r={},Object.keys(n).forEach(function(t){r[t]=n[t]}),r.put=":])([:",void k(r,function(t,e){if(!t){var n=+new Date;r=e.indexOf('"put":":])([:"'),h(T,e=e.slice(0,r+6)+i+e.slice(r+14)),console.STAT&&console.STAT(n,+new Date-n,"say slice")}});function h(t,e){t||(a.raw=e,d(n,o))}k(n,h)}}(),g.hi=function(e){var t=e.wire||{};e.id?v.peers[e.url||e.id]=e:(t=e.id=e.id||String.random(9),g.say({dam:"?",pid:s.opt.pid},v.peers[t]=e),delete m.s[e.last]),e.met=e.met||+new Date,t.hied||s.on(t.hied="hi",e),t=e.queue,e.queue=[],setTimeout.each(t||[],function(t){_(t,e)},0,9)},g.bye=function(t){s.on("bye",t);var e=+new Date;e-=t.met||e,g.bye.time=((g.bye.time||e)+e)/2},g.hear["!"]=function(t,e){v.log("Error:",t.err)},g.hear["?"]=function(t,e){t.pid&&(e.pid||(e.pid=t.pid),t["@"])||(g.say({dam:"?",pid:v.pid,"@":t["#"]},e),delete m.s[e.last])},s.on("create",function(t){t.opt.pid=t.opt.pid||String.random(9),this.to.next(t),t.on("out",g.say)}),s.on("bye",function(t,e){t=v.peers[t.id||t]||t,this.to.next(t),t.bye?t.bye():(e=t.wire)&&e.close&&e.close(),delete v.peers[t.id],t.wire=null});var o={};return s.on("bye",function(t,e){this.to.next(t),(e=console.STAT)&&(e.peers=(e.peers||0)-1),(e=t.url)&&(o[e]=!0,setTimeout(function(){delete o[e]},v.lack||9e3))}),s.on("hi",function(e,n){this.to.next(e),(n=console.STAT)&&(n.peers=(n.peers||0)+1),(n=e.url)&&o[n]&&(delete o[n],v.super||setTimeout.each(Object.keys(s.next),function(t){s.next[t];(n={})[t]=s.graph[t],n=String.hash(n),g.say({"##":n,get:{"#":t}},e)}))}),g}}catch(t){}})(f,"./mesh"),f(function(t){var c=f("../index");c.Mesh=f("./mesh"),c.on("opt",function(t){if(this.to.next(t),!t.once){var o=t.opt;if(!1!==o.WebSocket){var e=c.window||{},n=o.WebSocket||e.WebSocket||e.webkitWebSocket||e.mozWebSocket;if(n){o.WebSocket=n;var i=o.mesh=o.mesh||c.Mesh(t);i.wire||o.wire;i.wire=o.wire=u,setTimeout(function(){o.super||t.on("out",{dam:"hi"})},1);var r=1998,a=""+void 0!=typeof document&&document}}}function u(e){try{if(!e||!e.url)return n&&n(e);var t=e.url.replace(/^http/,"ws"),n=e.wire=new o.WebSocket(t);return n.onclose=function(){o.mesh.bye(e),s(e)},n.onerror=function(t){s(e)},n.onopen=function(){o.mesh.hi(e)},n.onmessage=function(t){t&&o.mesh.hear(t.data||t,e)},n}catch(t){}}function s(e){clearTimeout(e.defer),a&&e.retry<=0||(e.retry=(e.retry||o.retry+1||60)-(-e.tried+(e.tried=+new Date)<4*r?1:0),e.defer=setTimeout(function t(){if(a&&a.hidden)return setTimeout(t,r);u(e)},r))}})})(f,"./websocket"),f(function(t){if("undefined"!=typeof Gun){var o;try{o=(Gun.window||function(){}).localStorage}catch(t){}o||(Gun.log("Warning: No localStorage exists to persist data to!"),o={setItem:function(t,e){this[t]=e},removeItem:function(t){delete this[t]},getItem:function(t){return this[t]}}),Gun.on("create",function e(n){this.to.next(n);var r,i,a=n.opt,u=(n.graph,[]);if(!1!==a.localStorage){a.prefix=a.file||"gun/";try{r=e[a.prefix]=e[a.prefix]||JSON.parse(o.getItem(a.prefix))||{}}catch(t){r=e[a.prefix]={}}n.on("get",function(t){this.to.next(t);var e,n,o,i=t.get;i&&(e=i["#"])&&((n=r[e]||void 0)&&(o=i["."])&&!Object.plain(o)&&(n=Gun.state.ify({},o,Gun.state.is(n,o),n[o],e)),Gun.on.get.ack(t,n))}),n.on("put",function(t){this.to.next(t);var e=t.put,n=e["#"],o=e["."];r[n]=Gun.state.ify(r[n],o,e[">"],e[":"],n),t["@"]||u.push(t["#"]),i=i||setTimeout(s,a.wait||1)})}function s(){var e,t=u;clearTimeout(i),i=!1,u=[];try{o.setItem(a.prefix,JSON.stringify(r))}catch(t){Gun.log((e=t||"localStorage failure")+" Consider using GUN's IndexedDB plugin for RAD for more storage space, https://gun.eco/docs/RAD#install"),n.on("localStorage:error",{err:e,get:a.prefix,put:r})}(e||Object.empty(a.peers))&&setTimeout.each(t,function(t){n.on("in",{"@":t,err:e,ok:0})})}})}})(f,"./localStorage")}(); \ No newline at end of file diff --git a/src/ask.js b/src/ask.js index 52df939d..5fa0a5cb 100644 --- a/src/ask.js +++ b/src/ask.js @@ -15,7 +15,7 @@ module.exports = function ask(cb, as){ } return true; } - var id = (as && as['#']) || Math.random().toString(36).slice(2); + var id = (as && as['#']) || random(9); if(!cb){ return id } var to = this.on(id, cb, as); to.err = to.err || setTimeout(function(){ to.off(); @@ -23,4 +23,5 @@ module.exports = function ask(cb, as){ }, lack); return id; } +var random = String.random || function(){ return Math.random().toString(36).slice(2) } \ No newline at end of file diff --git a/src/get.js b/src/get.js index 4510ab87..a47f72ea 100644 --- a/src/get.js +++ b/src/get.js @@ -67,6 +67,7 @@ Gun.chain.get = function(key, cb, as){ }; wait = {}; // end quick hack. } // call: + if(root.pass){ if(root.pass[id+at.id]){ return } root.pass[id+at.id] = 1 } if(opt.on){ opt.ok.call(at.$, data, at.get, msg, eve || any); return } // TODO: Also consider breaking `this` since a lot of people do `=>` these days and `.call(` has slower performance. if(opt.v2020){ opt.ok(msg, eve || any); return } Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {}); msg = tmp; msg.put = data; // 2019 COMPATIBILITY! TODO: GET RID OF THIS! diff --git a/src/localStorage.js b/src/localStorage.js index a048e081..f8a35099 100644 --- a/src/localStorage.js +++ b/src/localStorage.js @@ -35,6 +35,7 @@ Gun.on('create', function lg(root){ disk[soul] = Gun.state.ify(disk[soul], key, put['>'], put[':'], soul); // merge into disk object if(!msg['@']){ acks.push(msg['#']) } // then ack any non-ack write. // TODO: use batch id. if(to){ return } + //flush();return; to = setTimeout(flush, opt.wait || 1); // that gets saved as a whole to disk every 1ms }); function flush(){ diff --git a/src/put.js b/src/put.js index fbf00fef..3eeda5d8 100644 --- a/src/put.js +++ b/src/put.js @@ -17,6 +17,7 @@ Gun.chain.put = function(data, cb, as){ // I rewrote it :) as.todo = [{it: as.data, ref: as.$}]; as.turn = as.turn || turn; as.ran = as.ran || ran; + //var path = []; as.via.back(at => { at.get && path.push(at.get.slice(0,9)) }); path = path.reverse().join('.'); // TODO: Perf! We only need to stun chains that are being modified, not necessarily written to. (function walk(){ var to = as.todo, at = to.pop(), d = at.it, cid = at.ref && at.ref._.id, v, k, cat, tmp, g; @@ -41,12 +42,13 @@ Gun.chain.put = function(data, cb, as){ // I rewrote it :) (as.wait || (as.wait = {}))[id] = ''; tmp = (cat.ref = (g? d : k? at.ref.get(k) : at.ref))._; (tmp = (d && (d._||'')['#']) || tmp.soul || tmp.link)? resolve({soul: tmp}) : cat.ref.get(resolve, {run: as.run, /*hatch: 0,*/ v2020:1, out:{get:{'.':' '}}}); // TODO: BUG! This should be resolve ONLY soul to prevent full data from being loaded. // Fixed now? + //setTimeout(function(){ if(F){ return } console.log("I HAVE NOT BEEN CALLED!", path, id, cat.ref._.id, k) }, 9000); var F; // MAKE SURE TO ADD F = 1 below! function resolve(msg, eve){ - if(cat.link['#']){ return as.ran(as) } + var end = cat.link['#']; if(eve){ eve.off(); eve.rid(msg) } // TODO: Too early! Check all peers ack not found. // TODO: BUG maybe? Make sure this does not pick up a link change wipe, that it uses the changign link instead. - var soul = msg.soul || (tmp = (msg.$$||msg.$)._||'').soul || tmp.link || ((tmp = tmp.put||'')._||'')['#'] || tmp['#'] || (((tmp = msg.put||'') && msg.$$)? tmp['#'] : (tmp['=']||tmp[':']||'')['#']); - stun(as, msg.$); + var soul = end || msg.soul || (tmp = (msg.$$||msg.$)._||'').soul || tmp.link || ((tmp = tmp.put||'')._||'')['#'] || tmp['#'] || (((tmp = msg.put||'') && msg.$$)? tmp['#'] : (tmp['=']||tmp[':']||'')['#']); + !end && stun(as, msg.$); if(!soul && !at.link['#']){ // check soul link above us (at.wait || (at.wait = [])).push(function(){ resolve(msg, eve) }) // wait return; @@ -108,7 +110,6 @@ function ran(as){ (tmp = function(){ // this is not official yet, but quick solution to hack in for now. if(!stun){ return } ran.end(stun, root); - //console.log("PUT HATCH END", as.run, Object.keys(stun.add||'')); setTimeout.each(Object.keys(stun = stun.add||''), function(cb){ if(cb = stun[cb]){cb()} }); // resume the stunned reads // Any perf reasons to CPU schedule this .keys( ? }).hatch = tmp; // this is not official yet ^ //console.log(1, "PUT", as.run, as.graph); diff --git a/src/root.js b/src/root.js index 9f3fe20d..95eccb28 100644 --- a/src/root.js +++ b/src/root.js @@ -39,6 +39,7 @@ Gun.ask = require('./ask'); return gun; } function universe(msg){ + //if(!F){ var eve = this; setTimeout(function(){ universe.call(eve, msg,1) },Math.random() * 100);return; } // ADD F TO PARAMS! if(!msg){ return } if(msg.out === universe){ this.to.next(msg); return } var eve = this, as = eve.as, at = as.at || as, gun = at.$, dup = at.dup, tmp, DBG = msg.DBG; @@ -139,8 +140,8 @@ Gun.ask = require('./ask'); if((tmp = ctx.msg) && (tmp = tmp.put) && (tmp = tmp[soul])){ state_ify(tmp, key, state, val, soul) } // necessary! or else out messages do not get SEA transforms. graph[soul] = state_ify(graph[soul], key, state, val, soul); if(tmp = (root.next||'')[soul]){ tmp.on('in', msg) } - eve.to.next(msg); fire(ctx); + eve.to.next(msg); } function fire(ctx, msg){ var root; if(ctx.stop){ return } @@ -156,19 +157,20 @@ Gun.ask = require('./ask'); ctx.root.on('out', msg); } function ack(msg){ // aggregate ACKs. - var id = msg['@'] || '', root = (msg.$._||'').root, tmp; - // TODO: check for the sharded message err and transfer it onto the original batch? - if(!(tmp = id._)){ /*console.log("TODO: handle ack id.");*/ return } - tmp.acks = (tmp.acks||0) + 1; - if(tmp.err = msg.err){ - msg['@'] = tmp['#']; - --tmp.stun; - } - if(0 == tmp.stun && tmp.acks == tmp.all){ // TODO: if ack is synchronous this may not work? - root && root.on('in', {'@': tmp['#'], err: msg.err, ok: msg.err? u : 'shard'}); - msg.err && fire(tmp); - return; + var id = msg['@'] || '', ctx; + if(!(ctx = id._)){ return } + ctx.acks = (ctx.acks||0) + 1; + if(ctx.err = msg.err){ + msg['@'] = ctx['#']; + fire(ctx); // TODO: BUG? How it skips/stops propagation of msg if any 1 item is error, this would assume a whole batch/resync has same malicious intent. } + if(!ctx.stop && !ctx.crack){ ctx.crack = ctx.match && ctx.match.push(function(){back(ctx)}) } // handle synchronous acks + back(ctx); + } + function back(ctx){ + if(!ctx || !ctx.root){ return } + if(ctx.stun || ctx.acks !== ctx.all){ return } + ctx.root.on('in', {'@': ctx['#'], err: ctx.err, ok: ctx.err? u : {'':1}}); } var ERR = "Error: Invalid graph!"; diff --git a/src/shim.js b/src/shim.js index 1cbed3d4..83496170 100644 --- a/src/shim.js +++ b/src/shim.js @@ -48,7 +48,7 @@ Object.keys = Object.keys || function(o){ } ;(function(){ // max ~1ms or before stack overflow var u, sT = setTimeout, l = 0, c = 0, sI = (typeof setImmediate !== ''+u && setImmediate) || sT; // queueMicrotask faster but blocks UI - sT.poll = sT.poll || function(f){ + sT.poll = sT.poll || function(f){ //f(); return; // for testing if((1 >= (+new Date - l)) && c++ < 3333){ f(); return } sI(function(){ l = +new Date; f() },c=0) } diff --git a/src/websocket.js b/src/websocket.js index c182d427..17b57e5b 100644 --- a/src/websocket.js +++ b/src/websocket.js @@ -2,6 +2,9 @@ var Gun = require('../index'); Gun.Mesh = require('./mesh'); +// TODO: resync upon reconnect online/offline +//window.ononline = window.onoffline = function(){ console.log('online?', navigator.onLine) } + Gun.on('opt', function(root){ this.to.next(root); if(root.once){ return }