This commit is contained in:
Mark Nadal 2017-01-21 22:06:56 -08:00
parent 9002593435
commit 377fa7900f
2 changed files with 67 additions and 40 deletions

77
gun.js
View File

@ -939,8 +939,11 @@
} }
function get(at, cat){ function get(at, cat){
var soul = at.get[_soul], node = cat.graph[soul], field = at.get[_field], tmp; var soul = at.get[_soul], node = cat.graph[soul], field = at.get[_field], tmp;
if(!node){ return }
var next = cat.next || (cat.next = {}), as = (next[soul] || (next[soul] = cat.gun.get(soul)))._; var next = cat.next || (cat.next = {}), as = (next[soul] || (next[soul] = cat.gun.get(soul)))._;
if(!node){
as.ask = 1;
return;
}
if(field){ if(field){
if(!obj_has(node, field)){ return } if(!obj_has(node, field)){ return }
tmp = Gun.obj.put(Gun.node.soul.ify({}, soul), field, node[field]); tmp = Gun.obj.put(Gun.node.soul.ify({}, soul), field, node[field]);
@ -1158,8 +1161,6 @@
/*if(cat.field && (tmp = back.map)){ /*if(cat.field && (tmp = back.map)){
tmp.on('in', obj_to(at, {get: cat.get, gun: cat.gun})); tmp.on('in', obj_to(at, {get: cat.get, gun: cat.gun}));
} else*/ } else*/
console.debug(3, 'in', cat.get, at.put, cat.maps, cat.next);
console.debug(2, 'in', cat.get, at.put, cat.maps, cat.next);
if(cat.maps){ if(cat.maps){
var proxy = obj_to(at, {get: cat.get, gun: cat.gun}); // TODO: BUG! Broken via! var proxy = obj_to(at, {get: cat.get, gun: cat.gun}); // TODO: BUG! Broken via!
obj_map(cat.maps, function(cat){ obj_map(cat.maps, function(cat){
@ -1177,8 +1178,9 @@
if(cat.soul){ if(cat.soul){
return; return;
} }
// TODO: At some point be compatible with non-gun specific data.
if(u === put){ if(u === put){
if(cat === coat){ if(cat.field){
not(cat, at); not(cat, at);
} else { } else {
Gun.obj.del(coat.maps, cat.id); Gun.obj.del(coat.maps, cat.id);
@ -1196,44 +1198,51 @@
} }
}*/ }*/
if(Gun.val.is(put)){ if(Gun.val.is(put)){
if(cat === coat){ if(cat.field){
not(cat, at); not(cat, at);
} else { } else {
(coat.maps || (coat.maps = {}))[cat.id] = cat; (coat.maps || (coat.maps = {}))[cat.id] = cat;
(cat.mapped || (cat.mapped = {}))[coat.id] = coat; (cat.mapped || (cat.mapped = {}))[coat.id] = coat;
if(u === coat.put){ ev.stun() } // Let coat's event retrigger the map if(u === coat.put){ ev.stun() } // If we have it but coat does not, that means we got things out of order and coat will get it. Once coat gets it, it will tell us again.
} }
return true; return true;
} }
if(coat.soul && cat.field){ if(cat.field){
cat.put = coat.put; if(coat.soul){
} cat.put = coat.put;
if(coat.field && u === coat.put || Gun.val.rel.is(coat.put)){ // just in case a `map` beats the field. }
coat.put = at.put; } else
if(coat.field){
if(tmp = Gun.node.soul(put)){
coat.put = (cat.root.get(tmp)._).put;
} else {
// TODO: At some point be compatible with non-gun specific data.
}
} }
return; return;
}; };
if(coat !== cat){ if(coat !== cat){
(coat.maps || (coat.maps = {}))[cat.id] = cat; (coat.maps || (coat.maps = {}))[cat.id] = cat;
(cat.mapped || (cat.mapped = {}))[coat.id] = coat; (cat.mapped || (cat.mapped = {}))[coat.id] = coat;
if(coat.proxy){
//return true;
}
} }
if(coat.proxy){ if(coat.proxy){
if(rel === coat.proxy.rel){ if(rel === coat.proxy.rel){
ev.stun(); ev.stun();
//ask(cat, rel); // In the use cases so far, it is important that this is commented out and therefore not used! Test 'uncached synchronous map on mutate', so if at any point you are working through the tests and need to uncomment it that suggests there is a point where an already present chain with the same relation hasn't/wasn't able to load the asked for children. Because currently with it commented out (if it weren't) it produces false positive undefineds to children - which if we need to have this uncommented, we might be able to find a logical case where we can detect that those are unnecessary (perhaps by checking the at.put value). //ask(cat, rel); // In the use cases so far, it is important that this is commented out and therefore not used! Test 'uncached synchronous map on mutate', so if at any point you are working through the tests and need to uncomment it that suggests there is a point where an already present chain with the same relation hasn't/wasn't able to load the asked for children. Because currently with it commented out (if it weren't) it produces false positive undefineds to children - which if we need to have this uncommented, we might be able to find a logical case where we can detect that those are unnecessary (perhaps by checking the at.put value).
tmp = coat.proxy.ref._; tmp = coat.proxy.ref;
at.put = coat.put = tmp.put; if(obj_has(tmp, 'put')){
coat.put = tmp.put;
}
return true; return true;
} }
not(coat, at); not(coat, at);
} }
coat.proxy = {rel: rel, ref: coat.root.get(rel)}; coat.proxy = {rel: rel, ref: (tmp = coat.root.get(rel)._)};
coat.proxy.sub = (tmp = coat.proxy.ref._).on('in', input, coat); // TODO: BUG!!! If you have disabled the event system itself handling promise/observable then you might have to do some manual work here. FIXED? With below `put` check. Note: Most everything else in this values function seems to be rock solid. coat.proxy.sub = tmp.on('in', input, coat); // TODO: BUG!!! If you have disabled the event system itself handling promise/observable then you might have to do some manual work here. FIXED? With below `put` check. Note: Most everything else in this values function seems to be rock solid.
if(obj_has(tmp, 'put')){ if(obj_has(tmp, 'put')){
coat.put = tmp.put; // TODO: BUG? We might want to retrigger ourselves to hit maps? I am pretty sure that if this has observable behavior we need to re-trigger. Note: Most everything else in this values function seems to be rock solid. coat.put = tmp.put; // TODO: BUG? We might want to retrigger ourselves to hit maps? I am pretty sure that if this has observable behavior we need to re-trigger. Note: Most everything else in this values function seems to be rock solid.
// consider `gun.get('users').map().path('foo').on(cb)` followed by `gun.put(GRAPH)`?
// fairly confident this needs to re-trigger.
} }
tmp = coat.put; tmp = coat.put;
ask(cat, rel); ask(cat, rel);
@ -1281,31 +1290,31 @@
at.put = u; at.put = u;
} }
at.on('in', { at.on('in', {
via: at, // TODO: BUG? mismatching scope?
get: key, get: key,
put: u,
gun: gun, gun: gun,
via: at // TODO: BUG? mismatching scope? put: u
}) });
}); });
} }
function ask(cat, soul){ function ask(cat, soul){
var tmp; var tmp;
if(cat.ask){ if(cat.ask){
if(0 >= cat.ask){ return } if(0 >= cat.ask){ return }
tmp = cat.root.get(soul); tmp = cat.root.get(soul)._;
tmp._.on('out', { tmp.on('out', {
get: {'#': soul}, get: {'#': soul},
gun: tmp, '#': Gun.on.ask(Gun.HAM.synth, tmp.gun),
'#': Gun.on.ask(Gun.HAM.synth, tmp) gun: tmp.gun
}); });
return; return;
} }
if(0 === cat.ask){ return } if(0 === cat.ask){ return }
obj_map(cat.next, function(gun, key){ obj_map(cat.next, function(gun, key){
gun._.on('out', { (gun._).on('out', {
get: {'#': soul, '.': key}, get: {'#': soul, '.': key},
gun: gun, '#': Gun.on.ask(Gun.HAM.synth, gun),
'#': Gun.on.ask(Gun.HAM.synth, gun) gun: gun
}); });
}); });
} }
@ -1690,9 +1699,10 @@
Gun.HAM.synth = function(at, ev){ var gun = this; Gun.HAM.synth = function(at, ev){ var gun = this;
var cat = gun._, root = cat.root._, put = {}, tmp; var cat = gun._, root = cat.root._, put = {}, tmp;
if(!at.put){ if(!at.put){
if(obj_has(cat, 'put')){ return }
cat.on('in', { cat.on('in', {
get: cat.get, get: cat.get,
put: cat.put = u, put: cat.put,
gun: gun, gun: gun,
via: at via: at
}) })
@ -1712,7 +1722,6 @@
Gun.HAM.synth.call(cat.gun, at, ev) Gun.HAM.synth.call(cat.gun, at, ev)
return; return;
} }
console.debug(1, '->', soul, node);
gun._.on('in', { gun._.on('in', {
put: node, put: node,
get: soul, get: soul,
@ -1980,11 +1989,11 @@
if(opt.change){ if(opt.change){
data = at.put; data = at.put;
} }
// DEDUPLICATE // DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE
if(tmp.put === data && tmp.get === id){ return } if(tmp.put === data && tmp.get === id && !Gun.node.soul(data)){ return }
tmp.put = data; tmp.put = data;
tmp.get = id; tmp.get = id;
// DEDUPLICATE // DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE
cat.last = data; cat.last = data;
if(opt.as){ if(opt.as){
opt.ok.call(opt.as, at, ev); opt.ok.call(opt.as, at, ev);
@ -2182,7 +2191,7 @@
if(Gun.obj.has(lex, '.')){var tmp = data[lex['.']];data = {_: data._};if(u !== tmp){data[lex['.']] = tmp}} if(Gun.obj.has(lex, '.')){var tmp = data[lex['.']];data = {_: data._};if(u !== tmp){data[lex['.']] = tmp}}
//console.log('@@@@@@@@@@@@local get', data, at); //console.log('@@@@@@@@@@@@local get', data, at);
gun.back(-1).on('in', {'@': at['#'], put: Gun.graph.node(data)}); gun.back(-1).on('in', {'@': at['#'], put: Gun.graph.node(data)});
//},100); //},11);
} }
Gun.on('put', put); Gun.on('put', put);
Gun.on('get', get); Gun.on('get', get);

View File

@ -1710,14 +1710,18 @@ describe('Gun', function(){
pet: {b:2, name: "Frisky"} pet: {b:2, name: "Frisky"}
} }
}, s)}); }, s)});
var check = {}; var check = {}, count = {};
gun.get('u/m/mutate/n/u').map().on(function(v,f){ gun.get('u/m/mutate/n/u').map().on(function(v,f){
check[v.name] = f; check[v.name] = f;
count[v.name] = (count[v.name] || 0) + 1;
//console.log("*****************", f,v); //console.log("*****************", f,v);
if(check.Alice && check.Bob && check['Alice Zzxyz']){ if(check.Alice && check.Bob && check['Alice Zzxyz']){
setTimeout(function(){ setTimeout(function(){
expect(done.last).to.be.ok(); expect(done.last).to.be.ok();
expect(check['Alice Aabca']).to.not.be.ok(); expect(check['Alice Aabca']).to.not.be.ok();
expect(count['Alice']).to.be(1);
expect(count['Bob']).to.be(1);
expect(count['Alice Zzxyz']).to.be(1);
done(); done();
},100); },100);
} }
@ -1761,15 +1765,20 @@ describe('Gun', function(){
pet: {b:2, name: "Frisky"} pet: {b:2, name: "Frisky"}
} }
}, s)}); }, s)});
var check = {}; var check = {}, count = {};
gun.get('u/m/p/mutate/n/u').map().path('name').on(function(v,f){ gun.get('u/m/p/mutate/n/u').map().path('name').on(function(v,f){
check[v] = f; check[v] = f;
count[v] = (count[v] || 0) + 1;
//console.log("*************", f,v);
if(check.Alice && check.Bob && check['Alice Zzxyz']){ if(check.Alice && check.Bob && check['Alice Zzxyz']){
setTimeout(function(){ setTimeout(function(){
var a = Gun.obj.map(gun._.graph['u/m/p/m/n/u/soul'], function(v,f,t){t(v)}); var a = Gun.obj.map(gun._.graph['u/m/p/m/n/u/soul'], function(v,f,t){t(v)});
expect(a.length).to.be(2); expect(a.length).to.be(2);
expect(done.last).to.be.ok(); expect(done.last).to.be.ok();
expect(check['Alice Aabca']).to.not.be.ok(); expect(check['Alice Aabca']).to.not.be.ok();
expect(count.Alice).to.be(1);
expect(count.Bob).to.be(1);
expect(count['Alice Zzxyz']).to.be(1);
done(); done();
},100); },100);
} }
@ -1805,13 +1814,18 @@ describe('Gun', function(){
pet: {b:2, name: "Frisky"} pet: {b:2, name: "Frisky"}
} }
}, s)}); }, s)});
var check = {}; var check = {}, count = {};
gun.get('u/m/p/n/mutate/n/u').map().path('pet').on(function(v,f){ gun.get('u/m/p/n/mutate/n/u').map().path('pet').on(function(v,f){
check[v.name] = f; check[v.name] = f;
count[v.name] = (count[v.name] || 0) + 1;
//console.log("*****************", f,v);
if(check.Fluffy && check.Frisky && check.Fuzzball){ if(check.Fluffy && check.Frisky && check.Fuzzball){
setTimeout(function(){ setTimeout(function(){
expect(done.last).to.be.ok(); expect(done.last).to.be.ok();
expect(check['Fluffs']).to.not.be.ok(); expect(check['Fluffs']).to.not.be.ok();
expect(count.Fluffy).to.be(1);
expect(count.Frisky).to.be(1);
expect(count.Fuzzball).to.be(1);
done(); done();
},100); },100);
} }
@ -1837,13 +1851,17 @@ describe('Gun', function(){
it("get before put in memory", function(done){ it("get before put in memory", function(done){
var gun = Gun(); var gun = Gun();
var check = {}; var check = {};
var count = {};
gun.get('g/n/m/f/l/n/r').map().on(function(v,f){ gun.get('g/n/m/f/l/n/r').map().on(function(v,f){
console.log("***********", f,v); console.log("***********", f,v);
check[f] = v; check[f] = v;
count[f] = (count[f] || 0) + 1;
if(check.alice && check.bob && check.alice.PhD){ if(check.alice && check.bob && check.alice.PhD){
expect(check.alice.age).to.be(24); expect(check.alice.age).to.be(24);
expect(check.bob.age).to.be(26); expect(check.bob.age).to.be(26);
expect(check.alice.PhD).to.be(true); expect(check.alice.PhD).to.be(true);
expect(count.alice).to.be(2);
expect(count.bob).to.be(1);
done(); done();
} }
}); });
@ -1873,7 +1891,6 @@ describe('Gun', function(){
} }
}); });
setTimeout(function(){ setTimeout(function(){
console.debug.i=1;console.log("----------");
gun.get('GALICE1').put({PhD: true}); gun.get('GALICE1').put({PhD: true});
},300); },300);
}); });
@ -1913,6 +1930,7 @@ describe('Gun', function(){
gun.get('users').path('alice').on(cb); gun.get('users').path('alice').on(cb);
}) })
*/ */
return;
it("in memory get after", function(done){ it("in memory get after", function(done){
console.debug.i=1;console.log("-----------------------------"); console.debug.i=1;console.log("-----------------------------");
var gun = Gun(); var gun = Gun();
@ -1942,7 +1960,7 @@ describe('Gun', function(){
} }
}); });
var check = {}; var check = {};
gun.get('g/n/m/f/l/n').path('bob.spouse.work').on(function(v,f){ console.log("!!!!!!!!!", f, v);});return; //gun.get('g/n/m/f/l/n').path('bob.spouse.work').on(function(v,f){ console.log("!!!!!!!!!", f, v);});return;
gun.get('g/n/m/f/l/n').map().on(function(v,f){ gun.get('g/n/m/f/l/n').map().on(function(v,f){
check[f] = v; check[f] = v;
console.log("*******************", f, v); console.log("*******************", f, v);