diff --git a/Procfile b/Procfile index 0a818360..27c577d6 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: node init.js \ No newline at end of file +web: node examples/admin/app.js \ No newline at end of file diff --git a/examples/admin/app.js b/examples/admin/app.js new file mode 100644 index 00000000..20fb878a --- /dev/null +++ b/examples/admin/app.js @@ -0,0 +1,25 @@ +console.log("If modules not found, run `npm install` in example/admin folder!"); +var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || 8888; +var express = require('express'); +var bodyParser = require('body-parser'); +var app = express(); +var Gun = require('gun'); + +var gun = Gun({ + peers: 'http://localhost:' + port + '/gun' + ,s3: require('../../test/shotgun') // replace this with your own keys! +}); + +app.use(express.static(__dirname)) + .use(bodyParser.json()) + .use(gun.server); + +app.listen(port); +console.log('Express started on port ' + port + ' with /gun'); + +gun.load('blob/data', function(){ // ugly little idempotent initializer, in case no data is set + gun.set({_:{'#': "yVbyf7BqlXVQQUOE5cw9rf8h",'>':{hello: 1407328713707,from: 1407328713707}}, // this is an actual gun object, this won't overwrite any new changes + hello: "world", + from: "Mark Nadal" + }).key('blob/data'); +}); \ No newline at end of file diff --git a/examples/admin/data.json b/examples/admin/data.json deleted file mode 100644 index 6a5cb0ee..00000000 --- a/examples/admin/data.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "_":{ - "#":"yVbyf7BqlXVQQUOE5cw9rf8h", - ">":{ - "hello":1407328713707, - "from":1407328713707 - } - }, - "hello":"world", - "from":"Mark Nadal" -} \ No newline at end of file diff --git a/examples/admin/index.html b/examples/admin/index.html index d3837ea7..4e9948d5 100644 --- a/examples/admin/index.html +++ b/examples/admin/index.html @@ -3,9 +3,6 @@ - @@ -37,9 +34,6 @@
{{key}}: {{val}} -
  • @@ -53,31 +47,32 @@
  • \ No newline at end of file diff --git a/examples/admin/package.json b/examples/admin/package.json new file mode 100644 index 00000000..4cd8d27b --- /dev/null +++ b/examples/admin/package.json @@ -0,0 +1,9 @@ +{ + "name": "admin", + "main": "app.js", + "dependencies": { + "express": "~>4.9.0", + "body-parser": "~>1.8.1", + "gun": "~>0.0.2b" + } +} \ No newline at end of file diff --git a/examples/node_modules/gun/index.js b/examples/node_modules/gun/index.js new file mode 100644 index 00000000..292363e0 --- /dev/null +++ b/examples/node_modules/gun/index.js @@ -0,0 +1 @@ +module.exports = require('../../shots'); \ No newline at end of file diff --git a/examples/social/server.js b/examples/social/server.js index 9f9ca45e..c399e0d1 100644 --- a/examples/social/server.js +++ b/examples/social/server.js @@ -1,7 +1,11 @@ var fs = require('fs'); var http = require('http'); var qs = require('querystring'); -var gun = require('../../test/shotgun'); +var Gun = require('gun'); +var gun = Gun({ + peers: 'http://localhost:8888/gun' + ,s3: require('../../test/shotgun') // replace this with your own keys! +}); http.route = function(url){ console.log(url); diff --git a/examples/social/sign.js b/examples/social/sign.js index 843aeedb..a1504431 100644 --- a/examples/social/sign.js +++ b/examples/social/sign.js @@ -1,8 +1,12 @@ var sign = {}; -var gun = require('../../test/shotgun'); +var Gun = require('gun'); +var gun = Gun({ + peers: 'http://localhost:8888/gun' + ,s3: require('../../test/shotgun') // replace this with your own keys! +}); sign.user = {} -sign.user.create = function(form, cb, shell){ // TODO: REDO THIS TO MATCH GUN +sign.user.create = function(form, cb, shell){ sign.crypto(form, function(err, user){ if(err || !user){ return cb(err) } user = {key: user.key, salt: user.salt}; @@ -11,28 +15,9 @@ sign.user.create = function(form, cb, shell){ // TODO: REDO THIS TO MATCH GUN cb(null, user); }); }; - -/* -gun.load('email/mark@accelsor.com') - .path('friends') - .match({name: "David Oliveros"}) - .path('friends') - .match({activity: 'surfer'}) - .get(function(surfer){ - sendEmail("Mark wants to leanr how ot surf, and you are a friend of a friend"); - }); -*/ sign.server = function(req, res){ console.log("sign.server", req.headers, req.body); - /*res.emit('data', {ok: 1}); - res.emit('data', {ok: 2}); - res.emit('data', {ok: 3}); - res.emit('data', {ok: 4}); - setTimeout(function(){ - res.emit('end', {ok: 5}); - }, 5000); - return;*/ if(!req.body || !req.body.email){ return res.emit('end', {err: "That email does not exist."}) } var user = gun.load('email/' + req.body.email, function(data){ // this callback is called the magazine, since it holds the clip console.log("data from key", data); diff --git a/fixtures/network.js b/fixtures/network.js index 9098efef..c8c50316 100644 --- a/fixtures/network.js +++ b/fixtures/network.js @@ -33,7 +33,9 @@ b.forEach(function (user, i) { user.friends = chance.shuffle(users).slice(chance.integer({ min: 20, max: (num < 120)? num : 120 })); }); -var gun = require('../test/shotgun'); +var gun = require('gun')({ + s3: require('../test/shotgun') // replace this with your own keys! +}); gun.set(b[0]); diff --git a/gate/s3.js b/gate/s3.js index c9701c3a..06671654 100644 --- a/gate/s3.js +++ b/gate/s3.js @@ -67,7 +67,7 @@ s.batch = s.batch || {}; if(s.batch[id]){ return s } s.batch[id] = (s.batch[id] || 0) + 1; - console.log("no batch!", id); + console.log("no batch!"); s.S3().getObject(m, function(e,r){ var d, t, m, r = r || (this && this.httpResponse); if(e || !r){ return s.own.on(id).emit(e) } diff --git a/gate/s3pricing.html b/gate/s3pricing.html new file mode 100644 index 00000000..cf13f4fb --- /dev/null +++ b/gate/s3pricing.html @@ -0,0 +1,64 @@ + + + + + + + + + +
    +

    + This page is for throughput calculation, it assumes continuous load non-stop. +

    + + + \ No newline at end of file diff --git a/gun.js b/gun.js index 5952f411..57a3bebe 100644 --- a/gun.js +++ b/gun.js @@ -9,53 +9,64 @@ Gun.is = function(gun){ return (gun instanceof Gun)? true : false } Gun._ = {}; Gun.chain = Gun.prototype; - Gun.chain._ = {}; - Gun.chain._.opt = {}; - Gun.chain._.nodes = {}; - Gun.chain._.chain = {}; - Gun.chain._.trace = []; - Gun.chain._.keys = {}; Gun.chain.init = function(opt, stun){ // idempotently update or set options var gun = this; - gun._.events = gun._.events || Gun.on.split(); // we may not want it global for each gun instance? - gun._.events.trace = gun._.events.trace || 0; - gun._.events.at = gun._.events.at || 0; + gun._ = gun._ || {}; + gun.__ = gun.__ || {}; + if(!opt){ return gun } + gun.__.opt = gun.__.opt || {}; + gun.__.keys = gun.__.keys || {}; + gun.__.nodes = gun.__.nodes || {}; if(Gun.text.is(opt)){ opt = {peers: opt} } if(Gun.list.is(opt)){ opt = {peers: opt} } if(Gun.text.is(opt.peers)){ opt.peers = [opt.peers] } if(Gun.list.is(opt.peers)){ opt.peers = Gun.obj.map(opt.peers, function(n,f,m){ m(n,{}) }) } - gun._.opt.peers = opt.peers || gun._.opt.peers || {}; - gun._.opt.uuid = opt.uuid || gun._.opt.uuid || {}; - gun._.opt.hook = gun._.opt.hook || {}; + gun.__.opt.peers = opt.peers || gun.__.opt.peers || {}; + gun.__.opt.uuid = opt.uuid || gun.__.opt.uuid || {}; + gun.__.opt.hook = gun.__.opt.hook || {}; Gun.obj.map(opt.hook, function(h, f){ if(!Gun.fns.is(h)){ return } - gun._.opt.hook[f] = h; + gun.__.opt.hook[f] = h; }); if(!stun){ Gun.on('init').emit(gun, opt) } return gun; } + Gun.chain.chain = function(from){ + var gun = Gun(); + from = from || this; + gun.__ = from.__; + gun._ = {}; + Gun.obj.map(from._, function(val, field){ + gun._[field] = val; + }); + gun._.events = Gun.on.split(); // we want events per chain + gun._.events.trace = gun._.events.trace || 0; + gun._.events.at = gun._.events.at || 0; + return gun; + } Gun.chain.load = function(key, cb, opt){ - var gun = this; + var gun = this.chain(); cb = cb || function(){}; - if(cb.node = gun._.keys[key]){ // set this to the current node, too! + if(cb.node = gun.__.keys[key]){ // set this to the current node, too! Gun.log("from gun"); // remember to do all the same stack stuff here also! return cb(Gun.obj.copy(gun._.node = cb.node)), gun; // TODO: BUG: This needs to be frozen/copied, and react the same as below! } cb.fn = function(){} gun._.key = key; // missing: hear shots! - if(Gun.fns.is(gun._.opt.hook.load)){ - gun._.opt.hook.load(key, function(err, data){ + if(Gun.fns.is(gun.__.opt.hook.load)){ + gun.__.opt.hook.load(key, function(err, data){ gun._.loaded = (gun._.loaded || 0) + 1; // TODO: loading should be idempotent even if we got an err or no data - if(err){ return (gun._.chain.dud||cb.fn)(err) } - if(!data){ return (gun._.chain.blank||cb.fn)() } - var nodes = {}, node; - nodes[data._[own.sym.id]] = data;// missing: transform data, merging it! NO, THIS IS DONE WRONG, do a real check. - Gun.union(gun._.nodes, nodes); - node = gun._.keys[key] = gun._.nodes[data._[own.sym.id]]; - cb(Gun.obj.copy(gun._.node = node)); - gun._.events.on(gun._.events.at += 1).emit(node); - gun._.events.at = 0; // ???? reset it back once everything is done? + if(err){ return (gun._.dud||cb.fn)(err) } + if(!data){ return (gun._.blank||cb.fn)() } + var context = {nodes: {}}; + context.nodes[data._[own.sym.id]] = data; + context = Gun.chain.set.now.union.call(gun, context.nodes); // data safely transformed + if(context.err){ return (gun._.dud||cb.fn)(context.err) } + gun._.node = gun.__.keys[key] = gun.__.nodes[data._[own.sym.id]]; + cb(Gun.obj.copy(gun._.node)); + gun._.events.on(gun._.events.at += 1).emit(gun._.node); + gun._.events.at = 0; // ???? reset it back once everything is done? the returns above don't allow for this. }, opt); } else { Gun.log("Warning! You have no persistence layer to load from!"); @@ -65,9 +76,9 @@ Gun.chain.key = function(key, cb){ // TODO: Need to setImmediate if not loaded yet? Gun.log("make key", key); cb = cb || function(){}; - this._.keys[key] = this._.node; - if(Gun.fns.is(this._.opt.hook.key)){ - this._.opt.hook.key(key, this._.node, function(err, data){ + this.__.keys[key] = this._.node; + if(Gun.fns.is(this.__.opt.hook.key)){ + this.__.opt.hook.key(key, this._.node, function(err, data){ Gun.log("key made", key); if(err){ return cb(err) } return cb(null); @@ -78,9 +89,9 @@ return this; } Gun.chain.path = function(path){ // The focal point follows the path - var gun = this; + var gun = this.chain(); path = path.split('.'); - Gun.log("PATH stack trace", gun._.events.trace + 1); + Gun.log("PATH stack trace", gun._.events.trace + 1, 'was it before loaded?', this._); gun._.events.on(gun._.events.trace += 1).event(function trace(node){ Gun.log("stack at", gun._.events.at); if(!path.length){ // if the path resolves to another node, we finish here @@ -104,9 +115,9 @@ } } }); - if(gun._.loaded){ + if(this._.loaded){ // this was the previous chain, gun is the new one console.log("Send off!", gun._.events.at + 1); - gun._.events.on(gun._.events.at += 1).emit(gun._.node); + gun._.events.on(gun._.events.at += 1).emit(this._.node); } return gun; } @@ -130,7 +141,8 @@ The live state at point of confirmation may or may not be different than when it was called. If this causes any application-level concern, it can compare against the live data by immediately reading it, or accessing the logs if enabled. */ - Gun.chain.set = function(val, cb){ // TODO: set failed miserably to catch depth references in social tests + Gun.chain.set = function(val, cb, opt){ // TODO: set failed miserably to catch depth references in social tests + opt = opt || {}; var gun = this, set; if(gun._.field){ // a field cannot be 0! set = {}; // in case we are doing a set on a field, not on a node @@ -144,10 +156,10 @@ if(set.err){ return cb(set.err), gun } set = gun.set.now(set.nodes, Gun.time.is()); // set time state on nodes? if(set.err){ return cb(set.err), gun } - Gun.union(gun._.nodes, set.nodes); // while this maybe should return a list of the nodes that were changed, we want to send the actual delta - gun._.node = gun._.nodes[cb.root._[own.sym.id]] || cb.root; // TODO? Maybe BUG! if val is a new node on a field, _.node should now be that! Or will that happen automatically? - if(Gun.fns.is(gun._.opt.hook.set)){ - gun._.opt.hook.set(set.nodes, function(err, data){ // now iterate through those nodes to S3 and get a callback once all are saved + Gun.union(gun.__.nodes, set.nodes); // while this maybe should return a list of the nodes that were changed, we want to send the actual delta + gun._.node = gun.__.nodes[cb.root._[own.sym.id]] || cb.root; // TODO? Maybe BUG! if val is a new node on a field, _.node should now be that! Or will that happen automatically? + if(Gun.fns.is(gun.__.opt.hook.set)){ + gun.__.opt.hook.set(set.nodes, function(err, data){ // now iterate through those nodes to S3 and get a callback once all are saved Gun.log("gun set hook callback called"); if(err){ return cb(err) } return cb(null); @@ -174,15 +186,34 @@ }); return context; } + Gun.chain.set.now.union = function(prime){ + var gun = Gun.is(this)? this : null + , context = {nodes: {}}; + if(!gun){ + context.err = {err: "No gun instance!", corrupt: true}; + return context; + } + Gun.obj.map(prime, function(node){ + var set = Gun.ify.call(gun, node); + if(set.err){ return context.err = set.err } + Gun.obj.map(set.nodes, function(node, id){ + context.nodes[id] = node; + console.log("Gun set.now.union ----->", node); + }); + }); + if(context.err){ return context } + Gun.union(gun.__.nodes, context.nodes); // need to move good primes onto context.nodes; + return context; + } Gun.chain.match = function(){ // same as path, except using objects return this; } Gun.chain.blank = function(blank){ - this._.chain.blank = Gun.fns.is(blank)? blank : function(){}; + this._.blank = Gun.fns.is(blank)? blank : function(){}; return this; } Gun.chain.dud = function(dud){ - this._.chain.dud = Gun.fns.is(dud)? dud : function(){}; + this._.dud = Gun.fns.is(dud)? dud : function(){}; return this; } Gun.fns = {}; @@ -311,11 +342,11 @@ }()); Gun.roulette = function(l, c){ var gun = Gun.is(this)? this : {}; - if(gun._ && gun._.opt && gun._.opt.uuid){ - if(Gun.fns.is(gun._.opt.uuid)){ - return gun._.opt.uuid(l, c); + if(gun._ && gun.__.opt && gun.__.opt.uuid){ + if(Gun.fns.is(gun.__.opt.uuid)){ + return gun.__.opt.uuid(l, c); } - l = l || gun._.opt.uuid.length; + l = l || gun.__.opt.uuid.length; } return Gun.text.random(l, c); } @@ -379,6 +410,7 @@ var serverState = Gun.time.is(); // add more checks? var state = HAM(serverState, deltaStates[field], states[field], deltaValue, current[field]); + console.log("HAM:", field, deltaValue, deltaStates[field], current[field], 'the', state, (deltaStates[field] - serverState)); if(state.err){ Gun.log(".!HYPOTHETICAL AMNESIA MACHINE ERR!.", state.err); return; @@ -428,7 +460,7 @@ } }({})); ;(function(Serializer){ - Gun.ify = function(data, gun){ // TODO: BUG: Modify lists to include HAM state + Gun.ify = function(data){ // TODO: BUG: Modify lists to include HAM state var gun = Gun.is(this)? this : {} , context = { nodes: {} @@ -586,7 +618,7 @@ Page.load = function(key, cb, opt){ cb = cb || function(){}; opt = opt || {}; - Gun.obj.map(gun._.opt.peers, function(peer, url){ + Gun.obj.map(gun.__.opt.peers, function(peer, url){ Page.ajax(url + '/' + key, null, function(data){ Gun.log('via', url, key, data); // alert(data + data.hello + data.from + data._); @@ -594,8 +626,18 @@ }); }); } + Page.set = function(nodes, cb){ + cb = cb || function(){}; + // TODO: batch and throttle later. + console.log('ajax set', nodes); + Gun.obj.map(gun.__.opt.peers, function(peer, url){ + Page.ajax(url, nodes, function(reply){ + console.log("set confirmed?", reply); + }); + }); + } Page.ajax = - this.ajax = + window.ajax = function(url, data, cb, opt){ /* via Sockjs@1.0.0 @@ -611,6 +653,8 @@ data = u; } else { try{data = JSON.stringify(data); + opt.headers = opt.headers || {}; + opt.headers["Content-Type"] = "application/json;charset=utf-8"; }catch(e){} } opt.method = (data? 'POST' : 'GET'); @@ -686,11 +730,6 @@ if(opt.cookies || opt.credentials || opt.withCredentials){ opt.xhr.withCredentials = true; } - try{opt.xhr.open(opt.method, url, true); - } catch(e) { - opt.error(); - return; - } opt.xhr.onreadystatechange = function(){ if(!opt.xhr){ return } var reply, status; @@ -708,12 +747,29 @@ opt.done(false); } } + try{opt.xhr.open(opt.method, url, true); + } catch(e) { + opt.error(); + return; + } + if(opt.headers){ + try{for(var i in opt.headers){ + if(opt.headers.hasOwnProperty(i)){ + opt.xhr.setRequestHeader(i, opt.headers[i]); + } + } + } catch(e) { + opt.error(); + return; + } + } try{opt.xhr.send(data); }catch(e){ opt.error(); } return opt; } - gun._.opt.hook.load = gun._.opt.hook.load || Page.load; + gun.__.opt.hook.load = gun.__.opt.hook.load || Page.load; + gun.__.opt.hook.set = gun.__.opt.hook.set || Page.set; }); }({})); \ No newline at end of file diff --git a/package.json b/package.json index 3b4dd4da..9650508d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { "name": "gun" -, "version": "0.0.2a" +, "version": "0.0.2b" , "author": "Mark Nadal" , "description": "Graph engine." , "engines": { @@ -9,6 +9,8 @@ "mime": "~>1.2.11", "aws-sdk": "~>2.0.0", "request": "~>2.39.0" + + ,"express": "~>4.9.0","body-parser": "~>1.8.1" } , "devDependencies": { "chance": "~>2.39.0" diff --git a/shots.js b/shots.js index c4d1ad12..bdc3849c 100644 --- a/shots.js +++ b/shots.js @@ -4,52 +4,83 @@ , url = require('url') , meta = {}; Gun.on('init').event(function(gun, opt){ - gun.server = gun.server || function(req, res){ // where is the data? is it JSON? declare contentType=JSON from client? - console.log("gun server has requests!", req.headers, req.body, req.url, req.method); + gun.server = gun.server || function(req, res, next){ // where is the data? is it JSON? declare contentType=JSON from client? /*meta.CORS(req, res); res.emit('data', {way: 'cool'}); res.emit('data', {shish: 'kabob'}); res.emit('data', {I: 'love'}); res.end(); return;*/ - if(!req || !res){ return } - if(!req.url){ return } - if(!req.method){ return } + next = next || function(){}; + if(!req || !res){ return next() } + if(!req.url){ return next() } + if(!req.method){ return next() } var tmp = {}; tmp.url = url.parse(req.url, true); - if(!gun.server.regex.test(tmp.url.pathname)){ return } - tmp.key = tmp.url.pathname.replace(gun.server.regex,'').replace(/^\//i,''); // strip the base - if(!tmp.key){ - return meta.JSON(res, {gun: true}); + if(!gun.server.regex.test(tmp.url.pathname)){ return next() } + tmp.key = tmp.url.pathname.replace(gun.server.regex,'') || ''; + if(tmp.key.toLowerCase() === '.js'){ + res.writeHead(200, {'Content-Type': 'text/javascript'}); + res.end(gun.server.js = gun.server.js || require('fs').readFileSync(__dirname + '/gun.js')); + return; } - if('get' === req.method.toLowerCase()){ // get is used as subscribe - // raw test for now: - s3.load(tmp.key, function(err, data){ + console.log("\ngun server has requests!", req.method, req.url, req.headers, req.body); + tmp.key = tmp.key.replace(/^\//i,'') || ''; // strip the base + tmp.method = (req.method||'').toLowerCase(); + if('get' === tmp.method){ // get is used as subscribe + if(!tmp.key){ + return meta.JSON(res, {gun: true}); + } + // raw test for now, no auth: + gun.load(tmp.key, function(err, data){ console.log("gun subscribed!", err, data); meta.CORS(req, res); return meta.JSON(res, data || err); }) } else - if('post' === req.method.toLowerCase()){ // post is used as patch, sad that patch has such poor support - + if('post' === tmp.method || 'patch' === tmp.method){ // post is used as patch, sad that patch has such poor support + if(!req.body){ + console.log("Warn: No body on POST?"); + } + // raw test for now, no auth: + // should probably load all the nodes first? + var context = Gun.chain.set.now.union.call(gun, req.body); // data safely transformed + if(context.err){ + return meta.JSON(res, context.err); // need to standardize errors more + } + console.log("-------- union ---------");Gun.obj.map(gun.__.nodes, function(node){ console.log(node); });console.log("------------------------"); + /* + WARNING! TODO: BUG! Do not send OK confirmation if amnesiaQuaratine is activated! Not until after it has actually been processed!!! + */ + if(Gun.fns.is(gun.__.opt.hook.set)){ + gun.__.opt.hook.set(context.nodes, function(err, data){ // now iterate through those nodes to S3 and get a callback once all are saved + if(err){ + return meta.JSON(res, {err: err}); // server should handle the error for the client first! Not force client to re-attempt. + } + meta.JSON(res, {ok: 1}); // need to standardize OKs, OK:1 not good. + }); + } else { + context.err = "Warning! You have no persistence layer to save to!"; + Gun.log(context.err); + } } } gun.server.regex = /^\/gun/i; - var s3 = gun._.opt.s3 = gun._.opt.s3 || S3(opt && opt.s3); - s3.path = s3.path || opt.s3.path || ''; - s3.keyed = s3.keyed || opt.s3.keyed || ''; - s3.nodes = s3.nodes || opt.s3.nodes || '_/nodes/'; - gun._.opt.batch = opt.batch || gun._.opt.batch || 10; - gun._.opt.throttle = opt.throttle || gun._.opt.throttle || 2; - if(!gun._.opt.keepMaxSockets){ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = Infinity } // WARNING: Document this! + var s3 = gun.__.opt.s3 = gun.__.opt.s3 || S3(opt && opt.s3); + s3.prefix = s3.prefix || opt.s3.prefix || ''; + s3.prekey = s3.prekey || opt.s3.prekey || ''; + s3.prenode = s3.prenode || opt.s3.prenode || '_/nodes/'; + gun.__.opt.batch = opt.batch || gun.__.opt.batch || 10; + gun.__.opt.throttle = opt.throttle || gun.__.opt.throttle || 2; + if(!gun.__.opt.keepMaxSockets){ require('https').globalAgent.maxSockets = require('http').globalAgent.maxSockets = Infinity } // WARNING: Document this! s3.load = s3.load || function(key, cb, opt){ cb = cb || function(){}; opt = opt || {}; if(opt.id){ - key = s3.path + s3.nodes + key; + key = s3.prefix + s3.prenode + key; } else { - key = s3.path + s3.keyed + key; + key = s3.prefix + s3.prekey + key; } s3.get(key, function(err, data, text, meta){ console.log('via s3', key); @@ -83,13 +114,13 @@ } }); }); - if(gun._.opt.batch < s3.batching){ + if(gun.__.opt.batch < s3.batching){ return s3.set.now(); } - if(!gun._.opt.throttle){ + if(!gun.__.opt.throttle){ return s3.set.now(); } - s3.wait = s3.wait || setTimeout(s3.set.now, gun._.opt.throttle * 1000); // in seconds + s3.wait = s3.wait || setTimeout(s3.set.now, gun.__.opt.throttle * 1000); // in seconds } s3.set.now = s3.set.now || function(){ clearTimeout(s3.wait); @@ -99,8 +130,8 @@ , batch = s3.batch[s3.next]; s3.next = Gun.time.is(); Gun.obj.map(batch, function put(exists, id){ - var node = gun._.nodes[id]; // the batch does not actually have the nodes, but what happens when we do cold data? Could this be gone? - s3.put(s3.path + s3.nodes + id, node, function(err, reply){ + var node = gun.__.nodes[id]; // the batch does not actually have the nodes, but what happens when we do cold data? Could this be gone? + s3.put(s3.prefix + s3.prenode + id, node, function(err, reply){ console.log("s3 put reply", id, err, reply); if(err || !reply){ put(exists, id); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop! @@ -123,7 +154,7 @@ if(!id){ return cb({err: "No ID!"}); } - s3.put(s3.path + s3.keyed + key, '', function(err, reply){ // key is 2 bytes??? Should be smaller + s3.put(s3.prefix + s3.prekey + key, '', function(err, reply){ // key is 2 bytes??? Should be smaller console.log("s3 put reply", id, err, reply); if(err || !reply){ s3.key(key, node, cb); // naive implementation of retry TODO: BUG: need backoff and anti-infinite-loop! diff --git a/test/common.js b/test/common.js index 1ef6fabc..34797761 100644 --- a/test/common.js +++ b/test/common.js @@ -62,7 +62,9 @@ describe('Gun', function(){ it('path', function(done){ this.timeout(9000); - var gun = require('./shotgun'); + var gun = require('gun')({ + s3: require('./shotgun') // replace this with your own keys! + }); gun.load('d1ed426098eae2bba8c60605e1e4552f66281770', null, {id: true}) // get Rodney Morris .path('parent.parent.first') // Rodney's parent is Juan Colon, whose parent is Francis Peters .get(function(val){ diff --git a/test/shotgun.js b/test/shotgun.js index 31090381..8096145b 100644 --- a/test/shotgun.js +++ b/test/shotgun.js @@ -1,7 +1,6 @@ var keys; if(process.env.LIVE || (process.env.NODE_ENV === 'production')){ // Keys are provided by environment configs on the server - //process.env['redis-install'] = '/tmp'; } else { // Keys are hosted outside this folder, you must provide your own with environment variables. if((require('fs').existsSync||require('path').existsSync)(keys = __dirname + '/../../../linux/.ssh/keys-gun.js')){ @@ -9,10 +8,13 @@ if(process.env.LIVE || (process.env.NODE_ENV === 'production')){ } } +module.exports = keys || {}; +/* var Gun = require('../shots'); var gun = Gun({ peers: 'http://localhost:8888/gun' ,s3: keys }); -module.exports = gun; \ No newline at end of file +module.exports = gun; +*/ \ No newline at end of file