mirror of
https://github.com/amark/gun.git
synced 2025-10-14 00:59:35 +00:00
put recursive once on map
This commit is contained in:
parent
69c476e74b
commit
921000adc2
220
gun.js
220
gun.js
@ -279,7 +279,6 @@
|
|||||||
if(dup.check(tmp)){ return } dup.track(tmp);
|
if(dup.check(tmp)){ return } dup.track(tmp);
|
||||||
tmp = msg._; msg._ = ('function' == typeof tmp)? tmp : function(){};
|
tmp = msg._; msg._ = ('function' == typeof tmp)? tmp : function(){};
|
||||||
(msg.$ && (msg.$ === (msg.$._||'').$)) || (msg.$ = gun);
|
(msg.$ && (msg.$ === (msg.$._||'').$)) || (msg.$ = gun);
|
||||||
console.only(2, 'uni', msg);
|
|
||||||
if(msg['@'] && !msg.put){ ack(msg) }
|
if(msg['@'] && !msg.put){ ack(msg) }
|
||||||
if(!at.ask(msg['@'], msg)){ // is this machine listening for an ack?
|
if(!at.ask(msg['@'], msg)){ // is this machine listening for an ack?
|
||||||
DBG && (DBG.u = +new Date);
|
DBG && (DBG.u = +new Date);
|
||||||
@ -302,7 +301,7 @@
|
|||||||
}*/
|
}*/
|
||||||
var put = msg.put;
|
var put = msg.put;
|
||||||
var DBG = ctx.DBG = msg.DBG;
|
var DBG = ctx.DBG = msg.DBG;
|
||||||
if(put['#'] && put['.']){ root.on('put', msg); return } // TODO: BUG! This needs to call HAM instead.
|
if(put['#'] && put['.']){ root && root.on('put', msg); return } // TODO: BUG! This needs to call HAM instead.
|
||||||
DBG && (DBG.p = S);
|
DBG && (DBG.p = S);
|
||||||
ctx['#'] = msg['#'];
|
ctx['#'] = msg['#'];
|
||||||
ctx.msg = msg;
|
ctx.msg = msg;
|
||||||
@ -314,7 +313,8 @@
|
|||||||
if(nj != ni){ nj = ni;
|
if(nj != ni){ nj = ni;
|
||||||
if(!(soul = nl[ni])){
|
if(!(soul = nl[ni])){
|
||||||
ctx.stun--; // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.
|
ctx.stun--; // TODO: 'forget' feature in SEA tied to this, bad approach, but hacked in for now. Any changes here must update there.
|
||||||
fire(ctx);
|
ctx.hatch && ctx.hatch(); // TODO: rename/rework how put & this interact.
|
||||||
|
//fire(ctx); // ABC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!(node = put[soul])){ err = ERR+cut(soul)+"no node." } else
|
if(!(node = put[soul])){ err = ERR+cut(soul)+"no node." } else
|
||||||
@ -681,25 +681,37 @@
|
|||||||
function input(msg){
|
function input(msg){
|
||||||
// manhattan:
|
// manhattan:
|
||||||
var eve = this, cat = eve.as, root = cat.root, gun = msg.$ || (msg.$ = cat.$), at = (gun||'')._ || empty, tmp = msg.put||'', soul = tmp['#'], key = tmp['.'], change = tmp['=']||tmp[':'], state = tmp['>'] || -Infinity, link, sat;
|
var eve = this, cat = eve.as, root = cat.root, gun = msg.$ || (msg.$ = cat.$), at = (gun||'')._ || empty, tmp = msg.put||'', soul = tmp['#'], key = tmp['.'], change = tmp['=']||tmp[':'], state = tmp['>'] || -Infinity, link, sat;
|
||||||
|
|
||||||
if(tmp && tmp._ && tmp._['#']){ // convert from old format
|
if(tmp && tmp._ && tmp._['#']){ // convert from old format
|
||||||
return setTimeout.each(Object.keys(tmp).sort(), function(k){
|
return setTimeout.each(Object.keys(tmp).sort(), function(k){
|
||||||
if('_' == k || !(state = state_is(tmp, k))){ return }
|
if('_' == k || !(state = state_is(tmp, k))){ return }
|
||||||
cat.on('in', {put: {'#': tmp._['#'], '.': k, ':': tmp[k], '>': state}});
|
cat.on('in', {put: {'#': tmp._['#'], '.': k, ':': tmp[k], '>': state}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
//console.log("howza?", cat.soul, cat.has, cat.id, (msg.seen||'')[cat.id]);
|
|
||||||
if((msg.seen||'')[cat.id]){ return } (msg.seen || (msg.seen = function(){}))[cat.id] = cat;
|
if((msg.seen||'')[cat.id]){ return } (msg.seen || (msg.seen = function(){}))[cat.id] = cat;
|
||||||
|
|
||||||
if(cat.ask && key){
|
if(cat.ask && key){
|
||||||
if(cat.soul && state >= state_is(root.graph[soul], key)){ // faster than HAM
|
if(cat.soul && state >= state_is(root.graph[soul], key)){ // faster than HAM
|
||||||
cat.put = state_ify(cat.put, key, state, change, soul);
|
cat.put = state_ify(cat.put, key, state, change, soul);
|
||||||
}
|
}
|
||||||
if(cat.has && state >= state_is(root.graph[soul], key)){ // faster than HAM
|
if(cat.has && at.soul){
|
||||||
|
cat.put = at.put;
|
||||||
|
} else
|
||||||
|
if(cat.has && at === cat && state >= state_is(root.graph[soul], key)){ // faster than HAM
|
||||||
cat.put = change;
|
cat.put = change;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cat.soul && at === cat){ // (1) we're a root node chain.
|
||||||
|
} else
|
||||||
|
if(cat.has && at === cat){ // (2)
|
||||||
|
} else
|
||||||
|
if(cat.has && at.soul){ // (3) we're a proxy for a root node.
|
||||||
|
Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] }, tmp = {});
|
||||||
|
tmp.get = cat.has; tmp.$ = cat.$; tmp.$$ = at; msg = tmp;
|
||||||
|
} else {}
|
||||||
|
|
||||||
eve.to.next(msg); // 1st API job is to call all the listeners.
|
eve.to.next(msg); // 1st API job is to call all the listeners.
|
||||||
//if(cat !== at && !(at = at.next[key])){ atnextkey; return }
|
|
||||||
//if(!(state < at.state)){ at.state = state } // invert logic cause NaN falses. // TODO: BUG: prevent async errors
|
|
||||||
setTimeout.each(Object.keys(cat.act||''), function(act){ // 1st API job is to call all chain listeners.
|
setTimeout.each(Object.keys(cat.act||''), function(act){ // 1st API job is to call all chain listeners.
|
||||||
(act = cat.act[act]) && act(msg);
|
(act = cat.act[act]) && act(msg);
|
||||||
},0,99);
|
},0,99);
|
||||||
@ -707,6 +719,7 @@
|
|||||||
if(!(lat = cat.echo[lat])){ return }
|
if(!(lat = cat.echo[lat])){ return }
|
||||||
lat.on('in', msg);
|
lat.on('in', msg);
|
||||||
},0,99);
|
},0,99);
|
||||||
|
|
||||||
if(u === change){ // 1st edge case: If we have a brand new database, no data will be found.
|
if(u === change){ // 1st edge case: If we have a brand new database, no data will be found.
|
||||||
cat.put = u; // empty out the cache if, for example, alice's car's color no longer exists (relative to alice) if alice no longer has a car.
|
cat.put = u; // empty out the cache if, for example, alice's car's color no longer exists (relative to alice) if alice no longer has a car.
|
||||||
delete cat.link; // TODO: Empty out links, maps, echos, acks/asks, etc.?
|
delete cat.link; // TODO: Empty out links, maps, echos, acks/asks, etc.?
|
||||||
@ -716,7 +729,6 @@
|
|||||||
},0,99);
|
},0,99);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(at.soul){
|
if(at.soul){
|
||||||
if((sat = cat.next) && (sat = sat[key])){
|
if((sat = cat.next) && (sat = sat[key])){
|
||||||
tmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] }); tmp.$ = sat.$;
|
tmp = {}; Object.keys(msg).forEach(function(k){ tmp[k] = msg[k] }); tmp.$ = sat.$;
|
||||||
@ -724,7 +736,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if('string' == typeof (link = valid(change))){
|
if('string' == typeof (link = valid(change))){
|
||||||
if(cat.has){
|
if((cat.has && at === cat)){
|
||||||
sat = root.$.get(cat.link = link)._; // grab what we're linking to.
|
sat = root.$.get(cat.link = link)._; // grab what we're linking to.
|
||||||
if((sat.echo || (sat.echo = {}))[cat.id]){ return } // we've already added ourself.
|
if((sat.echo || (sat.echo = {}))[cat.id]){ return } // we've already added ourself.
|
||||||
sat.echo[cat.id] = cat; // add ourselves to it.
|
sat.echo[cat.id] = cat; // add ourselves to it.
|
||||||
@ -960,8 +972,8 @@
|
|||||||
}
|
}
|
||||||
function ack(msg, ev){
|
function ack(msg, ev){
|
||||||
// manhattan:
|
// manhattan:
|
||||||
var as = this.as, at = as.$._;
|
var as = this.as, at = as.$._, get = as.get||'', tmp = (msg.put||'')[get['#']]||'';
|
||||||
if(Object.empty(msg.put, '_')){
|
if(!msg.put || ('string' == typeof get['.'] && u === tmp[at.get])){
|
||||||
if(at.put !== u){ return }
|
if(at.put !== u){ return }
|
||||||
at.on('in', {
|
at.on('in', {
|
||||||
get: at.get,
|
get: at.get,
|
||||||
@ -1139,44 +1151,47 @@
|
|||||||
;USE(function(module){
|
;USE(function(module){
|
||||||
var Gun = USE('./root');
|
var Gun = USE('./root');
|
||||||
Gun.chain.put = function(data, cb, as){ // I rewrote it :)
|
Gun.chain.put = function(data, cb, as){ // I rewrote it :)
|
||||||
var gun = this, at = gun._;
|
var gun = this, at = gun._, root = at.root;
|
||||||
as = as || {};
|
as = as || {};
|
||||||
|
(root.stun = root.stun || {})[at.id] = (as.stun = as.stun || {});
|
||||||
as.ack = as.ack || cb;
|
as.ack = as.ack || cb;
|
||||||
as.via = as.via || gun;
|
as.via = as.via || gun;
|
||||||
as.data = as.data || data;
|
as.data = as.data || data;
|
||||||
as.soul || (as.soul = at.soul || ('string' == typeof cb && cb));
|
as.soul || (as.soul = at.soul || ('string' == typeof cb && cb));
|
||||||
var s = as.state = as.state || Gun.state();
|
var s = as.state = as.state || Gun.state();
|
||||||
if(!as.soul){ return get(as), gun }
|
if(!as.soul){ return get(as), gun }
|
||||||
as.$ = at.root.$.get(as.soul);
|
as.$ = root.$.get(as.soul);
|
||||||
as.todo = [{it: as.data, ref: as.$}];
|
as.todo = [{it: as.data, ref: as.$}];
|
||||||
as.turn = as.turn || turn;
|
as.turn = as.turn || turn;
|
||||||
as.ran = as.ran || ran;
|
as.ran = as.ran || ran;
|
||||||
|
root.stun._ = (root.stun._ || 0) + 1;
|
||||||
var S = +new Date;
|
var S = +new Date;
|
||||||
(function walk(){
|
(function walk(){
|
||||||
var to = as.todo, at = to.pop(), d = at.it, v, k, cat, tmp;
|
var to = as.todo, at = to.pop(), d = at.it, v, k, cat, tmp, g;
|
||||||
|
(tmp = at.ref) && (root.stun[tmp._.id] = as.stun); // stun
|
||||||
if(tmp = at.todo){
|
if(tmp = at.todo){
|
||||||
k = tmp.pop(); d = d[k];
|
k = tmp.pop(); d = d[k];
|
||||||
if(tmp.length){ to.push(at) }
|
if(tmp.length){ to.push(at) }
|
||||||
}
|
}
|
||||||
if(!(v = valid(d))){
|
if(!(v = valid(d)) && !(g = Gun.is(d))){
|
||||||
if(!Object.plain(d)){ (as.ack||noop).call(as, as.out = {err: Gun.log("Invalid data, " + typeof d + " at " + (as.path||[]).join('.'))}); return }
|
if(!Object.plain(d)){ (as.ack||noop).call(as, as.out = {err: Gun.log("Invalid data, " + typeof d + " at " + (as.path||[]).join('.'))}); return }
|
||||||
var seen = as.seen || (as.seen = []), i = seen.length;
|
var seen = as.seen || (as.seen = []), i = seen.length;
|
||||||
while(i--){ if(d === (tmp = seen[i]).it){ v = d = tmp.link; break } }
|
while(i--){ if(d === (tmp = seen[i]).it){ v = d = tmp.link; break } }
|
||||||
}
|
}
|
||||||
if(k && v){ at.node = state_ify(at.node, k, s, d) } // handle soul later.
|
if(k && v){ at.node = state_ify(at.node, k, s, d) } // handle soul later.
|
||||||
else {
|
else {
|
||||||
as.seen.push(cat = {it: d, link: {}, todo: Object.keys(d).sort().reverse()});
|
as.seen.push(cat = {it: d, link: {}, todo: g? [] : Object.keys(d).sort().reverse()});
|
||||||
at.node = state_ify(at.node, k, s, cat.link);
|
at.node = state_ify(at.node, k, s, cat.link);
|
||||||
to.push(cat);
|
!g && to.push(cat);
|
||||||
// ---------------
|
// ---------------
|
||||||
var id = seen.length;
|
var id = as.seen.length;
|
||||||
(as.wait || (as.wait = {}))[id] = '';
|
(as.wait || (as.wait = {}))[id] = '';
|
||||||
tmp = (cat.ref = (k? at.ref.get(k) : at.ref))._;
|
tmp = (cat.ref = (g? d : k? at.ref.get(k) : at.ref))._;
|
||||||
(tmp = tmp.soul || tmp.link || tmp.dub)? resolve({soul: tmp}) : cat.ref.get(resolve);
|
(tmp = tmp.soul || tmp.link || tmp.dub)? resolve({soul: tmp}) : cat.ref.get(resolve, {stun: 0});
|
||||||
function resolve(msg, eve){
|
function resolve(msg, eve){
|
||||||
if(eve){ eve.off(); eve.rid(msg) } // TODO: Too early! Check all peers ack not found.
|
if(eve){ eve.off(); eve.rid(msg) } // TODO: Too early! Check all peers ack not found.
|
||||||
console.log("PUT get soul::::::::::::::", msg.soul || msg.get, msg.put, msg, msg.$ && msg.$._.id);
|
var soul = msg.soul || ((tmp = msg.put) && (tmp = tmp._) && (tmp = tmp['#'])) || ((tmp = msg.put) && (tmp = tmp['='] || tmp[':']) && tmp['#']) || ((tmp = msg.put) && tmp['#']);
|
||||||
var soul = msg.soul || ((tmp = msg.put) && (tmp = tmp._) && (tmp = tmp['#'])) || ((tmp = msg.put) && (tmp = tmp['='] || tmp[':']) && tmp['#']) || ((tmp = msg.put) && tmp['#']);
|
(tmp = msg.$) && (root.stun[tmp._.id] = as.stun); // stun
|
||||||
if(!soul){
|
if(!soul){
|
||||||
soul = [];
|
soul = [];
|
||||||
msg.$.back(function(at){
|
msg.$.back(function(at){
|
||||||
@ -1185,7 +1200,8 @@
|
|||||||
});
|
});
|
||||||
soul = msg.$._.dub = soul.reverse().join('/');
|
soul = msg.$._.dub = soul.reverse().join('/');
|
||||||
}
|
}
|
||||||
((as.graph || (as.graph = {}))[cat.link['#'] = soul] = (cat.node || (cat.node = {_:{}})))._['#'] = soul;
|
cat.link['#'] = soul;
|
||||||
|
!g && (((as.graph || (as.graph = {}))[soul] = (cat.node || (cat.node = {_:{}})))._['#'] = soul);
|
||||||
delete as.wait[id];
|
delete as.wait[id];
|
||||||
as.ran(as);
|
as.ran(as);
|
||||||
};
|
};
|
||||||
@ -1199,15 +1215,18 @@
|
|||||||
|
|
||||||
function ran(as){
|
function ran(as){
|
||||||
if(as.todo.length || !Object.empty(as.wait)){ return }
|
if(as.todo.length || !Object.empty(as.wait)){ return }
|
||||||
delete as.via._.stun;
|
|
||||||
var cat = (as.$.back(-1)._), ask = cat.ask(function(ack){
|
var cat = (as.$.back(-1)._), ask = cat.ask(function(ack){
|
||||||
cat.root.on('ack', ack);
|
cat.root.on('ack', ack);
|
||||||
if(ack.err){ Gun.log(ack) }
|
if(ack.err){ Gun.log(ack) }
|
||||||
if(++acks > (as.acks || 0)){ this.off() } // Adjustable ACKs! Only 1 by default.
|
if(++acks > (as.acks || 0)){ this.off() } // Adjustable ACKs! Only 1 by default.
|
||||||
if(!as.ack){ return }
|
if(!as.ack){ return }
|
||||||
as.ack(ack, this);
|
as.ack(ack, this);
|
||||||
}, as.opt), acks = 0;
|
}, as.opt), acks = 0, stun = as.stun;
|
||||||
(as.via._).on('out', {put: as.out = as.graph, opt: as.opt, '#': ask});
|
if((tmp = cat.root.stun) && --tmp._ === 0){ delete cat.root.stun }
|
||||||
|
(tmp = function(){ // this is not official yet, but quick solution to hack in for now.
|
||||||
|
setTimeout.each(Object.keys(stun||''), function(cb){if(cb = stun[cb]){cb()}});
|
||||||
|
}).hatch = tmp; // this is not official yet ^
|
||||||
|
(as.via._).on('out', {put: as.out = as.graph, opt: as.opt, '#': ask, _: tmp});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(as){
|
function get(as){
|
||||||
@ -1236,26 +1255,8 @@
|
|||||||
|
|
||||||
;USE(function(module){
|
;USE(function(module){
|
||||||
var Gun = USE('./index');
|
var Gun = USE('./index');
|
||||||
Gun.chain.on = function(tag, arg, eas, as){
|
|
||||||
var gun = this, at = gun._, tmp, act, off;
|
|
||||||
if(typeof tag === 'string'){
|
|
||||||
if(!arg){ return at.on(tag) }
|
|
||||||
act = at.on(tag, arg, eas || at, as);
|
|
||||||
if(eas && eas.$){
|
|
||||||
(eas.subs || (eas.subs = [])).push(act);
|
|
||||||
}
|
|
||||||
return gun;
|
|
||||||
}
|
|
||||||
var opt = arg;
|
|
||||||
opt = (true === opt)? {change: true} : opt || {};
|
|
||||||
opt.at = at;
|
|
||||||
opt.ok = tag;
|
|
||||||
//opt.last = {};
|
|
||||||
gun.get(ok, opt); // TODO: PERF! Event listener leak!!!?
|
|
||||||
return gun;
|
|
||||||
}
|
|
||||||
Gun.chain.on = function(tag, arg, eas, as){ // don't rewrite!
|
Gun.chain.on = function(tag, arg, eas, as){ // don't rewrite!
|
||||||
var gun = this, cat = gun._, act, off, id, tmp;
|
var gun = this, cat = gun._, root = cat.root, act, off, id, tmp;
|
||||||
if(typeof tag === 'string'){
|
if(typeof tag === 'string'){
|
||||||
if(!arg){ return cat.on(tag) }
|
if(!arg){ return cat.on(tag) }
|
||||||
act = cat.on(tag, arg, eas || cat, as);
|
act = cat.on(tag, arg, eas || cat, as);
|
||||||
@ -1270,71 +1271,30 @@
|
|||||||
opt.ok = tag;
|
opt.ok = tag;
|
||||||
//opt.last = {};
|
//opt.last = {};
|
||||||
//gun.get(ok, opt); // TODO: PERF! Event listener leak!!!?
|
//gun.get(ok, opt); // TODO: PERF! Event listener leak!!!?
|
||||||
console.only(1, '.on(');
|
|
||||||
((cat.act||(cat.act={}))[id = tmp||String.random(7)] = function one(msg, eve){
|
((cat.act||(cat.act={}))[id = tmp||String.random(7)] = function one(msg, eve){
|
||||||
console.log("(((ON", msg);
|
var at = msg.$._, data = at.put, tmp;
|
||||||
|
if(opt.stun===u && (tmp = root.stun) && (tmp = tmp[at.id] || tmp[at.back.id])){ // Remember! If you port this into `.get(cb` make sure you allow stun:0 skip option for `.put(`.
|
||||||
|
tmp[id] = function(){one(msg,eve)};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// call:
|
||||||
|
if(opt.as){
|
||||||
|
opt.ok.call(opt.as, msg, eve);
|
||||||
|
} else {
|
||||||
|
opt.ok.call(at.$, data, msg.get || at.get, msg, eve);
|
||||||
|
}
|
||||||
}).at = cat;
|
}).at = cat;
|
||||||
cat.on('out', {get: {}});
|
cat.on('out', {get: {}});
|
||||||
return gun;
|
return gun;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ok(msg, ev){ var opt = this;
|
|
||||||
var gun = msg.$, at = (gun||{})._ || {}, data = at.put || msg.put, cat = opt.at, tmp;
|
|
||||||
if(u === data){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(tmp = msg.$$){
|
|
||||||
tmp = (msg.$$._);
|
|
||||||
if(u === tmp.put){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data = tmp.put;
|
|
||||||
}
|
|
||||||
if(opt.change){ // TODO: BUG? Move above the undef checks?
|
|
||||||
data = msg.put;
|
|
||||||
}
|
|
||||||
// DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE
|
|
||||||
//if(tmp.put === data && tmp.get === id && !Gun.node.soul(data)){ return }
|
|
||||||
//tmp.put = data;
|
|
||||||
//tmp.get = id;
|
|
||||||
// DEDUPLICATE // TODO: NEEDS WORK! BAD PROTOTYPE
|
|
||||||
//at.last = data;
|
|
||||||
if(opt.as){
|
|
||||||
opt.ok.call(opt.as, msg, ev);
|
|
||||||
} else {
|
|
||||||
opt.ok.call(gun, data, msg.get, msg, ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rules:
|
// Rules:
|
||||||
// 1. If cached, should be fast, but not read while write.
|
// 1. If cached, should be fast, but not read while write.
|
||||||
// 2. Should not retrigger other listeners, should get triggered even if nothing found.
|
// 2. Should not retrigger other listeners, should get triggered even if nothing found.
|
||||||
// 3. If the same callback passed to many different once chains, each should resolve - an unsubscribe from the same callback should not effect the state of the other resolving chains, if you do want to cancel them all early you should mutate the callback itself with a flag & check for it at top of callback
|
// 3. If the same callback passed to many different once chains, each should resolve - an unsubscribe from the same callback should not effect the state of the other resolving chains, if you do want to cancel them all early you should mutate the callback itself with a flag & check for it at top of callback
|
||||||
Gun.chain.once = function(cb, opt){
|
|
||||||
var gun = this, at = gun._, data = at.put;
|
|
||||||
if(0 < at.ack && u !== data){
|
|
||||||
(cb || noop).call(gun, data, at.get);
|
|
||||||
return gun;
|
|
||||||
}
|
|
||||||
if(cb){
|
|
||||||
(opt = opt || {}).ok = cb;
|
|
||||||
opt.at = at;
|
|
||||||
opt.out = {'#': String.random(9)};
|
|
||||||
gun.get(val, {as: opt});
|
|
||||||
opt.async = true; //opt.async = at.stun? 1 : true;
|
|
||||||
} else {
|
|
||||||
Gun.log.once("valonce", "Chainable once is experimental, its behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.");
|
|
||||||
var chain = gun.chain();
|
|
||||||
chain._.nix = gun.once(function(){
|
|
||||||
chain._.on('in', gun._);
|
|
||||||
});
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
return gun;
|
|
||||||
}
|
|
||||||
Gun.chain.once = function(cb, opt){ opt = opt || {}; // avoid rewriting
|
Gun.chain.once = function(cb, opt){ opt = opt || {}; // avoid rewriting
|
||||||
var gun = this, cat = gun._, root = cat.root, data = cat.put, id, tmp;
|
var gun = this, cat = gun._, root = cat.root, data = cat.put, id, one, tmp;
|
||||||
//(root.act[tmp = ++root.acts] = cat.act[tmp] = function(msg, eve, to){
|
//(root.act[tmp = ++root.acts] = cat.act[tmp] = function(msg, eve, to){
|
||||||
((cat.act||(cat.act={}))[id = tmp||String.random(7)] = function one(msg, eve, to){
|
((cat.act||(cat.act={}))[id = tmp||String.random(7)] = function(msg, eve, to){
|
||||||
if(!(tmp = msg.put)){
|
if(!(tmp = msg.put)){
|
||||||
console.log('not found');
|
console.log('not found');
|
||||||
return;
|
return;
|
||||||
@ -1343,54 +1303,20 @@
|
|||||||
// probably already getting it.
|
// probably already getting it.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var at = msg.$._;
|
var at = msg.$._, one = (at.one||(at.one={}));
|
||||||
if(!(tmp = at.soul || at.link)){
|
if('' === one[id]){ return }
|
||||||
delete cat.act[id]; // TODO: BUG? What about map?
|
if(!(tmp = at.soul || at.link)){ once(); return }
|
||||||
cb.call(at.$, at.put, console.log("fix once key!"))
|
clearTimeout(one[id]); one[id] = setTimeout(once, opt.wait||99);
|
||||||
return;
|
function once(){
|
||||||
|
one[id] = ''; if(cat.soul || cat.has){ delete cat.act[id] }
|
||||||
|
if(u === (tmp = ((msg.$||'')._||'').put)){ tmp = ((msg.$$||'')._||'').put }
|
||||||
|
cb.call(at.$, tmp, msg.get || at.get);
|
||||||
}
|
}
|
||||||
clearTimeout(one.to);
|
|
||||||
one.to = setTimeout(function(){
|
|
||||||
delete cat.act[id]; // TODO: BUG? What about map?
|
|
||||||
cb.call(at.$, at.put, console.log("fix once key"));
|
|
||||||
}, opt.wait||99);
|
|
||||||
}).at = cat;
|
}).at = cat;
|
||||||
cat.on('out', {get: {}});
|
cat.on('out', {get: {}});
|
||||||
return gun;
|
return gun;
|
||||||
}
|
}
|
||||||
|
|
||||||
// You have a list, it contains Bob's uncle and Sally's husband.
|
|
||||||
// How many times should your callback fire? Once, or twice? Sally's husband is Bob's uncle.
|
|
||||||
function val(msg, eve, to){
|
|
||||||
if(!msg.$){ eve.off(); return }
|
|
||||||
var opt = this.as, cat = opt.at, gun = msg.$, at = gun._, data = at.put || msg.put, link, tmp;
|
|
||||||
if(at.has && !at.link && 'string' != typeof Gun.valid(data) && !((data||'')._||'')['#']){
|
|
||||||
//console.log(".once primitive!", at.link, data);
|
|
||||||
}
|
|
||||||
if(tmp = msg.$$){
|
|
||||||
link = tmp = (msg.$$._);
|
|
||||||
if(u !== link.put){
|
|
||||||
data = link.put;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((tmp = eve.wait) && (tmp = tmp[at.id])){ clearTimeout(tmp) }
|
|
||||||
eve.ack = (eve.ack||0)+1;
|
|
||||||
// TODO: super should not be in core code, bring AXE up into core instead to fix?
|
|
||||||
if(!to && u === data && !at.root.opt.super && eve.ack <= (opt.acks || Object.keys(at.root.opt.peers).length)){ return }
|
|
||||||
if((!to && (u === data || at.soul || at.link || (link && !(0 < link.ack))))
|
|
||||||
|| (u === data && !at.root.opt.super && (tmp = Object.keys(at.root.opt.peers).length) && (!to && (link||at).ack < tmp))){
|
|
||||||
tmp = (eve.wait = {})[at.id] = setTimeout(function(){
|
|
||||||
console.log("TIME!!!!");
|
|
||||||
val.call({as:opt}, msg, eve, tmp || 1);
|
|
||||||
}, opt.wait || 99);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//if(link && u === link.put && (tmp = rel.is(data))){ data = Gun.node.ify({}, tmp) }
|
|
||||||
if(link && u === link.put && 'string' == typeof (tmp = Gun.valid(data))){ (data = {_:{},'>':{}})['#'] = tmp; }
|
|
||||||
eve.rid? eve.rid(msg) : eve.off();
|
|
||||||
opt.ok.call(gun || opt.$, data, msg.get);
|
|
||||||
}
|
|
||||||
|
|
||||||
Gun.chain.off = function(){
|
Gun.chain.off = function(){
|
||||||
// make off more aggressive. Warning, it might backfire!
|
// make off more aggressive. Warning, it might backfire!
|
||||||
var gun = this, at = gun._, tmp;
|
var gun = this, at = gun._, tmp;
|
||||||
@ -1439,7 +1365,7 @@
|
|||||||
if(chain = cat.each){ return chain }
|
if(chain = cat.each){ return chain }
|
||||||
cat.each = chain = gun.chain();
|
cat.each = chain = gun.chain();
|
||||||
chain._.nix = gun.back('nix');
|
chain._.nix = gun.back('nix');
|
||||||
gun.on('in', map, chain._);
|
gun.on(map, {as: chain._});
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
Gun.log.once("mapfn", "Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.");
|
Gun.log.once("mapfn", "Map functions are experimental, their behavior and API may change moving forward. Please play with it and report bugs and ideas on how to improve it.");
|
||||||
@ -1454,11 +1380,19 @@
|
|||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
function map(msg){
|
function map(msg){
|
||||||
if(!msg.put || Gun.valid(msg.put)){ return this.to.next(msg) }
|
if(!msg.put || Gun.valid(msg.put)){ this.to.next(msg); return }
|
||||||
if(this.as.nix){ this.off() } // TODO: Ugly hack!
|
if(this.as.nix){ this.off() } // TODO: Ugly hack!
|
||||||
Object.keys(msg.put).forEach(each, {at: this.as, msg: msg});
|
Object.keys(msg.put).forEach(each, {at: this.as, msg: msg});
|
||||||
this.to.next(msg);
|
this.to.next(msg);
|
||||||
}
|
}
|
||||||
|
function map(msg){
|
||||||
|
var cat = this, gun = msg.$, put = msg.put;
|
||||||
|
if(!put){ return }
|
||||||
|
var soul = put['#'], k = put['.'], val = put['=']||put[':'];
|
||||||
|
// TODO: lex match!
|
||||||
|
//console.log("let's go!!!!!!!!!!!!!!!!!", k, gun._.id, gun._.get);
|
||||||
|
((tmp = gun.get(k)._).echo || (tmp.echo = {}))[cat.id] = tmp.echo[cat.id] || cat;
|
||||||
|
}
|
||||||
function each(k){
|
function each(k){
|
||||||
if('_' === k){ return }
|
if('_' === k){ return }
|
||||||
var msg = this.msg, v = msg.put[k], gun = msg.$, at = gun._, cat = this.at, tmp = at.lex;
|
var msg = this.msg, v = msg.put[k], gun = msg.$, at = gun._, cat = this.at, tmp = at.lex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user