mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
commit
83d6eadebb
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,5 +1,18 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 0.3.3
|
||||
|
||||
- You can now link nodes natively, `gun.get('mark').path('owner').put(gun.get('cat'))`!
|
||||
- Sets (or tables, collections, lists) are now easily done with `gun.get('users').set(gun.get('person/mark'))`.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
Bug fixes.
|
||||
|
||||
## 0.3.1
|
||||
|
||||
Bug fixes.
|
||||
|
||||
## 0.3
|
||||
|
||||
Migration Guide! Migrate by changing `.attach(` to `.wsp(` on your server if you have one with gun. Remove `.set()` (delete it), and change `.set($DATA)` (where you call set with something) to `.path('I' + Date.now() + 'R' + Gun.text.random(5)).put($DATA)`. If you have NodeJS style callbacks in your `.get` (which documentation previously recommended that you shouldn't) they previous took `err, graph` and now they take `err, node` (which means now using callback style is fine to use). Inside of `.not()` no longer use `return` or `this`, instead (probably) use `gun` and no `return`. If you are a module developer, use `opt.wire` now instead of `opt.hooks` and message Mark since he needs to talk to you since the wire protocol has changed.
|
||||
|
34
gun.js
34
gun.js
@ -548,13 +548,23 @@
|
||||
Gun.chain.put = function(val, cb, opt){
|
||||
opt = opt || {};
|
||||
cb = cb || function(){}; cb.hash = {};
|
||||
var gun = this, chain = gun.chain(), drift = Gun.time.now();
|
||||
var gun = this, chain = gun.chain(), tmp = {val: val}, drift = Gun.time.now();
|
||||
function put(at){
|
||||
if(cb.hash[at.hash = at.hash || Gun.on.at.hash(at)]){ return } // if we have already seen this hash...
|
||||
cb.hash[at.hash] = true; // else mark that we're processing the data (failure to write could still occur).
|
||||
var val = tmp.val;
|
||||
var ctx = {obj: val}; // prep the value for serialization
|
||||
ctx.soul = at.field? at.soul : (at.at && at.at.soul) || at.soul; // figure out where we are
|
||||
ctx.field = at.field? at.field : (at.at && at.at.field) || at.field; // did we come from some where?
|
||||
if(Gun.is(val)){
|
||||
if(!ctx.field){ return cb.call(chain, {err: ctx.err = Gun.log('No field to link node to!')}), chain._.at('err').emit(ctx.err) }
|
||||
return val.val(function(node){
|
||||
var soul = Gun.is.node.soul(node);
|
||||
if(!soul){ return cb.call(chain, {err: ctx.err = Gun.log('Only a node can be linked! Not "' + node + '"!')}), chain._.at('err').emit(ctx.err) }
|
||||
tmp.val = Gun.is.rel.ify(soul);
|
||||
put(at);
|
||||
});
|
||||
}
|
||||
if(cb.hash[at.hash = at.hash || Gun.on.at.hash(at)]){ return } // if we have already seen this hash...
|
||||
cb.hash[at.hash] = true; // else mark that we're processing the data (failure to write could still occur).
|
||||
ctx.by = chain.__.by(ctx.soul);
|
||||
ctx.not = at.not || (at.at && at.at.not);
|
||||
Gun.obj.del(at, 'not'); Gun.obj.del(at.at || at, 'not'); // the data is no longer not known! // TODO: BUG! It could have been asynchronous by the time we now delete these properties. Don't other parts of the code assume their deletion is synchronous?
|
||||
@ -951,6 +961,18 @@
|
||||
return chain;
|
||||
}
|
||||
|
||||
Gun.chain.set = function(item, cb, opt){
|
||||
var gun = this, ctx = {};
|
||||
if(!Gun.is(item)){ return cb.call(gun, {err: Gun.log('Set only supports node references currently!')}), gun }
|
||||
item.val(function(node){
|
||||
if(ctx.done){ return } ctx.done = true;
|
||||
var put = {}, soul = Gun.is.node.soul(node);
|
||||
if(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not "' + node + '"!')}) }
|
||||
gun.put(Gun.obj.put(put, soul, Gun.is.rel.ify(soul)), cb, opt);
|
||||
})
|
||||
return gun;
|
||||
}
|
||||
|
||||
Gun.chain.init = function(cb, opt){
|
||||
var gun = this;
|
||||
gun._.at('null').event(function(at){
|
||||
@ -1100,7 +1122,7 @@
|
||||
if(!this.Gun){ return }
|
||||
if(!window.JSON){ throw new Error("Include JSON first: ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js") } // for old IE use
|
||||
|
||||
;(function(exports){ // TODO: BUG!!!! Remove the artificial setTimeout!!!!!
|
||||
;(function(exports){
|
||||
function s(){}
|
||||
s.put = function(key, val){ return store.setItem(key, Gun.text.ify(val)) }
|
||||
s.get = function(key, cb){ setTimeout(function(){ return cb(null, Gun.obj.ify(store.getItem(key) || null)) },1)}
|
||||
@ -1260,9 +1282,9 @@
|
||||
if(!c){ return }
|
||||
if(ws && ws.close instanceof Function){ ws.close() }
|
||||
if(1006 === c.code){ // websockets cannot be used
|
||||
ws = r.ws.peers[opt.base] = false;
|
||||
/*ws = r.ws.peers[opt.base] = false; // 1006 has mixed meanings, therefore we can no longer respect it.
|
||||
r.transport(opt, cb);
|
||||
return;
|
||||
return;*/
|
||||
}
|
||||
ws = r.ws.peers[opt.base] = null; // this will make the next request try to reconnect
|
||||
setTimeout(function(){
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gun",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "Graph engine",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -1714,7 +1714,8 @@ describe('Gun', function(){
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('put gun node', function(done){
|
||||
it('put gun node', function(done){
|
||||
var gun = Gun();
|
||||
var mark = gun.put({age: 23, name: "Mark Nadal"});
|
||||
var amber = gun.put({age: 23, name: "Amber Nadal"});
|
||||
mark.path('wife').put(amber, function(err){
|
||||
@ -1722,6 +1723,27 @@ describe('Gun', function(){
|
||||
});
|
||||
mark.path('wife.name').val(function(val){
|
||||
expect(val).to.be("Amber Nadal");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('put gun node on node', function(done){
|
||||
var gun = Gun();
|
||||
var mark = gun.put({age: 23, name: "Mark Nadal"});
|
||||
var amber = gun.put({age: 23, name: "Amber Nadal"});
|
||||
mark.put(amber, function(err){
|
||||
expect(err).to.be.ok();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('put gun path on path', function(done){
|
||||
var gun = Gun();
|
||||
var mark = gun.put({age: 23, name: "Mark Nadal"});
|
||||
var amber = gun.put({age: 23, name: "Amber Nadal"});
|
||||
mark.path('wife').put(amber.path('age'), function(err){
|
||||
expect(err).to.be.ok();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
@ -3698,6 +3720,51 @@ describe('Gun', function(){
|
||||
});
|
||||
},100);
|
||||
});
|
||||
|
||||
it.skip("gun path via gun path", function(done){ // TODO: Future feature?
|
||||
var gun = Gun();
|
||||
var book = gun.put({ name: 'Potato Cooking' });
|
||||
var author = gun.put({ name: 'Bob Bobson' });
|
||||
author.path(book.path('name')).put(book);
|
||||
});
|
||||
|
||||
it("gun set", function(done){
|
||||
var gun = Gun();
|
||||
var users = gun.get('users');
|
||||
var alice = gun.put({name: 'alice', birth: Math.random()}).key('person/alice');
|
||||
var bob = gun.put({name: 'bob', birth: Math.random()}).key('person/bob');
|
||||
var carl = gun.put({name: 'carl', birth: Math.random()}).key('person/carl');
|
||||
var dave = gun.put({name: 'dave', birth: Math.random()}).key('person/dave');
|
||||
|
||||
users.set(alice).set(bob).set(carl).set(dave);
|
||||
|
||||
alice.path('friends').set(bob).set(carl);
|
||||
bob.path('friends').set(alice);
|
||||
dave.path('friends').set(alice).set(carl);
|
||||
|
||||
var team = gun.get('team/lions').put({name: "Lions"});
|
||||
team.path('members').set(alice).set(bob);
|
||||
|
||||
alice.path('team').put(team);
|
||||
bob.path('team').put(team);
|
||||
|
||||
dave.path('friends').map().path('team.members').map().val(function(member){
|
||||
//console.log("Dave's friend is on a team that has", member.name, "on it.");
|
||||
if('alice' === member.name){
|
||||
done.alice = true;
|
||||
} else
|
||||
if('bob' === member.name){
|
||||
done.bob = true;
|
||||
} else {
|
||||
expect(member).to.not.be.ok();
|
||||
}
|
||||
if(done.alice && done.bob){
|
||||
setTimeout(function(){
|
||||
done();
|
||||
},10);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Streams', function(){
|
||||
|
Loading…
x
Reference in New Issue
Block a user