From 693eeb6b072f6ac5dd0079eaf819775827f74c5d Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Mon, 14 Sep 2020 22:12:08 +0200 Subject: [PATCH 1/8] Initialize editorconfig --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..86cfb1c26 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# 2d0e4a3f-ac19-430c-bf1b-46c68651ce21 +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_size = 2 +indent_style = space + +[*.{php,html}] +indent_size = 4 + +[Makefile*] +indent_style = tab From 1af8feca9ac7554887e6d768b1b4f8749e89b859 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Tue, 15 Sep 2020 00:49:32 +0200 Subject: [PATCH 2/8] Initial leveldb adapter --- gun.js | 69 ++++++++++++ gun.min.js | 2 +- package-lock.json | 154 ++++++++++++++++++++++++- package.json | 2 + src/adapters/leveldb.js | 68 +++++++++++ test/panic/leveldb.js | 242 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 src/adapters/leveldb.js create mode 100644 test/panic/leveldb.js diff --git a/gun.js b/gun.js index 3cc08128c..940d20524 100644 --- a/gun.js +++ b/gun.js @@ -1936,6 +1936,75 @@ function uuid(){ return Gun.state.lex() + Gun.text.random(7) } })(USE, './set'); + ;USE(function(module){ + var Gun = USE('../index'); + + Gun.on('create', function(root) { + var ev = this.to; + var opt = root.opt; + + if (root.once) { + return ev.next(root); + } + + // Check if the given 'level' argument implements all the components we need + // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api + if ( + (!opt.level) || + ('object' !== typeof opt.level) || + ('function' !== typeof opt.level.get) || + ('function' !== typeof opt.level.put) || + ('function' !== typeof opt.level.createReadStream) + ) { + return ev.next(root); + } + + // How to write + root.on('put', function(msg){ + this.to.next(msg); + + var put = msg.put; + var soul = put['#']; + var key = put['.']; + var val = put[':']; + var state = put['>']; + + // only ack non-acks. + if (!msg['@']) { + (acks[msg['#']] = (tmp = (msg._||'').lot || {})).lS = (tmp.lS||0)+1; + } + + // Fetch current state + opt.level.get(soul, function(err, data) { + if (data) data = JSON.parse(data); + + // Serialize & store + var toStore = JSON.stringify(Gun.state.ify(data, key, state, val, soul)); + opt.level.put(soul, toStore, function(err, data) { + if (err) return; + // TODO: ack here? + }); + }); + + }); + + // How to read + root.on('get', function(msg){ + this.to.next(msg); + var get = msg.get; + var soul = get['#']; + opt.level.get(soul, function(err, data) { + if (err) return; + if (data) data = JSON.parse(data); + root.on('in', {'@': soul, put: Gun.graph.node(data), lS: 1}); + }); + + }); + + }); + + })(USE, './adapters/leveldb'); + ;USE(function(module){ if(typeof Gun === 'undefined'){ return } // TODO: localStorage is Browser only. But it would be nice if it could somehow plugin into NodeJS compatible localStorage APIs? diff --git a/gun.min.js b/gun.min.js index a462116e3..b1329d4f9 100644 --- a/gun.min.js +++ b/gun.min.js @@ -1 +1 @@ -!function(){function _(e,t){return t?require(e):e.slice?_[o(e)]:function(t,n){e(t={exports:{}}),_[o(n)]=t.exports};function o(t){return t.split("/").slice(-1).toString().replace(".js","")}}if("undefined"!=typeof module)var b=module;_(function(t){var n,l,p={};function e(t,n){v(this,n)&&void 0!==this[n]||(this[n]=t)}function o(t,n){var e=this.n;if(!e||!(n===e||g(e)&&v(e,n)))return void 0!==n||void 0}function h(t,n){2!==arguments.length?(h.r=h.r||[]).push(t):(h.r=h.r||{})[t]=n}p.fn={is:function(t){return!!t&&"function"==typeof t}},p.bi={is:function(t){return t instanceof Boolean||"boolean"==typeof t}},p.num={is:function(t){return!d(t)&&(0<=t-parseFloat(t)+1||1/0===t||-1/0===t)}},p.text={is:function(t){return"string"==typeof t}},p.text.ify=function(t){return p.text.is(t)?t:"undefined"!=typeof JSON?JSON.stringify(t):t&&t.toString?t.toString():t},p.text.random=function(t,n){var e="";for(t=t||24,n=n||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0"]||n["<"])||o===n["="]&&(e=n["*"]||n[">"]||n["<"],t.slice(0,(e||"").length)===e||o===n["*"]&&(o!==n[">"]&&o!==n["<"]?t>=n[">"]&&t<=n["<"]:o!==n[">"]&&t>=n[">"]||o!==n["<"]&&t<=n["<"])))},p.text.hash=function(t,n){if("string"==typeof t){if(n=n||0,!t.length)return n;for(var e=0,o=t.length;e");function f(t,n){k!==n&&u.ify(this.o,n,this.s)}u.drift=0,u.is=function(t,n,e){var o=n&&t&&t[k]&&t[k][s]||e;if(o)return v(o=o[n])?o:-1/0},u.lex=function(){return u().toString(36).replace(".","")},u.ify=function(t,n,e,o,i){if(!t||!t[k]){if(!i)return;t=a.soul.ify(t,i)}var r=l(t[k],s);return void 0!==n&&n!==k&&(v(e)&&(r[n]=e),void 0!==o&&(t[n]=o)),t},u.to=function(t,n,e){var o=(t||{})[n];return h(o)&&(o=g(o)),u.ify(e,n,u.is(t,n),o,a.soul(t))},u.map=function(i,r,a){var t=h(t=i||r)?t:null;return i=m(i=i||r)?i:null,t&&!i?(r=v(r)?r:u(),t[k]=t[k]||{},d(t,f,{o:t,s:r}),t):(a=a||h(r)?r:void 0,r=v(r)?r:u(),function(t,n,e,o){if(!i)return f.call({o:e,s:r},t,n),t;i.call(a||this||{},t,n,e,o),p(e,n)&&void 0===e[n]||f.call({o:e,s:r},t,n)})};var c=n.obj,l=c.as,p=c.has,h=c.is,d=c.map,g=c.copy,v=n.num.is,m=n.fn.is,k=a._;t.exports=u})(_,"./state"),_(function(t){var a=_("./type"),u=_("./val"),s=_("./node"),i={};function r(t,n){if(!t||n!==s.soul(t)||!s.is(t,this.fn,this.as))return!0;this.cb&&(e.n=t,e.as=this.as,this.cb.call(e.as,t,n,e))}function e(t){t&&s.is(e.n,t,e.as)}function f(t,n){var e;return(e=function(t,n){var e,o=t.seen,i=o.length;for(;i--;)if(e=o[i],n.obj===e.obj)return e;o.push(n)}(t,n))?e:(n.env=t,n.soul=c,s.ify(n.obj,o,n)&&(n.link=n.link||u.link.ify(s.soul(n.node)),n.obj!==t.shell&&(t.graph[u.link.is(n.link)]=n.node)),n)}function o(t,n,e){var o,i,r=this,a=r.env;if(s._===n&&g(t,u.link._))return e._;if(o=l(t,n,e,r,a)){if(n||(r.node=r.node||e||{},g(t,s._)&&s.soul(t)&&(r.node._=b(t._)),r.node=s.soul.ify(r.node,u.link.is(r.link)),r.link=r.link||u.link.ify(s.soul(r.node))),(i=a.map)&&(i.call(a.as||{},t,n,e,r),g(e,n))){if(void 0===(t=e[n]))return void d(e,n);if(!(o=l(t,n,e,r,a)))return}if(!n)return r.node;if(!0===o)return t;if((i=f(a,{obj:t,path:r.path.concat(n)})).node)return i.link}}function c(t){var n=this,e=u.link.is(n.link),o=n.env.graph;n.link=n.link||u.link.ify(t),n.link[u.link._]=t,n.node&&n.node[s._]&&(n.node[s._][u.link._]=t),g(o,e)&&(o[t]=o[e],d(o,e))}function l(t,n,e,o,i){var r;return!!u.is(t)||(h(t)?1:(r=i.invalid)?l(t=r.call(i.as||{},t,n,e),n,e,o,i):(i.err="Invalid value at '"+o.path.concat(n).join(".")+"'!",void(a.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}function p(t,n){var e,o;if(s._!==n)(e=u.link.is(t))?(o=this.opt.seen[e])?this.obj[n]=o:this.obj[n]=this.opt.seen[e]=i.to(this.graph,e,this.opt):this.obj[n]=t;else{if(v(t,u.link._))return;this.obj[n]=b(t)}}i.is=function(t,n,e,o){return!(!t||!h(t)||v(t))&&!k(t,r,{cb:n,fn:e,as:o})},i.ify=function(t,n,e){var o={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:"function"==typeof n&&(n.map=n):n={},"string"==typeof e&&(n.soul=n.soul||e,e=void 0),n.soul&&(o.link=u.link.ify(n.soul)),n.shell=(e||{}).shell,n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||e,f(n,o),n.root=o.node,n.graph},i.node=function(t){var n=s.soul(t);if(n)return m({},n,t)},i.to=function(t,n,e){if(t){var o={};return e=e||{seen:{}},k(t[n],p,{obj:o,graph:t,opt:e}),o}};a.fn.is;var n=a.obj,h=n.is,d=n.del,g=n.has,v=n.empty,m=n.put,k=n.map,b=n.copy;t.exports=i})(_,"./graph"),_(function(t){_("./onto"),t.exports=function(t,n){if(this.on){if("function"!=typeof t){if(!t||!n)return;var e=t["#"]||t,o=(this.tag||"")[e];if(!o)return;return o=this.on(e,n),clearTimeout(o.err),!0}e=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return e;var i=this.on(e,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK yet.",lack:!0}),i.off()},(this.opt||{}).lack||9e3),e}}})(_,"./ask"),_(function(t){var u=_("./type");t.exports=function(i){var r={s:{}},a=r.s;i=i||{max:1e3,age:27e3},r.check=function(t){return!!a[t]&&n(t)};var n=r.track=function(t){var n=a[t]||(a[t]={});return n.was=+new Date,r.to||(r.to=setTimeout(r.drop,i.age+9)),n};return r.drop=function(e){var o=+new Date;u.obj.map(a,function(t,n){t&&(e||i.age)>o-t.was||delete a[n]}),r.to=null,console.STAT&&9<(e=new Date-o)&&console.STAT(o,e,"dup drop")},r}})(_,"./dup"),_(function(t){function x(t){return t instanceof x?(this._={$:this}).$:this instanceof x?x.create(this._={$:this,opt:t}):new x(t)}x.is=function(t){return t instanceof x||t&&t._&&t===t._.$||!1},x.version=.202,(x.chain=x.prototype).toJSON=function(){};var n=_("./type");function r(t,n,e,o){var i=this,r=x.state.is(e,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+o+"'!";var a=i.graph[o]||G,u=x.state.is(a,n,!0),s=a[n],f=x.HAM(i.machine,r,u,t,s);f.incoming?(i.put[o]=x.state.to(e,n,i.put[o]),(i.diff||(i.diff={}))[o]=x.state.to(e,n,i.diff[o]),i.souls[o]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function a(t,n){var e=this,o=e.$._,i=(o.next||G)[n];if(!i){if(!(o.opt||G).super)return void(e.souls[n]=!1);i=e.$.get(n)._}var r=e.map[n]={put:t,get:n,$:i.$},a={ctx:e,msg:r};e.async=!!o.tag.node,e.ack&&(r["@"]=e.ack),m(t,u,a),e.async&&(e.and||o.on("node",function(t){this.to.next(t),t===e.map[t.get]&&(e.souls[t.get]=!1,m(t.put,s,t),m(e.souls,function(t){if(t)return t})||e.c||(e.c=1,this.off(),m(e.map,f,e)))}),e.and=!0,o.on("node",r))}function u(t,n){var e=this.ctx,o=e.graph,i=this.msg,r=i.get,a=i.put,u=i.$._;o[r]=x.state.to(a,n,o[r]),e.async||(u.put=x.state.to(a,n,u.put))}function s(t,n){var e=this.put,o=this.$._;o.put=x.state.to(e,n,o.put)}function f(t,n){t.$&&(this.cat.stop=this.stop,t.$._.on("in",t),this.cat.stop=null)}function c(t,n){if(t!==this.graph[n])return!0}n.obj.to(n,x),x.HAM=_("./HAM"),x.val=_("./val"),x.node=_("./node"),x.state=_("./state"),x.graph=_("./graph"),x.on=_("./onto"),x.ask=_("./ask"),x.dup=_("./dup"),x.puff=_("./puff"),function(){function f(t){if(t)if(t.out!==f){var n,e=this.as,o=e.at||e,i=o.$,r=o.dup,a=t.DBG;(n=t["#"])||(n=t["#"]=p(9)),r.check(n)||(r.track(n),n=t._,t._="function"==typeof n?n:function(){},t.$&&t.$===(t.$._||"").$||(t.$=i),o.ask(t["@"],t)||(a&&(a.u=+new Date),t.get&&x.on._get(t,i),!t.put)?(a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.out=f,o.on("out",t),a&&(a.ue=+new Date)):u(t))}else this.to.next(t)}function u(t){if(t){var n,e,o=t._||"",i=o.root=((t.$||"")._||"").root,r=t.put,a=t["#"],u=o.DBG=t.DBG;if(r["#"]&&r["."])i.on("put",t);else{o.out=t,o.lot={s:0,more:1};var s=+new Date;for(var f in u&&(u.p=s),r){var c,l=r[f];if(!l){n=m+k(f)+"no node.";break}if(!(e=l._)){n=m+k(f)+"no meta.";break}if(f!==e[T]){n=m+k(f)+"soul not same.";break}if(!(c=e[A])){n=m+k(f)+"no state.";break}for(var p in l)if(S!==p){var h=l[p],d=c[p];if(w===d){n=m+k(p)+"on"+k(f)+"no state.";break}if(!D(h)){n=m+k(p)+"on"+k(f)+"bad "+typeof h+k(h);break}g(h,p,f,d,t)}if(n)break}u&&(u.pe=+new Date),console.STAT&&(console.STAT(s,new Date-s,"mix"),console.STAT(s,o.lot.s,"mix #")),(o.err=n)?i.on("in",{"@":a,err:x.log(n)}):(--o.lot.more||v(o),o.stun||t["@"]||i.on("in",{"@":a,ok:-1}))}}}function g(t,n,e,o,i){var r,a=i._||"",u=a.root,s=u.graph[e]||G,f=j(s,n,1),c=s[n],l=_(),p=b(l,o,f,t,c);if(p.incoming){(r=a.lot||"").s++,r.more++,(a.stun||(a.stun={}))[e+n]=1;var h=a.DBG;h&&(h.ph=h.ph||+new Date),u.on("put",{"#":i["#"],"@":i["@"],put:{"#":e,".":n,":":t,">":o},_:a})}else if(p.defer){var d=o-l;return setTimeout(function(){g(t,n,e,o,i)},y"];t["#"];o[a]=$(o[a],u,f,s,a),function(t,n,e,o,i){var r,a,u=t.root;if((u.opt||"").super&&u.$.get(n),!(u&&(a=u.next)&&(a=a[n])&&a.$))return;(r=t.put||(t.put={}))[n]=$(r[n],e,i,o,n),a.put=$(a.put,e,i,o,n)}(i,a,u,w!==(e=r["="])?e:s,f),(e=i.out)&&(e=e.put)&&(e[a]=$(e[a],u,f,s,a)),--i.lot.more||v(i),this.to.next(t)}function v(t){if(!t.err){var n,e={},o=t.root,i=o.next||"",r=t.put,a=+new Date;for(var u in r){var s=r[u];(n=i[u])&&n.$&&(o.stop=e,n.on("in",{$:n.$,get:u,put:s}),o.stop=null)}console.STAT&&console.STAT(a,new Date-a,"fire"),t.DBG&&(t.DBG.f=+new Date),(n=t.out)&&(n.out=f,o.on("out",n))}}x.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||x.on,t.ask=t.ask||x.ask,t.dup=t.dup||x.dup();var n=t.$.opt(t.opt);return t.once||(t.on("in",f,t),t.on("out",f,t),t.on("put",e,t),x.on("create",t),t.on("create",t)),t.once=1,n},x.on.put=u;var m="Error: Invalid graph!",k=function(t){return" '"+(""+t).slice(0,9)+"...' "},b=x.HAM,y=2147483647,_=x.state}(),x.on._put=function(t,n){var e=n._,o={$:n,graph:e.graph,put:{},map:{},souls:{},machine:x.state(),ack:t["@"],cat:e,stop:{}};if(x.obj.map(t.put,c,o)){if(x.graph.is(t.put,null,r,o)||(o.err="Error: Invalid graph!"),o.err)return e.on("in",{"@":t["#"],err:x.log(o.err)});if(m(o.put,a,o),o.async||m(o.map,f,o),w!==o.defer){var i=o.defer-o.machine;setTimeout(function(){x.on._put(t,n)},i>MD?MD:i)}o.diff&&e.on("put",v(t,{put:o.diff}))}},x.on._get=function(t,n){var e=n._,o=t.get,i=o[T],r=e.graph[i],a=o[k],u=(e.next||(e.next={}))[i],s=(t._||"").DBG=t.DBG;if(s&&(s.g=+new Date),!r)return e.on("get",t);if(a){if("string"!=typeof a||!g(r,a))return e.on("get",t);r=x.state.to(r,a)}else r=x.window?x.obj.copy(r):r;r=x.graph.node(r),(u||G).ack;function f(){}f.ram=f.faith=!0,s&&(s.ga=+new Date),e.on("in",{"@":t["#"],put:r,ram:1,$:n,_:f}),s&&(s.gm=+new Date),e.on("get",t),s&&(s.gd=+new Date)},x.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return d(t)||(t={}),d(n.opt)||(n.opt=t),l(e)&&(e=[e]),o(e)&&(e=m(e,function(t,n,e){(n={}).id=n.url=t,e(t,n)}),d(n.opt.peers)||(n.opt.peers={}),n.opt.peers=v(e,n.opt.peers)),n.opt.peers=n.opt.peers||{},m(t,function t(n,e){!g(this,e)||i.is(n)||h.empty(n)?this[e]=n:n&&n.constructor!==Object&&!o(n)||m(n,t,this[e])},n.opt),x.on("opt",n),x.obj.native(),this},x.obj.native=function(){var t=Object.prototype;for(var n in t)console.log("Native Object.prototype polluted, reverting",n),delete t[n]};var w,e,o=x.list.is,i=x.text,l=i.is,p=i.random,h=x.obj,d=(h.empty,h.is),g=h.has,v=h.to,m=h.map,$=(h.copy,x.state.lex,x.state.ify),j=x.state.is,T=x.val.link._,k=".",S=x.node._,D=x.val.is,A=(x.val.link.is,x.state._),G={};(x.log=function(){return x.log.off||e.log.apply(e,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,e){return(e=x.log.once)[t]=e[t]||0,e[t]++||x.log(n)},"undefined"!=typeof window&&((window.GUN=window.Gun=x).window=window);try{void 0!==b&&(b.exports=x)}catch(t){}((t.exports=x).window||"").console=(x.window||"").console||{log:function(){}},(e=console).only=function(t,n){return e.only.i&&t===e.only.i&&e.only.i++&&(e.log.apply(e,arguments)||n)},x.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!")})(_,"./root"),_(function(t){var u=_("./root");u.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var e=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=e;o(r.acks||0)&&this.off(),r.ack&&r.ack(t,this)},r.opt),e=0,o=n.root.now;a.del(n.root,"now");var i=n.root.mum;n.root.mum={},r.ref._.on("out",{$:r.ref,put:r.out=r.env.graph,opt:r.opt,"#":t}),n.root.mum=i?a.to(i,n.root.mum):i,n.root.now=o,r.via._.on("res",{}),delete r.via._.tag.res},r),r.res&&r.res())}function f(r,t,n,a){var u=this,s=c.is(r);!t&&a.path.length&&(u.res||e)(function(){for(var t=a.path,n=u.ref,e=(u.opt,0),o=t.length;e .once, apologies unexpected."),this.once(t,n)},f.chain.once=function(t,n){var e=this,o=e._,i=o.put;if(0"];if(l[o]=Gun.state.ify(l[o],i,a,r,o),t["@"]||((f[t["#"]]=n=(t._||"").lot||{}).lS=(n.lS||0)+1),(c+=1)>=(u.batch||1e3))return p();s=s||setTimeout(p,u.wait||1)}),a.on("get",function(n){this.to.next(n);var e,o,i,r=n.get;function t(){if(r&&(e=r["#"])){var t=r["."];(o=l[e]||i)&&t&&(o=Gun.state.to(o,t)),a.on("in",{"@":n["#"],put:Gun.graph.node(o),lS:1})}}Gun.debug?setTimeout(t,1):t()});var p=function(t){var e;c=0,clearTimeout(s),s=!1;var n=f;f={},t&&(l=t);try{h.setItem(u.prefix,JSON.stringify(l))}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"),a.on("localStorage:error",{err:e,file:u.prefix,flush:l,retry:p})}(e||Gun.obj.empty(u.peers))&&Gun.obj.map(n,function(t,n){if(t){if(t.more)return void(f[n]=t);t.s!==t.lS&&(e="localStorage batch not same.")}a.on("in",{"@":n,err:e,ok:0})})}}})}})(_,"./adapters/localStorage"),_(function(t){var e,x=_("../type");function o(t,n){var e;if(!(n instanceof Object))return n;var o=+new Date;return x.obj.map(Object.keys(n).sort(),i,{to:e={},on:n}),console.STAT&&console.STAT(o,new Date-o,"sort"),e}function i(t){this.to[t]=this.on[t]}e=JSON.stringify,x.obj.hash=function(t,n){if(n||void 0!==(t=e(t,o)))return x.text.hash(n||t||"")},x.obj.hash.sort=o;var w=x.obj.is;x.obj.map;try{t.exports=function(f){var l=function(){},p=f.opt||{};p.log=p.log||console.log,p.gap=p.gap||p.wait||0,p.pack=p.pack||.3*(p.memory?1e3*p.memory*1e3:1399e6),p.puff=p.puff||9;var h,d,g,v=setTimeout.puff||setTimeout,m=f.dup,c=m.check,k=m.track,b=l.hear=function(t,i){if(t){if(p.pack<=t.length)return l.say({dam:"!",err:"Message too big!"},i);var r,n,e,o=t[0];if(l===this&&(b.d+=t.length||0,++b.c),"["!==o){if("{"===o||(t["#"]||w(t))&&(r=t)){try{r=r||JSON.parse(t)}catch(t){return p.log("DAM JSON parse error",t)}if(!r)return;if(r.DBG&&(r.DBG=e={DBG:r.DBG}),e&&(e.hp=+new Date),(n=r["#"])||(n=r["#"]=x.text.random(9)),o=c(n))return;if((r._=function(){}).via=l.leap=i,o=r.dam)return(o=l.hear[o])&&o(r,i,f),void k(n);var a,u=+new Date;e&&(e.is=u),f.on("in",r),e&&(e.hd=+new Date),console.STAT&&9<(a=new Date-u)&&console.STAT(u,a,"msg"),k(n).via=i,l.leap=null}}else{try{r=JSON.parse(t)}catch(t){p.log("DAM JSON parse error",t)}if(t="",!r)return;console.STAT&&console.STAT(+new Date,r.length,"# on hear batch");var s=p.puff;(function t(){for(var n,e=+new Date,o=0;o"]||n["<"])||o===n["="]&&(e=n["*"]||n[">"]||n["<"],t.slice(0,(e||"").length)===e||o===n["*"]&&(o!==n[">"]&&o!==n["<"]?t>=n[">"]&&t<=n["<"]:o!==n[">"]&&t>=n[">"]||o!==n["<"]&&t<=n["<"])))},p.text.hash=function(t,n){if("string"==typeof t){if(n=n||0,!t.length)return n;for(var e=0,o=t.length;e";function s(t,n){m!==n&&u.ify(this.o,n,this.s)}u.drift=0,u.is=function(t,n,e){var o=n&&t&&t[m]&&t[m][">"]||e;if(o)return v(o=o[n])?o:-1/0},u.lex=function(){return u().toString(36).replace(".","")},u.ify=function(t,n,e,o,i){if(!t||!t[m]){if(!i)return;t=a.soul.ify(t,i)}var r=c(t[m],">");return void 0!==n&&n!==m&&(v(e)&&(r[n]=e),void 0!==o&&(t[n]=o)),t},u.to=function(t,n,e){var o=(t||{})[n];return p(o)&&(o=d(o)),u.ify(e,n,u.is(t,n),o,a.soul(t))},u.map=function(i,r,a){var t=p(t=i||r)?t:null;return i=g(i=i||r)?i:null,t&&!i?(r=v(r)?r:u(),t[m]=t[m]||{},h(t,s,{o:t,s:r}),t):(a=a||p(r)?r:void 0,r=v(r)?r:u(),function(t,n,e,o){if(!i)return s.call({o:e,s:r},t,n),t;i.call(a||this||{},t,n,e,o),l(e,n)&&void 0===e[n]||s.call({o:e,s:r},t,n)})};var f=n.obj,c=f.as,l=f.has,p=f.is,h=f.map,d=f.copy,v=n.num.is,g=n.fn.is,m=a._;t.exports=u})(G,"./state"),G(function(t){var a=G("./type"),u=G("./val"),s=G("./node"),i={};function r(t,n){if(!t||n!==s.soul(t)||!s.is(t,this.fn,this.as))return!0;this.cb&&(e.n=t,e.as=this.as,this.cb.call(e.as,t,n,e))}function e(t){t&&s.is(e.n,t,e.as)}function f(t,n){var e;return(e=function(t,n){var e,o=t.seen,i=o.length;for(;i--;)if(e=o[i],n.obj===e.obj)return e;o.push(n)}(t,n))?e:(n.env=t,n.soul=c,s.ify(n.obj,o,n)&&(n.link=n.link||u.link.ify(s.soul(n.node)),n.obj!==t.shell&&(t.graph[u.link.is(n.link)]=n.node)),n)}function o(t,n,e){var o,i,r=this,a=r.env;if(s._===n&&g(t,u.link._))return e._;if(o=l(t,n,e,r,a)){if(n||(r.node=r.node||e||{},g(t,s._)&&s.soul(t)&&(r.node._=y(t._)),r.node=s.soul.ify(r.node,u.link.is(r.link)),r.link=r.link||u.link.ify(s.soul(r.node))),(i=a.map)&&(i.call(a.as||{},t,n,e,r),g(e,n))){if(t=e[n],h===t)return void v(e,n);if(!(o=l(t,n,e,r,a)))return}if(!n)return r.node;if(!0===o)return t;if((i=f(a,{obj:t,path:r.path.concat(n)})).node)return i.link}}function c(t){var n=this,e=u.link.is(n.link),o=n.env.graph;n.link=n.link||u.link.ify(t),n.link[u.link._]=t,n.node&&n.node[s._]&&(n.node[s._][u.link._]=t),g(o,e)&&(o[t]=o[e],v(o,e))}function l(t,n,e,o,i){var r;return!!u.is(t)||(d(t)?1:(r=i.invalid)?l(t=r.call(i.as||{},t,n,e),n,e,o,i):(i.err="Invalid value at '"+o.path.concat(n).join(".")+"'!",void(a.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}function p(t,n){var e,o;if(s._!==n)(e=u.link.is(t))?(o=this.opt.seen[e])?this.obj[n]=o:this.obj[n]=this.opt.seen[e]=i.to(this.graph,e,this.opt):this.obj[n]=t;else{if(m(t,u.link._))return;this.obj[n]=y(t)}}i.is=function(t,n,e,o){return!(!t||!d(t)||m(t))&&!b(t,r,{cb:n,fn:e,as:o})},i.ify=function(t,n,e){var o={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:"function"==typeof n&&(n.map=n):n={},"string"==typeof e&&(n.soul=n.soul||e,e=h),n.soul&&(o.link=u.link.ify(n.soul)),n.shell=(e||{}).shell,n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||e,f(n,o),n.root=o.node,n.graph},i.node=function(t){var n=s.soul(t);if(n)return k({},n,t)},i.to=function(t,n,e){if(t){var o={};return e=e||{seen:{}},b(t[n],p,{obj:o,graph:t,opt:e}),o}};a.fn.is;var h,n=a.obj,d=n.is,v=n.del,g=n.has,m=n.empty,k=n.put,b=n.map,y=n.copy;t.exports=i})(G,"./graph"),G(function(t){G("./onto"),t.exports=function(t,n){if(this.on){if("function"!=typeof t){if(!t||!n)return;var e=t["#"]||t,o=(this.tag||"")[e];if(!o)return;return o=this.on(e,n),clearTimeout(o.err),!0}e=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return e;var i=this.on(e,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK yet.",lack:!0}),i.off()},(this.opt||{}).lack||9e3),e}}})(G,"./ask"),G(function(t){var u=G("./type");t.exports=function(i){var r={s:{}},a=r.s;i=i||{max:1e3,age:27e3},r.check=function(t){return!!a[t]&&n(t)};var n=r.track=function(t){var n=a[t]||(a[t]={});return n.was=+new Date,r.to||(r.to=setTimeout(r.drop,i.age+9)),n};return r.drop=function(e){var o=+new Date;u.obj.map(a,function(t,n){t&&(e||i.age)>o-t.was||delete a[n]}),r.to=null,console.STAT&&9<(e=new Date-o)&&console.STAT(o,e,"dup drop")},r}})(G,"./dup"),G(function(t){function _(t){return t instanceof _?(this._={$:this}).$:this instanceof _?_.create(this._={$:this,opt:t}):new _(t)}_.is=function(t){return t instanceof _||t&&t._&&t===t._.$||!1},_.version=.202,_.chain=_.prototype,_.chain.toJSON=function(){};var n=G("./type");function r(t,n,e,o){var i=this,r=_.state.is(e,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+o+"'!";var a=i.graph[o]||A,u=_.state.is(a,n,!0),s=a[n],f=_.HAM(i.machine,r,u,t,s);f.incoming?(i.put[o]=_.state.to(e,n,i.put[o]),(i.diff||(i.diff={}))[o]=_.state.to(e,n,i.diff[o]),i.souls[o]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function a(t,n){var e=this,o=e.$._,i=(o.next||A)[n];if(!i){if(!(o.opt||A).super)return void(e.souls[n]=!1);i=e.$.get(n)._}var r=e.map[n]={put:t,get:n,$:i.$},a={ctx:e,msg:r};e.async=!!o.tag.node,e.ack&&(r["@"]=e.ack),m(t,u,a),e.async&&(e.and||o.on("node",function(t){this.to.next(t),t===e.map[t.get]&&(e.souls[t.get]=!1,m(t.put,s,t),m(e.souls,function(t){if(t)return t})||e.c||(e.c=1,this.off(),m(e.map,f,e)))}),e.and=!0,o.on("node",r))}function u(t,n){var e=this.ctx,o=e.graph,i=this.msg,r=i.get,a=i.put,u=i.$._;o[r]=_.state.to(a,n,o[r]),e.async||(u.put=_.state.to(a,n,u.put))}function s(t,n){var e=this.put,o=this.$._;o.put=_.state.to(e,n,o.put)}function f(t,n){t.$&&(this.cat.stop=this.stop,t.$._.on("in",t),this.cat.stop=null)}function c(t,n){if(t!==this.graph[n])return!0}n.obj.to(n,_),_.HAM=G("./HAM"),_.val=G("./val"),_.node=G("./node"),_.state=G("./state"),_.graph=G("./graph"),_.on=G("./onto"),_.ask=G("./ask"),_.dup=G("./dup"),_.puff=G("./puff"),function(){function f(t){var n,e,o,i,r,a;t&&(t.out!==f?(o=(e=(n=this.as).at||n).$,i=e.dup,a=t.DBG,(r=t["#"])||(r=t["#"]=p(9)),i.check(r)||(i.track(r),r=t._,t._="function"==typeof r?r:function(){},t.$&&t.$===(t.$._||"").$||(t.$=o),e.ask(t["@"],t)||(a&&(a.u=+new Date),t.get&&_.on._get(t,o),!t.put)?(a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.out=f,e.on("out",t),a&&(a.ue=+new Date)):u(t))):this.to.next(t))}function u(t){if(t){var n,e,o=t._||"",i=o.root=((o.$=t.$||"")._||"").root,r=t.put,a=t["#"],u=o.DBG=t.DBG;if(r["#"]&&r["."])i.on("put",t);else{o.out=t,o.lot={s:0,more:1};var s=+new Date;for(var f in u&&(u.p=s),r){var c,l=r[f];if(!l){n=g+m(f)+"no node.";break}if(!(e=l._)){n=g+m(f)+"no meta.";break}if(f!==e[j]){n=g+m(f)+"soul not same.";break}if(!(c=e[D])){n=g+m(f)+"no state.";break}for(var p in l)if(S!==p){var h=l[p],d=c[p];if(x===d){n=g+m(p)+"on"+m(f)+"no state.";break}if(!T(h)){n=g+m(p)+"on"+m(f)+"bad "+typeof h+m(h);break}!function t(n,e,o,i,r){var a,u=r._||"",s=u.root,f=s.graph;var c=f[o]||A,l=$(c,e,1),p=c[e];var h=y(),d=k(h,i,l,n,p);if(!d.incoming){if(d.defer){var v=i-h;return setTimeout(function(){t(n,e,o,i,r)},b":i},_:u})}(h,p,f,d,t)}if(n)break}u&&(u.pe=+new Date),console.STAT&&(console.STAT(s,new Date-s,"mix"),console.STAT(s,o.lot.s,"mix #")),(o.err=n)?i.on("in",{"@":a,err:_.log(n)}):(--o.lot.more||v(o),o.stun||t["@"]||i.on("in",{"@":a,ok:-1}))}}}function e(t){var n;(n=(t._||"").DBG)&&(n.pa=+new Date,n.pm=n.pm||+new Date);var e,o=this.as.graph,i=t._,r=t.put,a=r["#"],u=r["."],s=r[":"],f=r[">"];t["#"];o[a]=w(o[a],u,f,s,a),function(t,n,e,o,i){var r,a,u=t.root;if((u.opt||"").super&&u.$.get(n),!(u&&(a=u.next)&&(a=a[n])&&a.$))return;(r=t.put||(t.put={}))[n]=w(r[n],e,i,o,n),a.put=w(a.put,e,i,o,n)}(i,a,u,x!==(e=r["="])?e:s,f),(e=i.out)&&(e=e.put)&&(e[a]=w(e[a],u,f,s,a)),--i.lot.more||v(i),this.to.next(t)}function v(t){if(!t.err){var n,e={},o=((t.$||"")._||"").root,i=(o||"").next||"",r=t.put,a=+new Date;for(var u in r){var s=r[u];(n=i[u])&&n.$&&(o.stop=e,n.on("in",{$:n.$,get:u,put:s}),o.stop=null)}console.STAT&&console.STAT(a,new Date-a,"fire"),t.DBG&&(t.DBG.f=+new Date),(n=t.out)&&(n.out=f,o.on("out",n))}}_.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||_.on,t.ask=t.ask||_.ask,t.dup=t.dup||_.dup();var n=t.$.opt(t.opt);return t.once||(t.on("in",f,t),t.on("out",f,t),t.on("put",e,t),_.on("create",t),t.on("create",t)),t.once=1,n},_.on.put=u;var g="Error: Invalid graph!",m=function(t){return" '"+(""+t).slice(0,9)+"...' "},k=_.HAM,b=2147483647,y=_.state}(),_.on._put=function(t,n){var e,o=n._,i={$:n,graph:o.graph,put:{},map:{},souls:{},machine:_.state(),ack:t["@"],cat:o,stop:{}};if(_.obj.map(t.put,c,i)){if(_.graph.is(t.put,null,r,i)||(i.err="Error: Invalid graph!"),i.err)return o.on("in",{"@":t["#"],err:_.log(i.err)});m(i.put,a,i),i.async||m(i.map,f,i),x!==i.defer&&(e=i.defer-i.machine,setTimeout(function(){_.on._put(t,n)},e>MD?MD:e)),i.diff&&o.on("put",g(t,{put:i.diff}))}},_.on._get=function(t,n){var e=n._,o=t.get,i=o[j],r=e.graph[i],a=o[k],u=(e.next||(e.next={}))[i],s=(t._||"").DBG=t.DBG;if(s&&(s.g=+new Date),!r)return e.on("get",t);if(a){if("string"!=typeof a||!v(r,a))return e.on("get",t);r=_.state.to(r,a)}else r=_.window?_.obj.copy(r):r;r=_.graph.node(r),(u||A).ack;function f(){}f.ram=f.faith=!0,f.$=t.$,s&&(s.ga=+new Date),e.on("in",{"@":t["#"],put:r,ram:1,$:n,_:f}),s&&(s.gm=+new Date),e.on("get",t),s&&(s.gd=+new Date)},_.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return d(t)||(t={}),d(n.opt)||(n.opt=t),l(e)&&(e=[e]),o(e)&&(e=m(e,function(t,n,e){(n={}).id=n.url=t,e(t,n)}),d(n.opt.peers)||(n.opt.peers={}),n.opt.peers=g(e,n.opt.peers)),n.opt.peers=n.opt.peers||{},m(t,function t(n,e){!v(this,e)||i.is(n)||h.empty(n)?this[e]=n:n&&n.constructor!==Object&&!o(n)||m(n,t,this[e])},n.opt),_.on("opt",n),_.obj.native(),this},_.obj.native=function(){var t=Object.prototype;for(var n in t)console.log("Native Object.prototype polluted, reverting",n),delete t[n]};var x,e,o=_.list.is,i=_.text,l=i.is,p=i.random,h=_.obj,d=(h.empty,h.is),v=h.has,g=h.to,m=h.map,w=(h.copy,_.state.lex,_.state.ify),$=_.state.is,j=_.val.link._,k=".",S=_.node._,T=_.val.is,D=(_.val.link.is,_.state._),A={};_.log=function(){return _.log.off||e.log.apply(e,arguments),[].slice.call(arguments).join(" ")},_.log.once=function(t,n,e){return(e=_.log.once)[t]=e[t]||0,e[t]++||_.log(n)},"undefined"!=typeof window&&((window.GUN=window.Gun=_).window=window);try{void 0!==b&&(b.exports=_)}catch(t){}((t.exports=_).window||"").console=(_.window||"").console||{log:function(){}},(e=console).only=function(t,n){return e.only.i&&t===e.only.i&&e.only.i++&&(e.log.apply(e,arguments)||n)},_.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!")})(G,"./root"),G(function(t){var u=G("./root");u.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var e=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=e;o(r.acks||0)&&this.off(),r.ack&&r.ack(t,this)},r.opt),e=0,o=n.root.now;a.del(n.root,"now");var i=n.root.mum;n.root.mum={},r.ref._.on("out",{$:r.ref,put:r.out=r.env.graph,opt:r.opt,"#":t}),n.root.mum=i?a.to(i,n.root.mum):i,n.root.now=o,r.via._.on("res",{}),delete r.via._.tag.res},r),r.res&&r.res())}function c(r,t,n,a){var u=this,s=f.is(r);!t&&a.path.length&&(u.res||e)(function(){for(var t=a.path,n=u.ref,e=(u.opt,0),o=t.length;e .once, apologies unexpected."),this.once(t,n)},f.chain.once=function(t,n){var e=this,o=e._,i=o.put;if(0"];t["@"]||((acks[t["#"]]=tmp=(t._||"").lot||{}).lS=(tmp.lS||0)+1),u.level.get(o,function(t,n){n=n&&JSON.parse(n);var e=JSON.stringify(s.state.ify(n,i,a,r,o));u.level.put(o,e,function(t,n){})})}),void o.on("get",function(t){this.to.next(t);var e=t.get["#"];u.level.get(e,function(t,n){t||(n=n&&JSON.parse(n),o.on("in",{"@":e,put:s.graph.node(n),lS:1}))})})):t.next(o)})})(G,"./adapters/leveldb"),G(function(t){if("undefined"!=typeof Gun){var h;try{h=(Gun.window||function(){}).localStorage}catch(t){}h||(Gun.log("Warning: No localStorage exists to persist data to!"),h={setItem:function(t,n){this[t]=n},removeItem:function(t){delete this[t]},getItem:function(t){return this[t]}}),Gun.on("create",function(t){var n=this.to,e=t.opt;if(t.once)return n.next(t);if(!1===e.localStorage)return n.next(t);e.prefix=e.file||"gun/";var i,o,r,a,u=Gun.obj.ify(h.getItem("gap/"+e.prefix))||{},s=Gun.obj.empty;function f(t){var o;!t.err&&t.ok&&(o=t["@"],setTimeout(function(){Gun.obj.map(u,function(e,t){Gun.obj.map(e,function(t,n){o===t&&delete e[n]}),s(e)&&delete u[t]}),l()},e.wait||1))}s(u)||(r=Gun.obj.ify(h.getItem(e.prefix))||{},a={},Gun.obj.map(u,function(t,e){Gun.obj.map(t,function(t,n){a[e]=Gun.state.to(r[e],n,a[e])})}),setTimeout(function(){t.on("out",{put:a,"#":t.ask(f)})},1)),t.on("out",function(t){t.lS||(Gun.is(t.$)&&t.put&&!t["@"]&&(i=t["#"],Gun.graph.is(t.put,null,c),o=o||setTimeout(l,e.wait||1)),this.to.next(t))}),t.on("ack",f),n.next(t);var c=function(t,n,e,o){(u[o]||(u[o]={}))[n]=i},l=function(){clearTimeout(o),o=!1;try{h.setItem("gap/"+e.prefix,JSON.stringify(u))}catch(t){Gun.log(err=t||"localStorage failure")}}}),Gun.on("create",function(a){this.to.next(a);var u,s,f,c,l,p=a.opt;a.once||!1!==p.localStorage&&(p.prefix=p.file||"gun/",a.graph,u={},s=0,c=Gun.obj.ify(h.getItem(p.prefix))||{},a.on("localStorage",c),a.on("put",function(t){this.to.next(t);var n,e=t.put,o=e["#"],i=e["."],r=e[":"],a=e[">"];if(c[o]=Gun.state.ify(c[o],i,a,r,o),t["@"]||((u[t["#"]]=n=(t._||"").lot||{}).lS=(n.lS||0)+1),(s+=1)>=(p.batch||1e3))return l();f=f||setTimeout(l,p.wait||1)}),a.on("get",function(n){this.to.next(n);var e,o,i,r=n.get;function t(){var t;r&&(e=r["#"])&&(t=r["."],(o=c[e]||i)&&t&&(o=Gun.state.to(o,t)),a.on("in",{"@":n["#"],put:Gun.graph.node(o),lS:1}))}Gun.debug?setTimeout(t,1):t()}),l=function(t){var e;s=0,clearTimeout(f),f=!1;var n=u;u={},t&&(c=t);try{h.setItem(p.prefix,JSON.stringify(c))}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"),a.on("localStorage:error",{err:e,file:p.prefix,flush:c,retry:l})}(e||Gun.obj.empty(p.peers))&&Gun.obj.map(n,function(t,n){if(t){if(t.more)return void(u[n]=t);t.s!==t.lS&&(e="localStorage batch not same.")}a.on("in",{"@":n,err:e,ok:0})})})})}})(G,"./adapters/localStorage"),G(function(t){var e,x=G("../type");function o(t,n){var e;if(!(n instanceof Object))return n;var o=+new Date;return x.obj.map(Object.keys(n).sort(),i,{to:e={},on:n}),console.STAT&&console.STAT(o,new Date-o,"sort"),e}function i(t){this.to[t]=this.on[t]}e=JSON.stringify,x.obj.hash=function(t,n){if(n||void 0!==(t=e(t,o)))return x.text.hash(n||t||"")},x.obj.hash.sort=o;var w=x.obj.is;x.obj.map;try{t.exports=function(f){var l=function(){},p=f.opt||{};p.log=p.log||console.log,p.gap=p.gap||p.wait||0,p.pack=p.pack||.3*(p.memory?1e3*p.memory*1e3:1399e6),p.puff=p.puff||9;var h,d,v,g=setTimeout.puff||setTimeout,m=f.dup,c=m.check,k=m.track,b=l.hear=function(t,i){if(t){if(p.pack<=t.length)return l.say({dam:"!",err:"Message too big!"},i);var r,n,e,o=t[0];if(l===this&&(b.d+=t.length||0,++b.c),"["!==o){if("{"===o||(t["#"]||w(t))&&(r=t)){try{r=r||JSON.parse(t)}catch(t){return p.log("DAM JSON parse error",t)}if(!r)return;if(r.DBG&&(r.DBG=e={DBG:r.DBG}),e&&(e.hp=+new Date),(n=r["#"])||(n=r["#"]=x.text.random(9)),o=c(n))return;if((r._=function(){}).via=l.leap=i,o=r.dam)return(o=l.hear[o])&&o(r,i,f),void k(n);var a,u=+new Date;e&&(e.is=u),f.on("in",r),e&&(e.hd=+new Date),console.STAT&&9<(a=new Date-u)&&console.STAT(u,a,"msg"),k(n).via=i,l.leap=null}}else{try{r=JSON.parse(t)}catch(t){p.log("DAM JSON parse error",t)}if(t="",!r)return;console.STAT&&console.STAT(+new Date,r.length,"# on hear batch");var s=p.puff;(function t(){for(var n,e=+new Date,o=0;o']; + + // only ack non-acks. + if (!msg['@']) { + (acks[msg['#']] = (tmp = (msg._||'').lot || {})).lS = (tmp.lS||0)+1; + } + + // Fetch current state + opt.level.get(soul, function(err, data) { + if (data) data = JSON.parse(data); + + // Serialize & store + var toStore = JSON.stringify(Gun.state.ify(data, key, state, val, soul)); + opt.level.put(soul, toStore, function(err, data) { + if (err) return; + // TODO: ack here? + }); + }); + + }); + + // How to read + root.on('get', function(msg){ + this.to.next(msg); + var get = msg.get; + var soul = get['#']; + opt.level.get(soul, function(err, data) { + if (err) return; + if (data) data = JSON.parse(data); + root.on('in', {'@': soul, put: Gun.graph.node(data), lS: 1}); + }); + + }); + + }); + + \ No newline at end of file diff --git a/test/panic/leveldb.js b/test/panic/leveldb.js new file mode 100644 index 000000000..da6c622f2 --- /dev/null +++ b/test/panic/leveldb.js @@ -0,0 +1,242 @@ +const panic = require('panic-server'); +const clients = panic.clients; +const manager = require('panic-manager')(); + +const config = { + ip : require('ip').address(), + port : 8765, + servers : 3, + route : { + '/' : __dirname + '/index.html', + '/gun.js' : __dirname + '/../../gun.js', + '/jquery.js' : __dirname + '/../../examples/jquery.js' + } +}; + +panic.server().on('request', function(req, res){ + config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res); +}).listen(config.port); + +manager.start({ + clients: Array(config.servers).fill().map((u,i) => ({ + type: 'node', + port: config.port + i + 1, + })), + panic: `http://${config.ip}:${config.port}` +}); + +const servers = clients.filter('Node.js'); +const server = servers.pluck(1); +const alice = servers.excluding(server).pluck(1); +const bob = servers.excluding(server).excluding(alice).pluck(1); + +describe('Make sure the leveldb storage engine works', function() { + this.timeout(5 * 60 * 60 * 1000); + + it("Servers have joined!", function(){ + return servers.atLeast(config.servers); + }); + + it("GUN started!", () => { + return server.run(test => { + test.async(); + const root = (new Function('return this'))(); + const leveldown = require('leveldown'); + const levelup = require('levelup'); + const {i, config} = test.props; + const port = config.port + i; + + if (require('fs').existsSync('./lvldata')) { + console.error('Please delete previous data first!'); + return; + } + + const level = levelup(leveldown('./lvldata')); + const web = require('http').createServer((req, res) => { + res.end(`I am ${i}!`); + }); + + const Gun = require('../../../index.js'); + const gun = Gun({web, level}); + root.gun = gun; + root.level = level; + + web.listen(port, function(){ + test.done(); + }); + }, {i: 1, config}); + }); + + it('Alice save data', () => { + return alice.run(test => { + test.async(); + const root = (new Function('return this'))(); + const {config} = test.props; + const Gun = require('../../../index.js'); + + // Start gun + const gun = Gun({peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun', lack: 1000 * 60 * 60}); + root.gun = gun; + + // Save data + const ref = gun.get('asdf'); + ref.put({ hello: 'world' }, ack => { + if (ack.err) { + if (ack.lack) return test.fail('ACK timed out, turn your lack of ack up or throughput down'); + return test.fail(ack.err); + } + ref.off(); + test.done(); + }); + }, {config}); + }); + + it('Bob read data', () => { + return bob.run(test => { + test.async(); + const root = (new Function('return this'))(); + const {config} = test.props; + const Gun = require('../../../index.js'); + + // Start gun + const gun = Gun({peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun', lack: 1000 * 60 * 60}); + root.gun = gun; + + // Read data + const ref = gun.get('asdf'); + ref.on(data => { + if (data.hello !== 'world') { + return test.fail('Invalid data returned'); + } + ref.off(); + test.done(); + }); + + }, {config}); + }); + +// it("Bob read data", function(){ +// this.timeout(1000 * 60 * 60 * 5); +// //return alice.run(function(test){ +// return bob.run(function(test){ +// var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each/2; +// var raw = Gun.text.random(200, 'a');// "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; +// $('body').append($("
")); var $log = $('#log'); +// +// var ref = window.gun.get('asdf' + i); +// ref.on(function(data){ +// if((raw+i) !== data.hello){ return test.fail('wrong ' + i) } +// if(d){ return } d = true; +// c++; +// !(i % 1000) && console.log(i+'/'+l); +// !(i % 1000) && $log.prepend('

'+i+'/'+l+'

'); +// //console.log(i+'/'+l); +// ref.off(); +// if(c < l){ return } +// console.log("DONE!", c+'/'+l); +// $log.prepend('

DONE! '+i+'/'+l+'

'); +// setTimeout(function(){ +// test.done(); +// setTimeout(function(){ +// location = 'http://asdf'; +// }, 1500) +// }, 1); +// }); +// } +// function burst(){ +// if(i > l){ +// return; +// } +// for(var j = 0; j <= b; j++){ +// check(++i); +// } +// setTimeout(burst, env.config.wait); +// } +// burst(); +// }, {i: 1, config: config}); +// }); + + it("All finished", done => { + setTimeout(() => { + done(); + },100); + }); + + it('Shutdown everything', () => { + return clients.run(test => { + process.exit(); + }); + }); + +}); + +//var config = { +// IP: require('ip').address(), +// port: 8765, +// servers: 2, +// browsers: 3, +// each: 100000, //1000000, +// burst: 1, +// wait: 1, +// dir: __dirname, +// chunk: 1024 * 1024 * 10, +// notrad: false, +//} +//config.gundir = require('path').resolve(config.dir, '../../')+'/'; + +//var servers = clients.filter('Node.js'); +//var server = servers.pluck(1); +//var spawn = servers.excluding(server).pluck(1); +//var browsers = clients.excluding(servers); +//var alice = browsers.pluck(1); +//var bob = browsers.excluding(alice).pluck(1); +//var carl = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1); + + +// it("Carl read data", function(){ +// this.timeout(1000 * 60 * 60 * 5); +// //return alice.run(function(test){ +// return carl.run(function(test){ +// test.async(); +// console.log("I AM CARL"); +// localStorage.clear(); +// var env = test.props; +// var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: false}); +// window.gun = gun; +// var n = Gun.time.is(), i = env.config.each / 2, c = 0, b = env.config.burst, l = env.config.each; +// var raw = Gun.text.random(200, 'a');// "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; +// $('body').append($("
")); var $log = $('#log'); + +// function check(i){ +// if(i > l){ +// return; +// } +// var d; +// var ref = window.gun.get('asdf' + i); +// ref.on(function(data){ +// if((raw+i) !== data.hello){ return test.fail('wrong ' + i) } +// if(d){ return } d = true; +// c++; +// !(i % 1000) && console.log(i+'/'+l); +// !(i % 1000) && $log.prepend('

'+i+'/'+l+'

'); +// //console.log(i+'/'+l); +// ref.off(); +// if(c < (l / 2)){ return } +// console.log("DONE!", c+'/'+l); +// $log.prepend('

DONE! '+i+'/'+l+'

'); +// test.done(); +// }); +// } +// function burst(){ +// if(i > l){ +// return; +// } +// for(var j = 0; j <= b; j++){ +// check(++i); +// } +// setTimeout(burst, env.config.wait); +// } +// burst(); +// }, {i: 1, config: config}); +// }); + From c6e9e796c5ad03638a4997dda2ae0e512cdd7748 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Wed, 23 Sep 2020 17:43:30 +0200 Subject: [PATCH 3/8] Removed unused leveldb dependencies --- package-lock.json | 154 +--------------------------------------------- package.json | 2 - 2 files changed, 1 insertion(+), 155 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0945584a3..4a7521733 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,19 +92,6 @@ "@types/node": "*" } }, - "abstract-leveldown": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", - "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "immediate": "^3.2.3", - "level-concat-iterator": "~2.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, "accepts": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", @@ -272,6 +259,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "optional": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -416,16 +404,6 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "deferred-leveldown": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", - "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, - "requires": { - "abstract-leveldown": "~6.2.1", - "inherits": "^2.0.3" - } - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -576,15 +554,6 @@ "wtf-8": "1.0.0" } }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, "es-abstract": { "version": "1.17.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", @@ -744,12 +713,6 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, - "immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true - }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -860,65 +823,6 @@ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", "dev": true }, - "level-concat-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "dev": true - }, - "level-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", - "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", - "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.4.0", - "xtend": "^4.0.2" - } - }, - "level-supports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", - "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dev": true, - "requires": { - "xtend": "^4.0.2" - } - }, - "leveldown": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", - "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", - "dev": true, - "requires": { - "abstract-leveldown": "~6.2.1", - "napi-macros": "~2.0.0", - "node-gyp-build": "~4.1.0" - } - }, - "levelup": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", - "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "dev": true, - "requires": { - "deferred-leveldown": "~5.3.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~4.0.0", - "level-supports": "~1.0.0", - "xtend": "~4.0.0" - } - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -1020,12 +924,6 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "napi-macros": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", - "dev": true - }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -1042,12 +940,6 @@ "semver": "^5.7.0" } }, - "node-gyp-build": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", - "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", - "dev": true - }, "object-assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", @@ -1221,12 +1113,6 @@ "integrity": "sha1-SSIQiSM1vTExwKCN2i2T7DVD5CM=", "dev": true }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -1260,17 +1146,6 @@ "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", "optional": true }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1283,12 +1158,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", @@ -1507,15 +1376,6 @@ "es-abstract": "^1.17.5" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -1583,12 +1443,6 @@ "querystring": "0.2.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -1710,12 +1564,6 @@ "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", "dev": true }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 13ea5d486..27a21a8eb 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,6 @@ "@types/ws": "^7.2.1", "aws-sdk": "^2.528.0", "ip": "^1.1.5", - "leveldown": "^5.6.0", - "levelup": "^4.4.0", "mocha": "^6.2.0", "panic-manager": "^1.2.0", "panic-server": "^1.1.1", From 5690b8fb1a0964b691f45bc6d18c3393773caf82 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Wed, 23 Sep 2020 17:43:53 +0200 Subject: [PATCH 4/8] Moved leveldb adapter to lib as requested --- gun.js | 69 ----------------------------------------- lib/level.js | 47 ++++++++++++++++++++++++++++ src/adapters/leveldb.js | 68 ---------------------------------------- 3 files changed, 47 insertions(+), 137 deletions(-) create mode 100644 lib/level.js delete mode 100644 src/adapters/leveldb.js diff --git a/gun.js b/gun.js index 940d20524..3cc08128c 100644 --- a/gun.js +++ b/gun.js @@ -1936,75 +1936,6 @@ function uuid(){ return Gun.state.lex() + Gun.text.random(7) } })(USE, './set'); - ;USE(function(module){ - var Gun = USE('../index'); - - Gun.on('create', function(root) { - var ev = this.to; - var opt = root.opt; - - if (root.once) { - return ev.next(root); - } - - // Check if the given 'level' argument implements all the components we need - // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api - if ( - (!opt.level) || - ('object' !== typeof opt.level) || - ('function' !== typeof opt.level.get) || - ('function' !== typeof opt.level.put) || - ('function' !== typeof opt.level.createReadStream) - ) { - return ev.next(root); - } - - // How to write - root.on('put', function(msg){ - this.to.next(msg); - - var put = msg.put; - var soul = put['#']; - var key = put['.']; - var val = put[':']; - var state = put['>']; - - // only ack non-acks. - if (!msg['@']) { - (acks[msg['#']] = (tmp = (msg._||'').lot || {})).lS = (tmp.lS||0)+1; - } - - // Fetch current state - opt.level.get(soul, function(err, data) { - if (data) data = JSON.parse(data); - - // Serialize & store - var toStore = JSON.stringify(Gun.state.ify(data, key, state, val, soul)); - opt.level.put(soul, toStore, function(err, data) { - if (err) return; - // TODO: ack here? - }); - }); - - }); - - // How to read - root.on('get', function(msg){ - this.to.next(msg); - var get = msg.get; - var soul = get['#']; - opt.level.get(soul, function(err, data) { - if (err) return; - if (data) data = JSON.parse(data); - root.on('in', {'@': soul, put: Gun.graph.node(data), lS: 1}); - }); - - }); - - }); - - })(USE, './adapters/leveldb'); - ;USE(function(module){ if(typeof Gun === 'undefined'){ return } // TODO: localStorage is Browser only. But it would be nice if it could somehow plugin into NodeJS compatible localStorage APIs? diff --git a/lib/level.js b/lib/level.js new file mode 100644 index 000000000..e45c02f02 --- /dev/null +++ b/lib/level.js @@ -0,0 +1,47 @@ +var Gun = require('../index'); + +// Adds opts.level, where the value is an initialized levelup (or compatible) instance +Gun.on('create', function(root) { + this.to.next(root); + var opt = root.opt; + + // Check if the given 'level' argument implements all the components we need + // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api + if ( + (!opt.level) || + ('object' !== typeof opt.level) || + ('function' !== typeof opt.level.get) || + ('function' !== typeof opt.level.put) + ) { + return; + } + + // Register our store + opt.store = opt.store || factory(opt); +}); + +function factory(opt) { + var level = opt.level; + var store = {}; + + store.put = function(key, data, cb) { + level.put(key, data, function(err) { + cb(err, 'level'); + }); + }; + + store.get = function(key, cb) { + level.get(key, cb); + }; + + store.list = function(cb, match, params, cbs){ + level + .createKeyStream() + .on('data', cb) + .on('end', function() { + cb(); + }); + }; + + return store; +} diff --git a/src/adapters/leveldb.js b/src/adapters/leveldb.js deleted file mode 100644 index 06d534486..000000000 --- a/src/adapters/leveldb.js +++ /dev/null @@ -1,68 +0,0 @@ - - var Gun = require('../index'); - - Gun.on('create', function(root) { - var ev = this.to; - var opt = root.opt; - - if (root.once) { - return ev.next(root); - } - - // Check if the given 'level' argument implements all the components we need - // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api - if ( - (!opt.level) || - ('object' !== typeof opt.level) || - ('function' !== typeof opt.level.get) || - ('function' !== typeof opt.level.put) || - ('function' !== typeof opt.level.createReadStream) - ) { - return ev.next(root); - } - - // How to write - root.on('put', function(msg){ - this.to.next(msg); - - var put = msg.put; - var soul = put['#']; - var key = put['.']; - var val = put[':']; - var state = put['>']; - - // only ack non-acks. - if (!msg['@']) { - (acks[msg['#']] = (tmp = (msg._||'').lot || {})).lS = (tmp.lS||0)+1; - } - - // Fetch current state - opt.level.get(soul, function(err, data) { - if (data) data = JSON.parse(data); - - // Serialize & store - var toStore = JSON.stringify(Gun.state.ify(data, key, state, val, soul)); - opt.level.put(soul, toStore, function(err, data) { - if (err) return; - // TODO: ack here? - }); - }); - - }); - - // How to read - root.on('get', function(msg){ - this.to.next(msg); - var get = msg.get; - var soul = get['#']; - opt.level.get(soul, function(err, data) { - if (err) return; - if (data) data = JSON.parse(data); - root.on('in', {'@': soul, put: Gun.graph.node(data), lS: 1}); - }); - - }); - - }); - - \ No newline at end of file From d3cc2ec3146d0b512c9ad3ab10c436c816664dcc Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Wed, 23 Sep 2020 22:19:52 +0200 Subject: [PATCH 5/8] Non-exiting panic test --- lib/level.js | 28 +++++- package-lock.json | 173 +++++++++++++++++++++++++++++++++- package.json | 3 + test/panic/level.js | 221 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 421 insertions(+), 4 deletions(-) create mode 100644 test/panic/level.js diff --git a/lib/level.js b/lib/level.js index e45c02f02..2cf3f9217 100644 --- a/lib/level.js +++ b/lib/level.js @@ -1,10 +1,13 @@ -var Gun = require('../index'); +var Gun = ('undefined' !== typeof window) ? window.Gun : require('../gun'); +var debug = false; // Adds opts.level, where the value is an initialized levelup (or compatible) instance Gun.on('create', function(root) { this.to.next(root); var opt = root.opt; + if (debug) debug.emit('create'); + // Check if the given 'level' argument implements all the components we need // Intentionally doesn't check for levelup explicitly, to allow different handlers implementing the same api if ( @@ -21,23 +24,36 @@ Gun.on('create', function(root) { }); function factory(opt) { + if (debug) debug.emit('factory'); + var level = opt.level; var store = {}; store.put = function(key, data, cb) { + if (debug) debug.emit('put', key, data); level.put(key, data, function(err) { + if (debug && err) debug.emit('error', err); cb(err, 'level'); }); }; store.get = function(key, cb) { - level.get(key, cb); + if (debug) debug.emit('get', key); + level.get(key, function(err, data) { + if (err && (err.name === 'NotFoundError')) err = undefined; + if (debug && err) debug.emit('error', err); + cb(err, data); + }); }; store.list = function(cb, match, params, cbs){ + if (debug) debug.emit('list'); level .createKeyStream() - .on('data', cb) + .on('data', function(key) { + console.log("KEY", key); + cb(key); + }) .on('end', function() { cb(); }); @@ -45,3 +61,9 @@ function factory(opt) { return store; } + +// Export debug interface +if ('undefined' === typeof window) { + var EventEmitter = require('events').EventEmitter; + module.exports = debug = new EventEmitter(); +} diff --git a/package-lock.json b/package-lock.json index 4a7521733..08fc1ddcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,6 +92,19 @@ "@types/node": "*" } }, + "abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, "accepts": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", @@ -259,7 +272,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "optional": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -404,6 +416,16 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -554,6 +576,15 @@ "wtf-8": "1.0.0" } }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, "es-abstract": { "version": "1.17.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", @@ -713,6 +744,12 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, + "immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true + }, "indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -823,6 +860,65 @@ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", "dev": true }, + "level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "dev": true + }, + "level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, + "level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dev": true, + "requires": { + "xtend": "^4.0.2" + } + }, + "leveldown": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "dev": true, + "requires": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + } + }, + "levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dev": true, + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -924,6 +1020,12 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -940,6 +1042,12 @@ "semver": "^5.7.0" } }, + "node-gyp-build": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "dev": true + }, "object-assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", @@ -1113,6 +1221,12 @@ "integrity": "sha1-SSIQiSM1vTExwKCN2i2T7DVD5CM=", "dev": true }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -1146,6 +1260,17 @@ "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", "optional": true }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1158,6 +1283,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", @@ -1176,6 +1307,11 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, + "siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" + }, "socket.io": { "version": "1.7.4", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.4.tgz", @@ -1324,6 +1460,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha1-Gsig2Ug4SNFpXkGLbQMaPDzmjjs=" + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -1376,6 +1517,15 @@ "es-abstract": "^1.17.5" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -1443,6 +1593,12 @@ "querystring": "0.2.0" } }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -1477,6 +1633,15 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "why-is-node-running": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.0.tgz", + "integrity": "sha512-rxtN9D0lJaYyP92BR5yoyWecK2txBKmBIuS7GRbOPP5bXsT37/hBqcmTrlrt25DBr9p4WJb6c9LuYSJd89vHRQ==", + "requires": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + } + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -1564,6 +1729,12 @@ "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 27a21a8eb..5b16227bc 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "node": ">=0.8.4" }, "dependencies": { + "why-is-node-running": "^2.2.0", "ws": "^7.2.1" }, "optionalDependencies": { @@ -78,6 +79,8 @@ "@types/ws": "^7.2.1", "aws-sdk": "^2.528.0", "ip": "^1.1.5", + "leveldown": "^5.6.0", + "levelup": "^4.4.0", "mocha": "^6.2.0", "panic-manager": "^1.2.0", "panic-server": "^1.1.1", diff --git a/test/panic/level.js b/test/panic/level.js new file mode 100644 index 000000000..a910d8027 --- /dev/null +++ b/test/panic/level.js @@ -0,0 +1,221 @@ +const panic = require('panic-server'); +const clients = panic.clients; +const manager = require('panic-manager')(); + +require('events').EventEmitter.defaultMaxListeners = Infinity; + +const config = { + ip : require('ip').address(), + port : 8765, + servers : 3, + route : { + '/' : __dirname + '/index.html', + '/gun.js' : __dirname + '/../../gun.js', + '/jquery.js' : __dirname + '/../../examples/jquery.js' + } +}; + +const srv = panic.server(); +srv.on('request', (req, res) => { + config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res); +}).listen(config.port); + +manager.start({ + clients: Array(config.servers).fill().map((u,i) => ({ + type: 'node', + port: config.port + i + 1, + })), + panic: `http://${config.ip}:${config.port}` +}); + +const servers = clients.filter('Node.js'); +const server = servers.pluck(1); +const alice = servers.excluding(server).pluck(1); +const bob = servers.excluding(server).excluding(alice).pluck(1); + +describe('Make sure the leveldb storage engine works', function() { + this.timeout(5 * 60 * 60 * 1000); + + it("servers have joined!", function() { + return servers.atLeast(config.servers); + }); + + it("GUN started!", function() { + return server.run(function(test) { + test.async(); + const {config} = test.props; + + const leveldown = require('leveldown'); + const levelup = require('levelup'); + + if (require('fs').existsSync('./lvldata')) { + console.error('Please delete previous data first!'); + return; + } + + // Initialize gun opts + const opts = {}; + opts.level = global.level = levelup(leveldown('./lvldata')); + + // Load the libraries under test + const Gun = require('../../../index.js'); + const debug = require('../../../lib/level.js'); + + // Add debug messages + debug.on('get', key => console.log('LEVEL GET', key)); + debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); + debug.on('list', () => console.log('LEVEL LIST')); + debug.on('error', err => console.log('LEVEL ERROR', err)); + + // Track state (so we can wait on put, it's called late by radisk) + global.state = 0; + debug.on('put', () => global.state++); + + // Create server + opts.web = require('http').createServer((req, res) => { + res.end("Number five is alive!"); + }); + + // Initialize gun & start server + const gun = global.gun = Gun(opts); + opts.web.listen(config.port + 1, () => { + test.done(); + }); + }, {config}); + }); + + it("Alice saves data", function() { + return alice.run(function(test) { + test.async(); + const {config} = test.props; + const Gun = require('../../../index.js'); + + // Start gun + global.gun = Gun({ + peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun', + lack : 1000 * 60 * 60, + }); + + // Save data + const ref = gun.get('asdf'); + ref.put({ hello: 'world' }, ack => { + if (ack.err) { + if (ack.lack) return test.fail('ACK timed out, turn your lack of ack up or throughput down'); + return test.fail(ack.err); + } + ref.off(); + test.done(); + }); + + }, {config}); + }); + + it('Server read data', function() { + return server.run(function(test) { + test.async(); + + // Read data (triggers fetch from alice + write to disk) + const ref = gun.get('asdf'); + ref.on(data => { + if (data.hello !== 'world') { + return test.fail('Invalid data returned'); + } + ref.off(); + test.done(); + }); + + }); + }); + + it('Wait for server to store', function() { + return server.run(function(test) { + test.async(); + setTimeout(function awaitState() { + if (global.state < 2) return setTimeout(awaitState, 50); + test.done(); + }, 50); + }); + }); + + it('Close all original running nodes', function() { + clients.pluck(2).run(function() { + if (global.level) { + global.level.close(function() { + console.log('SHUTDOWN WITH LEVEL'); + process.exit(); + }); + } else { + console.log('SHUTDOWN WITHOUT LEVEL'); + process.exit(); + } + }); + }); + + it('Start bob', function() { + return bob.run(function(test) { + test.async(); + const {config} = test.props; + + const leveldown = require('leveldown'); + const levelup = require('levelup'); + + // Initialize gun opts + const opts = {}; + opts.level = global.level = levelup(leveldown('./lvldata')); + + // Load the libraries under test + const Gun = require('../../../index.js'); + const debug = require('../../../lib/level.js'); + + // Add debug messages + debug.on('get', key => console.log('LEVEL GET', key)); + debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); + debug.on('list', () => console.log('LEVEL LIST')); + debug.on('error', err => console.log('LEVEL ERROR', err)); + + // Create server + opts.web = require('http').createServer((req, res) => { + res.end("Number five is alive!"); + }); + + // Initialize gun & start server + const gun = global.gun = Gun(opts); + opts.web.listen(config.port + 1, () => { + test.done(); + }); + }, {config}); + }); + + it('Bob read', function() { + return bob.run(function(test) { + test.async(); + + // Read data + const ref = gun.get('asdf'); + ref.on(data => { + if (data.hello !== 'world') { + return test.fail('Invalid data returned'); + } + ref.off(); + test.done(); + }); + + }, {config}); + }); + + it('Shutdown bob', function() { + return clients.run(function() { + process.exit() + }); + }); + + after("All finished!", function() { + srv.close(); + console.log('AFTER'); + console.log(manager); + Object.keys(clients.clients).forEach(function(key) { + console.log(key); + }); + }); + +}); From 79da2df9e873ae174cb743536b545cb305f1ba99 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Thu, 24 Sep 2020 08:13:24 +0200 Subject: [PATCH 6/8] Removed some debug messages from leveldb panic test --- test/panic/level.js | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/test/panic/level.js b/test/panic/level.js index a910d8027..b9ec548ea 100644 --- a/test/panic/level.js +++ b/test/panic/level.js @@ -61,11 +61,11 @@ describe('Make sure the leveldb storage engine works', function() { const Gun = require('../../../index.js'); const debug = require('../../../lib/level.js'); - // Add debug messages - debug.on('get', key => console.log('LEVEL GET', key)); - debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); - debug.on('list', () => console.log('LEVEL LIST')); - debug.on('error', err => console.log('LEVEL ERROR', err)); + // // Add debug messages + // debug.on('get', key => console.log('LEVEL GET', key)); + // debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); + // debug.on('list', () => console.log('LEVEL LIST')); + // debug.on('error', err => console.log('LEVEL ERROR', err)); // Track state (so we can wait on put, it's called late by radisk) global.state = 0; @@ -141,11 +141,9 @@ describe('Make sure the leveldb storage engine works', function() { clients.pluck(2).run(function() { if (global.level) { global.level.close(function() { - console.log('SHUTDOWN WITH LEVEL'); process.exit(); }); } else { - console.log('SHUTDOWN WITHOUT LEVEL'); process.exit(); } }); @@ -167,11 +165,11 @@ describe('Make sure the leveldb storage engine works', function() { const Gun = require('../../../index.js'); const debug = require('../../../lib/level.js'); - // Add debug messages - debug.on('get', key => console.log('LEVEL GET', key)); - debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); - debug.on('list', () => console.log('LEVEL LIST')); - debug.on('error', err => console.log('LEVEL ERROR', err)); + // // Add debug messages + // debug.on('get', key => console.log('LEVEL GET', key)); + // debug.on('put', (key, value) => console.log('LEVEL PUT', key, value)); + // debug.on('list', () => console.log('LEVEL LIST')); + // debug.on('error', err => console.log('LEVEL ERROR', err)); // Create server opts.web = require('http').createServer((req, res) => { @@ -209,13 +207,9 @@ describe('Make sure the leveldb storage engine works', function() { }); }); - after("All finished!", function() { + it("All finished!", function(done) { srv.close(); - console.log('AFTER'); - console.log(manager); - Object.keys(clients.clients).forEach(function(key) { - console.log(key); - }); + done(); }); }); From 2f1b46a9dacac4fc7c5be461a202806ad6f1ff96 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Thu, 24 Sep 2020 08:17:10 +0200 Subject: [PATCH 7/8] Pre-PR cleanup --- gun.min.js | 2 +- package-lock.json | 19 ---- package.json | 1 - test/panic/leveldb.js | 242 ------------------------------------------ 4 files changed, 1 insertion(+), 263 deletions(-) delete mode 100644 test/panic/leveldb.js diff --git a/gun.min.js b/gun.min.js index b1329d4f9..a462116e3 100644 --- a/gun.min.js +++ b/gun.min.js @@ -1 +1 @@ -!function(){function G(e,t){return t?require(e):e.slice?G[o(e)]:function(t,n){e(t={exports:{}}),G[o(n)]=t.exports};function o(t){return t.split("/").slice(-1).toString().replace(".js","")}}var b;"undefined"!=typeof module&&(b=module),G(function(t){var n,l,p={};function e(t,n){g(this,n)&&void 0!==this[n]||(this[n]=t)}function o(t,n){var e=this.n;if(!e||!(n===e||v(e)&&g(e,n)))return void 0!==n||void 0}function h(t,n){if(2===arguments.length)return h.r=h.r||{},void(h.r[t]=n);h.r=h.r||[],h.r.push(t)}p.fn={is:function(t){return!!t&&"function"==typeof t}},p.bi={is:function(t){return t instanceof Boolean||"boolean"==typeof t}},p.num={is:function(t){return!d(t)&&(0<=t-parseFloat(t)+1||1/0===t||-1/0===t)}},p.text={is:function(t){return"string"==typeof t}},p.text.ify=function(t){return p.text.is(t)?t:"undefined"!=typeof JSON?JSON.stringify(t):t&&t.toString?t.toString():t},p.text.random=function(t,n){var e="";for(t=t||24,n=n||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";0"]||n["<"])||o===n["="]&&(e=n["*"]||n[">"]||n["<"],t.slice(0,(e||"").length)===e||o===n["*"]&&(o!==n[">"]&&o!==n["<"]?t>=n[">"]&&t<=n["<"]:o!==n[">"]&&t>=n[">"]||o!==n["<"]&&t<=n["<"])))},p.text.hash=function(t,n){if("string"==typeof t){if(n=n||0,!t.length)return n;for(var e=0,o=t.length;e";function s(t,n){m!==n&&u.ify(this.o,n,this.s)}u.drift=0,u.is=function(t,n,e){var o=n&&t&&t[m]&&t[m][">"]||e;if(o)return v(o=o[n])?o:-1/0},u.lex=function(){return u().toString(36).replace(".","")},u.ify=function(t,n,e,o,i){if(!t||!t[m]){if(!i)return;t=a.soul.ify(t,i)}var r=c(t[m],">");return void 0!==n&&n!==m&&(v(e)&&(r[n]=e),void 0!==o&&(t[n]=o)),t},u.to=function(t,n,e){var o=(t||{})[n];return p(o)&&(o=d(o)),u.ify(e,n,u.is(t,n),o,a.soul(t))},u.map=function(i,r,a){var t=p(t=i||r)?t:null;return i=g(i=i||r)?i:null,t&&!i?(r=v(r)?r:u(),t[m]=t[m]||{},h(t,s,{o:t,s:r}),t):(a=a||p(r)?r:void 0,r=v(r)?r:u(),function(t,n,e,o){if(!i)return s.call({o:e,s:r},t,n),t;i.call(a||this||{},t,n,e,o),l(e,n)&&void 0===e[n]||s.call({o:e,s:r},t,n)})};var f=n.obj,c=f.as,l=f.has,p=f.is,h=f.map,d=f.copy,v=n.num.is,g=n.fn.is,m=a._;t.exports=u})(G,"./state"),G(function(t){var a=G("./type"),u=G("./val"),s=G("./node"),i={};function r(t,n){if(!t||n!==s.soul(t)||!s.is(t,this.fn,this.as))return!0;this.cb&&(e.n=t,e.as=this.as,this.cb.call(e.as,t,n,e))}function e(t){t&&s.is(e.n,t,e.as)}function f(t,n){var e;return(e=function(t,n){var e,o=t.seen,i=o.length;for(;i--;)if(e=o[i],n.obj===e.obj)return e;o.push(n)}(t,n))?e:(n.env=t,n.soul=c,s.ify(n.obj,o,n)&&(n.link=n.link||u.link.ify(s.soul(n.node)),n.obj!==t.shell&&(t.graph[u.link.is(n.link)]=n.node)),n)}function o(t,n,e){var o,i,r=this,a=r.env;if(s._===n&&g(t,u.link._))return e._;if(o=l(t,n,e,r,a)){if(n||(r.node=r.node||e||{},g(t,s._)&&s.soul(t)&&(r.node._=y(t._)),r.node=s.soul.ify(r.node,u.link.is(r.link)),r.link=r.link||u.link.ify(s.soul(r.node))),(i=a.map)&&(i.call(a.as||{},t,n,e,r),g(e,n))){if(t=e[n],h===t)return void v(e,n);if(!(o=l(t,n,e,r,a)))return}if(!n)return r.node;if(!0===o)return t;if((i=f(a,{obj:t,path:r.path.concat(n)})).node)return i.link}}function c(t){var n=this,e=u.link.is(n.link),o=n.env.graph;n.link=n.link||u.link.ify(t),n.link[u.link._]=t,n.node&&n.node[s._]&&(n.node[s._][u.link._]=t),g(o,e)&&(o[t]=o[e],v(o,e))}function l(t,n,e,o,i){var r;return!!u.is(t)||(d(t)?1:(r=i.invalid)?l(t=r.call(i.as||{},t,n,e),n,e,o,i):(i.err="Invalid value at '"+o.path.concat(n).join(".")+"'!",void(a.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}function p(t,n){var e,o;if(s._!==n)(e=u.link.is(t))?(o=this.opt.seen[e])?this.obj[n]=o:this.obj[n]=this.opt.seen[e]=i.to(this.graph,e,this.opt):this.obj[n]=t;else{if(m(t,u.link._))return;this.obj[n]=y(t)}}i.is=function(t,n,e,o){return!(!t||!d(t)||m(t))&&!b(t,r,{cb:n,fn:e,as:o})},i.ify=function(t,n,e){var o={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:"function"==typeof n&&(n.map=n):n={},"string"==typeof e&&(n.soul=n.soul||e,e=h),n.soul&&(o.link=u.link.ify(n.soul)),n.shell=(e||{}).shell,n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||e,f(n,o),n.root=o.node,n.graph},i.node=function(t){var n=s.soul(t);if(n)return k({},n,t)},i.to=function(t,n,e){if(t){var o={};return e=e||{seen:{}},b(t[n],p,{obj:o,graph:t,opt:e}),o}};a.fn.is;var h,n=a.obj,d=n.is,v=n.del,g=n.has,m=n.empty,k=n.put,b=n.map,y=n.copy;t.exports=i})(G,"./graph"),G(function(t){G("./onto"),t.exports=function(t,n){if(this.on){if("function"!=typeof t){if(!t||!n)return;var e=t["#"]||t,o=(this.tag||"")[e];if(!o)return;return o=this.on(e,n),clearTimeout(o.err),!0}e=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return e;var i=this.on(e,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK yet.",lack:!0}),i.off()},(this.opt||{}).lack||9e3),e}}})(G,"./ask"),G(function(t){var u=G("./type");t.exports=function(i){var r={s:{}},a=r.s;i=i||{max:1e3,age:27e3},r.check=function(t){return!!a[t]&&n(t)};var n=r.track=function(t){var n=a[t]||(a[t]={});return n.was=+new Date,r.to||(r.to=setTimeout(r.drop,i.age+9)),n};return r.drop=function(e){var o=+new Date;u.obj.map(a,function(t,n){t&&(e||i.age)>o-t.was||delete a[n]}),r.to=null,console.STAT&&9<(e=new Date-o)&&console.STAT(o,e,"dup drop")},r}})(G,"./dup"),G(function(t){function _(t){return t instanceof _?(this._={$:this}).$:this instanceof _?_.create(this._={$:this,opt:t}):new _(t)}_.is=function(t){return t instanceof _||t&&t._&&t===t._.$||!1},_.version=.202,_.chain=_.prototype,_.chain.toJSON=function(){};var n=G("./type");function r(t,n,e,o){var i=this,r=_.state.is(e,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+o+"'!";var a=i.graph[o]||A,u=_.state.is(a,n,!0),s=a[n],f=_.HAM(i.machine,r,u,t,s);f.incoming?(i.put[o]=_.state.to(e,n,i.put[o]),(i.diff||(i.diff={}))[o]=_.state.to(e,n,i.diff[o]),i.souls[o]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function a(t,n){var e=this,o=e.$._,i=(o.next||A)[n];if(!i){if(!(o.opt||A).super)return void(e.souls[n]=!1);i=e.$.get(n)._}var r=e.map[n]={put:t,get:n,$:i.$},a={ctx:e,msg:r};e.async=!!o.tag.node,e.ack&&(r["@"]=e.ack),m(t,u,a),e.async&&(e.and||o.on("node",function(t){this.to.next(t),t===e.map[t.get]&&(e.souls[t.get]=!1,m(t.put,s,t),m(e.souls,function(t){if(t)return t})||e.c||(e.c=1,this.off(),m(e.map,f,e)))}),e.and=!0,o.on("node",r))}function u(t,n){var e=this.ctx,o=e.graph,i=this.msg,r=i.get,a=i.put,u=i.$._;o[r]=_.state.to(a,n,o[r]),e.async||(u.put=_.state.to(a,n,u.put))}function s(t,n){var e=this.put,o=this.$._;o.put=_.state.to(e,n,o.put)}function f(t,n){t.$&&(this.cat.stop=this.stop,t.$._.on("in",t),this.cat.stop=null)}function c(t,n){if(t!==this.graph[n])return!0}n.obj.to(n,_),_.HAM=G("./HAM"),_.val=G("./val"),_.node=G("./node"),_.state=G("./state"),_.graph=G("./graph"),_.on=G("./onto"),_.ask=G("./ask"),_.dup=G("./dup"),_.puff=G("./puff"),function(){function f(t){var n,e,o,i,r,a;t&&(t.out!==f?(o=(e=(n=this.as).at||n).$,i=e.dup,a=t.DBG,(r=t["#"])||(r=t["#"]=p(9)),i.check(r)||(i.track(r),r=t._,t._="function"==typeof r?r:function(){},t.$&&t.$===(t.$._||"").$||(t.$=o),e.ask(t["@"],t)||(a&&(a.u=+new Date),t.get&&_.on._get(t,o),!t.put)?(a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.out=f,e.on("out",t),a&&(a.ue=+new Date)):u(t))):this.to.next(t))}function u(t){if(t){var n,e,o=t._||"",i=o.root=((o.$=t.$||"")._||"").root,r=t.put,a=t["#"],u=o.DBG=t.DBG;if(r["#"]&&r["."])i.on("put",t);else{o.out=t,o.lot={s:0,more:1};var s=+new Date;for(var f in u&&(u.p=s),r){var c,l=r[f];if(!l){n=g+m(f)+"no node.";break}if(!(e=l._)){n=g+m(f)+"no meta.";break}if(f!==e[j]){n=g+m(f)+"soul not same.";break}if(!(c=e[D])){n=g+m(f)+"no state.";break}for(var p in l)if(S!==p){var h=l[p],d=c[p];if(x===d){n=g+m(p)+"on"+m(f)+"no state.";break}if(!T(h)){n=g+m(p)+"on"+m(f)+"bad "+typeof h+m(h);break}!function t(n,e,o,i,r){var a,u=r._||"",s=u.root,f=s.graph;var c=f[o]||A,l=$(c,e,1),p=c[e];var h=y(),d=k(h,i,l,n,p);if(!d.incoming){if(d.defer){var v=i-h;return setTimeout(function(){t(n,e,o,i,r)},b":i},_:u})}(h,p,f,d,t)}if(n)break}u&&(u.pe=+new Date),console.STAT&&(console.STAT(s,new Date-s,"mix"),console.STAT(s,o.lot.s,"mix #")),(o.err=n)?i.on("in",{"@":a,err:_.log(n)}):(--o.lot.more||v(o),o.stun||t["@"]||i.on("in",{"@":a,ok:-1}))}}}function e(t){var n;(n=(t._||"").DBG)&&(n.pa=+new Date,n.pm=n.pm||+new Date);var e,o=this.as.graph,i=t._,r=t.put,a=r["#"],u=r["."],s=r[":"],f=r[">"];t["#"];o[a]=w(o[a],u,f,s,a),function(t,n,e,o,i){var r,a,u=t.root;if((u.opt||"").super&&u.$.get(n),!(u&&(a=u.next)&&(a=a[n])&&a.$))return;(r=t.put||(t.put={}))[n]=w(r[n],e,i,o,n),a.put=w(a.put,e,i,o,n)}(i,a,u,x!==(e=r["="])?e:s,f),(e=i.out)&&(e=e.put)&&(e[a]=w(e[a],u,f,s,a)),--i.lot.more||v(i),this.to.next(t)}function v(t){if(!t.err){var n,e={},o=((t.$||"")._||"").root,i=(o||"").next||"",r=t.put,a=+new Date;for(var u in r){var s=r[u];(n=i[u])&&n.$&&(o.stop=e,n.on("in",{$:n.$,get:u,put:s}),o.stop=null)}console.STAT&&console.STAT(a,new Date-a,"fire"),t.DBG&&(t.DBG.f=+new Date),(n=t.out)&&(n.out=f,o.on("out",n))}}_.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||_.on,t.ask=t.ask||_.ask,t.dup=t.dup||_.dup();var n=t.$.opt(t.opt);return t.once||(t.on("in",f,t),t.on("out",f,t),t.on("put",e,t),_.on("create",t),t.on("create",t)),t.once=1,n},_.on.put=u;var g="Error: Invalid graph!",m=function(t){return" '"+(""+t).slice(0,9)+"...' "},k=_.HAM,b=2147483647,y=_.state}(),_.on._put=function(t,n){var e,o=n._,i={$:n,graph:o.graph,put:{},map:{},souls:{},machine:_.state(),ack:t["@"],cat:o,stop:{}};if(_.obj.map(t.put,c,i)){if(_.graph.is(t.put,null,r,i)||(i.err="Error: Invalid graph!"),i.err)return o.on("in",{"@":t["#"],err:_.log(i.err)});m(i.put,a,i),i.async||m(i.map,f,i),x!==i.defer&&(e=i.defer-i.machine,setTimeout(function(){_.on._put(t,n)},e>MD?MD:e)),i.diff&&o.on("put",g(t,{put:i.diff}))}},_.on._get=function(t,n){var e=n._,o=t.get,i=o[j],r=e.graph[i],a=o[k],u=(e.next||(e.next={}))[i],s=(t._||"").DBG=t.DBG;if(s&&(s.g=+new Date),!r)return e.on("get",t);if(a){if("string"!=typeof a||!v(r,a))return e.on("get",t);r=_.state.to(r,a)}else r=_.window?_.obj.copy(r):r;r=_.graph.node(r),(u||A).ack;function f(){}f.ram=f.faith=!0,f.$=t.$,s&&(s.ga=+new Date),e.on("in",{"@":t["#"],put:r,ram:1,$:n,_:f}),s&&(s.gm=+new Date),e.on("get",t),s&&(s.gd=+new Date)},_.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return d(t)||(t={}),d(n.opt)||(n.opt=t),l(e)&&(e=[e]),o(e)&&(e=m(e,function(t,n,e){(n={}).id=n.url=t,e(t,n)}),d(n.opt.peers)||(n.opt.peers={}),n.opt.peers=g(e,n.opt.peers)),n.opt.peers=n.opt.peers||{},m(t,function t(n,e){!v(this,e)||i.is(n)||h.empty(n)?this[e]=n:n&&n.constructor!==Object&&!o(n)||m(n,t,this[e])},n.opt),_.on("opt",n),_.obj.native(),this},_.obj.native=function(){var t=Object.prototype;for(var n in t)console.log("Native Object.prototype polluted, reverting",n),delete t[n]};var x,e,o=_.list.is,i=_.text,l=i.is,p=i.random,h=_.obj,d=(h.empty,h.is),v=h.has,g=h.to,m=h.map,w=(h.copy,_.state.lex,_.state.ify),$=_.state.is,j=_.val.link._,k=".",S=_.node._,T=_.val.is,D=(_.val.link.is,_.state._),A={};_.log=function(){return _.log.off||e.log.apply(e,arguments),[].slice.call(arguments).join(" ")},_.log.once=function(t,n,e){return(e=_.log.once)[t]=e[t]||0,e[t]++||_.log(n)},"undefined"!=typeof window&&((window.GUN=window.Gun=_).window=window);try{void 0!==b&&(b.exports=_)}catch(t){}((t.exports=_).window||"").console=(_.window||"").console||{log:function(){}},(e=console).only=function(t,n){return e.only.i&&t===e.only.i&&e.only.i++&&(e.log.apply(e,arguments)||n)},_.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!")})(G,"./root"),G(function(t){var u=G("./root");u.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var e=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=e;o(r.acks||0)&&this.off(),r.ack&&r.ack(t,this)},r.opt),e=0,o=n.root.now;a.del(n.root,"now");var i=n.root.mum;n.root.mum={},r.ref._.on("out",{$:r.ref,put:r.out=r.env.graph,opt:r.opt,"#":t}),n.root.mum=i?a.to(i,n.root.mum):i,n.root.now=o,r.via._.on("res",{}),delete r.via._.tag.res},r),r.res&&r.res())}function c(r,t,n,a){var u=this,s=f.is(r);!t&&a.path.length&&(u.res||e)(function(){for(var t=a.path,n=u.ref,e=(u.opt,0),o=t.length;e .once, apologies unexpected."),this.once(t,n)},f.chain.once=function(t,n){var e=this,o=e._,i=o.put;if(0"];t["@"]||((acks[t["#"]]=tmp=(t._||"").lot||{}).lS=(tmp.lS||0)+1),u.level.get(o,function(t,n){n=n&&JSON.parse(n);var e=JSON.stringify(s.state.ify(n,i,a,r,o));u.level.put(o,e,function(t,n){})})}),void o.on("get",function(t){this.to.next(t);var e=t.get["#"];u.level.get(e,function(t,n){t||(n=n&&JSON.parse(n),o.on("in",{"@":e,put:s.graph.node(n),lS:1}))})})):t.next(o)})})(G,"./adapters/leveldb"),G(function(t){if("undefined"!=typeof Gun){var h;try{h=(Gun.window||function(){}).localStorage}catch(t){}h||(Gun.log("Warning: No localStorage exists to persist data to!"),h={setItem:function(t,n){this[t]=n},removeItem:function(t){delete this[t]},getItem:function(t){return this[t]}}),Gun.on("create",function(t){var n=this.to,e=t.opt;if(t.once)return n.next(t);if(!1===e.localStorage)return n.next(t);e.prefix=e.file||"gun/";var i,o,r,a,u=Gun.obj.ify(h.getItem("gap/"+e.prefix))||{},s=Gun.obj.empty;function f(t){var o;!t.err&&t.ok&&(o=t["@"],setTimeout(function(){Gun.obj.map(u,function(e,t){Gun.obj.map(e,function(t,n){o===t&&delete e[n]}),s(e)&&delete u[t]}),l()},e.wait||1))}s(u)||(r=Gun.obj.ify(h.getItem(e.prefix))||{},a={},Gun.obj.map(u,function(t,e){Gun.obj.map(t,function(t,n){a[e]=Gun.state.to(r[e],n,a[e])})}),setTimeout(function(){t.on("out",{put:a,"#":t.ask(f)})},1)),t.on("out",function(t){t.lS||(Gun.is(t.$)&&t.put&&!t["@"]&&(i=t["#"],Gun.graph.is(t.put,null,c),o=o||setTimeout(l,e.wait||1)),this.to.next(t))}),t.on("ack",f),n.next(t);var c=function(t,n,e,o){(u[o]||(u[o]={}))[n]=i},l=function(){clearTimeout(o),o=!1;try{h.setItem("gap/"+e.prefix,JSON.stringify(u))}catch(t){Gun.log(err=t||"localStorage failure")}}}),Gun.on("create",function(a){this.to.next(a);var u,s,f,c,l,p=a.opt;a.once||!1!==p.localStorage&&(p.prefix=p.file||"gun/",a.graph,u={},s=0,c=Gun.obj.ify(h.getItem(p.prefix))||{},a.on("localStorage",c),a.on("put",function(t){this.to.next(t);var n,e=t.put,o=e["#"],i=e["."],r=e[":"],a=e[">"];if(c[o]=Gun.state.ify(c[o],i,a,r,o),t["@"]||((u[t["#"]]=n=(t._||"").lot||{}).lS=(n.lS||0)+1),(s+=1)>=(p.batch||1e3))return l();f=f||setTimeout(l,p.wait||1)}),a.on("get",function(n){this.to.next(n);var e,o,i,r=n.get;function t(){var t;r&&(e=r["#"])&&(t=r["."],(o=c[e]||i)&&t&&(o=Gun.state.to(o,t)),a.on("in",{"@":n["#"],put:Gun.graph.node(o),lS:1}))}Gun.debug?setTimeout(t,1):t()}),l=function(t){var e;s=0,clearTimeout(f),f=!1;var n=u;u={},t&&(c=t);try{h.setItem(p.prefix,JSON.stringify(c))}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"),a.on("localStorage:error",{err:e,file:p.prefix,flush:c,retry:l})}(e||Gun.obj.empty(p.peers))&&Gun.obj.map(n,function(t,n){if(t){if(t.more)return void(u[n]=t);t.s!==t.lS&&(e="localStorage batch not same.")}a.on("in",{"@":n,err:e,ok:0})})})})}})(G,"./adapters/localStorage"),G(function(t){var e,x=G("../type");function o(t,n){var e;if(!(n instanceof Object))return n;var o=+new Date;return x.obj.map(Object.keys(n).sort(),i,{to:e={},on:n}),console.STAT&&console.STAT(o,new Date-o,"sort"),e}function i(t){this.to[t]=this.on[t]}e=JSON.stringify,x.obj.hash=function(t,n){if(n||void 0!==(t=e(t,o)))return x.text.hash(n||t||"")},x.obj.hash.sort=o;var w=x.obj.is;x.obj.map;try{t.exports=function(f){var l=function(){},p=f.opt||{};p.log=p.log||console.log,p.gap=p.gap||p.wait||0,p.pack=p.pack||.3*(p.memory?1e3*p.memory*1e3:1399e6),p.puff=p.puff||9;var h,d,v,g=setTimeout.puff||setTimeout,m=f.dup,c=m.check,k=m.track,b=l.hear=function(t,i){if(t){if(p.pack<=t.length)return l.say({dam:"!",err:"Message too big!"},i);var r,n,e,o=t[0];if(l===this&&(b.d+=t.length||0,++b.c),"["!==o){if("{"===o||(t["#"]||w(t))&&(r=t)){try{r=r||JSON.parse(t)}catch(t){return p.log("DAM JSON parse error",t)}if(!r)return;if(r.DBG&&(r.DBG=e={DBG:r.DBG}),e&&(e.hp=+new Date),(n=r["#"])||(n=r["#"]=x.text.random(9)),o=c(n))return;if((r._=function(){}).via=l.leap=i,o=r.dam)return(o=l.hear[o])&&o(r,i,f),void k(n);var a,u=+new Date;e&&(e.is=u),f.on("in",r),e&&(e.hd=+new Date),console.STAT&&9<(a=new Date-u)&&console.STAT(u,a,"msg"),k(n).via=i,l.leap=null}}else{try{r=JSON.parse(t)}catch(t){p.log("DAM JSON parse error",t)}if(t="",!r)return;console.STAT&&console.STAT(+new Date,r.length,"# on hear batch");var s=p.puff;(function t(){for(var n,e=+new Date,o=0;o"]||n["<"])||o===n["="]&&(e=n["*"]||n[">"]||n["<"],t.slice(0,(e||"").length)===e||o===n["*"]&&(o!==n[">"]&&o!==n["<"]?t>=n[">"]&&t<=n["<"]:o!==n[">"]&&t>=n[">"]||o!==n["<"]&&t<=n["<"])))},p.text.hash=function(t,n){if("string"==typeof t){if(n=n||0,!t.length)return n;for(var e=0,o=t.length;e");function f(t,n){k!==n&&u.ify(this.o,n,this.s)}u.drift=0,u.is=function(t,n,e){var o=n&&t&&t[k]&&t[k][s]||e;if(o)return v(o=o[n])?o:-1/0},u.lex=function(){return u().toString(36).replace(".","")},u.ify=function(t,n,e,o,i){if(!t||!t[k]){if(!i)return;t=a.soul.ify(t,i)}var r=l(t[k],s);return void 0!==n&&n!==k&&(v(e)&&(r[n]=e),void 0!==o&&(t[n]=o)),t},u.to=function(t,n,e){var o=(t||{})[n];return h(o)&&(o=g(o)),u.ify(e,n,u.is(t,n),o,a.soul(t))},u.map=function(i,r,a){var t=h(t=i||r)?t:null;return i=m(i=i||r)?i:null,t&&!i?(r=v(r)?r:u(),t[k]=t[k]||{},d(t,f,{o:t,s:r}),t):(a=a||h(r)?r:void 0,r=v(r)?r:u(),function(t,n,e,o){if(!i)return f.call({o:e,s:r},t,n),t;i.call(a||this||{},t,n,e,o),p(e,n)&&void 0===e[n]||f.call({o:e,s:r},t,n)})};var c=n.obj,l=c.as,p=c.has,h=c.is,d=c.map,g=c.copy,v=n.num.is,m=n.fn.is,k=a._;t.exports=u})(_,"./state"),_(function(t){var a=_("./type"),u=_("./val"),s=_("./node"),i={};function r(t,n){if(!t||n!==s.soul(t)||!s.is(t,this.fn,this.as))return!0;this.cb&&(e.n=t,e.as=this.as,this.cb.call(e.as,t,n,e))}function e(t){t&&s.is(e.n,t,e.as)}function f(t,n){var e;return(e=function(t,n){var e,o=t.seen,i=o.length;for(;i--;)if(e=o[i],n.obj===e.obj)return e;o.push(n)}(t,n))?e:(n.env=t,n.soul=c,s.ify(n.obj,o,n)&&(n.link=n.link||u.link.ify(s.soul(n.node)),n.obj!==t.shell&&(t.graph[u.link.is(n.link)]=n.node)),n)}function o(t,n,e){var o,i,r=this,a=r.env;if(s._===n&&g(t,u.link._))return e._;if(o=l(t,n,e,r,a)){if(n||(r.node=r.node||e||{},g(t,s._)&&s.soul(t)&&(r.node._=b(t._)),r.node=s.soul.ify(r.node,u.link.is(r.link)),r.link=r.link||u.link.ify(s.soul(r.node))),(i=a.map)&&(i.call(a.as||{},t,n,e,r),g(e,n))){if(void 0===(t=e[n]))return void d(e,n);if(!(o=l(t,n,e,r,a)))return}if(!n)return r.node;if(!0===o)return t;if((i=f(a,{obj:t,path:r.path.concat(n)})).node)return i.link}}function c(t){var n=this,e=u.link.is(n.link),o=n.env.graph;n.link=n.link||u.link.ify(t),n.link[u.link._]=t,n.node&&n.node[s._]&&(n.node[s._][u.link._]=t),g(o,e)&&(o[t]=o[e],d(o,e))}function l(t,n,e,o,i){var r;return!!u.is(t)||(h(t)?1:(r=i.invalid)?l(t=r.call(i.as||{},t,n,e),n,e,o,i):(i.err="Invalid value at '"+o.path.concat(n).join(".")+"'!",void(a.list.is(t)&&(i.err+=" Use `.set(item)` instead of an Array."))))}function p(t,n){var e,o;if(s._!==n)(e=u.link.is(t))?(o=this.opt.seen[e])?this.obj[n]=o:this.obj[n]=this.opt.seen[e]=i.to(this.graph,e,this.opt):this.obj[n]=t;else{if(v(t,u.link._))return;this.obj[n]=b(t)}}i.is=function(t,n,e,o){return!(!t||!h(t)||v(t))&&!k(t,r,{cb:n,fn:e,as:o})},i.ify=function(t,n,e){var o={path:[],obj:t};return n?"string"==typeof n?n={soul:n}:"function"==typeof n&&(n.map=n):n={},"string"==typeof e&&(n.soul=n.soul||e,e=void 0),n.soul&&(o.link=u.link.ify(n.soul)),n.shell=(e||{}).shell,n.graph=n.graph||{},n.seen=n.seen||[],n.as=n.as||e,f(n,o),n.root=o.node,n.graph},i.node=function(t){var n=s.soul(t);if(n)return m({},n,t)},i.to=function(t,n,e){if(t){var o={};return e=e||{seen:{}},k(t[n],p,{obj:o,graph:t,opt:e}),o}};a.fn.is;var n=a.obj,h=n.is,d=n.del,g=n.has,v=n.empty,m=n.put,k=n.map,b=n.copy;t.exports=i})(_,"./graph"),_(function(t){_("./onto"),t.exports=function(t,n){if(this.on){if("function"!=typeof t){if(!t||!n)return;var e=t["#"]||t,o=(this.tag||"")[e];if(!o)return;return o=this.on(e,n),clearTimeout(o.err),!0}e=n&&n["#"]||Math.random().toString(36).slice(2);if(!t)return e;var i=this.on(e,t,n);return i.err=i.err||setTimeout(function(){i.next({err:"Error: No ACK yet.",lack:!0}),i.off()},(this.opt||{}).lack||9e3),e}}})(_,"./ask"),_(function(t){var u=_("./type");t.exports=function(i){var r={s:{}},a=r.s;i=i||{max:1e3,age:27e3},r.check=function(t){return!!a[t]&&n(t)};var n=r.track=function(t){var n=a[t]||(a[t]={});return n.was=+new Date,r.to||(r.to=setTimeout(r.drop,i.age+9)),n};return r.drop=function(e){var o=+new Date;u.obj.map(a,function(t,n){t&&(e||i.age)>o-t.was||delete a[n]}),r.to=null,console.STAT&&9<(e=new Date-o)&&console.STAT(o,e,"dup drop")},r}})(_,"./dup"),_(function(t){function x(t){return t instanceof x?(this._={$:this}).$:this instanceof x?x.create(this._={$:this,opt:t}):new x(t)}x.is=function(t){return t instanceof x||t&&t._&&t===t._.$||!1},x.version=.202,(x.chain=x.prototype).toJSON=function(){};var n=_("./type");function r(t,n,e,o){var i=this,r=x.state.is(e,n);if(!r)return i.err="Error: No state on '"+n+"' in node '"+o+"'!";var a=i.graph[o]||G,u=x.state.is(a,n,!0),s=a[n],f=x.HAM(i.machine,r,u,t,s);f.incoming?(i.put[o]=x.state.to(e,n,i.put[o]),(i.diff||(i.diff={}))[o]=x.state.to(e,n,i.diff[o]),i.souls[o]=!0):f.defer&&(i.defer=r<(i.defer||1/0)?r:i.defer)}function a(t,n){var e=this,o=e.$._,i=(o.next||G)[n];if(!i){if(!(o.opt||G).super)return void(e.souls[n]=!1);i=e.$.get(n)._}var r=e.map[n]={put:t,get:n,$:i.$},a={ctx:e,msg:r};e.async=!!o.tag.node,e.ack&&(r["@"]=e.ack),m(t,u,a),e.async&&(e.and||o.on("node",function(t){this.to.next(t),t===e.map[t.get]&&(e.souls[t.get]=!1,m(t.put,s,t),m(e.souls,function(t){if(t)return t})||e.c||(e.c=1,this.off(),m(e.map,f,e)))}),e.and=!0,o.on("node",r))}function u(t,n){var e=this.ctx,o=e.graph,i=this.msg,r=i.get,a=i.put,u=i.$._;o[r]=x.state.to(a,n,o[r]),e.async||(u.put=x.state.to(a,n,u.put))}function s(t,n){var e=this.put,o=this.$._;o.put=x.state.to(e,n,o.put)}function f(t,n){t.$&&(this.cat.stop=this.stop,t.$._.on("in",t),this.cat.stop=null)}function c(t,n){if(t!==this.graph[n])return!0}n.obj.to(n,x),x.HAM=_("./HAM"),x.val=_("./val"),x.node=_("./node"),x.state=_("./state"),x.graph=_("./graph"),x.on=_("./onto"),x.ask=_("./ask"),x.dup=_("./dup"),x.puff=_("./puff"),function(){function f(t){if(t)if(t.out!==f){var n,e=this.as,o=e.at||e,i=o.$,r=o.dup,a=t.DBG;(n=t["#"])||(n=t["#"]=p(9)),r.check(n)||(r.track(n),n=t._,t._="function"==typeof n?n:function(){},t.$&&t.$===(t.$._||"").$||(t.$=i),o.ask(t["@"],t)||(a&&(a.u=+new Date),t.get&&x.on._get(t,i),!t.put)?(a&&(a.uc=+new Date),this.to.next(t),a&&(a.ua=+new Date),t.out=f,o.on("out",t),a&&(a.ue=+new Date)):u(t))}else this.to.next(t)}function u(t){if(t){var n,e,o=t._||"",i=o.root=((t.$||"")._||"").root,r=t.put,a=t["#"],u=o.DBG=t.DBG;if(r["#"]&&r["."])i.on("put",t);else{o.out=t,o.lot={s:0,more:1};var s=+new Date;for(var f in u&&(u.p=s),r){var c,l=r[f];if(!l){n=m+k(f)+"no node.";break}if(!(e=l._)){n=m+k(f)+"no meta.";break}if(f!==e[T]){n=m+k(f)+"soul not same.";break}if(!(c=e[A])){n=m+k(f)+"no state.";break}for(var p in l)if(S!==p){var h=l[p],d=c[p];if(w===d){n=m+k(p)+"on"+k(f)+"no state.";break}if(!D(h)){n=m+k(p)+"on"+k(f)+"bad "+typeof h+k(h);break}g(h,p,f,d,t)}if(n)break}u&&(u.pe=+new Date),console.STAT&&(console.STAT(s,new Date-s,"mix"),console.STAT(s,o.lot.s,"mix #")),(o.err=n)?i.on("in",{"@":a,err:x.log(n)}):(--o.lot.more||v(o),o.stun||t["@"]||i.on("in",{"@":a,ok:-1}))}}}function g(t,n,e,o,i){var r,a=i._||"",u=a.root,s=u.graph[e]||G,f=j(s,n,1),c=s[n],l=_(),p=b(l,o,f,t,c);if(p.incoming){(r=a.lot||"").s++,r.more++,(a.stun||(a.stun={}))[e+n]=1;var h=a.DBG;h&&(h.ph=h.ph||+new Date),u.on("put",{"#":i["#"],"@":i["@"],put:{"#":e,".":n,":":t,">":o},_:a})}else if(p.defer){var d=o-l;return setTimeout(function(){g(t,n,e,o,i)},y"];t["#"];o[a]=$(o[a],u,f,s,a),function(t,n,e,o,i){var r,a,u=t.root;if((u.opt||"").super&&u.$.get(n),!(u&&(a=u.next)&&(a=a[n])&&a.$))return;(r=t.put||(t.put={}))[n]=$(r[n],e,i,o,n),a.put=$(a.put,e,i,o,n)}(i,a,u,w!==(e=r["="])?e:s,f),(e=i.out)&&(e=e.put)&&(e[a]=$(e[a],u,f,s,a)),--i.lot.more||v(i),this.to.next(t)}function v(t){if(!t.err){var n,e={},o=t.root,i=o.next||"",r=t.put,a=+new Date;for(var u in r){var s=r[u];(n=i[u])&&n.$&&(o.stop=e,n.on("in",{$:n.$,get:u,put:s}),o.stop=null)}console.STAT&&console.STAT(a,new Date-a,"fire"),t.DBG&&(t.DBG.f=+new Date),(n=t.out)&&(n.out=f,o.on("out",n))}}x.create=function(t){t.root=t.root||t,t.graph=t.graph||{},t.on=t.on||x.on,t.ask=t.ask||x.ask,t.dup=t.dup||x.dup();var n=t.$.opt(t.opt);return t.once||(t.on("in",f,t),t.on("out",f,t),t.on("put",e,t),x.on("create",t),t.on("create",t)),t.once=1,n},x.on.put=u;var m="Error: Invalid graph!",k=function(t){return" '"+(""+t).slice(0,9)+"...' "},b=x.HAM,y=2147483647,_=x.state}(),x.on._put=function(t,n){var e=n._,o={$:n,graph:e.graph,put:{},map:{},souls:{},machine:x.state(),ack:t["@"],cat:e,stop:{}};if(x.obj.map(t.put,c,o)){if(x.graph.is(t.put,null,r,o)||(o.err="Error: Invalid graph!"),o.err)return e.on("in",{"@":t["#"],err:x.log(o.err)});if(m(o.put,a,o),o.async||m(o.map,f,o),w!==o.defer){var i=o.defer-o.machine;setTimeout(function(){x.on._put(t,n)},i>MD?MD:i)}o.diff&&e.on("put",v(t,{put:o.diff}))}},x.on._get=function(t,n){var e=n._,o=t.get,i=o[T],r=e.graph[i],a=o[k],u=(e.next||(e.next={}))[i],s=(t._||"").DBG=t.DBG;if(s&&(s.g=+new Date),!r)return e.on("get",t);if(a){if("string"!=typeof a||!g(r,a))return e.on("get",t);r=x.state.to(r,a)}else r=x.window?x.obj.copy(r):r;r=x.graph.node(r),(u||G).ack;function f(){}f.ram=f.faith=!0,s&&(s.ga=+new Date),e.on("in",{"@":t["#"],put:r,ram:1,$:n,_:f}),s&&(s.gm=+new Date),e.on("get",t),s&&(s.gd=+new Date)},x.chain.opt=function(t){t=t||{};var n=this._,e=t.peers||t;return d(t)||(t={}),d(n.opt)||(n.opt=t),l(e)&&(e=[e]),o(e)&&(e=m(e,function(t,n,e){(n={}).id=n.url=t,e(t,n)}),d(n.opt.peers)||(n.opt.peers={}),n.opt.peers=v(e,n.opt.peers)),n.opt.peers=n.opt.peers||{},m(t,function t(n,e){!g(this,e)||i.is(n)||h.empty(n)?this[e]=n:n&&n.constructor!==Object&&!o(n)||m(n,t,this[e])},n.opt),x.on("opt",n),x.obj.native(),this},x.obj.native=function(){var t=Object.prototype;for(var n in t)console.log("Native Object.prototype polluted, reverting",n),delete t[n]};var w,e,o=x.list.is,i=x.text,l=i.is,p=i.random,h=x.obj,d=(h.empty,h.is),g=h.has,v=h.to,m=h.map,$=(h.copy,x.state.lex,x.state.ify),j=x.state.is,T=x.val.link._,k=".",S=x.node._,D=x.val.is,A=(x.val.link.is,x.state._),G={};(x.log=function(){return x.log.off||e.log.apply(e,arguments),[].slice.call(arguments).join(" ")}).once=function(t,n,e){return(e=x.log.once)[t]=e[t]||0,e[t]++||x.log(n)},"undefined"!=typeof window&&((window.GUN=window.Gun=x).window=window);try{void 0!==b&&(b.exports=x)}catch(t){}((t.exports=x).window||"").console=(x.window||"").console||{log:function(){}},(e=console).only=function(t,n){return e.only.i&&t===e.only.i&&e.only.i++&&(e.log.apply(e,arguments)||n)},x.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!")})(_,"./root"),_(function(t){var u=_("./root");u.chain.back=function(t,n){if(-1===(t=t||1)||1/0===t)return this._.root.$;if(1===t)return(this._.back||this._).$;var e=this._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){for(var o=0,i=t.length,r=e;o(r.acks||0)&&this.off(),r.ack&&r.ack(t,this)},r.opt),e=0,o=n.root.now;a.del(n.root,"now");var i=n.root.mum;n.root.mum={},r.ref._.on("out",{$:r.ref,put:r.out=r.env.graph,opt:r.opt,"#":t}),n.root.mum=i?a.to(i,n.root.mum):i,n.root.now=o,r.via._.on("res",{}),delete r.via._.tag.res},r),r.res&&r.res())}function f(r,t,n,a){var u=this,s=c.is(r);!t&&a.path.length&&(u.res||e)(function(){for(var t=a.path,n=u.ref,e=(u.opt,0),o=t.length;e .once, apologies unexpected."),this.once(t,n)},f.chain.once=function(t,n){var e=this,o=e._,i=o.put;if(0"];if(l[o]=Gun.state.ify(l[o],i,a,r,o),t["@"]||((f[t["#"]]=n=(t._||"").lot||{}).lS=(n.lS||0)+1),(c+=1)>=(u.batch||1e3))return p();s=s||setTimeout(p,u.wait||1)}),a.on("get",function(n){this.to.next(n);var e,o,i,r=n.get;function t(){if(r&&(e=r["#"])){var t=r["."];(o=l[e]||i)&&t&&(o=Gun.state.to(o,t)),a.on("in",{"@":n["#"],put:Gun.graph.node(o),lS:1})}}Gun.debug?setTimeout(t,1):t()});var p=function(t){var e;c=0,clearTimeout(s),s=!1;var n=f;f={},t&&(l=t);try{h.setItem(u.prefix,JSON.stringify(l))}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"),a.on("localStorage:error",{err:e,file:u.prefix,flush:l,retry:p})}(e||Gun.obj.empty(u.peers))&&Gun.obj.map(n,function(t,n){if(t){if(t.more)return void(f[n]=t);t.s!==t.lS&&(e="localStorage batch not same.")}a.on("in",{"@":n,err:e,ok:0})})}}})}})(_,"./adapters/localStorage"),_(function(t){var e,x=_("../type");function o(t,n){var e;if(!(n instanceof Object))return n;var o=+new Date;return x.obj.map(Object.keys(n).sort(),i,{to:e={},on:n}),console.STAT&&console.STAT(o,new Date-o,"sort"),e}function i(t){this.to[t]=this.on[t]}e=JSON.stringify,x.obj.hash=function(t,n){if(n||void 0!==(t=e(t,o)))return x.text.hash(n||t||"")},x.obj.hash.sort=o;var w=x.obj.is;x.obj.map;try{t.exports=function(f){var l=function(){},p=f.opt||{};p.log=p.log||console.log,p.gap=p.gap||p.wait||0,p.pack=p.pack||.3*(p.memory?1e3*p.memory*1e3:1399e6),p.puff=p.puff||9;var h,d,g,v=setTimeout.puff||setTimeout,m=f.dup,c=m.check,k=m.track,b=l.hear=function(t,i){if(t){if(p.pack<=t.length)return l.say({dam:"!",err:"Message too big!"},i);var r,n,e,o=t[0];if(l===this&&(b.d+=t.length||0,++b.c),"["!==o){if("{"===o||(t["#"]||w(t))&&(r=t)){try{r=r||JSON.parse(t)}catch(t){return p.log("DAM JSON parse error",t)}if(!r)return;if(r.DBG&&(r.DBG=e={DBG:r.DBG}),e&&(e.hp=+new Date),(n=r["#"])||(n=r["#"]=x.text.random(9)),o=c(n))return;if((r._=function(){}).via=l.leap=i,o=r.dam)return(o=l.hear[o])&&o(r,i,f),void k(n);var a,u=+new Date;e&&(e.is=u),f.on("in",r),e&&(e.hd=+new Date),console.STAT&&9<(a=new Date-u)&&console.STAT(u,a,"msg"),k(n).via=i,l.leap=null}}else{try{r=JSON.parse(t)}catch(t){p.log("DAM JSON parse error",t)}if(t="",!r)return;console.STAT&&console.STAT(+new Date,r.length,"# on hear batch");var s=p.puff;(function t(){for(var n,e=+new Date,o=0;o=0.8.4" }, "dependencies": { - "why-is-node-running": "^2.2.0", "ws": "^7.2.1" }, "optionalDependencies": { diff --git a/test/panic/leveldb.js b/test/panic/leveldb.js deleted file mode 100644 index da6c622f2..000000000 --- a/test/panic/leveldb.js +++ /dev/null @@ -1,242 +0,0 @@ -const panic = require('panic-server'); -const clients = panic.clients; -const manager = require('panic-manager')(); - -const config = { - ip : require('ip').address(), - port : 8765, - servers : 3, - route : { - '/' : __dirname + '/index.html', - '/gun.js' : __dirname + '/../../gun.js', - '/jquery.js' : __dirname + '/../../examples/jquery.js' - } -}; - -panic.server().on('request', function(req, res){ - config.route[req.url] && require('fs').createReadStream(config.route[req.url]).pipe(res); -}).listen(config.port); - -manager.start({ - clients: Array(config.servers).fill().map((u,i) => ({ - type: 'node', - port: config.port + i + 1, - })), - panic: `http://${config.ip}:${config.port}` -}); - -const servers = clients.filter('Node.js'); -const server = servers.pluck(1); -const alice = servers.excluding(server).pluck(1); -const bob = servers.excluding(server).excluding(alice).pluck(1); - -describe('Make sure the leveldb storage engine works', function() { - this.timeout(5 * 60 * 60 * 1000); - - it("Servers have joined!", function(){ - return servers.atLeast(config.servers); - }); - - it("GUN started!", () => { - return server.run(test => { - test.async(); - const root = (new Function('return this'))(); - const leveldown = require('leveldown'); - const levelup = require('levelup'); - const {i, config} = test.props; - const port = config.port + i; - - if (require('fs').existsSync('./lvldata')) { - console.error('Please delete previous data first!'); - return; - } - - const level = levelup(leveldown('./lvldata')); - const web = require('http').createServer((req, res) => { - res.end(`I am ${i}!`); - }); - - const Gun = require('../../../index.js'); - const gun = Gun({web, level}); - root.gun = gun; - root.level = level; - - web.listen(port, function(){ - test.done(); - }); - }, {i: 1, config}); - }); - - it('Alice save data', () => { - return alice.run(test => { - test.async(); - const root = (new Function('return this'))(); - const {config} = test.props; - const Gun = require('../../../index.js'); - - // Start gun - const gun = Gun({peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun', lack: 1000 * 60 * 60}); - root.gun = gun; - - // Save data - const ref = gun.get('asdf'); - ref.put({ hello: 'world' }, ack => { - if (ack.err) { - if (ack.lack) return test.fail('ACK timed out, turn your lack of ack up or throughput down'); - return test.fail(ack.err); - } - ref.off(); - test.done(); - }); - }, {config}); - }); - - it('Bob read data', () => { - return bob.run(test => { - test.async(); - const root = (new Function('return this'))(); - const {config} = test.props; - const Gun = require('../../../index.js'); - - // Start gun - const gun = Gun({peers: 'http://'+ config.ip + ':' + (config.port + 1) + '/gun', lack: 1000 * 60 * 60}); - root.gun = gun; - - // Read data - const ref = gun.get('asdf'); - ref.on(data => { - if (data.hello !== 'world') { - return test.fail('Invalid data returned'); - } - ref.off(); - test.done(); - }); - - }, {config}); - }); - -// it("Bob read data", function(){ -// this.timeout(1000 * 60 * 60 * 5); -// //return alice.run(function(test){ -// return bob.run(function(test){ -// var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each/2; -// var raw = Gun.text.random(200, 'a');// "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; -// $('body').append($("
")); var $log = $('#log'); -// -// var ref = window.gun.get('asdf' + i); -// ref.on(function(data){ -// if((raw+i) !== data.hello){ return test.fail('wrong ' + i) } -// if(d){ return } d = true; -// c++; -// !(i % 1000) && console.log(i+'/'+l); -// !(i % 1000) && $log.prepend('

'+i+'/'+l+'

'); -// //console.log(i+'/'+l); -// ref.off(); -// if(c < l){ return } -// console.log("DONE!", c+'/'+l); -// $log.prepend('

DONE! '+i+'/'+l+'

'); -// setTimeout(function(){ -// test.done(); -// setTimeout(function(){ -// location = 'http://asdf'; -// }, 1500) -// }, 1); -// }); -// } -// function burst(){ -// if(i > l){ -// return; -// } -// for(var j = 0; j <= b; j++){ -// check(++i); -// } -// setTimeout(burst, env.config.wait); -// } -// burst(); -// }, {i: 1, config: config}); -// }); - - it("All finished", done => { - setTimeout(() => { - done(); - },100); - }); - - it('Shutdown everything', () => { - return clients.run(test => { - process.exit(); - }); - }); - -}); - -//var config = { -// IP: require('ip').address(), -// port: 8765, -// servers: 2, -// browsers: 3, -// each: 100000, //1000000, -// burst: 1, -// wait: 1, -// dir: __dirname, -// chunk: 1024 * 1024 * 10, -// notrad: false, -//} -//config.gundir = require('path').resolve(config.dir, '../../')+'/'; - -//var servers = clients.filter('Node.js'); -//var server = servers.pluck(1); -//var spawn = servers.excluding(server).pluck(1); -//var browsers = clients.excluding(servers); -//var alice = browsers.pluck(1); -//var bob = browsers.excluding(alice).pluck(1); -//var carl = browsers.excluding(new panic.ClientList([alice, bob])).pluck(1); - - -// it("Carl read data", function(){ -// this.timeout(1000 * 60 * 60 * 5); -// //return alice.run(function(test){ -// return carl.run(function(test){ -// test.async(); -// console.log("I AM CARL"); -// localStorage.clear(); -// var env = test.props; -// var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: false}); -// window.gun = gun; -// var n = Gun.time.is(), i = env.config.each / 2, c = 0, b = env.config.burst, l = env.config.each; -// var raw = Gun.text.random(200, 'a');// "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; -// $('body').append($("
")); var $log = $('#log'); - -// function check(i){ -// if(i > l){ -// return; -// } -// var d; -// var ref = window.gun.get('asdf' + i); -// ref.on(function(data){ -// if((raw+i) !== data.hello){ return test.fail('wrong ' + i) } -// if(d){ return } d = true; -// c++; -// !(i % 1000) && console.log(i+'/'+l); -// !(i % 1000) && $log.prepend('

'+i+'/'+l+'

'); -// //console.log(i+'/'+l); -// ref.off(); -// if(c < (l / 2)){ return } -// console.log("DONE!", c+'/'+l); -// $log.prepend('

DONE! '+i+'/'+l+'

'); -// test.done(); -// }); -// } -// function burst(){ -// if(i > l){ -// return; -// } -// for(var j = 0; j <= b; j++){ -// check(++i); -// } -// setTimeout(burst, env.config.wait); -// } -// burst(); -// }, {i: 1, config: config}); -// }); - From 58ad588d6531219a539806f3414bf57bf77d0c59 Mon Sep 17 00:00:00 2001 From: Robin Bron Date: Thu, 24 Sep 2020 08:21:20 +0200 Subject: [PATCH 8/8] Renamed 'level' adapter to 'rlevel' due to rad --- lib/{level.js => rlevel.js} | 0 test/panic/{level.js => rlevel.js} | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename lib/{level.js => rlevel.js} (100%) rename test/panic/{level.js => rlevel.js} (98%) diff --git a/lib/level.js b/lib/rlevel.js similarity index 100% rename from lib/level.js rename to lib/rlevel.js diff --git a/test/panic/level.js b/test/panic/rlevel.js similarity index 98% rename from test/panic/level.js rename to test/panic/rlevel.js index b9ec548ea..6bda52a4f 100644 --- a/test/panic/level.js +++ b/test/panic/rlevel.js @@ -59,7 +59,7 @@ describe('Make sure the leveldb storage engine works', function() { // Load the libraries under test const Gun = require('../../../index.js'); - const debug = require('../../../lib/level.js'); + const debug = require('../../../lib/rlevel.js'); // // Add debug messages // debug.on('get', key => console.log('LEVEL GET', key)); @@ -163,7 +163,7 @@ describe('Make sure the leveldb storage engine works', function() { // Load the libraries under test const Gun = require('../../../index.js'); - const debug = require('../../../lib/level.js'); + const debug = require('../../../lib/rlevel.js'); // // Add debug messages // debug.on('get', key => console.log('LEVEL GET', key));