mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
Merge branch '0.5' of https://github.com/amark/gun into 0.5
This commit is contained in:
commit
de9c6ce1ae
60
examples/http-external-ws.js
Normal file
60
examples/http-external-ws.js
Normal file
@ -0,0 +1,60 @@
|
||||
var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 8080;
|
||||
|
||||
var Gun = require('../');
|
||||
var gun = Gun({
|
||||
file: 'data.json',
|
||||
s3: {
|
||||
key: '', // AWS Access Key
|
||||
secret: '', // AWS Secret Token
|
||||
bucket: '' // The bucket you want to save into
|
||||
}
|
||||
});
|
||||
|
||||
var server = require('http').createServer(function(req, res){
|
||||
if(gun.wsp.server(req, res)){
|
||||
return; // filters gun requests!
|
||||
}
|
||||
require('fs').createReadStream(require('path').join(__dirname, req.url)).on('error',function(){ // static files!
|
||||
res.writeHead(200, {'Content-Type': 'text/html'});
|
||||
res.end(require('fs').readFileSync(require('path').join(__dirname, 'index.html'))); // or default to index
|
||||
}).pipe(res); // stream
|
||||
});
|
||||
|
||||
// do not do this to attach server... instead pull websocket provider and use that.
|
||||
// gun.wsp(server);
|
||||
|
||||
var ws = require( 'ws' ); // default websocket provider gun used...
|
||||
var WebSocketServer = ws.server;
|
||||
|
||||
var wss = new WebSocketServer( {
|
||||
server: server, // 'ws' npm
|
||||
autoAcceptConnections : false // want to handle the request (websocket npm?)
|
||||
}
|
||||
|
||||
wss.on('connection',acceptConnection )
|
||||
|
||||
var gunPeers = []; // used as a list of connected clients.
|
||||
|
||||
Gun.on('out', function(msg){
|
||||
msg = JSON.stringify({headers:{},body:msg});
|
||||
gunPeers.forEach( function(peer){ peer.send( msg ) })
|
||||
})
|
||||
function acceptConnection( connection ) {
|
||||
// connection.upgradeReq.headers['sec-websocket-protocol'] === (if present) protocol requested by client
|
||||
// connection.upgradeReq.url === url request
|
||||
console.log( "connect?", req.upgradeReq.headers, req.upgradeReq.url )
|
||||
gunPeers.push( connection );
|
||||
connection.on( 'error',function(error){console.log( "WebSocket Error:", error } );
|
||||
connection.on( 'message',function(msg){gun.on('in',JSON.parse( msg.utf8Data).body)})
|
||||
connection.on( 'close', function(reason,desc){
|
||||
// gunpeers gone.
|
||||
var i = peers.findIndex( function(p){return p===connection} );
|
||||
if( i >= 0 )
|
||||
gunPeers.splice( i, 1 );
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
server.listen(port);
|
||||
|
||||
console.log('Server started on port ' + port + ' with ');
|
13
gun.js
13
gun.js
@ -2202,9 +2202,9 @@
|
||||
);
|
||||
}
|
||||
|
||||
function Client (url, options) {
|
||||
function Client (url, options, wscOptions ) {
|
||||
if (!(this instanceof Client)) {
|
||||
return new Client(url, options);
|
||||
return new Client(url, options, wscOptions);
|
||||
}
|
||||
|
||||
this.url = Client.formatURL(url);
|
||||
@ -2215,6 +2215,7 @@
|
||||
this.on = Gun.on;
|
||||
|
||||
this.options = options || {};
|
||||
this.options.wsc = wscOptions;
|
||||
this.resetBackoff();
|
||||
}
|
||||
|
||||
@ -2238,7 +2239,7 @@
|
||||
|
||||
connect: function () {
|
||||
var client = this;
|
||||
var socket = new Client.WebSocket(this.url);
|
||||
var socket = new Client.WebSocket(this.url, this.options.wsc.protocols, this.options.wsc );
|
||||
this.socket = socket;
|
||||
|
||||
// Forward messages into the emitter.
|
||||
@ -2355,7 +2356,9 @@
|
||||
null;
|
||||
}
|
||||
|
||||
Client.isSupported = Client.WebSocket !== null;
|
||||
Client.isSupported = !!Client.WebSocket;
|
||||
|
||||
if(!Client.isSupported){ return } // TODO: For now, don't do anything in browsers/servers that don't work. Later, use JSONP fallback and merge with server code?
|
||||
|
||||
// Ensure the protocol is correct.
|
||||
Client.formatURL = function (url) {
|
||||
@ -2418,7 +2421,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var client = new Client(url, options.backoff);
|
||||
var client = new Client(url, options.backoff, gun.Back('opt.wsc') || {protocols:null});
|
||||
|
||||
// Add it to the pool.
|
||||
Client.pool[url] = client;
|
||||
|
130
lib/file.js
130
lib/file.js
@ -6,73 +6,91 @@ var Gun = require('../gun'),
|
||||
fs = require('fs'),
|
||||
file = {};
|
||||
|
||||
function isUsingFileJS (context) {
|
||||
|
||||
// Options passed via .get or .put.
|
||||
var methodOptions = context.opt || {};
|
||||
|
||||
// Options set on the gun chain.
|
||||
var chainOption = context.gun.Back('opt.file');
|
||||
|
||||
// Favor method options over chain options.
|
||||
var file = methodOptions.hasOwnProperty('file')
|
||||
? methodOptions.file
|
||||
: chainOption;
|
||||
|
||||
// Return whether the module is disabled.
|
||||
return file !== false;
|
||||
}
|
||||
|
||||
// queue writes, adapted from https://github.com/toolness/jsondown/blob/master/jsondown.js
|
||||
var isWriting = false, queuedWrites = [];
|
||||
function writeFile(path, disk, at){
|
||||
if(isWriting) return queuedWrites.push(at);
|
||||
isWriting = true;
|
||||
var contents = JSON.stringify(disk, null, 2);
|
||||
fs.writeFile(String(path), contents, function(err) {
|
||||
var batch = queuedWrites.splice(0);
|
||||
isWriting = false;
|
||||
at.gun.Back(-1).on('in', {'@': at['#'], err: err, ok: err? false : 1});
|
||||
if(!batch.length){ return }
|
||||
batch.forEach(function(at){
|
||||
at.gun.Back(-1).on('in', {'@': at['#'], err: err, ok: err? false : 1});
|
||||
Gun.on('put', function(at){
|
||||
if(!file.use){ return }
|
||||
var graph = at.put, Graph = file.gun._.graph, opt = at.opt || {};
|
||||
Gun.obj.map(graph, function(node, soul){
|
||||
file.disk.graph[soul] = Graph[soul] || graph[soul];
|
||||
});
|
||||
graph = JSON.stringify(file.disk, null, 2);
|
||||
// TODO: Allow for a `fs.writeFile` compatible module, that is more reliable/safe, to be passed in through the options.
|
||||
fs.writeFile(opt.file || file.file, graph, function(err){
|
||||
file.gun.on('in', {
|
||||
'@': at['#'],
|
||||
ok: err? undefined : 1,
|
||||
err: err
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Gun.on('get', function(at){
|
||||
if(!file.use){ return }
|
||||
var soul = at.get['#'];
|
||||
if(!soul){ return }
|
||||
var node = file.disk.graph[soul];
|
||||
if(Gun.obj.has(at.get, '.')){
|
||||
node = field(node, at.get['.']);
|
||||
}
|
||||
file.gun.on('in', {
|
||||
put: Gun.graph.node(node),
|
||||
'@': at['#']
|
||||
})
|
||||
});
|
||||
|
||||
function field(node, field){
|
||||
if(!node){ return }
|
||||
var tmp = node[field];
|
||||
node = {_: node._};
|
||||
if(undefined !== tmp){
|
||||
node[field] = tmp;
|
||||
}
|
||||
tmp = node._;
|
||||
if(tmp['>']){
|
||||
tmp['>'] = Gun.obj.put({}, field, tmp['>'][field]);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
Gun.on('put', function(at){
|
||||
if (isUsingFileJS(at) === false) {
|
||||
return;
|
||||
}
|
||||
var gun = at.gun, graph = at.put, opt = at.opt || {};
|
||||
var __ = gun._.root._;
|
||||
Gun.obj.map(graph, function(node, soul){
|
||||
file.disk.graph[soul] = __.graph[soul] || graph[soul];
|
||||
});
|
||||
writeFile(opt.file || file.file, file.disk, at);
|
||||
});
|
||||
Gun.on('get', function(at){
|
||||
if (isUsingFileJS(at) === false) {
|
||||
return;
|
||||
}
|
||||
var gun = at.gun, lex = at.get;
|
||||
if(!lex){return}
|
||||
gun.Back(-1).on('in', {'@': at['#'], put: Gun.graph.node(file.disk.graph[lex['#']])});
|
||||
//at.cb(null, file.disk.graph[lex['#']]);
|
||||
});
|
||||
|
||||
Gun.on('opt', function(at){
|
||||
var gun = at.gun, opts = at.opt;
|
||||
if ((opts.file === false) || (opts.s3 && opts.s3.key)) {
|
||||
var gun = at.gun, opt = at.opt;
|
||||
if ((opt.file === false) || (opt.s3 && opt.s3.key)) {
|
||||
return; // don't use this plugin if S3 is being used.
|
||||
}
|
||||
Gun.log.once(
|
||||
'file-warning',
|
||||
'WARNING! This `file.js` module for gun is ' +
|
||||
'intended only for local development testing!'
|
||||
'intended for local development testing only!'
|
||||
);
|
||||
file.file = opts.file || file.file || 'data.json';
|
||||
file.raw = file.raw || (fs.existsSync || require('path').existsSync)(opts.file) ? fs.readFileSync(opts.file).toString() : null;
|
||||
file.use = true;
|
||||
file.file = String(opt.file || file.file || 'data.json');
|
||||
file.raw = file.raw || (fs.existsSync || require('path').existsSync)(file.file) ? fs.readFileSync(file.file).toString() : null;
|
||||
file.disk = file.disk || Gun.obj.ify(file.raw || {graph: {}});
|
||||
file.disk.graph = file.disk.graph || {};
|
||||
file.gun = gun;
|
||||
});
|
||||
|
||||
(function test(){
|
||||
return;
|
||||
try{
|
||||
var graph = Gun.obj.ify(fs.readFileSync('data.json').toString()).graph;
|
||||
var read;
|
||||
Gun().get('test/5').path('index').val(function(data){
|
||||
read = data;
|
||||
});
|
||||
console.log((5 === read)? "READ SUCCESS" : "FAIL");
|
||||
}catch(e){
|
||||
var gun = Gun(), i = 100, expect = 0;
|
||||
while(--i){
|
||||
expect += i;
|
||||
gun.get('test/' + i).put({ index: i, test: true });
|
||||
}
|
||||
setTimeout(function(){
|
||||
var graph = Gun.obj.ify(fs.readFileSync('data.json').toString()).graph;
|
||||
var count = 0;
|
||||
Gun.obj.map(graph, function(node){
|
||||
count += node.index;
|
||||
});
|
||||
console.log((expect && expect === count)? "WRITE SUCCESS! - RUN AGAIN" : "FAIL!");
|
||||
},100);
|
||||
};
|
||||
}());
|
||||
|
@ -134,7 +134,7 @@ API.connect = function () {
|
||||
var url = this.url;
|
||||
|
||||
// Open a new websocket.
|
||||
var socket = new WebSocket(url);
|
||||
var socket = new WebSocket(url, this.options.wsc.protocols, this.options.wsc);
|
||||
|
||||
// Re-use the previous listeners.
|
||||
socket._events = this._events;
|
||||
|
@ -74,6 +74,7 @@ Gun.on('opt', function (context) {
|
||||
if (sockets[url]) {
|
||||
return;
|
||||
}
|
||||
if (!options.wsc) options.wsc = gun.Back('opt.wsc') || { protocols:null };
|
||||
|
||||
var socket = Socket(url, options);
|
||||
sockets.add(url, socket);
|
||||
|
Loading…
x
Reference in New Issue
Block a user