time.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. ;(function(){
  2. var Gun = (typeof window !== "undefined")? window.Gun : require('../gun');
  3. var ify = Gun.node.ify, u;
  4. Gun.chain.time = function(data, a, b){
  5. if(data instanceof Function){
  6. return travel(data, a, b, this);
  7. }
  8. var gun = this, root = gun.back(-1);
  9. var cb = (a instanceof Function && a) || (b instanceof Function && b);
  10. if(Gun.is(data)){
  11. data.get(function(soul){
  12. if(!soul){
  13. return cb && cb({err: "Timegraph cannot link `undefined`!"});
  14. }
  15. gun.time(Gun.val.link.ify(soul), a, b);
  16. }, true);
  17. return gun;
  18. }
  19. opt = (cb === a)? b : a;
  20. opt = Gun.text.is(opt)? {key: opt} : opt || {};
  21. var t = new Date(Gun.state()).toISOString().split(/[\-t\:\.z]/ig);
  22. var p, tmp = t.pop();
  23. gun.get(function(soul){
  24. var id = soul;
  25. p = id;
  26. if(!p){ id = p = (gun.back('opt.uuid') || Gun.text.random)(9) }
  27. // could shrink this into a loop. Do later?
  28. t = [p].concat(t);
  29. var rid = opt.key || (gun.back('opt.uuid') || Gun.text.random)(9);
  30. var milli = ify({}, t.join(':'));
  31. milli[rid] = data;
  32. tmp = t.pop();
  33. var sec = ify({}, t.join(':'));
  34. sec[tmp] = milli;
  35. tmp = t.pop();
  36. var min = ify({}, t.join(':'));
  37. min[tmp] = sec;
  38. tmp = t.pop();
  39. var hour = ify({}, t.join(':'));
  40. hour[tmp] = min;
  41. tmp = t.pop();
  42. var day = ify({}, t.join(':'));
  43. day[tmp] = hour;
  44. tmp = t.pop();
  45. var month = ify({}, t.join(':'));
  46. month[tmp] = day;
  47. tmp = t.pop();
  48. var year = ify({}, t.join(':'));
  49. year[tmp] = month;
  50. tmp = t.pop();
  51. var time = ify({}, t.join(':') || id);
  52. time[tmp] = year;
  53. gun.put(time, cb);
  54. }, true);
  55. return gun;
  56. }
  57. function travel(cb, opt, b, gun){
  58. var root = gun.back(-1), tmp;
  59. (opt = Gun.num.is(opt)? {last: opt} : opt || {}).seen = opt.seen || {};
  60. var t = now(opt.start);
  61. gun.on(function(data, key, msg, eve){
  62. var at = msg.$._, id = at.link || at.soul || Gun.node.soul(data);
  63. if(!id){ return }
  64. if(false === opt.next){ eve.off() }
  65. else { opt.next = true }
  66. opt.start = [opt.id = id].concat(t);
  67. opt.low = opt.low || opt.start;
  68. opt.top = opt.top || opt.start;
  69. opt.now = [id].concat(now());
  70. //console.log("UPDATE");
  71. find(opt, cb, root, opt.at? opt.now : opt.at = opt.start);
  72. });
  73. return gun;
  74. }
  75. function now(t){
  76. return new Date(t || Gun.state()).toISOString().split(/[\-t\:\.z]/ig).slice(0,-1);
  77. }
  78. function find(o, cb, root, at, off){
  79. var at = at || o.at, t = at.join(':'), tmp;
  80. if(!off){
  81. if(o.seen[t]){ return }
  82. o.seen[t] = true;
  83. }
  84. var next = (o.low || o.start)[at.length];
  85. root.get(t).get(function(msg, ev){
  86. if(off){ ev.off() }
  87. var g = this;
  88. //console.log(at, msg.put);
  89. if(u === msg.put){
  90. find(o, cb, root, at.slice(0,-1), off);
  91. return;
  92. }
  93. if(7 < at.length){
  94. var l = Object.keys(msg.put).length;
  95. if(l === o.seen[t]){ return }
  96. var when = +(toDate(at));
  97. Gun.node.is(msg.put, function(v, k){
  98. cb(v, k, when, ev);
  99. if(o.last){ --o.last }
  100. });
  101. o.seen[t] = l;
  102. if(!o.last){ return }
  103. if(o.last <= 0){ return }
  104. o.low = at;
  105. var tmp = at.slice(0,-1);
  106. find(o, cb, root, tmp, true);
  107. return;
  108. }
  109. if(o.last && false !== off){
  110. var keys = Object.keys(msg.put).sort().reverse();
  111. var less = Gun.list.map(keys, function(k){
  112. if(parseFloat(k) < parseFloat(next)){ return k }
  113. });
  114. if(!less){
  115. find(o, cb, root, at.slice(0,-1), true);
  116. } else {
  117. var tmp = (at || o.at).slice();
  118. tmp.push(less);
  119. (o.low = tmp.slice()).push(Infinity);
  120. find(o, cb, root, tmp, true);
  121. }
  122. }
  123. if(off){ return }
  124. if(!o.next){ return }
  125. if(at < o.start.slice(0, at.length)){ return }
  126. var n = [o.id].concat(now()), top = n[at.length];
  127. Gun.node.is(msg.put, function(v, k){
  128. if(k > top){ return }
  129. (v = at.slice()).push(k);
  130. find(o, cb, root, v, false);
  131. });
  132. })
  133. }
  134. function toDate(at){
  135. at = at.slice(-7);
  136. return new Date(Date.UTC(at[0], parseFloat(at[1])-1, at[2], at[3], at[4], at[5], at[6]));
  137. }
  138. }());