From 638c2c3c23125622fbca3db1404111e36012c715 Mon Sep 17 00:00:00 2001 From: Mark Nadal Date: Wed, 17 Jan 2024 10:13:00 -0800 Subject: [PATCH] have unbuild function wrap to prevent scope leaks & allow RETURN hehehe so I can reject @bmatusiak 's lS change O:) O:) I love you you're a hero! later with @bmatusiak check sea.then for '../gun.js' vs '../' vs ... note: src/index -> core.js TODO: something about WebRTC candidates hitting ack decrement limits? --- gun.js | 6 +++--- lib/unbuild.js | 1 + sea/aeskey.js | 4 +++- sea/array.js | 4 +++- sea/auth.js | 13 ++++++++++--- sea/base64.js | 4 +++- sea/buffer.js | 4 +++- sea/certify.js | 4 +++- sea/create.js | 6 ++++-- sea/decrypt.js | 4 +++- sea/encrypt.js | 4 +++- sea/https.js | 8 ++++++-- sea/index.js | 6 ++++-- sea/pair.js | 4 +++- sea/recall.js | 6 ++++-- sea/root.js | 5 ++++- sea/sea.js | 8 +++++--- sea/secret.js | 4 +++- sea/settings.js | 4 +++- sea/sha1.js | 4 +++- sea/sha256.js | 4 +++- sea/share.js | 4 +++- sea/shim.js | 10 ++++++---- sea/sign.js | 4 +++- sea/then.js | 6 ++++-- sea/user.js | 4 +++- sea/verify.js | 4 +++- sea/work.js | 4 +++- src/ask.js | 4 +++- src/back.js | 4 +++- src/book.js | 7 ++++--- src/chain.js | 5 ++++- src/core.js | 10 ++++++++++ src/dup.js | 5 ++++- src/get.js | 5 ++++- src/index.js | 22 +++++++++++++++++----- src/localStorage.js | 4 +++- src/map.js | 6 ++++-- src/mesh.js | 20 ++++++++++++++------ src/on.js | 10 ++++++++-- src/onto.js | 4 +++- src/put.js | 4 +++- src/root.js | 15 ++++++++++++--- src/set.js | 6 ++++-- src/shim.js | 4 +++- src/state.js | 4 +++- src/valid.js | 6 ++++-- src/websocket.js | 6 ++++-- 48 files changed, 216 insertions(+), 78 deletions(-) create mode 100644 src/core.js diff --git a/gun.js b/gun.js index 69171f470..810dda61f 100644 --- a/gun.js +++ b/gun.js @@ -136,7 +136,7 @@ }; })(USE, './onto'); - ;USE(function(module){ ;(function(){ + ;USE(function(module){ // TODO: BUG! Unbuild will make these globals... CHANGE unbuild to wrap files in a function. // Book is a replacement for JS objects, maps, dictionaries. var sT = setTimeout, B = sT.Book || (sT.Book = function(text){ @@ -348,7 +348,6 @@ } try{module.exports=B}catch(e){} - }());//delete later. })(USE, './book'); ;USE(function(module){ @@ -716,7 +715,7 @@ tmp = keys.length; console.STAT && console.STAT(S, -(S - (S = +new Date)), 'got copied some'); DBG && (DBG.ga = +new Date); - root.on('in', {'@': to, '#': id, put: put, '%': (tmp? (id = text_rand(9)) : u), $: root.$, _: faith, DBG: DBG, FOO: 1}); + root.on('in', {'@': to, '#': id, put: put, '%': (tmp? (id = text_rand(9)) : u), $: root.$, _: faith, DBG: DBG}); console.STAT && console.STAT(S, +new Date - S, 'got in'); if(!tmp){ return } setTimeout.turn(go); @@ -1388,6 +1387,7 @@ var Gun = USE('./root'); USE('./shim'); USE('./onto'); + USE('./book'); USE('./valid'); USE('./state'); USE('./dup'); diff --git a/lib/unbuild.js b/lib/unbuild.js index 197fb7237..f2b5f7146 100644 --- a/lib/unbuild.js +++ b/lib/unbuild.js @@ -110,6 +110,7 @@ var undent = function(code, n){ if(rcode != code){ console.log("unbuild:","update",file); } + code = ";(function(){\n"+code+"\n}());"; write(file, code); recurse(); }()); diff --git a/sea/aeskey.js b/sea/aeskey.js index 20390b3f0..3f0a3d575 100644 --- a/sea/aeskey.js +++ b/sea/aeskey.js @@ -1,3 +1,4 @@ +;(function(){ var shim = require('./shim'); var S = require('./settings'); @@ -13,4 +14,5 @@ return await shim.subtle.importKey('jwk', jwkKey, {name:'AES-GCM'}, false, ['encrypt', 'decrypt']) } module.exports = importGen; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/array.js b/sea/array.js index e6fa57659..4de9dfb49 100644 --- a/sea/array.js +++ b/sea/array.js @@ -1,3 +1,4 @@ +;(function(){ require('./base64'); // This is Array extended to have .toString(['utf8'|'hex'|'base64']) @@ -22,4 +23,5 @@ } } module.exports = SeaArray; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/auth.js b/sea/auth.js index cdbdaea5e..76a0a70c1 100644 --- a/sea/auth.js +++ b/sea/auth.js @@ -1,3 +1,4 @@ +;(function(){ var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){}; // now that we have created a user, we want to authenticate them! @@ -7,7 +8,8 @@ var pass = (alias || (pair && !(pair.priv && pair.epriv))) && typeof args[1] === 'string' ? args[1] : null; var cb = args.filter(arg => typeof arg === 'function')[0] || null; // cb now can stand anywhere, after alias/pass or pair var opt = args && args.length > 1 && typeof args[args.length-1] === 'object' ? args[args.length-1] : {}; // opt is always the last parameter which typeof === 'object' and stands after cb - + var retries = typeof opt.retries === 'number' ? opt.retries : 9; + var gun = this, cat = (gun._), root = gun.back(-1); if(cat.ing){ @@ -30,6 +32,10 @@ var get = (act.list = (act.list||[]).concat(list||[])).shift(); if(u === get){ if(act.name){ return act.err('Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer.') } + if(alias && retries--){ + root.get('~@'+alias).once(act.a); + return; + } return act.err('Wrong user or password.') } root.get(get).once(act.a); @@ -74,7 +80,7 @@ if(SEA.window && ((gun.back('user')._).opt||opt).remember){ // TODO: this needs to be modular. try{var sS = {}; - sS = window.sessionStorage; // TODO: FIX BUG putting on `.is`! + sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`! sS.recall = true; sS.pair = JSON.stringify(pair); // auth using pair is more reliable than alias/pass }catch(e){} @@ -154,4 +160,5 @@ }catch(e){o={}}; return o; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/base64.js b/sea/base64.js index 5c4b4a1d4..95ceb3cc5 100644 --- a/sea/base64.js +++ b/sea/base64.js @@ -1,3 +1,4 @@ +;(function(){ var u; if(u+''== typeof btoa){ @@ -7,4 +8,5 @@ global.btoa = function(data){ return Buffer.from(data, "binary").toString("base64") }; global.atob = function(data){ return Buffer.from(data, "base64").toString("binary") }; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/buffer.js b/sea/buffer.js index 67fbe3188..6cd0ce6ab 100644 --- a/sea/buffer.js +++ b/sea/buffer.js @@ -1,3 +1,4 @@ +;(function(){ require('./base64'); // This is Buffer implementation used in SEA. Functionality is mostly @@ -76,4 +77,5 @@ SafeBuffer.prototype.toString = SeaArray.prototype.toString module.exports = SafeBuffer; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/certify.js b/sea/certify.js index b6145d011..f052b190b 100644 --- a/sea/certify.js +++ b/sea/certify.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); // This is to certify that a group of "certificants" can "put" anything at a group of matched "paths" to the certificate authority's graph @@ -69,4 +70,5 @@ }}); module.exports = SEA.certify; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/create.js b/sea/create.js index da3174814..5036fc560 100644 --- a/sea/create.js +++ b/sea/create.js @@ -1,3 +1,4 @@ +;(function(){ var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){}; @@ -94,11 +95,12 @@ } if(SEA.window){ try{var sS = {}; - sS = window.sessionStorage; + sS = SEA.window.sessionStorage; delete sS.recall; delete sS.pair; }catch(e){}; } return gun; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/decrypt.js b/sea/decrypt.js index 79fe6a90b..39f67b5a7 100644 --- a/sea/decrypt.js +++ b/sea/decrypt.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -39,4 +40,5 @@ }}); module.exports = SEA.decrypt; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/encrypt.js b/sea/encrypt.js index 4f0b6c9a8..50effa107 100644 --- a/sea/encrypt.js +++ b/sea/encrypt.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -37,4 +38,5 @@ }}); module.exports = SEA.encrypt; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/https.js b/sea/https.js index 4f12465f9..dd2438fa3 100644 --- a/sea/https.js +++ b/sea/https.js @@ -1,12 +1,16 @@ +;(function(){ var SEA = require('./root'); try{ if(SEA.window){ if(location.protocol.indexOf('s') < 0 && location.host.indexOf('localhost') < 0 && ! /^127\.\d+\.\d+\.\d+$/.test(location.hostname) - && location.protocol.indexOf('file:') < 0){ + && location.protocol.indexOf('blob:') < 0 + && location.protocol.indexOf('file:') < 0 + && location.origin != 'null'){ console.warn('HTTPS needed for WebCrypto in SEA, redirecting...'); location.protocol = 'https:'; // WebCrypto does NOT work without HTTPS! } } }catch(e){} - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/index.js b/sea/index.js index 4e5358f30..de21f0e51 100644 --- a/sea/index.js +++ b/sea/index.js @@ -1,6 +1,7 @@ +;(function(){ var SEA = require('./sea'), S = require('./settings'), noop = function() {}, u; - var Gun = (''+u != typeof window)? (window.Gun||{on:noop}) : require((''+u === typeof MODULE?'.':'')+'./gun', 1); + var Gun = (SEA.window||'').GUN || require((''+u === typeof MODULE?'.':'')+'./gun', 1); // After we have a GUN extension to make user registration/login easy, we then need to handle everything else. // We do this with a GUN adapter, we first listen to when a gun instance is created (and when its options change) @@ -66,7 +67,7 @@ check.any(eve, msg, val, key, soul, at, no, at.user||''); return; eve.to.next(msg); // not handled } - check.hash = function(eve, msg, val, key, soul, at, no){ + check.hash = function(eve, msg, val, key, soul, at, no){ // mark unbuilt @i001962 's epic hex contrib! SEA.work(val, null, function(data){ function hexToBase64(hexStr) { let base64 = ""; @@ -246,3 +247,4 @@ // TODO: Potential bug? If pub/priv key starts with `-`? IDK how possible. +}()); \ No newline at end of file diff --git a/sea/pair.js b/sea/pair.js index b01aad31a..d0d6f04ca 100644 --- a/sea/pair.js +++ b/sea/pair.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -70,4 +71,5 @@ }}); module.exports = SEA.pair; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/recall.js b/sea/recall.js index c8e5976a9..64a31d3ba 100644 --- a/sea/recall.js +++ b/sea/recall.js @@ -1,3 +1,4 @@ +;(function(){ var User = require('./user'), SEA = User.SEA, Gun = User.GUN; User.prototype.recall = function(opt, cb){ @@ -7,7 +8,7 @@ if(SEA.window){ try{ var sS = {}; - sS = window.sessionStorage; // TODO: FIX BUG putting on `.is`! + sS = SEA.window.sessionStorage; // TODO: FIX BUG putting on `.is`! if(sS){ (root._).opt.remember = true; ((gun.back('user')._).opt||opt).remember = true; @@ -24,4 +25,5 @@ */ return gun; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/root.js b/sea/root.js index 8ec30aaf8..83c0540bd 100644 --- a/sea/root.js +++ b/sea/root.js @@ -1,9 +1,11 @@ +;(function(){ // Security, Encryption, and Authorization: SEA.js // MANDATORY READING: https://gun.eco/explainers/data/security.html // IT IS IMPLEMENTED IN A POLYFILL/SHIM APPROACH. // THIS IS AN EARLY ALPHA! + if(typeof self !== "undefined"){ module.window = self } // should be safe for at least browser/worker/nodejs, need to check other envs like RN etc. if(typeof window !== "undefined"){ module.window = window } var tmp = module.window || module, u; @@ -13,4 +15,5 @@ try{ if(u+'' !== typeof MODULE){ MODULE.exports = SEA } }catch(e){} module.exports = SEA; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/sea.js b/sea/sea.js index c870ed3c3..522783328 100644 --- a/sea/sea.js +++ b/sea/sea.js @@ -1,3 +1,4 @@ +;(function(){ var shim = require('./shim'); // Practical examples about usage found in tests. @@ -16,7 +17,7 @@ // For documentation see https://nodejs.org/api/buffer.html SEA.Buffer = SEA.Buffer || require('./buffer'); - // These SEA functions support now only Promises or + // These SEA functions support now ony Promises or // async/await (compatible) code, use those like Promises. // // Creates a wrapper library around Web Crypto API @@ -45,7 +46,7 @@ // Obviously it is missing MANY necessary features. This is only an alpha release. // Please experiment with it, audit what I've done so far, and complain about what needs to be added. // SEA should be a full suite that is easy and seamless to use. - // Again, scroll near the top, where I provide an EXAMPLE of how to create a user and sign in. + // Again, scroll naer the top, where I provide an EXAMPLE of how to create a user and sign in. // Once logged in, the rest of the code you just read handled automatically signing/validating data. // But all other behavior needs to be equally easy, like opinionated ways of // Adding friends (trusted public keys), sending private messages, etc. @@ -55,4 +56,5 @@ module.exports = SEA // -------------- END SEA MODULES -------------------- // -- BEGIN SEA+GUN MODULES: BUNDLED BY DEFAULT UNTIL OTHERS USE SEA ON OWN ------- - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/secret.js b/sea/secret.js index 949ff398d..42ca8b3ed 100644 --- a/sea/secret.js +++ b/sea/secret.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -50,4 +51,5 @@ } module.exports = SEA.secret; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/settings.js b/sea/settings.js index c90088229..2fc07fe35 100644 --- a/sea/settings.js +++ b/sea/settings.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -41,4 +42,5 @@ SEA.opt = s; module.exports = s - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/sha1.js b/sea/sha1.js index 9272cffc5..67ffeec52 100644 --- a/sea/sha1.js +++ b/sea/sha1.js @@ -1,3 +1,4 @@ +;(function(){ // This internal func returns SHA-1 hashed data for KeyID generation const __shim = require('./shim') @@ -5,4 +6,5 @@ const ossl = __shim.ossl ? __shim.ossl : subtle const sha1hash = (b) => ossl.digest({name: 'SHA-1'}, new ArrayBuffer(b)) module.exports = sha1hash - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/sha256.js b/sea/sha256.js index f64660de4..62885ff65 100644 --- a/sea/sha256.js +++ b/sea/sha256.js @@ -1,3 +1,4 @@ +;(function(){ var shim = require('./shim'); module.exports = async function(d, o){ @@ -5,4 +6,5 @@ var hash = await shim.subtle.digest({name: o||'SHA-256'}, new shim.TextEncoder().encode(t)); return shim.Buffer.from(hash); } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/share.js b/sea/share.js index 1fd24f82c..b0c942729 100644 --- a/sea/share.js +++ b/sea/share.js @@ -1,3 +1,4 @@ +;(function(){ var User = require('./user'), SEA = User.SEA, Gun = User.GUN, noop = function(){}; User.prototype.pair = function(){ @@ -133,4 +134,5 @@ } */ module.exports = User - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/shim.js b/sea/shim.js index e955e736e..bf9e92037 100644 --- a/sea/shim.js +++ b/sea/shim.js @@ -1,3 +1,4 @@ +;(function(){ const SEA = require('./root') const api = {Buffer: require('./buffer')} @@ -15,10 +16,10 @@ })} if(SEA.window){ - api.crypto = window.crypto || window.msCrypto + api.crypto = SEA.window.crypto || SEA.window.msCrypto api.subtle = (api.crypto||o).subtle || (api.crypto||o).webkitSubtle; - api.TextEncoder = window.TextEncoder; - api.TextDecoder = window.TextDecoder; + api.TextEncoder = SEA.window.TextEncoder; + api.TextDecoder = SEA.window.TextDecoder; api.random = (len) => api.Buffer.from(api.crypto.getRandomValues(new Uint8Array(api.Buffer.alloc(len)))); } if(!api.TextDecoder) @@ -44,4 +45,5 @@ }} module.exports = api - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/sign.js b/sea/sign.js index f286dd0ca..0374a715b 100644 --- a/sea/sign.js +++ b/sea/sign.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -41,4 +42,5 @@ }}); module.exports = SEA.sign; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/then.js b/sea/then.js index 6c127ee39..bcbce33f0 100644 --- a/sea/then.js +++ b/sea/then.js @@ -1,9 +1,11 @@ +;(function(){ - var u, Gun = (''+u != typeof window)? (window.Gun||{chain:{}}) : require((''+u === typeof MODULE?'.':'')+'./gun', 1); + var u, Gun = (''+u != typeof GUN)? (GUN||{chain:{}}) : require((''+u === typeof MODULE?'.':'')+'./gun', 1); Gun.chain.then = function(cb, opt){ var gun = this, p = (new Promise(function(res, rej){ gun.once(res, opt); })); return cb? p.then(cb) : p; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/user.js b/sea/user.js index bbd9188fb..153108170 100644 --- a/sea/user.js +++ b/sea/user.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./sea'), Gun, u; if(SEA.window){ @@ -38,4 +39,5 @@ User.GUN = Gun; User.SEA = Gun.SEA = SEA; module.exports = User; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/verify.js b/sea/verify.js index b431badf5..794aa8ebc 100644 --- a/sea/verify.js +++ b/sea/verify.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -77,4 +78,5 @@ } SEA.opt.fallback = 2; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/sea/work.js b/sea/work.js index e6f68493a..6feeabaca 100644 --- a/sea/work.js +++ b/sea/work.js @@ -1,3 +1,4 @@ +;(function(){ var SEA = require('./root'); var shim = require('./shim'); @@ -39,4 +40,5 @@ }}); module.exports = SEA.work; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/ask.js b/src/ask.js index 5fa0a5cb4..c843aa3cb 100644 --- a/src/ask.js +++ b/src/ask.js @@ -1,3 +1,4 @@ +;(function(){ // request / response module, for asking and acking messages. require('./onto'); // depends upon onto! @@ -24,4 +25,5 @@ module.exports = function ask(cb, as){ return id; } var random = String.random || function(){ return Math.random().toString(36).slice(2) } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/back.js b/src/back.js index 6f522cbd8..a9009432f 100644 --- a/src/back.js +++ b/src/back.js @@ -1,3 +1,4 @@ +;(function(){ var Gun = require('./root'); Gun.chain.back = function(n, opt){ var tmp; @@ -37,4 +38,5 @@ Gun.chain.back = function(n, opt){ var tmp; return this; } var empty = {}, u; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/book.js b/src/book.js index f339c30f1..9a0c3b95c 100644 --- a/src/book.js +++ b/src/book.js @@ -1,4 +1,5 @@ - ;(function(){ +;(function(){ + // TODO: BUG! Unbuild will make these globals... CHANGE unbuild to wrap files in a function. // Book is a replacement for JS objects, maps, dictionaries. var sT = setTimeout, B = sT.Book || (sT.Book = function(text){ @@ -210,5 +211,5 @@ function decord(t){ } try{module.exports=B}catch(e){} -}());//delete later. - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/chain.js b/src/chain.js index d8278984f..84f401aa4 100644 --- a/src/chain.js +++ b/src/chain.js @@ -1,3 +1,4 @@ +;(function(){ // WARNING: GUN is very simple, but the JavaScript chaining API around GUN // is complicated and was extremely hard to build. If you port GUN to another @@ -28,6 +29,7 @@ function output(msg){ if(at.lex){ Object.keys(at.lex).forEach(function(k){ tmp[k] = at.lex[k] }, tmp = msg.get = msg.get || {}) } if(get['#'] || at.soul){ get['#'] = get['#'] || at.soul; + //root.graph[get['#']] = root.graph[get['#']] || {_:{'#':get['#'],'>':{}}}; msg['#'] || (msg['#'] = text_rand(9)); // A3120 ? back = (root.$.get(get['#'])._); if(!(get = get['.'])){ // soul @@ -247,4 +249,5 @@ function ack(msg, ev){ } var empty = {}, u, text_rand = String.random, valid = Gun.valid, obj_has = function(o, k){ return o && Object.prototype.hasOwnProperty.call(o, k) }, state = Gun.state, state_is = state.is, state_ify = state.ify; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/core.js b/src/core.js new file mode 100644 index 000000000..3fca93b68 --- /dev/null +++ b/src/core.js @@ -0,0 +1,10 @@ +;(function(){ + +var Gun = require('./root'); +require('./chain'); +require('./back'); +require('./put'); +require('./get'); +module.exports = Gun; + +}()); \ No newline at end of file diff --git a/src/dup.js b/src/dup.js index 8015c5a85..fa500e5e1 100644 --- a/src/dup.js +++ b/src/dup.js @@ -1,3 +1,4 @@ +;(function(){ require('./shim'); function Dup(opt){ @@ -11,6 +12,7 @@ function Dup(opt){ var it = s[id] || (s[id] = {}); it.was = dup.now = +new Date; if(!dup.to){ dup.to = setTimeout(dup.drop, opt.age + 9) } + if(dt.ed){ dt.ed(id) } return it; } dup.drop = function(age){ @@ -26,4 +28,5 @@ function Dup(opt){ return dup; } module.exports = Dup; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/get.js b/src/get.js index a47f72eaf..c1a6b022f 100644 --- a/src/get.js +++ b/src/get.js @@ -1,3 +1,4 @@ +;(function(){ var Gun = require('./root'); Gun.chain.get = function(key, cb, as){ @@ -110,6 +111,7 @@ function cache(key, back){ next[at.get = key] = at; if(back === cat.root.$){ at.soul = key; + //at.put = {}; } else if(cat.soul || cat.has){ at.has = key; @@ -153,4 +155,5 @@ function rid(at){ return; } var empty = {}, valid = Gun.valid, u; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/index.js b/src/index.js index f0cb99725..218919e64 100644 --- a/src/index.js +++ b/src/index.js @@ -1,8 +1,20 @@ +;(function(){ var Gun = require('./root'); -require('./chain'); -require('./back'); -require('./put'); -require('./get'); +require('./shim'); +require('./onto'); +require('./book'); +require('./valid'); +require('./state'); +require('./dup'); +require('./ask'); +require('./core'); +require('./on'); +require('./map'); +require('./set'); +require('./mesh'); +require('./websocket'); +require('./localStorage'); module.exports = Gun; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/localStorage.js b/src/localStorage.js index ff966c907..454e67d7f 100644 --- a/src/localStorage.js +++ b/src/localStorage.js @@ -1,3 +1,4 @@ +;(function(){ if(typeof Gun === 'undefined'){ return } @@ -64,4 +65,5 @@ Gun.on('create', function lg(root){ } }); - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/map.js b/src/map.js index f929c73e5..f6c5f9eb2 100644 --- a/src/map.js +++ b/src/map.js @@ -1,5 +1,6 @@ +;(function(){ -var Gun = require('./index'), next = Gun.chain.get.next; +var Gun = require('./root'), next = Gun.chain.get.next; Gun.chain.get.next = function(gun, lex){ var tmp; if(!Object.plain(lex)){ return (next||noop)(gun, lex) } if(tmp = ((tmp = lex['#'])||'')['='] || tmp){ return gun.get(tmp) } @@ -41,4 +42,5 @@ function map(msg){ this.to.next(msg); Gun.on.link(msg, cat); } var noop = function(){}, event = {stun: noop, off: noop}, u; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/mesh.js b/src/mesh.js index dc0e53703..267096bdf 100644 --- a/src/mesh.js +++ b/src/mesh.js @@ -1,3 +1,4 @@ +;(function(){ require('./shim'); @@ -84,12 +85,17 @@ function Mesh(root){ if(tmp = msg.ok){ msg._.near = tmp['/'] } var S = +new Date; DBG && (DBG.is = S); peer.SI = id; + dup_track.ed = function(d){ + if(id !== d){ return } + dup_track.ed = 0; + if(!(d = dup.s[id])){ return } + d.via = peer; + if(msg.get){ d.it = msg } + } root.on('in', mesh.last = msg); - //ECHO = msg.put || ECHO; !(msg.ok !== -3740) && mesh.say({ok: -3740, put: ECHO, '@': msg['#']}, peer); DBG && (DBG.hd = +new Date); console.STAT && console.STAT(S, +new Date - S, msg.get? 'msg get' : msg.put? 'msg put' : 'msg'); - (tmp = dup_track(id)).via = peer; // don't dedup message ID till after, cause GUN has internal dedup check. - if(msg.get){ tmp.it = msg } + dup_track(id); // in case 'in' does not call track. if(ash){ dup_track(ash) } //dup.track(tmp+hash, true).it = it(msg); mesh.leap = mesh.last = null; // warning! mesh.leap could be buggy. } @@ -129,12 +135,13 @@ function Mesh(root){ !loop && dup_track(id);//.it = it(msg); // track for 9 seconds, default. Earth<->Mars would need more! // always track, maybe move this to the 'after' logic if we split function. //if(msg.put && (msg.err || (dup.s[id]||'').err)){ return false } // TODO: in theory we should not be able to stun a message, but for now going to check if it can help network performance preventing invalid data to relay. if(!(hash = msg['##']) && u !== msg.put && !meta.via && ack){ mesh.hash(msg, peer); return } // TODO: Should broadcasts be hashed? - if(!peer && ack){ peer = ((tmp = dup.s[ack]) && (tmp.via || ((tmp = tmp.it) && (tmp = tmp._) && tmp.via))) || ((tmp = mesh.last) && ack === tmp['#'] && mesh.leap) } // warning! mesh.leap could be buggy! mesh last check reduces this. + if(!peer && ack){ peer = ((tmp = dup.s[ack]) && (tmp.via || ((tmp = tmp.it) && (tmp = tmp._) && tmp.via))) || ((tmp = mesh.last) && ack === tmp['#'] && mesh.leap) } // warning! mesh.leap could be buggy! mesh last check reduces this. // TODO: CLEAN UP THIS LINE NOW? `.it` should be reliable. if(!peer && ack){ // still no peer, then ack daisy chain 'tunnel' got lost. if(dup.s[ack]){ return } // in dups but no peer hints that this was ack to ourself, ignore. console.STAT && console.STAT(+new Date, ++SMIA, 'total no peer to ack to'); // TODO: Delete this now. Dropping lost ACKs is protocol fine now. return false; } // TODO: Temporary? If ack via trace has been lost, acks will go to all peers, which trashes browser bandwidth. Not relaying the ack will force sender to ask for ack again. Note, this is technically wrong for mesh behavior. + if(ack && !msg.put && !hash && ((dup.s[ack]||'').it||'')['##']){ return false } // If we're saying 'not found' but a relay had data, do not bother sending our not found. // Is this correct, return false? // NOTE: ADD PANIC TEST FOR THIS! if(!peer && mesh.way){ return mesh.way(msg) } DBG && (DBG.yh = +new Date); if(!(raw = meta.raw)){ mesh.raw(msg, peer); return } @@ -195,7 +202,7 @@ function Mesh(root){ var hash = msg['##'], ack = msg['@']; if(hash && ack){ if(!meta.via && dup_check(ack+hash)){ return false } // for our own out messages, memory & storage may ack the same thing, so dedup that. Tho if via another peer, we already tracked it upon hearing, so this will always trigger false positives, so don't do that! - if((tmp = (dup.s[ack]||'').it) || ((tmp = mesh.last) && ack === tmp['#'])){ + if(tmp = (dup.s[ack]||'').it){ if(hash === tmp['##']){ return false } // if ask has a matching hash, acking is optional. if(!tmp['##']){ tmp['##'] = hash } // if none, add our hash to ask so anyone we relay to can dedup. // NOTE: May only check against 1st ack chunk, 2nd+ won't know and still stream back to relaying peers which may then dedup. Any way to fix this wasted bandwidth? I guess force rate limiting breaking change, that asking peer has to ask for next lexical chunk. } @@ -343,4 +350,5 @@ function Mesh(root){ try{ module.exports = Mesh }catch(e){} - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/on.js b/src/on.js index c2fc13865..4731a4792 100644 --- a/src/on.js +++ b/src/on.js @@ -1,5 +1,6 @@ +;(function(){ -var Gun = require('./index'); +var Gun = require('./root'); Gun.chain.on = function(tag, arg, eas, as){ // don't rewrite! var gun = this, cat = gun._, root = cat.root, act, off, id, tmp; if(typeof tag === 'string'){ @@ -103,6 +104,10 @@ Gun.chain.off = function(){ } } // TODO: delete cat.one[map.id]? + if (tmp = cat.any) { + delete cat.any; + cat.any = {}; + } if(tmp = cat.ask){ delete tmp[at.get]; } @@ -128,4 +133,5 @@ Gun.chain.off = function(){ return gun; } var empty = {}, noop = function(){}, u; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/onto.js b/src/onto.js index e510e1658..dbfc54490 100644 --- a/src/onto.js +++ b/src/onto.js @@ -1,3 +1,4 @@ +;(function(){ // On event emitter generic javascript utility. module.exports = function onto(tag, arg, as){ @@ -33,4 +34,5 @@ module.exports = function onto(tag, arg, as){ if((tag = tag.to) && u !== arg){ tag.next(arg) } return tag; }; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/put.js b/src/put.js index d0c955533..6caa43629 100644 --- a/src/put.js +++ b/src/put.js @@ -1,3 +1,4 @@ +;(function(){ var Gun = require('./root'); Gun.chain.put = function(data, cb, as){ // I rewrote it :) @@ -152,4 +153,5 @@ function check(d, tmp){ return ((d && (tmp = d.constructor) && tmp.name) || type var u, empty = {}, noop = function(){}, turn = setTimeout.turn, valid = Gun.valid, state_ify = Gun.state.ify; var iife = function(fn,as){fn.call(as||empty)} - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/root.js b/src/root.js index f0ef4c030..6ad0a7a4f 100644 --- a/src/root.js +++ b/src/root.js @@ -1,3 +1,4 @@ +;(function(){ function Gun(o){ @@ -201,6 +202,9 @@ Gun.ask = require('./ask'); Gun.on.get = function(msg, gun){ var root = gun._, get = msg.get, soul = get['#'], node = root.graph[soul], has = get['.']; var next = root.next || (root.next = {}), at = next[soul]; + + // TODO: Azarattum bug, what is in graph is not same as what is in next. Fix! + // queue concurrent GETs? // TODO: consider tagging original message into dup for DAM. // TODO: ^ above? In chat app, 12 messages resulted in same peer asking for `#user.pub` 12 times. (same with #user GET too, yipes!) // DAM note: This also resulted in 12 replies from 1 peer which all had same ##hash but none of them deduped because each get was different. @@ -221,10 +225,14 @@ Gun.ask = require('./ask'); }*/ var ctx = msg._||{}, DBG = ctx.DBG = msg.DBG; DBG && (DBG.g = +new Date); - //console.log("GET:", get, node, has); + //console.log("GET:", get, node, has, at); + //if(!node && !at){ return root.on('get', msg) } + //if(has && node){ // replace 2 below lines to continue dev? if(!node){ return root.on('get', msg) } if(has){ - if('string' != typeof has || u === node[has]){ return root.on('get', msg) } + if('string' != typeof has || u === node[has]){ + if(!((at||'').next||'')[has]){ root.on('get', msg); return } + } node = state_ify({}, has, state_is(node, has), node[has], soul); // If we have a key in-memory, do we really need to fetch? // Maybe... in case the in-memory key we have is a local write @@ -301,4 +309,5 @@ module.exports = Gun; ;"Please do not remove welcome log unless you are paying for a monthly sponsorship, thanks!"; Gun.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!"); - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/set.js b/src/set.js index 36a7cb255..e07bc75f3 100644 --- a/src/set.js +++ b/src/set.js @@ -1,5 +1,6 @@ +;(function(){ -var Gun = require('./index'); +var Gun = require('./root'); Gun.chain.set = function(item, cb, opt){ var gun = this, root = gun.back(-1), soul, tmp; cb = cb || function(){}; @@ -20,4 +21,5 @@ Gun.chain.set = function(item, cb, opt){ }) return item; } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/shim.js b/src/shim.js index 59963495a..c77947d16 100644 --- a/src/shim.js +++ b/src/shim.js @@ -1,3 +1,4 @@ +;(function(){ // Shim for generic javascript utilities. String.random = function(l, c){ @@ -82,4 +83,5 @@ Object.keys = Object.keys || function(o){ } e && e(r); }())})(); }()); - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/state.js b/src/state.js index 542a4c71f..a72555eb8 100644 --- a/src/state.js +++ b/src/state.js @@ -1,3 +1,4 @@ +;(function(){ require('./shim'); function State(){ @@ -25,4 +26,5 @@ State.ify = function(n, k, s, v, soul){ // put a key's state on a node. return n; } module.exports = State; - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/valid.js b/src/valid.js index 84d21990e..098497c8e 100644 --- a/src/valid.js +++ b/src/valid.js @@ -1,9 +1,10 @@ +;(function(){ // Valid values are a subset of JSON: null, binary, number (!Infinity), text, // or a soul relation. Arrays need special algorithms to handle concurrency, // so they are not supported directly. Use an extension that supports them if // needed but research their problems first. -module.exports = function (v) { +module.exports = function(v){ // "deletes", nulling out keys. return v === null || "string" === typeof v || @@ -13,4 +14,5 @@ module.exports = function (v) { ("number" === typeof v && v != Infinity && v != -Infinity && v === v) || (!!v && "string" == typeof v["#"] && Object.keys(v).length === 1 && v["#"]); } - \ No newline at end of file + +}()); \ No newline at end of file diff --git a/src/websocket.js b/src/websocket.js index ee3531df4..67d6d6cde 100644 --- a/src/websocket.js +++ b/src/websocket.js @@ -1,5 +1,6 @@ +;(function(){ -var Gun = require('./index'); +var Gun = require('./root'); Gun.Mesh = require('./mesh'); // TODO: resync upon reconnect online/offline @@ -57,4 +58,5 @@ Gun.on('opt', function(root){ var doc = (''+u !== typeof document) && document; }); var noop = function(){}, u; - \ No newline at end of file + +}()); \ No newline at end of file