map chain

This commit is contained in:
Mark Nadal 2015-06-08 21:27:33 -07:00
parent 45122b5d9a
commit 5b2c0477a1
3 changed files with 99 additions and 32 deletions

66
gun.js
View File

@ -364,40 +364,42 @@
Things that wait and merge many things together should be an abstraction ontop of path.
*/
Chain.path = function(path, cb){
var gun = this.chain(), ctx = {};
var gun = this.chain();
cb = cb || function(){};
path = (Gun.text.ify(path) || '').split('.');
// TODO: Hmmm once also? figure it out later.
gun.back._.status('node').event(function trace($){ // TODO: Check for field as well and merge?
var node = gun.__.graph[$.soul], field = Gun.text.ify(path.shift()), val;
if(path.length){
gun.back._.status('node').event(function($){
var ctx = {path: (Gun.text.ify(path) || '').split('.')};
(function trace($){ // TODO: Check for field as well and merge?
var node = gun.__.graph[$.soul], field = Gun.text.ify(ctx.path.shift()), val;
if(ctx.path.length){
if(Gun.is.soul(val = node[field])){
gun.get(val, function(err, data){
if(err){ return cb.call(gun, err, data) }
if(!data){ return cb.call(gun, null) }
trace({soul: Gun.is.soul.on(data)});
});
} else {
cb.call(gun, null);
}
} else
if(!Gun.obj.has(node, field)){ // TODO: THIS MAY NOT BE CORRECT BEHAVIOR!!!!
cb.call(gun, null, null, field);
gun._.on('soul').emit({soul: $.soul, field: field}); // if .put is after, makes sense. If anything else, makes sense to wait.
gun._.on('node').emit({soul: $.soul, field: field});
} else
if(Gun.is.soul(val = node[field])){
gun.get(val, function(err, data){
if(err){ return cb.call(gun, err, data) }
if(!data){ return cb.call(gun, null) }
trace({soul: Gun.is.soul.on(data)});
cb.call(gun, err, data); // TODO: Should we attach field here, does map?
if(err || !data){ return }
gun._.on('node').emit({soul: Gun.is.soul(val)});
});
gun._.on('soul').emit({soul: Gun.is.soul(val), field: null, from: $.soul, at: field});
} else {
cb.call(gun, null);
cb.call(gun, null, val, field);
gun._.on('soul').emit({soul: $.soul, field: field});
gun._.on('node').emit({soul: $.soul, field: field});
}
} else
if(!Gun.obj.has(node, field)){ // TODO: THIS MAY NOT BE CORRECT BEHAVIOR!!!!
cb.call(gun, null, null, field);
gun._.on('soul').emit({soul: $.soul, field: field}); // if .put is after, makes sense. If anything else, makes sense to wait.
gun._.on('node').emit({soul: $.soul, field: field});
} else
if(Gun.is.soul(val = node[field])){
gun.get(val, function(err, data){
cb.call(gun, err, data);
if(err || !data){ return }
gun._.status('node').emit({soul: Gun.is.soul(val)});
});
gun._.on('soul').emit({soul: Gun.is.soul(val), field: null, from: $.soul, at: field});
} else {
cb.call(gun, null, val, field);
gun._.on('soul').emit({soul: $.soul, field: field});
gun._.on('node').emit({soul: $.soul, field: field});
}
}($));
});
return gun;
@ -520,18 +522,20 @@
return gun;
}
Chain.map = function(cb, opt){
var gun = this, ctx = {};
var gun = this.chain();
opt = (Gun.obj.is(opt)? opt : (opt? {node: true} : {}));
cb = cb || function(){};
gun._.status('node').event(function($){
gun.back._.status('node').event(function($){
var node = gun.__.graph[$.soul];
Gun.obj.map(node, function(val, field){
if(Gun._.meta == field){ return }
if(Gun.is.soul(val)){
gun.get(val).val(function(val){ // should map have support for `.not`?
cb.call(this, val, field);
gun.get(val).val(function(node){ // TODO: should map have support for `.not`? error?
cb.call(this, node, field); // TODO: Should this be NodeJS style or not?
gun._.on('node').emit({soul: Gun.is.soul(val)}); // TODO: Same as above, include field?
});
gun._.on('soul').emit({soul: Gun.is.soul(val), field: null, from: $.soul, at: field});
} else {
if(opt.node){ return } // {node: true} maps over only sub nodes.
cb.call(gun, val, field);

64
test/chain.js Normal file
View File

@ -0,0 +1,64 @@
var expect = global.expect = require("./expect");
var Gun = Gun || require('../gun');
describe('All', function(){
var gun = Gun();
it('map chain', function(done){
var c = 0, map = gun.put({a: {here: 'you'}, b: {go: 'dear'}, c: {sir: '!'} });
map.map().val(function(obj, field){
c++;
if(field === 'a'){
done.a = obj.here;
expect(obj.here).to.be('you');
}
if(field === 'b'){
done.b = obj.go;
expect(obj.go).to.be('dear');
}
if(field === 'c'){
done.c = obj.sir;
expect(obj.sir).to.be('!');
}
if(c === 3){
done();
}
});
});
it('map chain path', function(done){
var c = 0, map = gun.put({
a: {name: "Mark",
pet: {coat: "tabby", name: "Hobbes"}
}, b: {name: "Alice",
pet: {coat: "calico", name: "Cali"}
},c: {name: "Bob",
pet: {coat: "tux", name: "Casper"}
}
});
map.map().path('pet').val(function(obj, field){
console.log('test', obj, field);
c++;
if(obj.name === 'Hobbes'){
done.hobbes = obj.name;
expect(obj.name).to.be('Hobbes');
expect(obj.coat).to.be('tabby');
}
if(obj.name === 'Cali'){
done.cali = obj.name;
expect(obj.name).to.be('Cali');
expect(obj.coat).to.be('calico');
}
if(obj.name === 'Casper'){
done.casper = obj.name;
expect(obj.name).to.be('Casper');
expect(obj.coat).to.be('tux');
}
if(done.hobbes && done.cali && done.casper){
done();
}
});
});
});

View File

@ -1,7 +1,6 @@
var expect = global.expect = require("./expect");
var Gun = Gun || require('../gun');
Gun.log.verbose = true;
(typeof window === 'undefined') && require('../lib/file');
describe('All', function(){