mirror of
https://github.com/amark/gun.git
synced 2026-03-22 16:13:47 +00:00
Merge branch 'master' into master
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body style="text-align: center;">
|
||||
<h1 id="when" style="font-size: 7vw; margin-top: 43vh;"></h1>
|
||||
<h1 id="when" style="font-size: 7vw; margin-top: 43vh; font-family: monospace;"></h1>
|
||||
</body>
|
||||
<script src="/gun.js"></script>
|
||||
<script src="/gun/nts.js"></script>
|
||||
@@ -16,4 +16,4 @@
|
||||
when.innerHTML = print;
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
43
gun.js
43
gun.js
@@ -49,10 +49,10 @@
|
||||
if(t.slice(0, (tmp||'').length) === tmp){ return true }
|
||||
if(u !== o['*']){ return false }
|
||||
if(u !== o['>'] && u !== o['<']){
|
||||
return (t > o['>'] && t < o['<'])? true : false;
|
||||
return (t >= o['>'] && t <= o['<'])? true : false;
|
||||
}
|
||||
if(u !== o['>'] && t > o['>']){ return true }
|
||||
if(u !== o['<'] && t < o['<']){ return true }
|
||||
if(u !== o['>'] && t >= o['>']){ return true }
|
||||
if(u !== o['<'] && t <= o['<']){ return true }
|
||||
return false;
|
||||
}
|
||||
Type.list = {is: function(l){ return (l instanceof Array) }}
|
||||
@@ -958,7 +958,7 @@
|
||||
if(tmp){ return }
|
||||
msg.$ = back.$;
|
||||
} else
|
||||
if(obj_has(back.put, get)){
|
||||
if(obj_has(back.put, get)){ // TODO: support #LEX !
|
||||
put = (back.$.get(get)._);
|
||||
if(!(tmp = put.ack)){ put.ack = -1 }
|
||||
back.on('in', {
|
||||
@@ -1178,14 +1178,16 @@
|
||||
});
|
||||
}
|
||||
function ask(at, soul){
|
||||
var tmp = (at.root.$.get(soul)._);
|
||||
if(at.ack){
|
||||
tmp.on('out', {get: {'#': soul}});
|
||||
var tmp = (at.root.$.get(soul)._), lex = at.lex;
|
||||
if(at.ack || lex){
|
||||
(lex = lex||{})['#'] = soul;
|
||||
tmp.on('out', {get: lex});
|
||||
if(!at.ask){ return } // TODO: PERFORMANCE? More elegant way?
|
||||
}
|
||||
tmp = at.ask; Gun.obj.del(at, 'ask');
|
||||
obj_map(tmp || at.next, function(neat, key){
|
||||
neat.on('out', {get: {'#': soul, '.': key}});
|
||||
var lex = neat.lex || {}; lex['#'] = soul; lex['.'] = lex['.'] || key;
|
||||
neat.on('out', {get: lex});
|
||||
});
|
||||
Gun.obj.del(at, 'ask'); // TODO: PERFORMANCE? More elegant way?
|
||||
}
|
||||
@@ -1985,7 +1987,7 @@
|
||||
}
|
||||
(msg._ = function(){}).via = peer;
|
||||
if((tmp = msg['><'])){
|
||||
(msg._).to = Type.obj.map(tmp.split(','), function(k,i,m){m(k,true)});
|
||||
(msg._).to = Type.obj.map(tmp.split(','), tomap);
|
||||
}
|
||||
if(msg.dam){
|
||||
if(tmp = mesh.hear[msg.dam]){
|
||||
@@ -2008,6 +2010,7 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
var tomap = function(k,i,m){m(k,true)};
|
||||
|
||||
;(function(){
|
||||
mesh.say = function(msg, peer, o){
|
||||
@@ -2062,7 +2065,6 @@
|
||||
peer.say(raw);
|
||||
} else
|
||||
if(wire.send){
|
||||
if(wire.readyState && 1 != wire.readyState){ throw "socket not ready yet!" }
|
||||
wire.send(raw);
|
||||
}
|
||||
}catch(e){
|
||||
@@ -2130,11 +2132,12 @@
|
||||
tmp = tmp.id = tmp.id || Type.text.random(9);
|
||||
mesh.say({dam: '?'}, opt.peers[tmp] = peer);
|
||||
}
|
||||
if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer); }
|
||||
// tmp = peer.queue; peer.queue = [];
|
||||
// Type.obj.map(tmp, function(msg){
|
||||
// mesh.say(msg, peer);
|
||||
// });
|
||||
if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) }
|
||||
// @rogowski I need this here by default for now to fix go1dfish's bug
|
||||
tmp = peer.queue; peer.queue = [];
|
||||
Type.obj.map(tmp, function(msg){
|
||||
mesh.say(msg, peer);
|
||||
});
|
||||
}
|
||||
mesh.bye = function(peer){
|
||||
Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect
|
||||
@@ -2143,12 +2146,12 @@
|
||||
mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }
|
||||
mesh.hear['?'] = function(msg, peer){
|
||||
if(!msg.pid){
|
||||
// return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);
|
||||
mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);
|
||||
var tmp = peer.queue; peer.queue = [];
|
||||
Type.obj.map(tmp, function(msg){
|
||||
mesh.say(msg, peer);
|
||||
});
|
||||
// @rogowski I want to re-enable this AXE logic with some fix/merge later.
|
||||
// var tmp = peer.queue; peer.queue = [];
|
||||
// Type.obj.map(tmp, function(msg){
|
||||
// mesh.say(msg, peer);
|
||||
// });
|
||||
return;
|
||||
}
|
||||
peer.id = peer.id || msg.pid;
|
||||
|
||||
@@ -5,8 +5,8 @@ Gun.on('opt', function(root){
|
||||
if(root.once){ return }
|
||||
root.on('in', function(msg){
|
||||
//Msg did not have a peer property saved before, so nothing ever went further
|
||||
if(!msg.mesh || !msg.BYE){ return this.to.next(msg) }
|
||||
var peer = msg.mesh.via;
|
||||
if(!msg._ || !msg.BYE){ return this.to.next(msg) }
|
||||
var peer = msg._.via;
|
||||
(peer.bye = peer.bye || []).push(msg.BYE);
|
||||
})
|
||||
root.on('bye', function(peer){
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
const gc_enable = root.opt.gc_enable ? root.opt.gc_enable : true;
|
||||
const gc_delay = root.opt.gc_delay ? root.opt.gc_delay : 1000;
|
||||
|
||||
const gc_info_enable = root.opt.gc_info_enable ? root.opt.gc_info_enable : true;
|
||||
const gc_info_enable = ("gc_info_enable" in root.opt) ? root.opt.gc_info_enable : true;
|
||||
const gc_info = root.opt.gc_info ? root.opt.gc_info : 5000;
|
||||
const gc_info_mini = root.opt.gc_info_mini ? root.opt.gc_info_mini : false;
|
||||
|
||||
@@ -127,6 +127,7 @@
|
||||
|
||||
//Executed every time a node gets modified
|
||||
root.on("put", function(e) {
|
||||
this.to.next(e);
|
||||
var ctime = Date.now();
|
||||
var souls = Object.keys(e.put || empty); // get all of the nodes in the update
|
||||
for (var i = 0; i < souls.length; i++) { // iterate over them and add them
|
||||
@@ -219,4 +220,4 @@
|
||||
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
|
||||
}
|
||||
});
|
||||
}());
|
||||
}());
|
||||
|
||||
@@ -3,7 +3,8 @@ var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
|
||||
Gun.on('create', function(root){
|
||||
this.to.next(root);
|
||||
var opt = root.opt;
|
||||
if(false === opt.multicast){ return }
|
||||
if(false === opt.multicast){ return }
|
||||
if(true !== opt.multicast){ return } // disable multicast by default for now.
|
||||
|
||||
var udp = opt.multicast = opt.multicast || {};
|
||||
udp.address = udp.address || '233.255.255.255';
|
||||
|
||||
@@ -236,16 +236,22 @@
|
||||
// if a node is requested and some of it is cached... the other parts might not be.
|
||||
//}
|
||||
}
|
||||
var g = function Get(){}, tmp;
|
||||
g.lex = function(file){
|
||||
o.span = (u !== o.start) || (u !== o.end);
|
||||
var g = function Get(){};
|
||||
g.lex = function(file){ var tmp;
|
||||
file = (u === file)? u : decodeURIComponent(file);
|
||||
if(!file || file > (o.next || key || o.start || o.end || '')){
|
||||
if(o.next){ g.file = file }
|
||||
tmp = o.next || key || (o.reverse? o.end || '\uffff' : o.start || '');
|
||||
if(!file || (o.reverse? file < tmp : file > tmp)){
|
||||
if(o.next || o.reverse){ g.file = file }
|
||||
if(tmp = Q[g.file]){
|
||||
tmp.push({key: key, ack: cb, file: g.file, opt: o});
|
||||
return true;
|
||||
}
|
||||
Q[g.file] = [{key: key, ack: cb, file: g.file, opt: o}];
|
||||
if(!g.file){
|
||||
g.it(null, u, {});
|
||||
return true;
|
||||
}
|
||||
r.parse(g.file, g.it);
|
||||
return true;
|
||||
}
|
||||
@@ -266,12 +272,15 @@
|
||||
if(!o.some){ o.some = (u !== data) }
|
||||
if(u !== data){ as.ack(g.err, data, o) }
|
||||
else if(!as.file){ !o.some && as.ack(g.err, u, o); return }
|
||||
if(/*!last || */last === tmp){ !o.some && as.ack(g.err, u, o); return }
|
||||
if(last && last > tmp && 0 != last.indexOf(tmp)){ !o.some && as.ack(g.err, u, o); return }
|
||||
if(!o.span){
|
||||
if(/*!last || */last === tmp){ !o.some && as.ack(g.err, u, o); return }
|
||||
if(last && last > tmp && 0 != last.indexOf(tmp)){ !o.some && as.ack(g.err, u, o); return }
|
||||
}
|
||||
if(o.some && o.parsed >= o.limit){ return }
|
||||
o.next = as.file;
|
||||
r.read(tmp, as.ack, o);
|
||||
}
|
||||
if(o.reverse){ g.lex.reverse = true }
|
||||
r.list(g.lex);
|
||||
}
|
||||
}());
|
||||
@@ -320,7 +329,6 @@
|
||||
return map(q, p.ack);
|
||||
}
|
||||
}
|
||||
|
||||
var start; LOG && (start = (+new Date)); // keep this commented out in production!
|
||||
var tmp = p.split(data), pre = [], i, k, v;
|
||||
if(!tmp || 0 !== tmp[1]){
|
||||
@@ -373,9 +381,10 @@
|
||||
var dir, q, f = String.fromCharCode(28), ef = ename(f);
|
||||
r.list = function(cb){
|
||||
if(dir){
|
||||
var tmp = {reverse: (cb.reverse)? 1 : 0};
|
||||
Radix.map(dir, function(val, key){
|
||||
return cb(key);
|
||||
}) || cb();
|
||||
}, tmp) || cb();
|
||||
return;
|
||||
}
|
||||
if(q){ return q.push(cb) } q = [cb];
|
||||
@@ -420,9 +429,7 @@
|
||||
r.list.dir = dir = rad;
|
||||
tmp = q; q = null;
|
||||
Gun.list.map(tmp, function(cb){
|
||||
Radix.map(dir, function(val, key){
|
||||
return cb(key);
|
||||
}) || cb();
|
||||
r.list(cb);
|
||||
});
|
||||
}
|
||||
}());
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
var keys = (t[_]||no).sort || (t[_] = function $(){ $.sort = Object.keys(t).sort(); return $ }()).sort;
|
||||
//var keys = Object.keys(t).sort();
|
||||
opt = (true === opt)? {branch: true} : (opt || {});
|
||||
if(opt.reverse){ keys = keys.slice().reverse() }
|
||||
var start = opt.start, end = opt.end;
|
||||
var i = 0, l = keys.length;
|
||||
for(;i < l; i++){ var key = keys[i], tree = t[key], tmp, p, pt;
|
||||
@@ -64,7 +65,7 @@
|
||||
p = pre.slice(); p.push(key);
|
||||
pt = p.join('');
|
||||
if(u !== start && pt < (start||'').slice(0,pt.length)){ continue }
|
||||
if(u !== end && end < pt){ continue }
|
||||
if(u !== end && (end || '\uffff') < pt){ continue }
|
||||
if(u !== (tmp = tree[''])){
|
||||
tmp = cb(tmp, pt, key, pre);
|
||||
if(u !== tmp){ return tmp }
|
||||
|
||||
@@ -3,7 +3,13 @@ function Store(opt){
|
||||
opt.log = opt.log || console.log;
|
||||
opt.file = String(opt.file || 'radata');
|
||||
var fs = require('fs'), u;
|
||||
|
||||
var store = function Store(){};
|
||||
if(Store[opt.file]){
|
||||
console.log("Warning: reusing same fs store and options as 1st.");
|
||||
return Store[opt.file];
|
||||
}
|
||||
Store[opt.file] = store;
|
||||
|
||||
store.put = function(file, data, cb){
|
||||
var random = Math.random().toString(36).slice(-3);
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
}}catch(e){}
|
||||
|
||||
var store = function Store(){};
|
||||
if(Store[opt.file]){
|
||||
console.log("Warning: reusing same IndexedDB store and options as 1st.");
|
||||
return Store[opt.file];
|
||||
}
|
||||
Store[opt.file] = store;
|
||||
|
||||
store.start = function(){
|
||||
var o = indexedDB.open(opt.file, 1);
|
||||
o.onupgradeneeded = function(eve){ (eve.target.result).createObjectStore(opt.file) }
|
||||
|
||||
10
lib/rs3.js
10
lib/rs3.js
@@ -7,7 +7,7 @@ var u, AWS;
|
||||
Gun.on('create', function(root){
|
||||
this.to.next(root);
|
||||
var opt = root.opt;
|
||||
if(!(opt.s3 && opt.s3.bucket) && !process.env.AWS_S3_BUCKET){ return }
|
||||
if(!opt.s3 && !process.env.AWS_S3_BUCKET){ return }
|
||||
opt.batch = opt.batch || (1000 * 10);
|
||||
opt.until = opt.until || (1000 * 3);
|
||||
opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB
|
||||
@@ -41,8 +41,14 @@ function Store(opt){
|
||||
opt.file = String(opt.file || 'radata');
|
||||
var opts = opt.s3, s3 = opts.s3;
|
||||
var c = {p: {}, g: {}, l: {}};
|
||||
|
||||
|
||||
var store = function Store(){};
|
||||
if(Store[opt.file]){
|
||||
console.log("Warning: reusing same S3 store and options as 1st.");
|
||||
return Store[opt.file];
|
||||
}
|
||||
Store[opt.file] = store;
|
||||
|
||||
store.put = function(file, data, cb){
|
||||
var params = {Bucket: opts.bucket, Key: file, Body: data};
|
||||
//console.log("RS3 PUT ---->", (data||"").slice(0,20));
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
require('./file');
|
||||
require('./evict');
|
||||
require('./multicast');
|
||||
require('./stats');
|
||||
if('debug' === process.env.GUN_ENV){ require('./debug') }
|
||||
module.exports = Gun;
|
||||
}());
|
||||
|
||||
43
lib/stats.js
Normal file
43
lib/stats.js
Normal file
@@ -0,0 +1,43 @@
|
||||
var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
|
||||
|
||||
Gun.on('opt', function(root){
|
||||
this.to.next(root);
|
||||
if(root.once){ return }
|
||||
if(typeof process === 'undefined'){ return }
|
||||
if(typeof require === 'undefined'){ return }
|
||||
var noop = function(){};
|
||||
var os = require('os') || {};
|
||||
var fs = require('fs') || {};
|
||||
fs.existsSync = fs.existsSync || require('path').existsSync;
|
||||
if(!fs.existsSync){ return }
|
||||
if(!process){ return }
|
||||
process.uptime = process.uptime || noop;
|
||||
process.cpuUsage = process.cpuUsage || noop;
|
||||
process.memoryUsage = process.memoryUsage || noop;
|
||||
os.totalmem = os.totalmem || noop;
|
||||
os.freemem = os.freemem || noop;
|
||||
os.loadavg = os.loadavg || noop;
|
||||
os.cpus = os.cpus || noop;
|
||||
setTimeout(function(){
|
||||
root.stats = Gun.obj.ify((fs.existsSync(__dirname+'/../stats.'+root.opt.file) && fs.readFileSync(__dirname+'/../stats.'+root.opt.file).toString())) || {};
|
||||
root.stats.up = root.stats.up || {};
|
||||
root.stats.up.start = root.stats.up.start || +(new Date);
|
||||
root.stats.up.count = (root.stats.up.count || 0) + 1;
|
||||
},1);
|
||||
setInterval(function(){
|
||||
if(!root.stats){ root.stats = {} }
|
||||
var stats = root.stats, tmp;
|
||||
(stats.up||{}).time = process.uptime();
|
||||
stats.memory = process.memoryUsage() || {};
|
||||
stats.memory.totalmem = os.totalmem();
|
||||
stats.memory.freemem = os.freemem();
|
||||
stats.cpu = process.cpuUsage() || {};
|
||||
stats.cpu.loadavg = os.loadavg();
|
||||
stats.peers = {};
|
||||
stats.peers.count = Object.keys(root.opt.peers||{}).length;
|
||||
stats.node = {};
|
||||
stats.node.count = Object.keys(root.graph||{}).length;
|
||||
fs.writeFile(__dirname+'/../stats.'+root.opt.file, JSON.stringify(stats, null, 2), function(err){});
|
||||
}, 1000 * 15);
|
||||
Object.keys = Object.keys || function(o){ return Gun.obj.map(o, function(v,k,t){t(k)}) }
|
||||
});
|
||||
@@ -61,6 +61,7 @@ Gun.on('create', function(root){
|
||||
if((tmp = get['%']) || opt.limit){
|
||||
opt.limit = (tmp <= (opt.pack || (1000 * 100)))? tmp : 1;
|
||||
}
|
||||
if(has['-'] || (soul||{})['-']){ opt.reverse = true }
|
||||
//console.log("RAD get:", key, opt);
|
||||
//var start = (+new Date); // console.log("GET!", id, JSON.stringify(key));
|
||||
rad(key||'', function(err, data, o){
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gun",
|
||||
"version": "0.2019.416",
|
||||
"version": "0.2019.428",
|
||||
"description": "A realtime, decentralized, offline-first, graph data synchronization engine.",
|
||||
"main": "index.js",
|
||||
"browser": "gun.js",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
var Gun = require('../index');
|
||||
var Type = require('../type');
|
||||
|
||||
@@ -20,7 +21,7 @@ function Mesh(ctx){
|
||||
return;
|
||||
}
|
||||
// add hook for AXE?
|
||||
if (Gun.AXE && opt && opt.super) { Gun.AXE.say(msg, mesh.say, this); return; } // rogowski
|
||||
if (Gun.AXE) { Gun.AXE.say(msg, mesh.say, this); return; }
|
||||
mesh.say(msg);
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ function Mesh(ctx){
|
||||
}
|
||||
(msg._ = function(){}).via = peer;
|
||||
if((tmp = msg['><'])){
|
||||
(msg._).to = Type.obj.map(tmp.split(','), function(k,i,m){m(k,true)});
|
||||
(msg._).to = Type.obj.map(tmp.split(','), tomap);
|
||||
}
|
||||
if(msg.dam){
|
||||
if(tmp = mesh.hear[msg.dam]){
|
||||
@@ -71,6 +72,7 @@ function Mesh(ctx){
|
||||
return;
|
||||
}
|
||||
}
|
||||
var tomap = function(k,i,m){m(k,true)};
|
||||
|
||||
;(function(){
|
||||
mesh.say = function(msg, peer, o){
|
||||
@@ -125,7 +127,6 @@ function Mesh(ctx){
|
||||
peer.say(raw);
|
||||
} else
|
||||
if(wire.send){
|
||||
if(wire.readyState && 1 != wire.readyState){ throw "socket not ready yet!" }
|
||||
wire.send(raw);
|
||||
}
|
||||
}catch(e){
|
||||
@@ -194,6 +195,7 @@ function Mesh(ctx){
|
||||
mesh.say({dam: '?'}, opt.peers[tmp] = peer);
|
||||
}
|
||||
if(!tmp.hied){ ctx.on(tmp.hied = 'hi', peer) }
|
||||
// @rogowski I need this here by default for now to fix go1dfish's bug
|
||||
tmp = peer.queue; peer.queue = [];
|
||||
Type.obj.map(tmp, function(msg){
|
||||
mesh.say(msg, peer);
|
||||
@@ -203,16 +205,20 @@ function Mesh(ctx){
|
||||
Type.obj.del(opt.peers, peer.id); // assume if peer.url then reconnect
|
||||
ctx.on('bye', peer);
|
||||
}
|
||||
|
||||
mesh.hear['!'] = function(msg, peer){ opt.log('Error:', msg.err) }
|
||||
mesh.hear['?'] = function(msg, peer){
|
||||
if(!msg.pid){
|
||||
return mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);
|
||||
mesh.say({dam: '?', pid: opt.pid, '@': msg['#']}, peer);
|
||||
// @rogowski I want to re-enable this AXE logic with some fix/merge later.
|
||||
// var tmp = peer.queue; peer.queue = [];
|
||||
// Type.obj.map(tmp, function(msg){
|
||||
// mesh.say(msg, peer);
|
||||
// });
|
||||
return;
|
||||
}
|
||||
peer.id = peer.id || msg.pid;
|
||||
mesh.hi(peer);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
@@ -233,4 +239,4 @@ Mesh.hash = function(s){ // via SO
|
||||
|
||||
try{ module.exports = Mesh }catch(e){}
|
||||
|
||||
|
||||
|
||||
12
src/chain.js
12
src/chain.js
@@ -37,7 +37,7 @@ function output(msg){
|
||||
if(tmp){ return }
|
||||
msg.$ = back.$;
|
||||
} else
|
||||
if(obj_has(back.put, get)){
|
||||
if(obj_has(back.put, get)){ // TODO: support #LEX !
|
||||
put = (back.$.get(get)._);
|
||||
if(!(tmp = put.ack)){ put.ack = -1 }
|
||||
back.on('in', {
|
||||
@@ -257,14 +257,16 @@ function not(at, msg){
|
||||
});
|
||||
}
|
||||
function ask(at, soul){
|
||||
var tmp = (at.root.$.get(soul)._);
|
||||
if(at.ack){
|
||||
tmp.on('out', {get: {'#': soul}});
|
||||
var tmp = (at.root.$.get(soul)._), lex = at.lex;
|
||||
if(at.ack || lex){
|
||||
(lex = lex||{})['#'] = soul;
|
||||
tmp.on('out', {get: lex});
|
||||
if(!at.ask){ return } // TODO: PERFORMANCE? More elegant way?
|
||||
}
|
||||
tmp = at.ask; Gun.obj.del(at, 'ask');
|
||||
obj_map(tmp || at.next, function(neat, key){
|
||||
neat.on('out', {get: {'#': soul, '.': key}});
|
||||
var lex = neat.lex || {}; lex['#'] = soul; lex['.'] = lex['.'] || key;
|
||||
neat.on('out', {get: lex});
|
||||
});
|
||||
Gun.obj.del(at, 'ask'); // TODO: PERFORMANCE? More elegant way?
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ function map(msg){
|
||||
function each(v,k){
|
||||
if(n_ === k){ return }
|
||||
var msg = this.msg, gun = msg.$, at = gun._, cat = this.at, tmp = at.lex;
|
||||
if(tmp && !Gun.text.match(k, tmp['.'] || tmp['#'] || tmp)){ return } // TODO: Ugly hack!
|
||||
if(tmp && !Gun.text.match(k, tmp['.'] || tmp['#'] || tmp)){ return } // review?
|
||||
((tmp = gun.get(k)._).echo || (tmp.echo = {}))[cat.id] = tmp.echo[cat.id] || cat;
|
||||
}
|
||||
var obj_map = Gun.obj.map, noop = function(){}, event = {stun: noop, off: noop}, n_ = Gun.node._, u;
|
||||
|
||||
36
src/type.js
36
src/type.js
@@ -18,28 +18,22 @@ Type.text.random = function(l, c){
|
||||
while(l > 0){ s += c.charAt(Math.floor(Math.random() * c.length)); l-- }
|
||||
return s;
|
||||
}
|
||||
Type.text.match = function(t, o){ var r = false;
|
||||
t = t || '';
|
||||
o = Type.text.is(o)? {'=': o} : o || {}; // {'~', '=', '*', '<', '>', '+', '-', '?', '!'} // ignore case, exactly equal, anything after, lexically larger, lexically lesser, added in, subtacted from, questionable fuzzy match, and ends with.
|
||||
if(Type.obj.has(o,'~')){ t = t.toLowerCase(); o['='] = (o['='] || o['~']).toLowerCase() }
|
||||
if(Type.obj.has(o,'=')){ return t === o['='] }
|
||||
if(Type.obj.has(o,'*')){ if(t.slice(0, o['*'].length) === o['*']){ r = true; t = t.slice(o['*'].length) } else { return false }}
|
||||
if(Type.obj.has(o,'!')){ if(t.slice(-o['!'].length) === o['!']){ r = true } else { return false }}
|
||||
if(Type.obj.has(o,'+')){
|
||||
if(Type.list.map(Type.list.is(o['+'])? o['+'] : [o['+']], function(m){
|
||||
if(t.indexOf(m) >= 0){ r = true } else { return true }
|
||||
})){ return false }
|
||||
Type.text.match = function(t, o){ var tmp, u;
|
||||
if('string' !== typeof t){ return false }
|
||||
if('string' == typeof o){ o = {'=': o} }
|
||||
o = o || {};
|
||||
tmp = (o['='] || o['*'] || o['>'] || o['<']);
|
||||
if(t === tmp){ return true }
|
||||
if(u !== o['=']){ return false }
|
||||
tmp = (o['*'] || o['>'] || o['<']);
|
||||
if(t.slice(0, (tmp||'').length) === tmp){ return true }
|
||||
if(u !== o['*']){ return false }
|
||||
if(u !== o['>'] && u !== o['<']){
|
||||
return (t >= o['>'] && t <= o['<'])? true : false;
|
||||
}
|
||||
if(Type.obj.has(o,'-')){
|
||||
if(Type.list.map(Type.list.is(o['-'])? o['-'] : [o['-']], function(m){
|
||||
if(t.indexOf(m) < 0){ r = true } else { return true }
|
||||
})){ return false }
|
||||
}
|
||||
if(Type.obj.has(o,'>')){ if(t > o['>']){ r = true } else { return false }}
|
||||
if(Type.obj.has(o,'<')){ if(t < o['<']){ r = true } else { return false }}
|
||||
function fuzzy(t,f){ var n = -1, i = 0, c; for(;c = f[i++];){ if(!~(n = t.indexOf(c, n+1))){ return false }} return true } // via http://stackoverflow.com/questions/9206013/javascript-fuzzy-search
|
||||
if(Type.obj.has(o,'?')){ if(fuzzy(t, o['?'])){ r = true } else { return false }} // change name!
|
||||
return r;
|
||||
if(u !== o['>'] && t >= o['>']){ return true }
|
||||
if(u !== o['<'] && t <= o['<']){ return true }
|
||||
return false;
|
||||
}
|
||||
Type.list = {is: function(l){ return (l instanceof Array) }}
|
||||
Type.list.slit = Array.prototype.slice;
|
||||
|
||||
@@ -6,6 +6,8 @@ describe('Gun', function(){
|
||||
if(typeof window !== 'undefined'){ env = window }
|
||||
root = env.window? env.window : global;
|
||||
try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}
|
||||
try{ localStorage.clear() }catch(e){}
|
||||
try{ indexedDB.deleteDatabase('radatatest') }catch(e){}
|
||||
try{ require('fs').unlinkSync('data.json') }catch(e){}
|
||||
try{ require('../lib/fsrm')('radatatest') }catch(e){}
|
||||
//root.Gun = root.Gun || require('../gun');
|
||||
|
||||
@@ -7,13 +7,12 @@ var Gun;
|
||||
root = env.window? env.window : global;
|
||||
try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}
|
||||
try{ indexedDB.deleteDatabase('radatatest') }catch(e){}
|
||||
try{ require('fs').unlinkSync('data.json') }catch(e){}
|
||||
try{ require('../../lib/fsrm')('radatatest') }catch(e){}
|
||||
//root.Gun = root.Gun || require('../gun');
|
||||
if(root.Gun){
|
||||
root.Gun = root.Gun;
|
||||
root.Gun.TESTING = true;
|
||||
} else {
|
||||
try{ require('fs').unlinkSync('data.json') }catch(e){}
|
||||
try{ require('../../lib/fsrm')('radatatest') }catch(e){}
|
||||
root.Gun = require('../../gun');
|
||||
root.Gun.TESTING = true;
|
||||
//require('../lib/file');
|
||||
@@ -31,6 +30,7 @@ Gun = root.Gun
|
||||
if(Gun.window && !Gun.window.RindexedDB){ return }
|
||||
|
||||
var opt = {};
|
||||
opt.file = 'radatatest';
|
||||
var Radisk = (Gun.window && Gun.window.Radisk) || require('../../lib/radisk');
|
||||
opt.store = ((Gun.window && Gun.window.RindexedDB) || require('../../lib/rfs'))(opt);
|
||||
opt.chunk = 1000;
|
||||
@@ -110,6 +110,20 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam
|
||||
expect(Gun.obj.empty(all)).to.be.ok();
|
||||
done();
|
||||
});
|
||||
|
||||
it('radix reverse', function(done){
|
||||
var r = Radix(), tmp;
|
||||
r('alice', 1);r('bob', 2);r('carl', 3);r('dave', 4);
|
||||
Radix.map(r, function(v,k, a,b){
|
||||
tmp = v;
|
||||
}, {reverse: 1});
|
||||
expect(tmp).to.be(1);
|
||||
Radix.map(r, function(v,k, a,b){
|
||||
tmp = v;
|
||||
});
|
||||
expect(tmp).to.be(4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Radisk', function(){
|
||||
@@ -138,6 +152,25 @@ var names = ["Adalard","Adora","Aia","Albertina","Alfie","Allyn","Amabil","Ammam
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
/*it('read contacts reverse', function(done){
|
||||
var opt = {};
|
||||
opt.reverse = true;
|
||||
opt.end = 'nothing';
|
||||
opt.start = 'marcy';
|
||||
var first, last;
|
||||
rad('', function(err, data){
|
||||
console.log("???", err, data);
|
||||
return;
|
||||
Radix.map(data, function(v,k){
|
||||
console.log(k, v);
|
||||
//delete all[find+k];
|
||||
});
|
||||
//if(!Gun.obj.empty(all)){ return }
|
||||
//done();
|
||||
}, opt);
|
||||
});
|
||||
console.log("UNDO THIS RETURN!!!");return;*/
|
||||
|
||||
it('read contacts start end', function(done){
|
||||
var opt = {};
|
||||
|
||||
@@ -7,24 +7,22 @@ var Gun;
|
||||
root = env.window? env.window : global;
|
||||
try{ env.window && root.localStorage && root.localStorage.clear() }catch(e){}
|
||||
try{ indexedDB.deleteDatabase('radatatest') }catch(e){}
|
||||
try{ require('fs').unlinkSync('data.json') }catch(e){}
|
||||
try{ require('../../lib/fsrm')('radatatest') }catch(e){}
|
||||
//root.Gun = root.Gun || require('../gun');
|
||||
if(root.Gun){
|
||||
root.Gun = root.Gun;
|
||||
root.Gun.TESTING = true;
|
||||
} else {
|
||||
try{ require('fs').unlinkSync('data.json') }catch(e){}
|
||||
try{ require('../../lib/fsrm')('radatatest') }catch(e){}
|
||||
root.Gun = require('../../gun');
|
||||
root.Gun.TESTING = true;
|
||||
//require('../lib/file');
|
||||
require('../lib/store');
|
||||
require('../lib/rfs');
|
||||
require('../../lib/store');
|
||||
require('../../lib/rfs');
|
||||
}
|
||||
|
||||
if(root.Gun.SEA){
|
||||
//Gun = root.Gun = root.Gun;
|
||||
} else {
|
||||
var expect = global.expect = require("../expect");
|
||||
try{ var expect = global.expect = require("../expect") }catch(e){}
|
||||
|
||||
if(!root.Gun.SEA){
|
||||
require('../../sea.js');
|
||||
}
|
||||
}(this));
|
||||
|
||||
Reference in New Issue
Block a user