mirror of
https://github.com/amark/gun.git
synced 2025-06-05 21:56:51 +00:00
timegraph experiment
This commit is contained in:
parent
a173c04a3c
commit
71ccb5d37f
11
gun.js
11
gun.js
@ -361,11 +361,11 @@
|
||||
var Node = USE('./node');
|
||||
function State(){
|
||||
var t;
|
||||
if(perf){
|
||||
t = start + perf.now();
|
||||
} else {
|
||||
/*if(perf){
|
||||
t = start + perf.now(); // Danger: Accuracy decays significantly over time, even if precise.
|
||||
} else {*/
|
||||
t = time();
|
||||
}
|
||||
//}
|
||||
if(last < t){
|
||||
return N = 0, last = t + State.drift;
|
||||
}
|
||||
@ -500,7 +500,7 @@
|
||||
if(!(is = valid(v,k,n, at,env))){ return }
|
||||
if(!k){
|
||||
at.node = at.node || n || {};
|
||||
if(obj_has(v, Node._)){
|
||||
if(obj_has(v, Node._)){ // && Node.soul(v) ? for safety ?
|
||||
at.node._ = obj_copy(v._);
|
||||
}
|
||||
at.node = Node.soul.ify(at.node, Val.rel.is(at.rel));
|
||||
@ -1386,6 +1386,7 @@
|
||||
} function no(v,k){ if(v){ return true } }
|
||||
|
||||
function map(v,k,n, at){ var as = this;
|
||||
//if(Gun.is(v)){} // TODO: HANDLE!
|
||||
if(k || !at.path.length){ return }
|
||||
(as.res||iife)(function(){
|
||||
var path = at.path, ref = as.ref, opt = as.opt;
|
||||
|
2
gun.min.js
vendored
2
gun.min.js
vendored
File diff suppressed because one or more lines are too long
123
lib/time.js
Normal file
123
lib/time.js
Normal file
@ -0,0 +1,123 @@
|
||||
;(function(){
|
||||
var ify = Gun.node.ify, u;
|
||||
Gun.chain.time = function(data, cb, opt){
|
||||
if(Gun.is(data)){
|
||||
var soul = data._.soul;
|
||||
if(!soul){ return cb({err: "Only root level node references supported currently, hopefully will change this in the future."}), this }
|
||||
data = Gun.val.rel.ify(soul);
|
||||
}
|
||||
if(data instanceof Function){
|
||||
return travel(data, cb, opt, this);
|
||||
}
|
||||
opt = opt || {};
|
||||
var t = new Date(Gun.state()).toISOString().split(/[\-t\:\.z]/ig);
|
||||
var gun = this, root = gun.back(-1);
|
||||
var p, tmp = t.pop();
|
||||
gun.get('_', function(msg, ev){ ev.off();
|
||||
var id = (msg.put && msg.put['#']) || ((root.back('opt.uuid') || Gun.text.random)(6) + ':'); // TODO: BUG! THIS SHOULD NOT BE HARDCODED.
|
||||
p = id;
|
||||
// could shrink this into a loop. Do later?
|
||||
var rid = (root.back('opt.uuid') || Gun.text.random)(9);
|
||||
var milli = ify({}, p + t.join(':'));
|
||||
milli[rid] = data;
|
||||
tmp = t.pop();
|
||||
var sec = ify({}, p + t.join(':'));
|
||||
sec[tmp] = milli;
|
||||
tmp = t.pop();
|
||||
var min = ify({}, p + t.join(':'));
|
||||
min[tmp] = sec;
|
||||
tmp = t.pop();
|
||||
var hour = ify({}, p + t.join(':'));
|
||||
hour[tmp] = min;
|
||||
tmp = t.pop();
|
||||
var day = ify({}, p + t.join(':'));
|
||||
day[tmp] = hour;
|
||||
tmp = t.pop();
|
||||
var month = ify({}, p + t.join(':'));
|
||||
month[tmp] = day;
|
||||
tmp = t.pop();
|
||||
var year = ify({}, p + t.join(':'));
|
||||
year[tmp] = month;
|
||||
tmp = t.pop();
|
||||
var time = ify({}, p + t.join(':'));
|
||||
time[tmp] = year;
|
||||
var ref = root.put(time);
|
||||
gun.put(ref, cb);
|
||||
})
|
||||
return gun;
|
||||
}
|
||||
function travel(cb, opt, b, gun){
|
||||
var root = gun.back(-1), tmp;
|
||||
(opt = Gun.num.is(opt)? {start: opt} : opt || {}).seen = opt.seen || {};
|
||||
var t = new Date(opt.start || Gun.state()).toISOString().split(/[\-t\:\.z]/ig).slice(0,-1);
|
||||
gun.get('_', function(msg, ev){ ev.off();
|
||||
var id = (msg.put && msg.put['#']);
|
||||
if(':' == id[id.length-1]){
|
||||
id = id.slice(0,-1);
|
||||
} else {
|
||||
id = null;
|
||||
}
|
||||
if(!id){ return Gun.log("Could not find time index.") }
|
||||
opt.at = opt.start = [id].concat(t);
|
||||
find(opt, cb, root);
|
||||
})
|
||||
return gun;
|
||||
}
|
||||
function find(o, cb, root){
|
||||
var at = o.at, t = at.join(':');
|
||||
if(1 == at.length){ t += ':' }
|
||||
if(o.seen[t]){ return } o.seen[t] = true;
|
||||
var next = o.start[at.length];
|
||||
root.get(t).get(function(msg, ev){
|
||||
var g = this;
|
||||
if(/*true || */u === msg.put){
|
||||
o.at = at.slice(0,-1);
|
||||
console.debug(5, o.at);
|
||||
console.debug(4, o.at);
|
||||
console.debug(3, o.at);
|
||||
console.debug(2, o.at);
|
||||
console.debug(1, o.at);
|
||||
find(o, cb, root);
|
||||
}
|
||||
if(7 < at.length){
|
||||
Gun.node.is(msg.put, function(v, k){
|
||||
cb(v, k, ev);
|
||||
if(o.last){ --o.last }
|
||||
})
|
||||
if(!o.last){ return }
|
||||
if(o.last <= 0){ return }
|
||||
var tmp = {seen: {}};
|
||||
tmp.last = o.last;
|
||||
tmp.start = tmp.at = o.at;
|
||||
tmp.at = tmp.at.slice(0,-1);
|
||||
tmp.was = true;
|
||||
find(tmp, cb, root);
|
||||
return;
|
||||
}
|
||||
if(u === msg.put){ return }
|
||||
if(o.last){
|
||||
var keys = Object.keys(msg.put).sort().reverse();
|
||||
var less = Gun.list.map(keys, function(k){
|
||||
if(parseFloat(k) < parseFloat(next)){ return k }
|
||||
})
|
||||
if(!less){
|
||||
o.at = at.slice(0,-1);
|
||||
find(o, cb, root);
|
||||
return;
|
||||
}
|
||||
o.at.push(less);
|
||||
(o.start = o.at.slice()).push(Infinity);
|
||||
o.at.length === 8 && (console.debug.i = console.debug.i || 1);
|
||||
find(o, cb, root);
|
||||
return;
|
||||
}
|
||||
Gun.node.is(msg.put, function(v, k){
|
||||
if(k < o.start[at.length]){ return }
|
||||
(o.at = at.slice()).push(k)
|
||||
//console.log('>>>>>', o.at);
|
||||
find(o, cb, root);
|
||||
})
|
||||
//console.log(o.at, msg.put, o.start[o.at.length]);
|
||||
})
|
||||
}
|
||||
}());
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gun",
|
||||
"version": "0.9.993",
|
||||
"version": "0.9.994",
|
||||
"description": "A realtime, decentralized, offline-first, graph data synchronization engine.",
|
||||
"main": "index.js",
|
||||
"browser": "gun.min.js",
|
||||
|
68
sea.js
68
sea.js
@ -1303,6 +1303,44 @@
|
||||
})
|
||||
}
|
||||
}
|
||||
User.prototype.grant = function(to, cb){
|
||||
console.log("`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!");
|
||||
var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';
|
||||
gun.back(function(at){ if(at.pub){ return } path += (at.get||'') });
|
||||
(async function(){
|
||||
var enc, sec = await user.get('trust').get(pair.pub).get(path).then();
|
||||
sec = await SEA.decrypt(sec, pair);
|
||||
if(!sec){
|
||||
sec = SEA.random(16).toString();
|
||||
enc = await SEA.encrypt(sec, pair);
|
||||
user.get('trust').get(pair.pub).get(path).put(enc);
|
||||
}
|
||||
var pub = to.get('pub').then();
|
||||
var epub = to.get('epub').then();
|
||||
pub = await pub; epub = await epub;
|
||||
var dh = await SEA.secret(epub, pair);
|
||||
enc = await SEA.encrypt(sec, dh);
|
||||
user.get('trust').get(pub).get(path).put(enc, cb);
|
||||
}());
|
||||
return gun;
|
||||
}
|
||||
User.prototype.secret = function(data, cb){
|
||||
console.log("`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!");
|
||||
var gun = this, user = gun.back(-1).user(), pair = user.pair(), path = '';
|
||||
gun.back(function(at){ if(at.pub){ return } path += (at.get||'') });
|
||||
(async function(){
|
||||
var enc, sec = await user.get('trust').get(pair.pub).get(path).then();
|
||||
sec = await SEA.decrypt(sec, pair);
|
||||
if(!sec){
|
||||
sec = SEA.random(16).toString();
|
||||
enc = await SEA.encrypt(sec, pair);
|
||||
user.get('trust').get(pair.pub).get(path).put(enc);
|
||||
}
|
||||
enc = await SEA.encrypt(data, sec);
|
||||
gun.put(enc, cb);
|
||||
}());
|
||||
return gun;
|
||||
}
|
||||
module.exports = User
|
||||
})(USE, './create');
|
||||
|
||||
@ -1320,7 +1358,7 @@
|
||||
var id = uuid(), pub = at.user;
|
||||
if(!pub || !(pub = at.user._.sea) || !(pub = pub.pub)){ return id }
|
||||
id = id + '~' + pub;
|
||||
if(cb){ cb(null, id) }
|
||||
if(cb && cb.call){ cb(null, id) }
|
||||
return id;
|
||||
}
|
||||
at.on('in', security, at); // now listen to all input data, acting as a firewall.
|
||||
@ -1428,7 +1466,8 @@
|
||||
check['user'+soul+key] = 1;
|
||||
if(user && (user = user._) && user.sea && pub === user.pub){
|
||||
//var id = Gun.text.random(3);
|
||||
SEA.sign(val, user.sea).then(function(data){ var rel;
|
||||
SEA.sign(val, user.sea, function(data){ var rel;
|
||||
if(u === data){ return each.end({err: SEA.err || 'Pub signature fail.'}) }
|
||||
if(rel = Gun.val.rel.is(val)){
|
||||
(at.sea.own[rel] = at.sea.own[rel] || {})[pub] = true;
|
||||
}
|
||||
@ -1440,7 +1479,7 @@
|
||||
return;
|
||||
}
|
||||
// TODO: consider async/await and drop callback pattern...
|
||||
SEA.verify(val, pub).then(function(data){ var rel, tmp;
|
||||
SEA.verify(val, pub, function(data){ var rel, tmp;
|
||||
if(u === data){ // make sure the signature matches the account it claims to be on.
|
||||
return each.end({err: "Unverified data."}); // reject any updates that are signed with a mismatched account.
|
||||
}
|
||||
@ -1457,7 +1496,7 @@
|
||||
if(!user || !(user = user._) || !(user = user.sea)){
|
||||
if((tmp = soul.split('~')) && 2 == tmp.length){
|
||||
check['any'+soul+key] = 1;
|
||||
SEA.verify(val, (pub = tmp[1])).then(function(data){ var rel;
|
||||
SEA.verify(val, (pub = tmp[1]), function(data){ var rel;
|
||||
if(!data){ return each.end({err: "Mismatched owner on '" + key + "'."}) }
|
||||
if((rel = Gun.val.rel.is(data)) && (tmp = rel.split('~')) && 2 === tmp.length){
|
||||
if(pub === tmp[1]){
|
||||
@ -1472,13 +1511,29 @@
|
||||
check['any'+soul+key] = 1;
|
||||
at.on('secure', function(msg){ this.off();
|
||||
check['any'+soul+key] = 0;
|
||||
if(at.opt.secure){ msg = null }
|
||||
each.end(msg || {err: "Data cannot be modified."});
|
||||
}).on.on('secure', msg);
|
||||
//each.end({err: "Data cannot be modified."});
|
||||
return;
|
||||
}
|
||||
if(!(tmp = soul.split('~')) || 2 !== tmp.length){
|
||||
each.end({err: "Soul is missing public key at '" + key + "'."});
|
||||
if(at.opt.secure){
|
||||
each.end({err: "Soul is missing public key at '" + key + "'."});
|
||||
return;
|
||||
}
|
||||
if(val && val.slice && 'SEA{' === (val).slice(0,4)){
|
||||
check['any'+soul+key] = 0;
|
||||
each.end({ok: 1});
|
||||
return;
|
||||
}
|
||||
check['any'+soul+key] = 1;
|
||||
SEA.sign(val, user, function(data){
|
||||
if(u === data){ return each.end({err: 'Any signature failed.'}) }
|
||||
node[key] = data;
|
||||
check['any'+soul+key] = 0;
|
||||
each.end({ok: 1});
|
||||
});
|
||||
return;
|
||||
}
|
||||
var pub = tmp[1];
|
||||
@ -1494,7 +1549,8 @@
|
||||
return;
|
||||
}*/
|
||||
check['any'+soul+key] = 1;
|
||||
SEA.sign(val, user).then(function(data){
|
||||
SEA.sign(val, user, function(data){
|
||||
if(u === data){ return each.end({err: 'My signature fail.'}) }
|
||||
node[key] = data;
|
||||
check['any'+soul+key] = 0;
|
||||
each.end({ok: 1});
|
||||
|
@ -3,11 +3,11 @@
|
||||
// is complicated and was extremely hard to build. If you port GUN to another
|
||||
// language, consider implementing an easier API to build.
|
||||
var Gun = require('./root');
|
||||
Gun.chain.chain = function(){
|
||||
var at = this._, chain = new this.constructor(this), cat = chain._, root;
|
||||
Gun.chain.chain = function(sub){
|
||||
var gun = this, at = gun._, chain = new (sub || gun).constructor(gun), cat = chain._, root;
|
||||
cat.root = root = at.root;
|
||||
cat.id = ++root.once;
|
||||
cat.back = this._;
|
||||
cat.back = gun._;
|
||||
cat.on = Gun.on;
|
||||
cat.on('in', input, cat); // For 'in' if I add my own listeners to each then I MUST do it before in gets called. If I listen globally for all incoming data instead though, regardless of individual listeners, I can transform the data there and then as well.
|
||||
cat.on('out', output, cat); // However for output, there isn't really the global option. I must listen by adding my own listener individually BEFORE this one is ever called.
|
||||
|
@ -6,7 +6,7 @@ function Gun(o){
|
||||
return Gun.create(this._ = {gun: this, opt: o});
|
||||
}
|
||||
|
||||
Gun.is = function(gun){ return (gun instanceof Gun) }
|
||||
Gun.is = function(gun){ return (gun instanceof Gun) || (gun && gun._ && gun._.gun && true) || false }
|
||||
|
||||
Gun.version = 0.9;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user