mirror of
https://github.com/amark/gun.git
synced 2025-03-30 15:08:33 +00:00
Merge branch 'master' into sea
This commit is contained in:
commit
e057c89a2f
@ -167,7 +167,7 @@ Technically, **GUN is a graph synchronization protocol** with a *lightweight emb
|
||||
|
||||
This would not be possible without **community contributors**, big shout out to:
|
||||
|
||||
**[ajmeyghani](https://github.com/ajmeyghani) ([Learn GUN Basics with Diagrams](https://medium.com/@ajmeyghani/gundb-a-graph-database-in-javascript-3860a08d873c))**; **[anywhichway](https://github.com/anywhichway) ([Block Storage](https://github.com/anywhichway/gun-block))**; **[beebase](https://github.com/beebase) ([Quasar](https://github.com/beebase/gun-vuex-quasar))**; **[BrockAtkinson](https://github.com/BrockAtkinson) ([brunch config](https://github.com/BrockAtkinson/brunch-gun))**; **[Brysgo](https://github.com/brysgo) ([GraphQL](https://github.com/brysgo/graphql-gun))**; **[d3x0r](https://github.com/d3x0r) ([SQLite](https://github.com/d3x0r/gun-db))**; **[forrestjt](https://github.com/forrestjt) ([file.js](https://github.com/amark/gun/blob/master/lib/file.js))**; **[hillct](https://github.com/hillct) (Docker)**; **[JosePedroDias](https://github.com/josepedrodias) ([graph visualizer](http://acor.sl.pt:9966))**; **[JuniperChicago](https://github.com/JuniperChicago) ([cycle.js bindings](https://github.com/JuniperChicago/cycle-gun))**; **[jveres](https://github.com/jveres) ([todoMVC](https://github.com/jveres/todomvc))**; **[kristianmandrup](https://github.com/kristianmandrup) ([edge](https://github.com/kristianmandrup/gun-edge))**; **[Lightnet](https://github.com/Lightnet)** ([Awesome Vue User Examples](https://glitch.com/edit/#!/jsvuegunui?path=README.md:1:0) & [User Kitchen Sink Playground](https://gdb-auth-vue-node.glitch.me/)); **[lmangani](https://github.com/lmangani) ([Cytoscape Visualizer](https://github.com/lmangani/gun-scape), [Cassandra](https://github.com/lmangani/gun-cassandra), [Fastify](https://github.com/lmangani/fastify-gundb), [LetsEncrypt](https://github.com/lmangani/polyGun-letsencrypt))**; **[mhelander](https://github.com/mhelander) ([SEA](https://github.com/amark/gun/blob/master/sea.js))**; [omarzion](https://github.com/omarzion) ([Sticky Note App](https://github.com/omarzion/stickies)); [PsychoLlama](https://github.com/PsychoLlama) ([LevelDB](https://github.com/PsychoLlama/gun-level)); **[RangerMauve](https://github.com/RangerMauve) ([schema](https://github.com/gundb/gun-schema))**; **[robertheessels](https://github.com/swifty) ([gun-p2p-auth](https://github.com/swifty/gun-p2p-auth))**; **[rogowski](https://github.com/rogowski) (AXE)**; [sbeleidy](https://github.com/sbeleidy); **[Sean Matheson](https://github.com/ctrlplusb) ([Observable/RxJS/Most.js bindings](https://github.com/ctrlplusb/gun-most))**; **[Shadyzpop](https://github.com/Shadyzpop) ([React Native example](https://github.com/amark/gun/tree/master/examples/react-native))**; **[sjones6](https://github.com/sjones6) ([Flint](https://github.com/sjones6/gun-flint))**; **[Stefdv](https://github.com/stefdv) (Polymer/web components)**; **[zrrrzzt](https://github.com/zrrrzzt) ([JWT Auth](https://gist.github.com/zrrrzzt/6f88dc3cedee4ee18588236756d2cfce))**; **[88dev](https://github.com/88dev) ([Database Viewer](https://github.com/88dev/gun-show))**;
|
||||
**[ajmeyghani](https://github.com/ajmeyghani) ([Learn GUN Basics with Diagrams](https://medium.com/@ajmeyghani/gundb-a-graph-database-in-javascript-3860a08d873c))**; **[anywhichway](https://github.com/anywhichway) ([Block Storage](https://github.com/anywhichway/gun-block))**; **[beebase](https://github.com/beebase) ([Quasar](https://github.com/beebase/gun-vuex-quasar))**; **[BrockAtkinson](https://github.com/BrockAtkinson) ([brunch config](https://github.com/BrockAtkinson/brunch-gun))**; **[Brysgo](https://github.com/brysgo) ([GraphQL](https://github.com/brysgo/graphql-gun))**; **[d3x0r](https://github.com/d3x0r) ([SQLite](https://github.com/d3x0r/gun-db))**; **[forrestjt](https://github.com/forrestjt) ([file.js](https://github.com/amark/gun/blob/master/lib/file.js))**; **[hillct](https://github.com/hillct) (Docker)**; **[JosePedroDias](https://github.com/josepedrodias) ([graph visualizer](http://acor.sl.pt:9966))**; **[JuniperChicago](https://github.com/JuniperChicago) ([cycle.js bindings](https://github.com/JuniperChicago/cycle-gun))**; **[jveres](https://github.com/jveres) ([todoMVC](https://github.com/jveres/todomvc))**; **[kristianmandrup](https://github.com/kristianmandrup) ([edge](https://github.com/kristianmandrup/gun-edge))**; **[Lightnet](https://github.com/Lightnet)** ([Awesome Vue User Examples](https://glitch.com/edit/#!/jsvuegunui?path=README.md:1:0) & [User Kitchen Sink Playground](https://gdb-auth-vue-node.glitch.me/)); **[lmangani](https://github.com/lmangani) ([Cytoscape Visualizer](https://github.com/lmangani/gun-scape), [Cassandra](https://github.com/lmangani/gun-cassandra), [Fastify](https://github.com/lmangani/fastify-gundb), [LetsEncrypt](https://github.com/lmangani/polyGun-letsencrypt))**; **[mhelander](https://github.com/mhelander) ([SEA](https://github.com/amark/gun/blob/master/sea.js))**; [omarzion](https://github.com/omarzion) ([Sticky Note App](https://github.com/omarzion/stickies)); [PsychoLlama](https://github.com/PsychoLlama) ([LevelDB](https://github.com/PsychoLlama/gun-level)); **[RangerMauve](https://github.com/RangerMauve) ([schema](https://github.com/gundb/gun-schema))**; **[robertheessels](https://github.com/swifty) ([gun-p2p-auth](https://github.com/swifty/gun-p2p-auth))**; **[rogowski](https://github.com/rogowski) (AXE)**; [sbeleidy](https://github.com/sbeleidy); **[sbiaudet](https://github.com/sbiaudet) ([C# Port](https://github.com/sbiaudet/cs-gun))**; **[Sean Matheson](https://github.com/ctrlplusb) ([Observable/RxJS/Most.js bindings](https://github.com/ctrlplusb/gun-most))**; **[Shadyzpop](https://github.com/Shadyzpop) ([React Native example](https://github.com/amark/gun/tree/master/examples/react-native))**; **[sjones6](https://github.com/sjones6) ([Flint](https://github.com/sjones6/gun-flint))**; **[Stefdv](https://github.com/stefdv) (Polymer/web components)**; **[zrrrzzt](https://github.com/zrrrzzt) ([JWT Auth](https://gist.github.com/zrrrzzt/6f88dc3cedee4ee18588236756d2cfce))**; **[xmonader](https://github.com/xmonader) ([Python Port](https://github.com/xmonader/pygundb))**; **[88dev](https://github.com/88dev) ([Database Viewer](https://github.com/88dev/gun-show))**;
|
||||
|
||||
I am missing many others, apologies, will be adding them soon!
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
<a id="share" class="hide"><div class="stick button">Share</div></a>
|
||||
<a id="share" class="hide"><div class="stick button">Request Ride</div></a>
|
||||
<div id="link" class="hide">
|
||||
<p>Copy and Paste this URL to your friends to share your location:</p>
|
||||
<center>
|
||||
|
59
gun.js
59
gun.js
@ -172,13 +172,13 @@
|
||||
var u, tag = (this.tag || (this.tag = {}))[tag] ||
|
||||
(this.tag[tag] = {tag: tag, to: onto._ = {
|
||||
next: function(arg){ var tmp;
|
||||
if((tmp = this.to)){
|
||||
if((tmp = this.to)){
|
||||
tmp.next(arg);
|
||||
}}
|
||||
}});
|
||||
if(arg instanceof Function){
|
||||
var be = {
|
||||
off: onto.off ||
|
||||
off: onto.off ||
|
||||
(onto.off = function(){
|
||||
if(this.next === onto._.next){ return !0 }
|
||||
if(this === this.the.last){
|
||||
@ -261,7 +261,7 @@
|
||||
if(v === Infinity){ return false } // we want this to be, but JSON does not support it, sad face.
|
||||
if(text_is(v) // by "text" we mean strings.
|
||||
|| bi_is(v) // by "binary" we mean boolean.
|
||||
|| num_is(v)){ // by "number" we mean integers or decimals.
|
||||
|| num_is(v)){ // by "number" we mean integers or decimals.
|
||||
return true; // simple values are valid.
|
||||
}
|
||||
return Val.rel.is(v) || false; // is the value a soul relation? Then it is valid and return it. If not, everything else remaining is an invalid data type. Custom extensions can be built on top of these primitives to support other types.
|
||||
@ -384,10 +384,10 @@
|
||||
State.ify = function(n, k, s, v, soul){ // put a key's state on a node.
|
||||
if(!n || !n[N_]){ // reject if it is not node-like.
|
||||
if(!soul){ // unless they passed a soul
|
||||
return;
|
||||
return;
|
||||
}
|
||||
n = Node.soul.ify(n, soul); // then make it so!
|
||||
}
|
||||
}
|
||||
var tmp = obj_as(n[N_], State._); // grab the states data.
|
||||
if(u !== k && k !== N_){
|
||||
if(num_is(s)){
|
||||
@ -400,7 +400,7 @@
|
||||
return n;
|
||||
}
|
||||
State.to = function(from, k, to){
|
||||
var val = from[k]; // BUGGY!
|
||||
var val = (from||{})[k];
|
||||
if(obj_is(val)){
|
||||
val = obj_copy(val);
|
||||
}
|
||||
@ -758,7 +758,7 @@
|
||||
if(!at){
|
||||
if(!(cat.opt||empty).super){
|
||||
ctx.souls[soul] = false;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
at = (ctx.$.get(soul)._);
|
||||
}
|
||||
@ -882,7 +882,7 @@
|
||||
;"Please do not remove these messages unless you are paying for a monthly sponsorship, thanks!";
|
||||
Gun.log.once("welcome", "Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!");
|
||||
;"Please do not remove these messages unless you are paying for a monthly sponsorship, thanks!";
|
||||
|
||||
|
||||
if(typeof window !== "undefined"){ (window.GUN = window.Gun = Gun).window = window }
|
||||
try{ if(typeof common !== "undefined"){ common.exports = Gun } }catch(e){}
|
||||
module.exports = Gun;
|
||||
@ -1082,7 +1082,7 @@
|
||||
//if(tmp[cat.id]){ return }
|
||||
tmp.is = tmp.is || at.put;
|
||||
tmp[cat.id] = at.put || true;
|
||||
//if(root.stop){
|
||||
//if(root.stop){
|
||||
eve.to.next(msg)
|
||||
//}
|
||||
relate(cat, msg, at, rel);
|
||||
@ -1095,7 +1095,7 @@
|
||||
var tmp = (at.root.$.get(rel)._);
|
||||
if(at.has){
|
||||
from = tmp;
|
||||
} else
|
||||
} else
|
||||
if(from.has){
|
||||
relate(from, msg, from, rel);
|
||||
}
|
||||
@ -1147,7 +1147,7 @@
|
||||
if(tmp = via.$){
|
||||
tmp = (chain = via.$.get(key))._;
|
||||
if(u === tmp.put || !Gun.val.link.is(data)){
|
||||
tmp.put = data;
|
||||
tmp.put = data;
|
||||
}
|
||||
}
|
||||
at.on('in', {
|
||||
@ -1287,13 +1287,16 @@
|
||||
return at;
|
||||
}
|
||||
function soul(gun, cb, opt, as){
|
||||
var cat = gun._, tmp;
|
||||
var cat = gun._, acks = 0, tmp;
|
||||
if(tmp = cat.soul){ return cb(tmp, as, cat), gun }
|
||||
if(tmp = cat.link){ return cb(tmp, as, cat), gun }
|
||||
gun.get(function(msg, ev){ // TODO: Bug! Needs once semantics?
|
||||
gun.get(function(msg, ev){
|
||||
if(u === msg.put && (tmp = (obj_map(cat.root.opt.peers, function(v,k,t){t(k)})||[]).length) && acks++ <= tmp){
|
||||
return;
|
||||
}
|
||||
ev.rid(msg);
|
||||
var at = ((at = msg.$) && at._) || {};
|
||||
tmp = at.link || at.soul || rel.is(msg.put) || node_soul(msg.put);
|
||||
tmp = at.link || at.soul || rel.is(msg.put) || node_soul(msg.put) || at.dub;
|
||||
cb(tmp, as, msg, ev);
|
||||
}, {out: {get: {'.':true}}});
|
||||
return gun;
|
||||
@ -1311,7 +1314,7 @@
|
||||
|
||||
//root.stop && (root.stop.ID = root.stop.ID || Gun.text.random(2));
|
||||
//if((tmp = root.stop) && (tmp = tmp[at.id] || (tmp[at.id] = {})) && tmp[cat.id]){ return } tmp && (tmp[cat.id] = true);
|
||||
if(eve.seen && at.id && eve.seen[at.id]){ return eve.to.next(msg) }
|
||||
if(eve.seen && at.id && eve.seen[at.id]){ return eve.to.next(msg) }
|
||||
//if((tmp = root.stop)){ if(tmp[at.id]){ return } tmp[at.id] = msg.root; } // temporary fix till a better solution?
|
||||
if((tmp = data) && tmp[rel._] && (tmp = rel.is(tmp))){
|
||||
tmp = ((msg.$$ = at.root.gun.get(tmp))._);
|
||||
@ -1344,7 +1347,7 @@
|
||||
//obj.del(map, at); // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.
|
||||
return;
|
||||
}
|
||||
var obj = Gun.obj, obj_has = obj.has, obj_to = Gun.obj.to;
|
||||
var obj = Gun.obj, obj_map = obj.map, obj_has = obj.has, obj_to = Gun.obj.to;
|
||||
var num_is = Gun.num.is;
|
||||
var rel = Gun.val.link, node_soul = Gun.node.soul, node_ = Gun.node._;
|
||||
var empty = {}, u;
|
||||
@ -1382,7 +1385,7 @@
|
||||
});
|
||||
return gun;
|
||||
}
|
||||
as.$ = gun = root.get(as.soul);
|
||||
as.$ = root.get(as.soul);
|
||||
as.ref = as.$;
|
||||
ify(as);
|
||||
return gun;
|
||||
@ -1537,8 +1540,8 @@
|
||||
as.data = obj_put({}, at.get, as.data);
|
||||
});
|
||||
}
|
||||
tmp = tmp || at.get;
|
||||
at = (at.root.$.get(tmp)._);
|
||||
tmp = tmp || at.soul || at.link || at.dub;// || at.get;
|
||||
at = tmp? (at.root.$.get(tmp)._) : at;
|
||||
as.soul = tmp;
|
||||
data = as.data;
|
||||
}
|
||||
@ -1756,13 +1759,12 @@
|
||||
var gun = this, soul;
|
||||
cb = cb || function(){};
|
||||
opt = opt || {}; opt.item = opt.item || item;
|
||||
if(soul = Gun.node.soul(item)){ return gun.set(gun.back(-1).get(soul), cb, opt) }
|
||||
if(soul = Gun.node.soul(item)){ item = Gun.obj.put({}, soul, Gun.val.link.ify(soul)) }
|
||||
if(!Gun.is(item)){
|
||||
var id = gun.back('opt.uuid')();
|
||||
if(id && Gun.obj.is(item)){
|
||||
return gun.set(gun._.root.$.put(item, id), cb, opt);
|
||||
if(Gun.obj.is(item)){;
|
||||
item = gun.back(-1).get(soul = soul || Gun.node.soul(item) || gun.back('opt.uuid')()).put(item);
|
||||
}
|
||||
return gun.get((Gun.state.lex() + Gun.text.random(7))).put(item, cb, opt);
|
||||
return gun.get(soul || (Gun.state.lex() + Gun.text.random(7))).put(item, cb, opt);
|
||||
}
|
||||
item.get(function(soul, o, msg){
|
||||
if(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not "' + msg.put + '"!')}) }
|
||||
@ -1858,7 +1860,7 @@
|
||||
var disk = Gun.obj.ify(store.getItem(opt.prefix)) || {};
|
||||
var lS = function(){}, u;
|
||||
root.on('localStorage', disk); // NON-STANDARD EVENT!
|
||||
|
||||
|
||||
root.on('put', function(at){
|
||||
this.to.next(at);
|
||||
Gun.graph.is(at.put, null, map);
|
||||
@ -1904,7 +1906,7 @@
|
||||
acks = {};
|
||||
if(data){ disk = data }
|
||||
try{store.setItem(opt.prefix, JSON.stringify(disk));
|
||||
}catch(e){
|
||||
}catch(e){
|
||||
Gun.log(err = (e || "localStorage failure") + " Consider using GUN's IndexedDB plugin for RAD for more storage space, temporary example at https://github.com/amark/gun/blob/master/test/tmp/indexedDB.html .");
|
||||
root.on('localStorage:error', {err: err, file: opt.prefix, flush: disk, retry: flush});
|
||||
}
|
||||
@ -1979,8 +1981,9 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.on('in', msg);
|
||||
|
||||
|
||||
return;
|
||||
} else
|
||||
if('[' === tmp){
|
||||
@ -2212,4 +2215,4 @@
|
||||
var noop = function(){};
|
||||
})(USE, './adapters/websocket');
|
||||
|
||||
}());
|
||||
}());
|
4
gun.min.js
vendored
4
gun.min.js
vendored
File diff suppressed because one or more lines are too long
@ -3,10 +3,10 @@ var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
|
||||
Gun.on('opt', function(root){
|
||||
this.to.next(root);
|
||||
if(root.once){ return }
|
||||
console.log("WARNING: `lib/bye` is out of date!");
|
||||
root.on('in', function(msg){
|
||||
if(!msg.peer || !msg.BYE){ return this.to.next(msg) }
|
||||
var peer = msg.peer();
|
||||
//Msg did not have a peer property saved before, so nothing ever went further
|
||||
if(!msg.mesh || !msg.BYE){ return this.to.next(msg) }
|
||||
var peer = msg.mesh.via;
|
||||
(peer.bye = peer.bye || []).push(msg.BYE);
|
||||
})
|
||||
root.on('bye', function(peer){
|
||||
@ -34,4 +34,4 @@ Gun.chain.bye = function(){
|
||||
return gun;
|
||||
}
|
||||
return bye;
|
||||
}
|
||||
}
|
||||
|
38
lib/metae.js
Normal file
38
lib/metae.js
Normal file
@ -0,0 +1,38 @@
|
||||
$(function(){
|
||||
var m = window.meta = {edit:[], os:{}}, ua = '';
|
||||
try{ua = navigator.userAgent.toLowerCase()}catch(e){}
|
||||
m.os.is = {
|
||||
win: (ua.search("win") >= 0)? "windows":false,
|
||||
lin: (ua.search("linux") >= 0)? "linux":false,
|
||||
mac: (ua.search("mac") >= 0)? "macintosh":false,
|
||||
and: (ua.search("android") >= 0)? "android":false,
|
||||
ios: (ua.search('ipod') >= 0
|
||||
|| ua.search('iphone') >= 0
|
||||
|| ua.search('ipad') >= 0)? "ios":false
|
||||
}
|
||||
m.key = {ctrl: 17, cmd: 91};
|
||||
m.key.meta = (m.os.is.win||m.os.is.lin||m.os.is.and)? m.key.ctrl : m.key.cmd;
|
||||
m.key.on = {};
|
||||
$(document).on('keydown', function(e){
|
||||
m.e = e;
|
||||
console.log('keydown', e.keyCode);
|
||||
m.key.on[e.code = e.keyCode] = !0;
|
||||
}).on('keyup', function(e){
|
||||
m.e = e;
|
||||
delete m.key.on[e.code = e.keyCode];
|
||||
}).on('keydown', '[contenteditable=true]', function(e){
|
||||
return;
|
||||
var r = monotype();
|
||||
console.log("keys down", Gun.obj.copy(m.key.on));
|
||||
$.each(m.edit, function(i,edit){ var tmp = true;
|
||||
$.each(edit.keys||[''], function(i,k){
|
||||
if(!m.key.on[k.length? k.charCodeAt(0) : k]){ tmp = false }
|
||||
});
|
||||
console.log(tmp, edit);
|
||||
})
|
||||
r.restore();
|
||||
});
|
||||
m.edit.push({keys: ['B'], on: function(){
|
||||
console.log('hi!');
|
||||
}})
|
||||
});
|
230
lib/monotype.js
Normal file
230
lib/monotype.js
Normal file
@ -0,0 +1,230 @@
|
||||
;var monotype = monotype || (function(monotype){
|
||||
monotype.range = function(n){
|
||||
var R, s, t, n = n || 0, win = monotype.win || window, doc = win.document;
|
||||
if(!arguments.length) return doc.createRange();
|
||||
if(!(win.Range && R instanceof Range)){
|
||||
s = win.getSelection? win.getSelection() : {};
|
||||
if(s.rangeCount){
|
||||
R = s.getRangeAt(n);
|
||||
} else {
|
||||
if(doc.createRange){
|
||||
R = doc.createRange();
|
||||
R.setStart(doc.body, 0);
|
||||
} else
|
||||
if (doc.selection){ // <IE9
|
||||
R = doc.selection.createRange();
|
||||
R = R.getBookmark();
|
||||
}
|
||||
}
|
||||
s.end = (s.extentNode || s.focusNode || R.startContainer);
|
||||
if(s.anchorNode === s.end){
|
||||
R.direction = s.anchorOffset <= (s.extentOffset || s.focusOffset || 0)? 1 : -1;
|
||||
} else
|
||||
if($.contains(s.anchorNode||{}, s.end||{})){
|
||||
s.end = $(s.anchorNode).contents().filter(s.end).length? s.end : $(s.end).parentsUntil(s.anchorNode).last()[0];
|
||||
R.direction = s.anchorOffset < $(s.anchorNode).contents().index(s.end)? 1 : -1; // Compare immediate descendants to see which comes first.
|
||||
} else {
|
||||
R.direction = s.anchorNode === R.endContainer? -1 : 1; // Checking against startContainer fails going backward.
|
||||
}
|
||||
}
|
||||
return R;
|
||||
}
|
||||
monotype.restore = function(R){
|
||||
var win = monotype.win, doc = win.document;
|
||||
if(R.R && R.restore){
|
||||
R.restore();
|
||||
return;
|
||||
}
|
||||
if(win.getSelection){
|
||||
var s = win.getSelection();
|
||||
s.removeAllRanges();
|
||||
if(s.extend && R.direction < 0){
|
||||
R.esC = R.startContainer;
|
||||
R.esO = R.startOffset;
|
||||
R.setStart(R.endContainer, R.endOffset);
|
||||
}
|
||||
s.addRange(R);
|
||||
R.esC && s.extend(R.esC, R.esO);
|
||||
} else {
|
||||
if(doc.body.createTextRange) { // <IE9
|
||||
var ier = doc.body.createTextRange();
|
||||
ier.moveToBookmark(R);
|
||||
ier.select();
|
||||
}
|
||||
}
|
||||
}
|
||||
monotype.text = function(n){
|
||||
return !n? false : (n.nodeType == 3 || n.nodeType == Node.TEXT_NODE);
|
||||
}
|
||||
monotype.prev = function(n,c,d){
|
||||
return !n? null : n === c? null
|
||||
: n[(d?'next':'previous')+'Sibling']?
|
||||
monotype.deep(n[(d?'next':'previous')+'Sibling'],d?-1:Infinity).container
|
||||
: monotype.prev($(n).parent()[0],c,d);
|
||||
}; monotype.next = function(n,c){ return monotype.prev(n,c,1) }
|
||||
monotype.deep = function(n, o, c, i){
|
||||
return i = (o === Infinity? $(n).contents().length-1 : o),
|
||||
i = (i === -1? 0 : i),
|
||||
(c = $(n).contents()).length?
|
||||
monotype.deep(c = c[i < c.length? i : c.length - 1], monotype.text(c)? 0 : o)
|
||||
: {
|
||||
container: n
|
||||
,offset: $(n).text() && o !== -1? (o === Infinity? $(n).text().length : o) : 0
|
||||
};
|
||||
}
|
||||
monotype.count = function(n, o, c){
|
||||
var g = monotype.deep(n, o)
|
||||
, m = g.container
|
||||
, i = g.offset || 0;
|
||||
while(m = monotype.prev(m,c)){
|
||||
i += $(m).text().length;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
monotype.hint = function(n, o, c){
|
||||
var g = monotype.deep(n, o)
|
||||
, m = g.container
|
||||
, i = g.offset || 0
|
||||
, h = [], t;
|
||||
while(m){
|
||||
h.push({
|
||||
t: t = $(m).text()
|
||||
,n: t? 'TEXT' : m.nodeName
|
||||
});
|
||||
m = t? null : monotype.prev(m,c);
|
||||
}
|
||||
if(h.length == 1 && h[0].t){
|
||||
return [];
|
||||
}
|
||||
if((t = $(n).contents()).length && o == t.length){
|
||||
h.push(1); // Indicate that the selection is after the last element.
|
||||
}
|
||||
return h;
|
||||
}
|
||||
monotype.reach = function(i, c, o){
|
||||
o = o || {};
|
||||
o.i = o.i || o.offset || 0;
|
||||
o.$ = o.$? o.$.jquery? o.$ : $(o.$)
|
||||
: o.container? $(o.container) : $(c);
|
||||
var n = monotype.deep(o.$[0], -1).container, t;
|
||||
while(n){
|
||||
t = $(n).text().length;
|
||||
if(i <= o.i + t){
|
||||
o.$ = $(n);
|
||||
o.i = i - o.i;
|
||||
n = null;
|
||||
} else {
|
||||
o.i += t;
|
||||
}
|
||||
n = monotype.next(n,c);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
return monotype;
|
||||
})(function(r,opt){
|
||||
r = r || {};
|
||||
opt = opt || {};
|
||||
monotype.win = opt.win || window;
|
||||
r = r.jquery || monotype.text(r)? {root: $(r)} : r;
|
||||
r.root = $(r.root || monotype.win.document.body);
|
||||
var t, m = monotype;
|
||||
//console.log('_______________________');
|
||||
r.R = m.range(0);
|
||||
r.H = {};
|
||||
r.H.R = $.extend({}, r.R);
|
||||
r.d = r.R.direction || 1;
|
||||
r.t = r.R.toString();
|
||||
r.H.s = m.hint(r.R.startContainer, r.R.startOffset, r.root[0]);
|
||||
r.s = m.count(r.R.startContainer, r.R.startOffset, r.root[0]);
|
||||
t = m.deep(r.R.startContainer, r.R.startOffset);
|
||||
(!t.offset && !r.H.s.length) && (r.s += 0.1); // At the beginning of a text, not at the end of a text.
|
||||
r.H.e = m.hint(r.R.endContainer, r.R.endOffset, r.root[0]);
|
||||
r.e = (function(n, o, c, t){
|
||||
if(r.R.collapsed
|
||||
|| (o === r.R.startOffset
|
||||
&& n === r.R.startContainer)){
|
||||
return r.s;
|
||||
} c = m.count(n, o, r.root[0]);
|
||||
t = m.deep(n, o);
|
||||
(!t.offset && !r.H.e.length) && (c += 0.1); // Same as above.
|
||||
return c;
|
||||
})(r.R.endContainer, r.R.endOffset);
|
||||
//console.log(r.s, r.R.startOffset, r.H.s, 'M',r.d,'E', r.H.e, r.R.endOffset, r.e);
|
||||
t = r.root.text();
|
||||
r.L = t.length;
|
||||
r.T = {
|
||||
s: t.slice(r.s - 9, r.s)
|
||||
,e: t.slice(r.e, r.e + 9)
|
||||
,t: function(){ return r.T.s + r.T.e }
|
||||
}
|
||||
r.range = function(){
|
||||
//console.log('----');
|
||||
r.H = r.H || {};
|
||||
var s = m.reach(r.s, r.root[0])
|
||||
, st = s.$.text()
|
||||
, e = m.reach(r.e, r.root[0])
|
||||
, et = e.$.text()
|
||||
, R = m.range()
|
||||
, p = function(g, c){ // TODO: BUG! Backtracking in non-Chrome and non-IE9+ browsers. IE9 doesn't like end selections.
|
||||
if(!c || !c.length){
|
||||
return g;
|
||||
}
|
||||
var n = g.$[0], f = [], i = 0, t;
|
||||
while((n = m.next(n,r.root[0])) && ++i < c.length){
|
||||
t = $(n).text();
|
||||
if(t){
|
||||
n = null;
|
||||
} else {
|
||||
f.push(n);
|
||||
}
|
||||
}
|
||||
n = $(f[f.length-1] || g.$);
|
||||
t = n.parent();
|
||||
if(c[c.length-1] === 1 || (i && f.length === i
|
||||
&& (f.length < c.length-1))){ // tests pass with this condition, yet failed without
|
||||
return {
|
||||
i: t.contents().length
|
||||
,$: t
|
||||
}
|
||||
}
|
||||
if(f.length < c.length - 1){ // despite above's addition, this still gets activated.
|
||||
f = t.contents().slice(n = t.contents().index(n));
|
||||
i = f.map(function(j){ return $(this).text()? (n+j+1) : null})[0] || t.contents().length;
|
||||
f = f.slice(0, i - n);
|
||||
n = f.last()[0];
|
||||
if(g.$[0] === n){
|
||||
return g;
|
||||
}
|
||||
return {
|
||||
$: t
|
||||
,i: t.contents().index(n)
|
||||
}
|
||||
}
|
||||
return {
|
||||
i: 0
|
||||
,$: n
|
||||
};
|
||||
}
|
||||
s = p(s, r.H.s);
|
||||
e = p(e, r.H.e);
|
||||
//console.log("START", parseInt(s.i), 'in """',(s.$[0]),'""" with hint of', r.H.s, 'from original', r.s);
|
||||
//console.log("END", parseInt(e.i), 'in """',(e.$[0]),'""" hint clue of', r.H.e, 'from original', r.e);
|
||||
R.setStart(s.$[0], parseInt(s.i));
|
||||
R.setEnd(e.$[0], parseInt(e.i));
|
||||
return R;
|
||||
}
|
||||
r.restore = function(R){
|
||||
if(r.R.startOffset !== r.H.R.startOffset
|
||||
|| r.R.endOffset !== r.H.R.endOffset
|
||||
|| r.R.startContainer !== r.H.R.startContainer
|
||||
|| r.R.endContainer !== r.H.R.endContainer){
|
||||
r.R = R = r.range();
|
||||
} else {
|
||||
R = r.R;
|
||||
}
|
||||
R.direction = r.d;
|
||||
m.restore(R);
|
||||
return r;
|
||||
}
|
||||
return r;
|
||||
});
|
@ -9,6 +9,7 @@
|
||||
fn && fn(a);
|
||||
});
|
||||
})
|
||||
return el;
|
||||
};
|
||||
var n = normalize, u;
|
||||
n.get = function(o, p){
|
||||
@ -97,31 +98,29 @@
|
||||
,function(a, tmp){ // convert
|
||||
if(!(tmp = n.get(a.opt,'convert.' + a.tag))){ return }
|
||||
a.attr = a.attr || n.attrs(a.$);
|
||||
a.$.replaceWith(a.$ = $('<'+ (a.tag = t.toLowerCase()) +'>').append(a.$.contents()));
|
||||
a.$.replaceWith(a.$ = $('<'+ (a.tag = tmp.toLowerCase()) +'>').append(a.$.contents()));
|
||||
h.attr(a.$, a.attr, a.attrs);
|
||||
}
|
||||
,function(a, tmp){ // lookahead
|
||||
if((tmp = n.joint(a.$,1)) && (t = t.contents()).length === 1 && a.tag === n.tag(t = t.first())){
|
||||
a.$.append(t.parent()); // no need to unwrap the child, since the recursion will do it for us
|
||||
if((tmp = n.joint(a.$,1)) && (tmp = tmp.contents()).length === 1 && a.tag === n.tag(tmp = tmp.first())){
|
||||
a.$.append(tmp.parent()); // no need to unwrap the child, since the recursion will do it for us
|
||||
}
|
||||
}
|
||||
,function(a){ // recurse
|
||||
// this needs to precede the exclusion and empty.
|
||||
normalize(a);
|
||||
}
|
||||
,function(a){ // exclude
|
||||
var t;
|
||||
,function(a, tmp){ // exclude
|
||||
if(!n.get(a.opt,'tags.' + a.tag)
|
||||
|| ((t = n.get(a.opt,'tags.'+ a.tag +'.exclude'))
|
||||
&& a.$.parents($.map(t,function(i,v){return v})+' ').length)
|
||||
|| ((tmp = n.get(a.opt,'tags.'+ a.tag +'.exclude'))
|
||||
&& a.$.parents($.map(tmp,function(i,v){return v})+' ').length)
|
||||
){
|
||||
a.$.replaceWith(a.$.contents());
|
||||
}
|
||||
}
|
||||
,function(a){ // prior
|
||||
var t;
|
||||
if((t = n.joint(a.$)).length && a.tag === n.tag(t)){
|
||||
t.append(a.$.contents());
|
||||
,function(a, tmp){ // prior
|
||||
if((tmp = n.joint(a.$)).length && a.tag === n.tag(tmp)){
|
||||
tmp.append(a.$.contents());
|
||||
}
|
||||
}
|
||||
,function(a){ // empty
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gun",
|
||||
"version": "0.9.999992",
|
||||
"version": "0.9.999995",
|
||||
"description": "A realtime, decentralized, offline-first, graph data synchronization engine.",
|
||||
"main": "index.js",
|
||||
"browser": "gun.min.js",
|
||||
|
18
sea.js
18
sea.js
@ -428,7 +428,7 @@
|
||||
SEA.verify = SEA.verify || (async (data, pair, cb, opt) => { try {
|
||||
const json = parse(data)
|
||||
if(false === pair){ // don't verify!
|
||||
const raw = (json !== data)?
|
||||
const raw = (json !== data)?
|
||||
(json.s && json.m)? parse(json.m) : data
|
||||
: json;
|
||||
if(cb){ try{ cb(raw) }catch(e){console.log(e)} }
|
||||
@ -441,11 +441,17 @@
|
||||
const jwk = S.jwk(pub)
|
||||
const key = await (shim.ossl || shim.subtle).importKey('jwk', jwk, S.ecdsa.pair, false, ['verify'])
|
||||
const hash = await sha256hash(json.m)
|
||||
var buf; try{buf = shim.Buffer.from(json.s, opt.encode || 'base64') // NEW DEFAULT!
|
||||
}catch(e){buf = shim.Buffer.from(json.s, 'utf8')} // AUTO BACKWARD OLD UTF8 DATA!
|
||||
const sig = new Uint8Array(buf)
|
||||
const check = await (shim.ossl || shim.subtle).verify(S.ecdsa.sign, key, sig, new Uint8Array(hash))
|
||||
if(!check){ throw "Signature did not match." }
|
||||
var buf; var sig; var check; try{
|
||||
buf = shim.Buffer.from(json.s, opt.encode || 'base64') // NEW DEFAULT!
|
||||
sig = new Uint8Array(buf)
|
||||
check = await (shim.ossl || shim.subtle).verify(S.ecdsa.sign, key, sig, new Uint8Array(hash))
|
||||
if(!check){ throw "Signature did not match." }
|
||||
}catch(e){
|
||||
buf = shim.Buffer.from(json.s, 'utf8') // AUTO BACKWARD OLD UTF8 DATA!
|
||||
sig = new Uint8Array(buf)
|
||||
check = await (shim.ossl || shim.subtle).verify(S.ecdsa.sign, key, sig, new Uint8Array(hash))
|
||||
if(!check){ throw "Signature did not match." }
|
||||
}
|
||||
const r = check? parse(json.m) : u;
|
||||
|
||||
if(cb){ try{ cb(r) }catch(e){console.log(e)} }
|
||||
|
@ -46,3 +46,4 @@
|
||||
}});
|
||||
|
||||
module.exports = SEA.verify;
|
||||
|
11
src/get.js
11
src/get.js
@ -61,13 +61,16 @@ function cache(key, back){
|
||||
return at;
|
||||
}
|
||||
function soul(gun, cb, opt, as){
|
||||
var cat = gun._, tmp;
|
||||
var cat = gun._, acks = 0, tmp;
|
||||
if(tmp = cat.soul){ return cb(tmp, as, cat), gun }
|
||||
if(tmp = cat.link){ return cb(tmp, as, cat), gun }
|
||||
gun.get(function(msg, ev){ // TODO: Bug! Needs once semantics?
|
||||
gun.get(function(msg, ev){
|
||||
if(u === msg.put && (tmp = (obj_map(cat.root.opt.peers, function(v,k,t){t(k)})||[]).length) && acks++ <= tmp){
|
||||
return;
|
||||
}
|
||||
ev.rid(msg);
|
||||
var at = ((at = msg.$) && at._) || {};
|
||||
tmp = at.link || at.soul || rel.is(msg.put) || node_soul(msg.put);
|
||||
tmp = at.link || at.soul || rel.is(msg.put) || node_soul(msg.put) || at.dub;
|
||||
cb(tmp, as, msg, ev);
|
||||
}, {out: {get: {'.':true}}});
|
||||
return gun;
|
||||
@ -118,7 +121,7 @@ function rid(at){
|
||||
//obj.del(map, at); // TODO: Warning: This unsubscribes ALL of this chain's listeners from this link, not just the one callback event.
|
||||
return;
|
||||
}
|
||||
var obj = Gun.obj, obj_has = obj.has, obj_to = Gun.obj.to;
|
||||
var obj = Gun.obj, obj_map = obj.map, obj_has = obj.has, obj_to = Gun.obj.to;
|
||||
var num_is = Gun.num.is;
|
||||
var rel = Gun.val.link, node_soul = Gun.node.soul, node_ = Gun.node._;
|
||||
var empty = {}, u;
|
||||
|
@ -30,7 +30,7 @@ Gun.chain.put = function(data, cb, as){
|
||||
});
|
||||
return gun;
|
||||
}
|
||||
as.$ = gun = root.get(as.soul);
|
||||
as.$ = root.get(as.soul);
|
||||
as.ref = as.$;
|
||||
ify(as);
|
||||
return gun;
|
||||
@ -185,8 +185,8 @@ function any(soul, as, msg, eve){
|
||||
as.data = obj_put({}, at.get, as.data);
|
||||
});
|
||||
}
|
||||
tmp = tmp || at.get;
|
||||
at = (at.root.$.get(tmp)._);
|
||||
tmp = tmp || at.soul || at.link || at.dub;// || at.get;
|
||||
at = tmp? (at.root.$.get(tmp)._) : at;
|
||||
as.soul = tmp;
|
||||
data = as.data;
|
||||
}
|
||||
|
@ -4,13 +4,12 @@ Gun.chain.set = function(item, cb, opt){
|
||||
var gun = this, soul;
|
||||
cb = cb || function(){};
|
||||
opt = opt || {}; opt.item = opt.item || item;
|
||||
if(soul = Gun.node.soul(item)){ return gun.set(gun.back(-1).get(soul), cb, opt) }
|
||||
if(soul = Gun.node.soul(item)){ item = Gun.obj.put({}, soul, Gun.val.link.ify(soul)) }
|
||||
if(!Gun.is(item)){
|
||||
var id = gun.back('opt.uuid')();
|
||||
if(id && Gun.obj.is(item)){
|
||||
return gun.set(gun._.root.$.put(item, id), cb, opt);
|
||||
if(Gun.obj.is(item)){;
|
||||
item = gun.back(-1).get(soul = soul || Gun.node.soul(item) || gun.back('opt.uuid')()).put(item);
|
||||
}
|
||||
return gun.get((Gun.state.lex() + Gun.text.random(7))).put(item, cb, opt);
|
||||
return gun.get(soul || (Gun.state.lex() + Gun.text.random(7))).put(item, cb, opt);
|
||||
}
|
||||
item.get(function(soul, o, msg){
|
||||
if(!soul){ return cb.call(gun, {err: Gun.log('Only a node can be linked! Not "' + msg.put + '"!')}) }
|
||||
|
@ -42,7 +42,7 @@ State.ify = function(n, k, s, v, soul){ // put a key's state on a node.
|
||||
return n;
|
||||
}
|
||||
State.to = function(from, k, to){
|
||||
var val = from[k]; // BUGGY!
|
||||
var val = (from||{})[k];
|
||||
if(obj_is(val)){
|
||||
val = obj_copy(val);
|
||||
}
|
||||
|
@ -3705,6 +3705,7 @@ describe('Gun', function(){
|
||||
});
|
||||
|
||||
it('Multiple subscribes should trigger', function(done){
|
||||
// thanks to @ivkan for reporting and providing test.
|
||||
var gun = Gun();
|
||||
var check = {};
|
||||
gun.get('m/s/key').put({property: 'value'});
|
||||
|
@ -3,8 +3,8 @@ var config = {
|
||||
port: 8765,
|
||||
servers: 2,
|
||||
browsers: 2,
|
||||
each: 100000,
|
||||
burst: 2,
|
||||
each: 500,
|
||||
burst: 50,
|
||||
wait: 1,
|
||||
notrad: true,
|
||||
route: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user