diff --git a/README.md b/README.md index d4a27dd7..510707bc 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ GUN is a realtime, distributed, offline-first, graph database engine. Lightweight and powerful, at just **~9KB** gzipped. - -[![1 minute demo of fault tolerance](http://img.youtube.com/vi/-i-11T5ZI9o/0.jpg)](https://youtu.be/-i-11T5ZI9o) + + ## Why? @@ -89,7 +89,7 @@ Designed with ♥ by Mark Nadal, the gun team, and many amazing contributors. L Thanks to the following people who have contributed to GUN, via code, issues, or conversation (this list has quickly become tremendously behind! We'll probably turn this into a dedicated wiki page so you can add yourself): -[agborkowski](https://github.com/agborkowski); [alexlafroscia](https://github.com/alexlafroscia); [anubiann00b](https://github.com/anubiann00b); [bromagosa](https://github.com/bromagosa); [coolaj86](https://github.com/coolaj86); [d-oliveros](https://github.com/d-oliveros), [danscan](https://github.com/danscan); **[forrestjt](https://github.com/forrestjt) ([file.js](https://github.com/amark/gun/blob/master/lib/file.js))**; [gedw99](https://github.com/gedw99); [HelloCodeMing](https://github.com/HelloCodeMing); **[JosePedroDias](https://github.com/josepedrodias) ([graph visualizer](http://acor.sl.pt:9966))**; **[jveres](https://github.com/jveres) ([todoMVC](https://github.com/jveres/todomvc) [live demo](http://todos.loqali.com/))**; [ndarilek](https://github.com/ndarilek); [onetom](https://github.com/onetom); [phpnode](https://github.com/phpnode); [PsychoLlama](https://github.com/PsychoLlama); **[RangerMauve](https://github.com/RangerMauve) ([schema](https://github.com/gundb/gun-schema))**; [riston](https://github.com/riston); [rootsical](https://github.com/rootsical); [rrrene](https://github.com/rrrene); [sbeleidy](https://github.com/sbeleidy) [ssr1ram](https://github.com/ssr1ram); [Xe](https://github.com/Xe); [zot](https://github.com/zot); +[agborkowski](https://github.com/agborkowski); [alexlafroscia](https://github.com/alexlafroscia); [anubiann00b](https://github.com/anubiann00b); [bromagosa](https://github.com/bromagosa); [coolaj86](https://github.com/coolaj86); [d-oliveros](https://github.com/d-oliveros), [danscan](https://github.com/danscan); **[forrestjt](https://github.com/forrestjt) ([file.js](https://github.com/amark/gun/blob/master/lib/file.js))**; [gedw99](https://github.com/gedw99); [HelloCodeMing](https://github.com/HelloCodeMing); **[JosePedroDias](https://github.com/josepedrodias) ([graph visualizer](http://acor.sl.pt:9966))**; **[jveres](https://github.com/jveres) ([todoMVC](https://github.com/jveres/todomvc))**; [ndarilek](https://github.com/ndarilek); [onetom](https://github.com/onetom); [phpnode](https://github.com/phpnode); [PsychoLlama](https://github.com/PsychoLlama); **[RangerMauve](https://github.com/RangerMauve) ([schema](https://github.com/gundb/gun-schema))**; [riston](https://github.com/riston); [rootsical](https://github.com/rootsical); [rrrene](https://github.com/rrrene); [sbeleidy](https://github.com/sbeleidy) [ssr1ram](https://github.com/ssr1ram); **[Stefdv](https://github.com/stefdv) ([Polymer/web components](http://stefdv.github.io/gun-collection/components/gun-collection/))**; [Xe](https://github.com/Xe); [zot](https://github.com/zot); [ayurmedia](https://github.com/ayurmedia); This list of contributors was manually compiled and alphabetically sorted. If we missed you, please submit an issue so we can get you added! diff --git a/examples/express-auth.js b/examples/express-auth.js new file mode 100644 index 00000000..c48061ac --- /dev/null +++ b/examples/express-auth.js @@ -0,0 +1,30 @@ +console.log("If modules not found, run `npm install` in /example folder!"); // git subtree push -P examples heroku master // OR // git subtree split -P examples master && git push heroku [['HASH']]:master --force +var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 80; + +var express = require('express'); +var app = express(); + +var Gun = require('gun'); +var gun = Gun({ + file: 'data.json', + s3: { + key: '', // AWS Access Key + secret: '', // AWS Secret Token + bucket: '' // The bucket you want to save into + } +}); + +gun.wsp(app/*, function(req, res, next){ + console.log("auth!", req, req.body['#']); + if('get' === req.method){ + if('example/todo/data' === req.body['#']){ + next(req, res); + } + } + if('put' === req.method){ + res({body: {err: "Permission denied!"}}); + } +}*/); +app.use(express.static(__dirname)).listen(port); + +console.log('Server started on port ' + port + ' with /gun'); \ No newline at end of file diff --git a/gun.js b/gun.js index 5fc45ec2..618064ff 100644 --- a/gun.js +++ b/gun.js @@ -127,9 +127,17 @@ } Type.time = {}; Type.time.is = function(t){ return t? t instanceof Date : (+new Date().getTime()) } - Type.time.now = function(t){ - return ((t=t||Type.time.is()) > (Type.time.now.last || -Infinity)? (Type.time.now.last = t) : Type.time.now(t + 1)) + (Type.time.now.drift || 0); // TODO: BUG? Should this go on the inside? - }; + Type.time.now = (function(){ + var time = Type.time.is, last = -Infinity, n = 0, d = 1000; + return function(){ + var t = time(); + if(last < t){ + n = 0; + return last = t; + } + return last = t + ((n += 1) / d); + } + }()); }(Util)); ;(function(exports){ // On event emitter generic javascript utility. function On(){}; @@ -530,13 +538,15 @@ var gun = this, root = (gun.__ && gun.__.gun)? gun.__.gun : (gun._ = gun.__ = {gun: gun}).gun.chain(); // if root does not exist, then create a root chain. root.__.by = root.__.by || function(f){ return gun.__.by[f] = gun.__.by[f] || {} }; root.__.graph = root.__.graph || {}; - root.__.opt = root.__.opt || {}; + root.__.opt = root.__.opt || {peers: {}}; root.__.opt.wire = root.__.opt.wire || {}; 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,{}) }) } - root.__.opt.peers = opt.peers || gun.__.opt.peers || {}; + Gun.obj.map(opt.peers, function(v, f){ + root.__.opt.peers[f] = v; + }); Gun.obj.map(opt.wire, function(h, f){ if(!Gun.fns.is(h)){ return } root.__.opt.wire[f] = h; @@ -908,6 +918,11 @@ } function each(val, field){ //if(!Gun.is.rel(val)){ path.call(this.gun, null, val, field);return;} + if(opt.node){ + if(!Gun.is.rel(val)){ + return; + } + } cb.hash[this.soul + field] = cb.hash[this.soul + field] || this.gun.path(field, path, {chain: chain, via: 'map'}); // TODO: path should reuse itself! We shouldn't have to do it ourselves. // TODO: // 1. Ability to turn off an event. // automatically happens within path since reusing is manual? @@ -1132,7 +1147,7 @@ }(Gun)); var root = this || {}; // safe for window, global, root, and 'use strict'. - if(root.window){ (root = window).Gun = Gun } + if(typeof window !== "undefined"){ (root = window).Gun = Gun } if(typeof module !== "undefined" && module.exports){ module.exports = Gun } if(typeof global !== "undefined"){ root = global; } root.console = root.console || {log: function(s){ return s }}; // safe for old browsers @@ -1163,7 +1178,8 @@ opt = opt || {}; var tab = gun.tab = gun.tab || {}; tab.store = tab.store || Tab.store; - tab.request = tab.request || request; + tab.request = tab.request || Gun.request; + if(!tab.request){ throw new Error("Default GUN driver could not find default network abstraction.") } tab.request.s = tab.request.s || {}; tab.headers = opt.headers || {}; tab.headers['gun-sid'] = tab.headers['gun-sid'] || Gun.text.random(); // stream id @@ -1173,7 +1189,8 @@ var soul = lex[Gun._.soul]; if(!soul){ return } cb = cb || function(){}; - (opt.headers = Gun.obj.copy(tab.headers)).id = tab.msg(); + var ropt = {}; + (ropt.headers = Gun.obj.copy(tab.headers)).id = tab.msg(); (function local(soul, cb){ tab.store.get(tab.prefix + soul, function(err, data){ if(!data){ return } // let the peers handle no data. @@ -1184,11 +1201,11 @@ }); }(soul, cb)); if(!(cb.local = opt.local)){ - tab.request.s[opt.headers.id] = tab.error(cb, "Error: Get failed!", function(reply){ + tab.request.s[ropt.headers.id] = tab.error(cb, "Error: Get failed!", function(reply){ setTimeout(function(){ tab.put(Gun.is.graph.ify(reply.body), function(){}, {local: true, peers: {}}) },1); // and flush the in memory nodes of this graph to localStorage after we've had a chance to union on it. }); Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){ var p = {}; - tab.request(url, lex, tab.request.s[opt.headers.id], opt); + tab.request(url, lex, tab.request.s[ropt.headers.id], ropt); cb.peers = true; }); var node = gun.__.graph[soul]; @@ -1198,18 +1215,18 @@ } tab.peers(cb); } tab.put = tab.put || function(graph, cb, opt){ - //console.log("SAVE", graph); cb = cb || function(){}; opt = opt || {}; - (opt.headers = Gun.obj.copy(tab.headers)).id = tab.msg(); + var ropt = {}; + (ropt.headers = Gun.obj.copy(tab.headers)).id = tab.msg(); Gun.is.graph(graph, function(node, soul){ if(!gun.__.graph[soul]){ return } tab.store.put(tab.prefix + soul, gun.__.graph[soul], function(err){if(err){ cb({err: err}) }}); }); if(!(cb.local = opt.local)){ - tab.request.s[opt.headers.id] = tab.error(cb, "Error: Put failed!"); + tab.request.s[ropt.headers.id] = tab.error(cb, "Error: Put failed!"); Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){ - tab.request(url, graph, tab.request.s[opt.headers.id], opt); + tab.request(url, graph, tab.request.s[ropt.headers.id], ropt); cb.peers = true; }); } tab.peers(cb); @@ -1287,16 +1304,25 @@ gun.__.opt.wire.get = gun.__.opt.wire.get || tab.get; gun.__.opt.wire.put = gun.__.opt.wire.put || tab.put; gun.__.opt.wire.key = gun.__.opt.wire.key || tab.key; + + Tab.request = tab.request; + Gun.Tab = Tab; }); +}.bind(this || module)({})); + + +;(function(Tab){ var request = (function(){ - function r(base, body, cb, opt){ - opt = opt || (base.length? {base: base} : base); - opt.base = opt.base || base; - opt.body = opt.body || body; + function r(base, body, cb, opt){ opt = opt || {}; + var o = base.length? {base: base} : {}; + o.base = opt.base || base; + o.body = opt.body || body; + o.headers = opt.headers; + o.url = opt.url; cb = cb || function(){}; - if(!opt.base){ return } - r.transport(opt, cb); + if(!o.base){ return } + r.transport(o, cb); } r.createServer = function(fn){ r.createServer.s.push(fn) } r.createServer.ing = function(req, cb){ @@ -1311,7 +1337,7 @@ r.jsonp(opt, cb); } r.ws = function(opt, cb){ - var ws, WS = window.WebSocket || window.mozWebSocket || window.webkitWebSocket; + var ws, WS = r.WebSocket || window.WebSocket || window.mozWebSocket || window.webkitWebSocket; if(!WS){ return } if(ws = r.ws.peers[opt.base]){ if(!ws.readyState){ return setTimeout(function(){ r.ws(opt, cb) },10), true } @@ -1328,9 +1354,10 @@ return true; } if(ws === false){ return } - ws = r.ws.peers[opt.base] = new WS(opt.base.replace('http','ws')); + try{ws = r.ws.peers[opt.base] = new WS(opt.base.replace('http','ws')); + }catch(e){} ws.onopen = function(o){ r.back = 2; r.ws(opt, cb) }; - ws.onclose = window.onbeforeunload = function(c){ + ws.onclose = function(c){ if(!c){ return } if(ws && ws.close instanceof Function){ ws.close() } if(1006 === c.code){ // websockets cannot be used @@ -1343,6 +1370,7 @@ r.ws(opt, function(){}); // opt here is a race condition, is it not? Does this matter? }, r.back *= r.backoff); }; + if(typeof window !== "undefined"){ window.onbeforeunload = ws.onclose; } ws.onmessage = function(m){ if(!m || !m.data){ return } var res; @@ -1351,15 +1379,17 @@ if(!res){ return } res.headers = res.headers || {}; if(res.headers['ws-rid']){ return (r.ws.cbs[res.headers['ws-rid']]||function(){})(null, res) } - //Gun.log("We have a pushed message!", res); if(res.body){ r.createServer.ing(res, function(res){ r(opt.base, null, null, res)}) } // emit extra events. }; - ws.onerror = function(e){ Gun.log(e); }; + ws.onerror = function(e){ console.log(e); }; return true; } r.ws.peers = {}; r.ws.cbs = {}; r.jsonp = function(opt, cb){ + if(typeof window === "undefined"){ + return cb("JSONP is currently browser only."); + } //Gun.log("jsonp send", opt); r.jsonp.ify(opt, function(url){ //Gun.log(url); @@ -1442,4 +1472,6 @@ } return r; }()); + if(typeof window !== "undefined"){ Gun.request = request } + if(typeof module !== "undefined" && module.exports){ module.exports.request = request } }.bind(this || module)({})); \ No newline at end of file diff --git a/lib/file.js b/lib/file.js index d49ababe..5515dc5e 100644 --- a/lib/file.js +++ b/lib/file.js @@ -40,12 +40,14 @@ Gun.on('opt').event(function(gun, opts) { gun.opt({wire: { get: function get(lex, cb, o){ var node, soul = lex[Gun._.soul]; + setImmediate(function(){ node = all.nodes[soul]; if(!node){ return cb(null) } cb(null, node); node = Gun.is.node.soul.ify({}, soul); cb(null, node); // end. cb(null, {}); // done. + }); }, put: function(graph, cb, o){ for (key in gun.__.graph) all.nodes[key]=gun.__.graph[key]||graph[key]; diff --git a/lib/server.js b/lib/server.js index 25e8ac91..9ee1cb79 100644 --- a/lib/server.js +++ b/lib/server.js @@ -2,7 +2,7 @@ console.log("Hello wonderful person! :) I'm mark@gunDB.io, message me for help or with hatemail. I want to hear from you! <3"); var Gun = require('../gun'); require('./s3'); - require('./wsp'); require('./file'); + require('./wsp'); module.exports = Gun; }()); diff --git a/lib/wsp.js b/lib/wsp.js index 46343fda..339d673b 100644 --- a/lib/wsp.js +++ b/lib/wsp.js @@ -1,5 +1,5 @@ ;(function(wsp){ - var Gun = require('../gun') + var Gun = require('../gun') , ws = require('ws').Server , http = require('./http') , url = require('url'); @@ -10,10 +10,10 @@ server = gun.__.opt.ws.server = gun.__.opt.ws.server || opt.ws.server || server; require('./ws')(gun.wsp.ws = gun.wsp.ws || new ws(gun.__.opt.ws), function(req, res){ var ws = this; - req.headers['gun-sid'] = ws.sid = ws.sid? ws.sid : req.headers['gun-sid']; + req.headers['gun-sid'] = ws.sid = (ws.sid? ws.sid : req.headers['gun-sid']); ws.sub = ws.sub || gun.wsp.on('network').event(function(msg){ if(!ws || !ws.send || !ws._socket || !ws._socket.writable){ return this.off() } - if(!msg || (msg.headers && msg.headers['gun-sid'] === ws.sid)){ return } + if(!msg || (ws.sid && msg.headers && msg.headers['gun-sid'] === ws.sid)){ return } if(msg && msg.headers){ delete msg.headers['ws-rid'] } // TODO: BUG? ^ What if other peers want to ack? Do they use the ws-rid or a gun declared id? try{ws.send(Gun.text.ify(msg)); @@ -23,7 +23,8 @@ }); gun.__.opt.ws.port = gun.__.opt.ws.port || opt.ws.port || port || 80; } - var wsp = gun.wsp = gun.wsp || function(server){ + var wsp = gun.wsp = gun.wsp || function(server, auth){ + gun.wsp.auth = auth; if(!server){ return gun } if(Gun.fns.is(server.address)){ if(server.address()){ @@ -112,15 +113,24 @@ // all streams, technically PATCH but implemented as PUT or POST, are forwarded to other trusted peers // except for the ones that are listed in the message as having already been sending to. // all states, implemented with GET, are replied to the source that asked for it. - function tran(req, res){ - if(!req || !res || !req.body || !req.headers || !req.headers.id){ return } - if(gun.wsp.msg(req.headers.id)){ return } - req.method = req.body? 'put' : 'get'; + function flow(req, res){ gun.wsp.on('network').emit(Gun.obj.copy(req)); if(req.headers.rid){ return } // no need to process. if(Gun.is.lex(req.body)){ return tran.get(req, res) } else { return tran.put(req, res) } - cb({body: {hello: 'world'}}); + } + function tran(req, res){ + if(!req || !res || !req.body || !req.headers || !req.headers.id){ return } + if(gun.wsp.msg(req.headers.id)){ return } + req.method = (req.body && !Gun.is.lex(req.body))? 'put' : 'get'; + if(gun.wsp.auth){ return gun.wsp.auth(req, function(reply){ + if(!reply.headers){ reply.headers = {} } + if(!reply.headers['Content-Type']){ reply.headers['Content-Type'] = tran.json } + if(!reply.rid){ reply.headers.rid = req.headers.id } + if(!reply.id){ reply.headers.id = gun.wsp.msg() } + res(reply); + }, flow) } + else { return flow(req, res) } } tran.get = function(req, cb){ var key = req.url.key @@ -140,7 +150,7 @@ //Gun.log("GET!", req); key = req.body; //Gun.log("tran.get", key); - var opt = {key: false}; + var opt = {key: false, local: true}; //gun.get(key, function(err, node){ (gun.__.opt.wire.get||function(key, cb){cb(null,null)})(key, function(err, node){ //Gun.log("tran.get", key, "<---", err, node); @@ -193,7 +203,7 @@ if(err){ return cb({headers: reply.headers, body: {err: err || "Failed."}}) } // TODO: err should already be an error object? cb({headers: reply.headers, body: {ok: ok || "Persisted."}}); //Gun.log("tran.put <------------------------", ok); - }); + }, {local: true}); }).err){ cb({headers: reply.headers, body: {err: req.err || "Union failed."}}) } } else { cb({headers: reply.headers, body: {err: "Not a valid graph!"}}); @@ -209,22 +219,55 @@ wsp(opt.server); } - setTimeout(function(){ // hack it in :( for now, since 0.4.x will allow us to have multiple drivers. - var proxy = gun.__.opt.wire; - var driver = { - put: function(graph, cb, opt){ - proxy.put(graph, cb, opt); - var msg = { - headers: {'Content-Type': 'application/json', id: gun.wsp.msg()}, - body: graph - }; - gun.wsp.on('network').emit(msg); - }, - get: proxy.get + if(gun.wsp.driver){ return } + var driver = gun.wsp.driver = {}; + var noop = function(){}; + var get = gun.__.opt.wire.get || noop; + var put = gun.__.opt.wire.put || noop; + var driver = { + put: function(graph, cb, opt){ + put(graph, cb, opt); + opt = opt || {}; + if(opt.local){ return } + var id = gun.wsp.msg(); + gun.wsp.on('network').emit({ // sent to dynamic peers! + headers: {'Content-Type': 'application/json', id: id}, + body: graph + }); + var ropt = {headers:{}, WebSocket: WebSocket}; + ropt.headers.id = id; + Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){ + Gun.request(url, graph, function(err, reply){ + reply.body = reply.body || reply.chunk || reply.end || reply.write; + if(err || !reply || (err = reply.body && reply.body.err)){ + return cb({err: Gun.log(err || "Put failed.") }); + } + cb(null, reply.body); + }, ropt); + }); + }, + get: function(lex, cb, opt){ + get(lex, cb, opt); + opt = opt || {}; + if(opt.local){ return } + if(!Gun.request){ return console.log("Server could not find default network abstraction.") } + var ropt = {headers:{}}; + ropt.headers.id = gun.wsp.msg(); + Gun.obj.map(opt.peers || gun.__.opt.peers, function(peer, url){ + Gun.request(url, lex, function(err, reply){ + reply.body = reply.body || reply.chunk || reply.end || reply.write; + if(err || !reply || (err = reply.body && reply.body.err)){ + return cb({err: Gun.log(err || "Get failed.") }); + } + cb(null, reply.body); + }, ropt); + }); } - gun.__.opt.wire = driver; - gun.opt({wire: driver}, true); - },1); - + } + var WebSocket = require('ws'); + Gun.request.WebSocket = WebSocket; + Gun.request.createServer(gun.wsp.wire); + gun.__.opt.wire = driver; + gun.opt({wire: driver}, true); }); }({})); \ No newline at end of file diff --git a/package.json b/package.json index 57caac27..089150b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gun", - "version": "0.3.92", + "version": "0.3.991", "description": "Graph engine", "main": "index.js", "scripts": { diff --git a/test/common.js b/test/common.js index c934c4ba..ef9ae2e7 100644 --- a/test/common.js +++ b/test/common.js @@ -3799,7 +3799,7 @@ describe('Gun', function(){ }); it("get context", function(done){ // TODO: HUH?????? This was randomly causing errors? - var gun = Gun(); + var gun = Gun(); var ref = gun.get('ctx/lol').get('ctx/foo').put({hello: 'world'}); gun.get('ctx/lol').val(function(implicit){ done.fail = true; @@ -3975,29 +3975,31 @@ describe('Gun', function(){ it("Don't put on parents", function(done){ // TODO: ADD TO 0.5 BRANCH! // Another Stefdv find. var test = gun.get('test'); - test.path('try.this.at.lvl4').put({msg:'hoi'}) - test.val(function(node,b){ - delete node._; - expect(Gun.obj.empty(node, 'try')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.try)]); + test.path('try.this.at.lvl4').put({msg:'hoi'}); + setTimeout(function(){ // TODO: Is this cheating?? + test.val(function(node,b){ + delete node._; + expect(Gun.obj.empty(node, 'try')).to.be.ok(); + node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.try)]); - delete node._; - expect(Gun.obj.empty(node, 'this')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.this)]); + delete node._; + expect(Gun.obj.empty(node, 'this')).to.be.ok(); + node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.this)]); + + delete node._; + expect(Gun.obj.empty(node, 'at')).to.be.ok(); + node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.at)]); - delete node._; - expect(Gun.obj.empty(node, 'at')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.at)]); + delete node._; + expect(Gun.obj.empty(node, 'lvl4')).to.be.ok(); + node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.lvl4)]); - delete node._; - expect(Gun.obj.empty(node, 'lvl4')).to.be.ok(); - node = Gun.obj.copy(gun.__.graph[Gun.is.rel(node.lvl4)]); - - delete node._; - expect(Gun.obj.empty(node, 'msg')).to.be.ok(); - expect(node.msg).to.be('hoi'); - done(); - }); + delete node._; + expect(Gun.obj.empty(node, 'msg')).to.be.ok(); + expect(node.msg).to.be('hoi'); + done(); + }); + },100); }); }); diff --git a/test/server/http.js b/test/server/http.js new file mode 100644 index 00000000..891cbfe0 --- /dev/null +++ b/test/server/http.js @@ -0,0 +1,15 @@ +//client.js writes data up to a listening hub.js, which relays to a server.js that reads the data. + +var http = require('http'); + +var Gun = require('../../index'); +var gun = Gun({ + file: 'http.json' +}); + + +var server = http.createServer(function(req, res){}); +gun.wsp(server); +server.listen(8080); + +console.log('Server started on port ' + 8080 + ' with /gun'); \ No newline at end of file diff --git a/test/server/node-client.js b/test/server/node-client.js new file mode 100644 index 00000000..ec423e5d --- /dev/null +++ b/test/server/node-client.js @@ -0,0 +1,9 @@ +var Gun = require('../../index'); + +var location = {host:"localhost"}; + +var gun = Gun( { file: 'read.json', peers: ['http://' + location.host + ':8080/gun'] }); + +gun.get( 'data' ).path('stuff').map(function(val,field){ console.log( field, "=", val ); } ); + +console.log( "done... wait forever?" ); \ No newline at end of file diff --git a/test/server/node-write.js b/test/server/node-write.js new file mode 100644 index 00000000..ce0aaf49 --- /dev/null +++ b/test/server/node-write.js @@ -0,0 +1,7 @@ +var Gun = require('../../index'); + +var location = {host:"localhost"}; + +var gun = Gun( { file: 'write.json', peers: ['http://' + location.host + ':8080/gun'] }); + +gun.get( 'data' ).path('stuff').put({a: {data: 1}, b: {data: 2}}); \ No newline at end of file