UNPKG

5.54 kBJavaScriptView Raw
1
2
3function Gun(o){
4 if(o instanceof Gun){ return (this._ = {gun: this}).gun }
5 if(!(this instanceof Gun)){ return new Gun(o) }
6 return Gun.create(this._ = {gun: this, opt: o});
7}
8
9Gun.is = function(gun){ return (gun instanceof Gun) }
10
11Gun.version = 0.6;
12
13Gun.chain = Gun.prototype;
14Gun.chain.toJSON = function(){};
15
16var Type = require('./type');
17Type.obj.to(Type, Gun);
18Gun.HAM = require('./HAM');
19Gun.val = require('./val');
20Gun.node = require('./node');
21Gun.state = require('./state');
22Gun.graph = require('./graph');
23Gun.dup = require('./dup');
24Gun.on = require('./onify')();
25
26Gun._ = { // some reserved key words, these are not the only ones.
27 node: Gun.node._ // all metadata of a node is stored in the meta property on the node.
28 ,soul: Gun.val.rel._ // a soul is a UUID of a node but it always points to the "latest" data known.
29 ,state: Gun.state._ // other than the soul, we store HAM metadata.
30 ,field: '.' // a field is a property on a node which points to a value.
31 ,value: '=' // the primitive value.
32}
33
34;(function(){
35 Gun.create = function(at){
36 at.on = at.on || Gun.on;
37 at.root = at.root || at.gun;
38 at.graph = at.graph || {};
39 at.dup = at.dup || new Gun.dup;
40 var gun = at.gun.opt(at.opt);
41 if(!at.once){
42 at.on('in', input, at);
43 at.on('out', output, at);
44 }
45 at.once = 1;
46 return gun;
47 }
48 function output(at){
49 //console.log("add to.next(at)!"); // TODO: BUG!!!!
50 var cat = this.as, gun = cat.gun, tmp;
51 // TODO: BUG! Outgoing `get` to read from in memory!!!
52 if(at.get && get(at, cat)){ return }
53 cat.on('in', obj_to(at, {gun: cat.gun})); // TODO: PERF! input now goes to output so it would be nice to reduce the circularity here for perf purposes.
54 if(at['#']){
55 cat.dup.track(at['#']);
56 }
57 if(!at.gun){
58 at = obj_to(at, {gun: gun});
59 }
60 Gun.on('out', at); // TODO: BUG! PERF? WARNING!!! A in-memory `put` triggers an out with an existing ID which reflows into IN which at the end also goes Gun OUT, and then this scope/function resumes and it triggers OUT again!
61 }
62 function get(at, cat){
63 var soul = at.get[_soul], node = cat.graph[soul], field = at.get[_field], tmp;
64 var next = cat.next || (cat.next = {}), as = /*(at.gun||empty)._ ||*/ (next[soul] || (next[soul] = cat.gun.get(soul)))._;
65 if(!node){ return }
66 if(field){
67 if(!obj_has(node, field)){ return }
68 tmp = Gun.obj.put(Gun.node.soul.ify({}, soul), field, node[field]);
69 node = Gun.state.ify(tmp, field, Gun.state.is(node, field));
70 }
71 as.on('in', {
72 put: node, // TODO: BUG! Clone node!
73 get: as.soul,
74 gun: as.gun
75 });
76 if(0 < as.ack){
77 return true;
78 }
79 }
80 function input(at){
81 //console.log("add to.next(at)"); // TODO: BUG!!!
82 var ev = this, cat = ev.as;
83 if(!at.gun){ at.gun = cat.gun }
84 if(!at['#'] && at['@']){
85 at['#'] = Gun.text.random(); // TODO: Use what is used other places instead.
86 if(Gun.on.ack(at['@'], at)){ return } // TODO: Consider not returning here, maybe, where this would let the "handshake" on sync occur for Holy Grail?
87 cat.dup.track(at['#']);
88 cat.on('out', at);
89 return;
90 }
91 if(at['#'] && cat.dup.check(at['#'])){ return }
92 cat.dup.track(at['#']);
93 if(Gun.on.ack(at['@'], at)){ return }
94 if(at.put){
95 Gun.HAM.synth(at, ev, cat.gun); // TODO: Clean up, just make it part of on('put')!
96 Gun.on('put', at);
97 }
98 if(at.get){ Gun.on('get', at) }
99 Gun.on('out', at);
100 }
101}());
102
103;(function(){
104 var ask = Gun.on.ask = function(cb, as){
105 var id = Gun.text.random();
106 if(cb){ ask.on(id, cb, as) }
107 return id;
108 }
109 ask.on = Gun.on;
110 Gun.on.ack = function(at, reply){
111 if(!at || !reply || !ask.on){ return }
112 var id = at['#'] || at;
113 if(!ask.tag || !ask.tag[id]){ return }
114 ask.on(id, reply);
115 return true;
116 }
117}());
118
119;(function(){
120 Gun.chain.opt = function(opt){
121 opt = opt || {};
122 var gun = this, at = gun._, tmp = opt.peers || opt;
123 if(!obj_is(opt)){ opt = {} }
124 if(!obj_is(at.opt)){ at.opt = opt }
125 if(text_is(tmp)){ tmp = [tmp] }
126 if(list_is(tmp)){
127 tmp = obj_map(tmp, function(url, i, map){
128 map(url, {url: url});
129 });
130 if(!obj_is(at.opt.peers)){ at.opt.peers = {}}
131 at.opt.peers = obj_to(tmp, at.opt.peers);
132 }
133 at.opt.peers = at.opt.peers || {};
134 obj_to(opt, at.opt); // copies options on to `at.opt` only if not already taken.
135 Gun.on('opt', at);
136 return gun;
137 }
138}());
139
140var text_is = Gun.text.is;
141var list_is = Gun.list.is;
142var obj = Gun.obj, obj_is = obj.is, obj_has = obj.has, obj_to = obj.to, obj_map = obj.map;
143var _soul = Gun._.soul, _field = Gun._.field;
144//var u;
145
146console.debug = function(i, s){ return (console.debug.i && i === console.debug.i && console.debug.i++) && (console.log.apply(console, arguments) || s) };
147
148Gun.log = function(){ return (!Gun.log.off && console.log.apply(console, arguments)), [].slice.call(arguments).join(' ') }
149Gun.log.once = function(w,s,o){ return (o = Gun.log.once)[w] = o[w] || 0, o[w]++ || Gun.log(s) }
150
151/* Please do not remove these messages unless you are paying for a monthly sponsorship, thanks! */
152Gun.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'!");
153/* Please do not remove these messages unless you are paying for a monthly sponsorship, thanks! */
154
155if(typeof window !== "undefined"){ window.Gun = Gun }
156if(typeof common !== "undefined"){ common.exports = Gun }
157module.exports = Gun;
158
\No newline at end of file