mirror of
https://github.com/amark/gun.git
synced 2025-06-09 15:46:44 +00:00
make Radisk available in browser for @fuchidahiro
This commit is contained in:
parent
ae3839c531
commit
9474753a8e
@ -44,6 +44,11 @@ ul, li {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.model, .none { display: none }
|
.model, .none { display: none }
|
||||||
|
.hide {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transition: all 2s;
|
||||||
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -81,8 +86,7 @@ ul, li {
|
|||||||
padding: 3%;
|
padding: 3%;
|
||||||
}
|
}
|
||||||
.gully {
|
.gully {
|
||||||
margin-top: 2em;
|
margin-bottom: 1%;
|
||||||
margin-bottom: 2em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sit { margin-bottom: 0; }
|
.sit { margin-bottom: 0; }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
if(typeof window !== "undefined"){
|
if(typeof window !== "undefined"){
|
||||||
var Gun = window.Gun;
|
var Gun = window.Gun;
|
||||||
} else {
|
} else {
|
||||||
var Gun = require('gun/gun');
|
var Gun = require('../gun');
|
||||||
}
|
}
|
||||||
Gun.chain.open || require('gun/lib/open');
|
Gun.chain.open || require('./open');
|
||||||
|
|
||||||
Gun.chain.load = function(cb, opt, at){
|
Gun.chain.load = function(cb, opt, at){
|
||||||
(opt = opt || {}).off = !0;
|
(opt = opt || {}).off = !0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
if(typeof window !== "undefined"){
|
if(typeof window !== "undefined"){
|
||||||
var Gun = window.Gun;
|
var Gun = window.Gun;
|
||||||
} else {
|
} else {
|
||||||
var Gun = require('gun/gun');
|
var Gun = require('../gun');
|
||||||
}
|
}
|
||||||
|
|
||||||
Gun.chain.open = function(cb, opt, at){
|
Gun.chain.open = function(cb, opt, at){
|
||||||
|
646
lib/radisk.js
646
lib/radisk.js
@ -1,342 +1,350 @@
|
|||||||
var fs = require('fs');
|
;(function(){
|
||||||
var Gun = require('../gun');
|
|
||||||
var Radix = require('./radix');
|
|
||||||
|
|
||||||
function Radisk(opt){
|
function Radisk(opt){
|
||||||
|
|
||||||
opt = opt || {};
|
opt = opt || {};
|
||||||
opt.file = String(opt.file || 'radata');
|
opt.file = String(opt.file || 'radata');
|
||||||
opt.until = opt.until || opt.wait || 1000; // default for HDDs
|
opt.until = opt.until || opt.wait || 1000; // default for HDDs
|
||||||
opt.batch = opt.batch || 10 * 1000;
|
opt.batch = opt.batch || 10 * 1000;
|
||||||
opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB
|
opt.chunk = opt.chunk || (1024 * 1024 * 10); // 10MB
|
||||||
opt.code = opt.code || {};
|
opt.code = opt.code || {};
|
||||||
opt.code.from = opt.code.from || '!';
|
opt.code.from = opt.code.from || '!';
|
||||||
|
|
||||||
function ename(t){ return encodeURIComponent(t).replace(/\*/g, '%2A') }
|
function ename(t){ return encodeURIComponent(t).replace(/\*/g, '%2A') }
|
||||||
|
|
||||||
if(!opt.store){
|
if(!opt.store){
|
||||||
return Gun.log("ERROR: Radisk needs `opt.store` interface with `{get: fn, put: fn, list: fn}`!");
|
return Gun.log("ERROR: Radisk needs `opt.store` interface with `{get: fn, put: fn, list: fn}`!");
|
||||||
}
|
}
|
||||||
if(!opt.store.put){
|
if(!opt.store.put){
|
||||||
return Gun.log("ERROR: Radisk needs `store.put` interface with `(file, data, cb)`!");
|
return Gun.log("ERROR: Radisk needs `store.put` interface with `(file, data, cb)`!");
|
||||||
}
|
}
|
||||||
if(!opt.store.get){
|
if(!opt.store.get){
|
||||||
return Gun.log("ERROR: Radisk needs `store.get` interface with `(file, cb)`!");
|
return Gun.log("ERROR: Radisk needs `store.get` interface with `(file, cb)`!");
|
||||||
}
|
}
|
||||||
if(!opt.store.list){
|
if(!opt.store.list){
|
||||||
return Gun.log("ERROR: Radisk needs a streaming `store.list` interface with `(cb)`!");
|
return Gun.log("ERROR: Radisk needs a streaming `store.list` interface with `(cb)`!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Any and all storage adapters should...
|
Any and all storage adapters should...
|
||||||
1. Because writing to disk takes time, we should batch data to disk. This improves performance, and reduces potential disk corruption.
|
1. Because writing to disk takes time, we should batch data to disk. This improves performance, and reduces potential disk corruption.
|
||||||
2. If a batch exceeds a certain number of writes, we should immediately write to disk when physically possible. This caps total performance, but reduces potential loss.
|
2. If a batch exceeds a certain number of writes, we should immediately write to disk when physically possible. This caps total performance, but reduces potential loss.
|
||||||
*/
|
*/
|
||||||
var r = function(key, val, cb){
|
var r = function(key, val, cb){
|
||||||
key = ''+key;
|
key = ''+key;
|
||||||
if(val instanceof Function){
|
if(val instanceof Function){
|
||||||
cb = val;
|
cb = val;
|
||||||
val = r.batch(key);
|
val = r.batch(key);
|
||||||
if(u !== val){
|
if(u !== val){
|
||||||
return cb(u, val);
|
return cb(u, val);
|
||||||
|
}
|
||||||
|
if(r.thrash.at){
|
||||||
|
val = r.thrash.at(key);
|
||||||
|
if(u !== val){
|
||||||
|
return cb(u, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log("READ FROM DISK");
|
||||||
|
return r.read(key, cb);
|
||||||
}
|
}
|
||||||
if(r.thrash.at){
|
r.batch(key, val);
|
||||||
val = r.thrash.at(key);
|
if(cb){ r.batch.acks.push(cb) }
|
||||||
|
if(++r.batch.ed >= opt.batch){ return r.thrash() } // (2)
|
||||||
|
clearTimeout(r.batch.to); // (1)
|
||||||
|
r.batch.to = setTimeout(r.thrash, opt.until || 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
r.batch = Radix();
|
||||||
|
r.batch.acks = [];
|
||||||
|
r.batch.ed = 0;
|
||||||
|
|
||||||
|
r.thrash = function(){
|
||||||
|
var thrash = r.thrash;
|
||||||
|
if(thrash.ing){ return thrash.more = true }
|
||||||
|
thrash.more = false;
|
||||||
|
thrash.ing = true;
|
||||||
|
var batch = thrash.at = r.batch, i = 0;
|
||||||
|
clearTimeout(r.batch.to);
|
||||||
|
r.batch = null;
|
||||||
|
r.batch = Radix();
|
||||||
|
r.batch.acks = [];
|
||||||
|
r.batch.ed = 0;
|
||||||
|
r.save(batch, function(err, ok){
|
||||||
|
if(++i > 1){ return }
|
||||||
|
if(err){ Gun.log(err) }
|
||||||
|
Gun.obj.map(batch.acks, function(cb){ cb(err, ok) });
|
||||||
|
thrash.at = null;
|
||||||
|
thrash.ing = false;
|
||||||
|
if(thrash.more){ thrash() }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
1. Find the first radix item in memory.
|
||||||
|
2. Use that as the starting index in the directory of files.
|
||||||
|
3. Find the first file that is lexically larger than it,
|
||||||
|
4. Read the previous file to that into memory
|
||||||
|
5. Scan through the in memory radix for all values lexically less than the limit.
|
||||||
|
6. Merge and write all of those to the in-memory file and back to disk.
|
||||||
|
7. If file to large, split. More details needed here.
|
||||||
|
*/
|
||||||
|
r.save = function(rad, cb){
|
||||||
|
var s = function Span(){};
|
||||||
|
s.find = function(tree, key){
|
||||||
|
if(key < s.start){ return }
|
||||||
|
s.start = key;
|
||||||
|
opt.store.list(s.lex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
s.lex = function(file){
|
||||||
|
file = (u === file)? u : decodeURIComponent(file);
|
||||||
|
if(!file || file > s.start){
|
||||||
|
s.mix(s.file || opt.code.from, s.start, s.end = file);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
s.file = file;
|
||||||
|
}
|
||||||
|
s.mix = function(file, start, end){
|
||||||
|
s.start = s.end = s.file = u;
|
||||||
|
r.parse(file, function(err, disk){
|
||||||
|
if(err){ return cb(err) }
|
||||||
|
Radix.map(rad, function(val, key){
|
||||||
|
if(key < start){ return }
|
||||||
|
if(end && end < key){ return s.start = key }
|
||||||
|
// PLUGIN: consider adding HAM as an extra layer of protection
|
||||||
|
disk(key, val); // merge batch[key] -> disk[key]
|
||||||
|
});
|
||||||
|
r.write(file, disk, s.next);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
s.next = function(err, ok){
|
||||||
|
if(s.err = err){ return cb(err) }
|
||||||
|
if(s.start){ return Radix.map(rad, s.find) }
|
||||||
|
cb(err, ok);
|
||||||
|
}
|
||||||
|
Radix.map(rad, s.find);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Any storage engine at some point will have to do a read in order to write.
|
||||||
|
This is true of even systems that use an append only log, if they support updates.
|
||||||
|
Therefore it is unavoidable that a read will have to happen,
|
||||||
|
the question is just how long you delay it.
|
||||||
|
*/
|
||||||
|
r.write = function(file, rad, cb){
|
||||||
|
var f = function Fractal(){};
|
||||||
|
f.text = '';
|
||||||
|
f.count = 0;
|
||||||
|
f.file = file;
|
||||||
|
f.each = function(val, key, k, pre){
|
||||||
|
f.count++;
|
||||||
|
var enc = Radisk.encode(pre.length) +'#'+ Radisk.encode(k) + (u === val? '' : '='+ Radisk.encode(val)) +'\n';
|
||||||
|
if(opt.chunk < f.text.length + enc.length){
|
||||||
|
f.text = '';
|
||||||
|
f.limit = Math.ceil(f.count/2);
|
||||||
|
f.count = 0;
|
||||||
|
f.sub = Radix();
|
||||||
|
Radix.map(rad, f.slice);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
f.text += enc;
|
||||||
|
}
|
||||||
|
f.write = function(){ opt.store.put(ename(file), f.text, cb) }
|
||||||
|
f.slice = function(val, key){
|
||||||
|
if(key < f.file){ return }
|
||||||
|
if(f.limit < (++f.count)){
|
||||||
|
var name = f.file;
|
||||||
|
f.file = key;
|
||||||
|
f.count = 0;
|
||||||
|
r.write(name, f.sub, f.next);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
f.sub(key, val);
|
||||||
|
}
|
||||||
|
f.next = function(err){
|
||||||
|
if(err){ return cb(err) }
|
||||||
|
f.sub = Radix();
|
||||||
|
if(!Radix.map(rad, f.slice)){
|
||||||
|
r.write(f.file, f.sub, cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!Radix.map(rad, f.each, true)){ f.write() }
|
||||||
|
}
|
||||||
|
|
||||||
|
r.read = function(key, cb){
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
||||||
|
if(RAD){ // cache
|
||||||
|
var val = RAD(key);
|
||||||
if(u !== val){
|
if(u !== val){
|
||||||
return cb(u, val);
|
return cb(u, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log("READ FROM DISK");
|
var g = function Get(){}, tmp;
|
||||||
return r.read(key, cb);
|
g.lex = function(file){
|
||||||
}
|
file = (u === file)? u : decodeURIComponent(file);
|
||||||
r.batch(key, val);
|
if(!file || file > key){
|
||||||
if(cb){ r.batch.acks.push(cb) }
|
if(tmp = q[g.file]){
|
||||||
if(++r.batch.ed >= opt.batch){ return r.thrash() } // (2)
|
tmp.push({key: key, ack: cb});
|
||||||
clearTimeout(r.batch.to); // (1)
|
return true;
|
||||||
r.batch.to = setTimeout(r.thrash, opt.until || 1);
|
}
|
||||||
}
|
q[g.file] = [{key: key, ack: cb}];
|
||||||
|
r.parse(g.file, g.it);
|
||||||
r.batch = Radix();
|
|
||||||
r.batch.acks = [];
|
|
||||||
r.batch.ed = 0;
|
|
||||||
|
|
||||||
r.thrash = function(){
|
|
||||||
var thrash = r.thrash;
|
|
||||||
if(thrash.ing){ return thrash.more = true }
|
|
||||||
thrash.more = false;
|
|
||||||
thrash.ing = true;
|
|
||||||
var batch = thrash.at = r.batch, i = 0;
|
|
||||||
clearTimeout(r.batch.to);
|
|
||||||
r.batch = null;
|
|
||||||
r.batch = Radix();
|
|
||||||
r.batch.acks = [];
|
|
||||||
r.batch.ed = 0;
|
|
||||||
r.save(batch, function(err, ok){
|
|
||||||
if(++i > 1){ return }
|
|
||||||
if(err){ Gun.log(err) }
|
|
||||||
Gun.obj.map(batch.acks, function(cb){ cb(err, ok) });
|
|
||||||
thrash.at = null;
|
|
||||||
thrash.ing = false;
|
|
||||||
if(thrash.more){ thrash() }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
1. Find the first radix item in memory.
|
|
||||||
2. Use that as the starting index in the directory of files.
|
|
||||||
3. Find the first file that is lexically larger than it,
|
|
||||||
4. Read the previous file to that into memory
|
|
||||||
5. Scan through the in memory radix for all values lexically less than the limit.
|
|
||||||
6. Merge and write all of those to the in-memory file and back to disk.
|
|
||||||
7. If file to large, split. More details needed here.
|
|
||||||
*/
|
|
||||||
r.save = function(rad, cb){
|
|
||||||
var s = function Span(){};
|
|
||||||
s.find = function(tree, key){
|
|
||||||
if(key < s.start){ return }
|
|
||||||
s.start = key;
|
|
||||||
opt.store.list(s.lex);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
s.lex = function(file){
|
|
||||||
file = (u === file)? u : decodeURIComponent(file);
|
|
||||||
if(!file || file > s.start){
|
|
||||||
s.mix(s.file || opt.code.from, s.start, s.end = file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
s.file = file;
|
|
||||||
}
|
|
||||||
s.mix = function(file, start, end){
|
|
||||||
s.start = s.end = s.file = u;
|
|
||||||
r.parse(file, function(err, disk){
|
|
||||||
if(err){ return cb(err) }
|
|
||||||
Radix.map(rad, function(val, key){
|
|
||||||
if(key < start){ return }
|
|
||||||
if(end && end < key){ return s.start = key }
|
|
||||||
// PLUGIN: consider adding HAM as an extra layer of protection
|
|
||||||
disk(key, val); // merge batch[key] -> disk[key]
|
|
||||||
});
|
|
||||||
r.write(file, disk, s.next);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
s.next = function(err, ok){
|
|
||||||
if(s.err = err){ return cb(err) }
|
|
||||||
if(s.start){ return Radix.map(rad, s.find) }
|
|
||||||
cb(err, ok);
|
|
||||||
}
|
|
||||||
Radix.map(rad, s.find);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Any storage engine at some point will have to do a read in order to write.
|
|
||||||
This is true of even systems that use an append only log, if they support updates.
|
|
||||||
Therefore it is unavoidable that a read will have to happen,
|
|
||||||
the question is just how long you delay it.
|
|
||||||
*/
|
|
||||||
r.write = function(file, rad, cb){
|
|
||||||
var f = function Fractal(){};
|
|
||||||
f.text = '';
|
|
||||||
f.count = 0;
|
|
||||||
f.file = file;
|
|
||||||
f.each = function(val, key, k, pre){
|
|
||||||
f.count++;
|
|
||||||
var enc = Radisk.encode(pre.length) +'#'+ Radisk.encode(k) + (u === val? '' : '='+ Radisk.encode(val)) +'\n';
|
|
||||||
if(opt.chunk < f.text.length + enc.length){
|
|
||||||
f.text = '';
|
|
||||||
f.limit = Math.ceil(f.count/2);
|
|
||||||
f.count = 0;
|
|
||||||
f.sub = Radix();
|
|
||||||
Radix.map(rad, f.slice);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
f.text += enc;
|
|
||||||
}
|
|
||||||
f.write = function(){ opt.store.put(ename(file), f.text, cb) }
|
|
||||||
f.slice = function(val, key){
|
|
||||||
if(key < f.file){ return }
|
|
||||||
if(f.limit < (++f.count)){
|
|
||||||
var name = f.file;
|
|
||||||
f.file = key;
|
|
||||||
f.count = 0;
|
|
||||||
r.write(name, f.sub, f.next);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
f.sub(key, val);
|
|
||||||
}
|
|
||||||
f.next = function(err){
|
|
||||||
if(err){ return cb(err) }
|
|
||||||
f.sub = Radix();
|
|
||||||
if(!Radix.map(rad, f.slice)){
|
|
||||||
r.write(f.file, f.sub, cb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!Radix.map(rad, f.each, true)){ f.write() }
|
|
||||||
}
|
|
||||||
|
|
||||||
r.read = function(key, cb){
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
// TODO: BUG!!! If a node spans multiple file chunks, it won't return all!
|
|
||||||
if(RAD){ // cache
|
|
||||||
var val = RAD(key);
|
|
||||||
if(u !== val){
|
|
||||||
return cb(u, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var g = function Get(){}, tmp;
|
|
||||||
g.lex = function(file){
|
|
||||||
file = (u === file)? u : decodeURIComponent(file);
|
|
||||||
if(!file || file > key){
|
|
||||||
if(tmp = q[g.file]){
|
|
||||||
tmp.push({key: key, ack: cb});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
q[g.file] = [{key: key, ack: cb}];
|
g.file = file;
|
||||||
r.parse(g.file, g.it);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
g.file = file;
|
g.it = function(err, disk){
|
||||||
|
if(g.err = err){ Gun.log(err) }
|
||||||
|
if(disk){ RAD = disk }
|
||||||
|
disk = q[g.file]; Gun.obj.del(q, g.file);
|
||||||
|
Gun.obj.map(disk, g.ack);
|
||||||
|
}
|
||||||
|
g.ack = function(as){
|
||||||
|
if(!as.ack){ return }
|
||||||
|
as.ack(g.err, (RAD || noop)(as.key));
|
||||||
|
}
|
||||||
|
opt.store.list(g.lex);
|
||||||
}
|
}
|
||||||
g.it = function(err, disk){
|
/*
|
||||||
if(g.err = err){ Gun.log(err) }
|
Let us start by assuming we are the only process that is
|
||||||
if(disk){ RAD = disk }
|
changing the directory or bucket. Not because we do not want
|
||||||
disk = q[g.file]; Gun.obj.del(q, g.file);
|
to be multi-process/machine, but because we want to experiment
|
||||||
Gun.obj.map(disk, g.ack);
|
with how much performance and scale we can get out of only one.
|
||||||
|
Then we can work on the harder problem of being multi-process.
|
||||||
|
*/
|
||||||
|
r.parse = function(file, cb){
|
||||||
|
var p = function Parse(){}, s = String.fromCharCode(31);
|
||||||
|
p.disk = Radix();
|
||||||
|
p.read = function(err, data){ var tmp;
|
||||||
|
if(err){ return cb(err) }
|
||||||
|
if(!data){ return cb(u, p.disk) }
|
||||||
|
var tmp = p.split(data), pre = [], i, k, v;
|
||||||
|
while(tmp){
|
||||||
|
k = v = u;
|
||||||
|
i = tmp[1];
|
||||||
|
tmp = p.split(tmp[2])||'';
|
||||||
|
if('#' == tmp[0]){
|
||||||
|
k = tmp[1];
|
||||||
|
pre = pre.slice(0,i);
|
||||||
|
if(i <= pre.length){
|
||||||
|
pre.push(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp = p.split(tmp[2])||'';
|
||||||
|
if('\n' == tmp[0]){ continue }
|
||||||
|
if('=' == tmp[0]){ v = tmp[1] }
|
||||||
|
if(u !== k && u !== v){ p.disk(pre.join(''), v) }
|
||||||
|
tmp = p.split(tmp[2]);
|
||||||
|
}
|
||||||
|
cb(u, p.disk);
|
||||||
|
};
|
||||||
|
p.split = function(t){
|
||||||
|
if(!t){ return }
|
||||||
|
var l = [], o = {}, i = -1, a = '', b, c;
|
||||||
|
while(c = t[++i]){
|
||||||
|
if(s === c){ break }
|
||||||
|
a += c;
|
||||||
|
}
|
||||||
|
if(!c){ return }
|
||||||
|
l[0] = a;
|
||||||
|
l[1] = b = Radisk.decode(t.slice(i), o);
|
||||||
|
l[2] = t.slice(i + o.i);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
opt.store.get(ename(file), p.read);
|
||||||
}
|
}
|
||||||
g.ack = function(as){
|
|
||||||
if(!as.ack){ return }
|
var q = {}, noop = function(){}, RAD, u;
|
||||||
as.ack(g.err, (RAD || noop)(as.key));
|
return r;
|
||||||
}
|
|
||||||
opt.store.list(g.lex);
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
Let us start by assuming we are the only process that is
|
|
||||||
changing the directory or bucket. Not because we do not want
|
;(function(){
|
||||||
to be multi-process/machine, but because we want to experiment
|
s = String.fromCharCode(31);
|
||||||
with how much performance and scale we can get out of only one.
|
Radisk.encode = function(d, o){
|
||||||
Then we can work on the harder problem of being multi-process.
|
var t = s, tmp;
|
||||||
*/
|
if(typeof d == 'string'){
|
||||||
r.parse = function(file, cb){
|
var i = -1, c;
|
||||||
var p = function Parse(){}, s = String.fromCharCode(31);
|
while(c = d[++i]){
|
||||||
p.disk = Radix();
|
if(s === c){
|
||||||
p.read = function(err, data){ var tmp;
|
t += s;
|
||||||
if(err){ return cb(err) }
|
|
||||||
if(!data){ return cb(u, p.disk) }
|
|
||||||
var tmp = p.split(data), pre = [], i, k, v;
|
|
||||||
while(tmp){
|
|
||||||
k = v = u;
|
|
||||||
i = tmp[1];
|
|
||||||
tmp = p.split(tmp[2])||'';
|
|
||||||
if('#' == tmp[0]){
|
|
||||||
k = tmp[1];
|
|
||||||
pre = pre.slice(0,i);
|
|
||||||
if(i <= pre.length){
|
|
||||||
pre.push(k);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp = p.split(tmp[2])||'';
|
return t + '"' + d + s;
|
||||||
if('\n' == tmp[0]){ continue }
|
|
||||||
if('=' == tmp[0]){ v = tmp[1] }
|
|
||||||
if(u !== k && u !== v){ p.disk(pre.join(''), v) }
|
|
||||||
tmp = p.split(tmp[2]);
|
|
||||||
}
|
|
||||||
cb(u, p.disk);
|
|
||||||
};
|
|
||||||
p.split = function(t){
|
|
||||||
if(!t){ return }
|
|
||||||
var l = [], o = {}, i = -1, a = '', b, c;
|
|
||||||
while(c = t[++i]){
|
|
||||||
if(s === c){ break }
|
|
||||||
a += c;
|
|
||||||
}
|
|
||||||
if(!c){ return }
|
|
||||||
l[0] = a;
|
|
||||||
l[1] = b = Radisk.decode(t.slice(i), o);
|
|
||||||
l[2] = t.slice(i + o.i);
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
opt.store.get(ename(file), p.read);
|
|
||||||
}
|
|
||||||
|
|
||||||
var q = {}, noop = function(){}, RAD, u;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
;(function(){
|
|
||||||
s = String.fromCharCode(31);
|
|
||||||
Radisk.encode = function(d, o){
|
|
||||||
var t = s, tmp;
|
|
||||||
if(typeof d == 'string'){
|
|
||||||
var i = -1, c;
|
|
||||||
while(c = d[++i]){
|
|
||||||
if(s === c){
|
|
||||||
t += s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t + '"' + d + s;
|
|
||||||
} else
|
|
||||||
if(d && d['#'] && (tmp = Gun.val.link.is(d))){
|
|
||||||
return t + '#' + tmp + t;
|
|
||||||
} else
|
|
||||||
if(Gun.num.is(d)){
|
|
||||||
return t + '+' + (d||0) + t;
|
|
||||||
} else
|
|
||||||
if(null === d){
|
|
||||||
return t + ' ' + t;
|
|
||||||
} else
|
|
||||||
if(true === d){
|
|
||||||
return t + '+' + t;
|
|
||||||
} else
|
|
||||||
if(false === d){
|
|
||||||
return t + '-' + t;
|
|
||||||
}// else
|
|
||||||
//if(binary){}
|
|
||||||
}
|
|
||||||
Radisk.decode = function(t, o){
|
|
||||||
var d = '', i = -1, n = 0, c, p;
|
|
||||||
if(s !== t[0]){ return }
|
|
||||||
while(c = t[++i]){
|
|
||||||
if(p){
|
|
||||||
if(s === c){
|
|
||||||
if(--n <= 0){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d += c;
|
|
||||||
} else
|
} else
|
||||||
if(s === c){
|
if(d && d['#'] && (tmp = Gun.val.link.is(d))){
|
||||||
++n;
|
return t + '#' + tmp + t;
|
||||||
} else {
|
} else
|
||||||
p = c || true;
|
if(Gun.num.is(d)){
|
||||||
|
return t + '+' + (d||0) + t;
|
||||||
|
} else
|
||||||
|
if(null === d){
|
||||||
|
return t + ' ' + t;
|
||||||
|
} else
|
||||||
|
if(true === d){
|
||||||
|
return t + '+' + t;
|
||||||
|
} else
|
||||||
|
if(false === d){
|
||||||
|
return t + '-' + t;
|
||||||
|
}// else
|
||||||
|
//if(binary){}
|
||||||
|
}
|
||||||
|
Radisk.decode = function(t, o){
|
||||||
|
var d = '', i = -1, n = 0, c, p;
|
||||||
|
if(s !== t[0]){ return }
|
||||||
|
while(c = t[++i]){
|
||||||
|
if(p){
|
||||||
|
if(s === c){
|
||||||
|
if(--n <= 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d += c;
|
||||||
|
} else
|
||||||
|
if(s === c){
|
||||||
|
++n;
|
||||||
|
} else {
|
||||||
|
p = c || true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(o){ o.i = i+1 }
|
||||||
|
if('"' === p){
|
||||||
|
return d;
|
||||||
|
} else
|
||||||
|
if('#' === p){
|
||||||
|
return Gun.val.link.ify(d);
|
||||||
|
} else
|
||||||
|
if('+' === p){
|
||||||
|
if(0 === d.length){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return parseFloat(d);
|
||||||
|
} else
|
||||||
|
if(' ' === p){
|
||||||
|
return null;
|
||||||
|
} else
|
||||||
|
if('-' === p){
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(o){ o.i = i+1 }
|
}());
|
||||||
if('"' === p){
|
|
||||||
return d;
|
if(typeof window !== "undefined"){
|
||||||
} else
|
var Gun = window.Gun;
|
||||||
if('#' === p){
|
var Radix = window.Radix;
|
||||||
return Gun.val.link.ify(d);
|
window.Radisk = Radisk;
|
||||||
} else
|
} else {
|
||||||
if('+' === p){
|
var Gun = require('../gun');
|
||||||
if(0 === d.length){
|
var Radix = require('./radix');
|
||||||
return true;
|
try{ module.exports = Radisk }catch(e){}
|
||||||
}
|
|
||||||
return parseFloat(d);
|
|
||||||
} else
|
|
||||||
if(' ' === p){
|
|
||||||
return null;
|
|
||||||
} else
|
|
||||||
if('-' === p){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Radisk.Radix = Radix;
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
Radisk.Radix = Radix;
|
|
||||||
|
|
||||||
module.exports = Radisk;
|
|
18
lib/radix.js
18
lib/radix.js
@ -1,8 +1,4 @@
|
|||||||
var Gun = require('../gun');
|
|
||||||
;(function(){
|
;(function(){
|
||||||
var map = Gun.obj.map, no = {}, u;
|
|
||||||
|
|
||||||
var $ = String.fromCharCode(30), _ = String.fromCharCode(29);
|
|
||||||
|
|
||||||
function Radix(){
|
function Radix(){
|
||||||
var radix = function(key, val, t){
|
var radix = function(key, val, t){
|
||||||
@ -46,6 +42,7 @@ var Gun = require('../gun');
|
|||||||
}
|
}
|
||||||
return radix;
|
return radix;
|
||||||
};
|
};
|
||||||
|
|
||||||
Radix.map = function map(radix, cb, opt, pre){ pre = pre || [];
|
Radix.map = function map(radix, cb, opt, pre){ pre = pre || [];
|
||||||
var t = radix[_] || radix, keys = Object.keys(t).sort(), i = 0, l = keys.length;
|
var t = radix[_] || radix, keys = Object.keys(t).sort(), i = 0, l = keys.length;
|
||||||
for(;i < l; i++){ var key = keys[i], tree = t[key], tmp;
|
for(;i < l; i++){ var key = keys[i], tree = t[key], tmp;
|
||||||
@ -64,7 +61,18 @@ var Gun = require('../gun');
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }
|
Object.keys = Object.keys || function(o){ return map(o, function(v,k,t){t(k)}) }
|
||||||
|
|
||||||
module.exports = Radix;
|
if(typeof window !== "undefined"){
|
||||||
|
var Gun = window.Gun;
|
||||||
|
window.Radix = Radix;
|
||||||
|
} else {
|
||||||
|
var Gun = require('../gun');
|
||||||
|
try{ module.exports = Radix }catch(e){}
|
||||||
|
}
|
||||||
|
|
||||||
|
var map = Gun.obj.map, no = {}, u;
|
||||||
|
var $ = String.fromCharCode(30), _ = String.fromCharCode(29);
|
||||||
|
|
||||||
}());
|
}());
|
61
lib/rfs.js
Normal file
61
lib/rfs.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
function Store(opt){
|
||||||
|
opt = opt || {};
|
||||||
|
opt.file = String(opt.file || 'radata');
|
||||||
|
|
||||||
|
var Gun = require('../gun'), fs = require('fs'), u;
|
||||||
|
var store = function Store(){};
|
||||||
|
store.put = function(file, data, cb){
|
||||||
|
var random = Math.random().toString(36).slice(-3)
|
||||||
|
fs.writeFile(opt.file+'-'+random+'.tmp', data, function(err, ok){
|
||||||
|
if(err){ return cb(err) }
|
||||||
|
move(opt.file+'-'+random+'.tmp', opt.file+'/'+file, cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
store.get = function(file, cb){
|
||||||
|
fs.readFile(opt.file+'/'+file, function(err, data){
|
||||||
|
if(err){
|
||||||
|
if('ENOENT' === (err.code||'').toUpperCase()){
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
Gun.log("ERROR:", err)
|
||||||
|
}
|
||||||
|
if(data){ data = data.toString() }
|
||||||
|
cb(err, data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
store.list = function(cb, match){
|
||||||
|
fs.readdir(opt.file, function(err, dir){
|
||||||
|
Gun.obj.map(dir, cb) || cb(); // Stream interface requires a final call to know when to be done.
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if(!fs.existsSync(opt.file)){ fs.mkdirSync(opt.file) }
|
||||||
|
//store.list(function(){ return true });
|
||||||
|
|
||||||
|
function move(oldPath, newPath, cb) {
|
||||||
|
fs.rename(oldPath, newPath, function (err) {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 'EXDEV') {
|
||||||
|
var readStream = fs.createReadStream(oldPath);
|
||||||
|
var writeStream = fs.createWriteStream(newPath);
|
||||||
|
|
||||||
|
readStream.on('error', cb);
|
||||||
|
writeStream.on('error', cb);
|
||||||
|
|
||||||
|
readStream.on('close', function () {
|
||||||
|
fs.unlink(oldPath, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
readStream.pipe(writeStream);
|
||||||
|
} else {
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Store;
|
97
lib/store.js
97
lib/store.js
@ -1,17 +1,21 @@
|
|||||||
var Gun = require('../gun');
|
if(typeof window === "undefined"){
|
||||||
var Radisk = require('./radisk');
|
var Gun = require('../gun');
|
||||||
var fs = require('fs');
|
}
|
||||||
var Radix = Radisk.Radix;
|
|
||||||
var u;
|
|
||||||
|
|
||||||
Gun.on('opt', function(ctx){
|
Gun.on('opt', function(ctx){
|
||||||
this.to.next(ctx);
|
this.to.next(ctx);
|
||||||
var opt = ctx.opt;
|
var opt = ctx.opt, u;
|
||||||
|
if(typeof window !== "undefined"){
|
||||||
|
opt.window = window;
|
||||||
|
}
|
||||||
if(ctx.once){ return }
|
if(ctx.once){ return }
|
||||||
if(false !== opt.localStorage && !process.env.AWS_S3_BUCKET){ return } // TODO: Remove this after migration.
|
if(false !== opt.localStorage && !(!opt.window && process.env.AWS_S3_BUCKET)){ return } // TODO: Remove this after migration.
|
||||||
if(false === opt.radisk){ return }
|
if(false === opt.radisk){ return }
|
||||||
console.log("BUG WARNING: Radix Storage Engine (RAD) has a known rare edge case, if data gets split between file chunks, a GET may only return the first chunk!!!");
|
console.log("BUG WARNING: Radix Storage Engine (RAD) has a known rare edge case, if data gets split between file chunks, a GET may only return the first chunk!!!");
|
||||||
opt.store = opt.store || Store(opt);
|
var Radisk = (opt.window && opt.window.Radisk) || require('./radisk');
|
||||||
|
var Radix = Radisk.Radix;
|
||||||
|
|
||||||
|
opt.store = opt.store || (!opt.window && require('./rfs')(opt));
|
||||||
var rad = Radisk(opt);
|
var rad = Radisk(opt);
|
||||||
|
|
||||||
ctx.on('put', function(at){
|
ctx.on('put', function(at){
|
||||||
@ -53,80 +57,3 @@ Gun.on('opt', function(ctx){
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function Store(opt){
|
|
||||||
opt = opt || {};
|
|
||||||
opt.file = String(opt.file || 'radata');
|
|
||||||
|
|
||||||
var store = function Store(){};
|
|
||||||
store.put = function(file, data, cb){
|
|
||||||
var random = Math.random().toString(36).slice(-3)
|
|
||||||
fs.writeFile(opt.file+'-'+random+'.tmp', data, function(err, ok){
|
|
||||||
if(err){ return cb(err) }
|
|
||||||
move(opt.file+'-'+random+'.tmp', opt.file+'/'+file, cb);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
store.get = function(file, cb){
|
|
||||||
fs.readFile(opt.file+'/'+file, function(err, data){
|
|
||||||
if(err){
|
|
||||||
if('ENOENT' === (err.code||'').toUpperCase()){
|
|
||||||
return cb(null);
|
|
||||||
}
|
|
||||||
Gun.log("ERROR:", err)
|
|
||||||
}
|
|
||||||
if(data){ data = data.toString() }
|
|
||||||
cb(err, data);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
store.list = function(cb, match){
|
|
||||||
fs.readdir(opt.file, function(err, dir){
|
|
||||||
Gun.obj.map(dir, cb) || cb(); // Stream interface requires a final call to know when to be done.
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if(!fs.existsSync(opt.file)){ fs.mkdirSync(opt.file) }
|
|
||||||
//store.list(function(){ return true });
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
|
|
||||||
function move(oldPath, newPath, cb) {
|
|
||||||
fs.rename(oldPath, newPath, function (err) {
|
|
||||||
if (err) {
|
|
||||||
if (err.code === 'EXDEV') {
|
|
||||||
var readStream = fs.createReadStream(oldPath);
|
|
||||||
var writeStream = fs.createWriteStream(newPath);
|
|
||||||
|
|
||||||
readStream.on('error', cb);
|
|
||||||
writeStream.on('error', cb);
|
|
||||||
|
|
||||||
readStream.on('close', function () {
|
|
||||||
fs.unlink(oldPath, cb);
|
|
||||||
});
|
|
||||||
|
|
||||||
readStream.pipe(writeStream);
|
|
||||||
} else {
|
|
||||||
cb(err);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Store;
|
|
||||||
|
|
||||||
|
|
||||||
;(function(){
|
|
||||||
return;
|
|
||||||
process.env.AWS_S3_BUCKET = 'test-s3';
|
|
||||||
process.env.AWS_ACCESS_KEY_ID = 'asdf';
|
|
||||||
process.env.AWS_SECRET_ACCESS_KEY = 'fdsa';
|
|
||||||
process.env.fakes3 = 'http://localhost:4567';
|
|
||||||
process.env.AWS_S3_THROTTLE = 0;
|
|
||||||
|
|
||||||
return;
|
|
||||||
global.Gun = require('../gun');
|
|
||||||
//require('./rs3');
|
|
||||||
|
|
||||||
|
|
||||||
require('../test/abc');
|
|
||||||
}());
|
|
@ -1,5 +1,5 @@
|
|||||||
if(typeof window === "undefined"){ //Not in the browser, Include from node
|
if(typeof window === "undefined"){ //Not in the browser, Include from node
|
||||||
var Gun = require('gun/gun');
|
var Gun = require('../gun');
|
||||||
}
|
}
|
||||||
|
|
||||||
;(function(){
|
;(function(){
|
||||||
|
@ -27,7 +27,11 @@
|
|||||||
var file = (((e.event || e).target || e).result || e), img = new Image();
|
var file = (((e.event || e).target || e).result || e), img = new Image();
|
||||||
img.src = file;
|
img.src = file;
|
||||||
img.onload = function(){
|
img.onload = function(){
|
||||||
if(!h && img.width > w){ h = img.height * (w / img.width) }
|
if(img.width < w && img.height < (h||Infinity)){
|
||||||
|
e.base64 = file;
|
||||||
|
return cb(e || file);
|
||||||
|
}
|
||||||
|
if(!h){ h = img.height * (w / img.width) }
|
||||||
var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');
|
var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');
|
||||||
canvas.width = w;
|
canvas.width = w;
|
||||||
canvas.height = h;
|
canvas.height = h;
|
||||||
|
@ -3,10 +3,12 @@ var config = {
|
|||||||
port: 8080,
|
port: 8080,
|
||||||
servers: 2,
|
servers: 2,
|
||||||
browsers: 2,
|
browsers: 2,
|
||||||
each: 2000,
|
each: 100,
|
||||||
burst: 50,
|
burst: 50,
|
||||||
wait: 1,
|
wait: 1,
|
||||||
dir: __dirname,
|
dir: __dirname,
|
||||||
|
chunk: 1024 * 10,
|
||||||
|
notrad: false,
|
||||||
route: {
|
route: {
|
||||||
'/': __dirname + '/index.html',
|
'/': __dirname + '/index.html',
|
||||||
'/gun.js': __dirname + '/../../gun.js',
|
'/gun.js': __dirname + '/../../gun.js',
|
||||||
@ -50,25 +52,19 @@ describe("Make sure the Radix Storage Engine (RSE) works.", function(){
|
|||||||
it("GUN started!", function(){
|
it("GUN started!", function(){
|
||||||
return server.run(function(test){
|
return server.run(function(test){
|
||||||
var env = test.props;
|
var env = test.props;
|
||||||
console.log("????", process.argv);
|
|
||||||
test.async();
|
test.async();
|
||||||
if(require('fs').existsSync('radata')){
|
if(require('fs').existsSync('radata')){
|
||||||
console.log("Please delete previous data first!");
|
console.log("Please delete previous data first!");
|
||||||
explode;
|
explode;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*setInterval(function(){
|
|
||||||
var mem = process.memoryUsage();
|
|
||||||
var u = Math.round(mem.heapUsed / 1024 / 1024 * 100) / 100;
|
|
||||||
console.log(u, 'MB of', Math.round(mem.heapTotal / 1024 / 1024 * 100) / 100);
|
|
||||||
}, 1000);*/
|
|
||||||
var port = env.config.port + env.i;
|
var port = env.config.port + env.i;
|
||||||
var server = require('http').createServer(function(req, res){
|
var server = require('http').createServer(function(req, res){
|
||||||
res.end("I am "+ env.i +"!");
|
res.end("I am "+ env.i +"!");
|
||||||
});
|
});
|
||||||
var Gun = require('gun');
|
var Gun = require('gun');
|
||||||
//require('gun/lib/store');
|
//require('gun/lib/store');
|
||||||
var gun = Gun({web: server, localStorage: false, until: 1, memory: 50, chunk: 1024 * 100});
|
var gun = Gun({web: server, localStorage: env.config.notrad, until: 1, memory: 50, chunk: env.config.chunk, file: 'radata'});
|
||||||
server.listen(port, function(){
|
server.listen(port, function(){
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
@ -86,7 +82,7 @@ describe("Make sure the Radix Storage Engine (RSE) works.", function(){
|
|||||||
console.log("I AM ALICE");
|
console.log("I AM ALICE");
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
var env = test.props;
|
var env = test.props;
|
||||||
var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: false});
|
var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 1) + '/gun', localStorage: env.config.notrad});
|
||||||
window.gun = gun;
|
window.gun = gun;
|
||||||
|
|
||||||
var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each;
|
var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each;
|
||||||
@ -154,7 +150,7 @@ describe("Make sure the Radix Storage Engine (RSE) works.", function(){
|
|||||||
});
|
});
|
||||||
var Gun = require('gun');
|
var Gun = require('gun');
|
||||||
//require('gun/lib/store');
|
//require('gun/lib/store');
|
||||||
var gun = Gun({web: server, localStorage: false, until: 1, memory: 50, chunk: 1024 * 100});
|
var gun = Gun({web: server, localStorage: env.config.notrad, until: 1, memory: 50, chunk: env.config.notrad, file: 'radata'});
|
||||||
server.listen(port, function(){
|
server.listen(port, function(){
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
@ -167,11 +163,12 @@ describe("Make sure the Radix Storage Engine (RSE) works.", function(){
|
|||||||
console.log("I AM BOB");
|
console.log("I AM BOB");
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
var env = test.props;
|
var env = test.props;
|
||||||
var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: false});
|
var gun = Gun({peers: 'http://'+ env.config.IP + ':' + (env.config.port + 2) + '/gun', localStorage: env.config.notrad});
|
||||||
window.gun = gun;
|
window.gun = gun;
|
||||||
|
|
||||||
var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each;
|
var n = Gun.time.is(), i = 0, c = 0, b = env.config.burst, l = env.config.each;
|
||||||
var raw = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
var raw = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
window.FOO = [];
|
||||||
|
|
||||||
function check(i){
|
function check(i){
|
||||||
if(i > l){
|
if(i > l){
|
||||||
@ -183,7 +180,8 @@ describe("Make sure the Radix Storage Engine (RSE) works.", function(){
|
|||||||
if((raw+i) !== data.hello){ return test.fail('wrong ' + i) }
|
if((raw+i) !== data.hello){ return test.fail('wrong ' + i) }
|
||||||
if(d){ return } d = true;
|
if(d){ return } d = true;
|
||||||
//!(c % b) &&
|
//!(c % b) &&
|
||||||
console.log(c+'/'+l);//, '@'+Math.floor(b/((-n + (n = Gun.time.is()))/1000))+'/sec'));
|
window.FOO.push(i);
|
||||||
|
console.log(c+'/'+l, 'yeah?', i, Gun.node.soul(data));//, '@'+Math.floor(b/((-n + (n = Gun.time.is()))/1000))+'/sec'));
|
||||||
window.GOT = c++;
|
window.GOT = c++;
|
||||||
//localStorage.clear();
|
//localStorage.clear();
|
||||||
ref.off();
|
ref.off();
|
||||||
|
34
test/radisk.html
Normal file
34
test/radisk.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<h1>Radisk</h1>
|
||||||
|
|
||||||
|
<script src="../examples/jquery.js"></script>
|
||||||
|
<script src="../gun.js"></script>
|
||||||
|
<script src="../lib/radix.js"></script>
|
||||||
|
<script src="../lib/radisk.js"></script>
|
||||||
|
<script src="../lib/store.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
function Store(opt){
|
||||||
|
console.log(opt);
|
||||||
|
opt = opt || {};
|
||||||
|
opt.file = String(opt.file || 'radata');
|
||||||
|
var storage = {};
|
||||||
|
var store = function Store(){};
|
||||||
|
store.put = function(file, data, cb){
|
||||||
|
storage[file] = data
|
||||||
|
cb(undefined, 1)
|
||||||
|
};
|
||||||
|
store.get = function(file, cb){
|
||||||
|
var temp = storage[file] || undefined
|
||||||
|
cb(temp)
|
||||||
|
};
|
||||||
|
store.list = function(cb, match){
|
||||||
|
var arr = Object.entries(storage)[0];
|
||||||
|
Gun.obj.map(arr, cb) || cb();
|
||||||
|
};
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
var gun = Gun({localStorage: false, store: Store()});
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user