state.js
2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
var Type = require('./type');
var Node = require('./node');
function State(){
var t;
/*if(perf){
t = start + perf.now(); // Danger: Accuracy decays significantly over time, even if precise.
} else {*/
t = +new Date;
//}
if(last < t){
return N = 0, last = t + State.drift;
}
return last = t + ((N += 1) / D) + State.drift;
}
var time = Type.time.is, last = -Infinity, N = 0, D = 1000; // WARNING! In the future, on machines that are D times faster than 2016AD machines, you will want to increase D by another several orders of magnitude so the processing speed never out paces the decimal resolution (increasing an integer effects the state accuracy).
var perf = (typeof performance !== 'undefined')? (performance.timing && performance) : false, start = (perf && perf.timing && perf.timing.navigationStart) || (perf = false);
var S_ = State._ = '>';
State.drift = 0;
State.is = function(n, k, o){ // convenience function to get the state on a key on a node and return it.
var tmp = (k && n && n[N_] && n[N_][S_]) || o;
if(!tmp){ return }
return num_is(tmp = tmp[k])? tmp : -Infinity;
}
State.lex = function(){ return State().toString(36).replace('.','') }
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;
}
n = Node.soul.ify(n, soul); // then make it so!
}
var tmp = obj_as(n[N_], S_); // grab the states data.
if(u !== k && k !== N_){
if(num_is(s)){
tmp[k] = s; // add the valid state.
}
if(u !== v){ // Note: Not its job to check for valid values!
n[k] = v;
}
}
return n;
}
State.to = function(from, k, to){
var val = (from||{})[k];
if(obj_is(val)){
val = obj_copy(val);
}
return State.ify(to, k, State.is(from, k), val, Node.soul(from));
}
;(function(){
State.map = function(cb, s, as){ var u; // for use with Node.ify
var o = obj_is(o = cb || s)? o : null;
cb = fn_is(cb = cb || s)? cb : null;
if(o && !cb){
s = num_is(s)? s : State();
o[N_] = o[N_] || {};
obj_map(o, map, {o:o,s:s});
return o;
}
as = as || obj_is(s)? s : u;
s = num_is(s)? s : State();
return function(v, k, o, opt){
if(!cb){
map.call({o: o, s: s}, v,k);
return v;
}
cb.call(as || this || {}, v, k, o, opt);
if(obj_has(o,k) && u === o[k]){ return }
map.call({o: o, s: s}, v,k);
}
}
function map(v,k){
if(N_ === k){ return }
State.ify(this.o, k, this.s) ;
}
}());
var obj = Type.obj, obj_as = obj.as, obj_has = obj.has, obj_is = obj.is, obj_map = obj.map, obj_copy = obj.copy;
var num = Type.num, num_is = num.is;
var fn = Type.fn, fn_is = fn.is;
var N_ = Node._, u;
module.exports = State;