FaC: Das alte Flag von Terminen, die in die Zeiterfassung übernommen worden sind, wird ebenfalls berücksichtigt.
207 lines
5.0 KiB
JavaScript
207 lines
5.0 KiB
JavaScript
var nanosocket = (function () {
|
|
'use strict';
|
|
|
|
var promise_1 = promise;
|
|
|
|
function promise() {
|
|
var resolve
|
|
, reject
|
|
, p = new Promise(function(res, rej){
|
|
resolve = res, reject = rej;
|
|
});
|
|
|
|
arguments.length && resolve(arguments[0]);
|
|
p.resolve = resolve;
|
|
p.reject = reject;
|
|
return p
|
|
}
|
|
|
|
var flatten = function flatten(p,v){
|
|
if (v instanceof Array) v = v.reduce(flatten, []);
|
|
return (p = p || []), p.concat(v)
|
|
};
|
|
|
|
var has = function has(o, k) {
|
|
return k in o
|
|
};
|
|
|
|
var def = function def(o, p, v, w){
|
|
if (o.host && o.host.nodeName) o = o.host;
|
|
if (p.name) v = p, p = p.name;
|
|
!has(o, p) && Object.defineProperty(o, p, { value: v, writable: w });
|
|
return o[p]
|
|
};
|
|
|
|
var emitterify = function emitterify(body) {
|
|
body = body || {};
|
|
def(body, 'emit', emit, 1);
|
|
def(body, 'once', once, 1);
|
|
def(body, 'off', off, 1);
|
|
def(body, 'on', on, 1);
|
|
body.on['*'] = body.on['*'] || [];
|
|
return body
|
|
|
|
function emit(type, pm, filter) {
|
|
var li = body.on[type.split('.')[0]] || []
|
|
, results = [];
|
|
|
|
for (var i = 0; i < li.length; i++)
|
|
if (!li[i].ns || !filter || filter(li[i].ns))
|
|
results.push(call(li[i].isOnce ? li.splice(i--, 1)[0] : li[i], pm));
|
|
|
|
for (var i = 0; i < body.on['*'].length; i++)
|
|
results.push(call(body.on['*'][i], [type, pm]));
|
|
|
|
return results.reduce(flatten, [])
|
|
}
|
|
|
|
function call(cb, pm){
|
|
return cb.next ? cb.next(pm)
|
|
: pm instanceof Array ? cb.apply(body, pm)
|
|
: cb.call(body, pm)
|
|
}
|
|
|
|
function on(type, opts, isOnce) {
|
|
var id = type.split('.')[0]
|
|
, ns = type.split('.')[1]
|
|
, li = body.on[id] = body.on[id] || []
|
|
, cb = typeof opts == 'function' ? opts : 0;
|
|
|
|
return !cb && ns ? (cb = body.on[id]['$'+ns]) ? cb : push(observable(body, opts))
|
|
: !cb && !ns ? push(observable(body, opts))
|
|
: cb && ns ? push((remove(li, body.on[id]['$'+ns] || -1), cb))
|
|
: cb && !ns ? push(cb)
|
|
: false
|
|
|
|
function push(cb){
|
|
cb.isOnce = isOnce;
|
|
cb.type = id;
|
|
if (ns) body.on[id]['$'+(cb.ns = ns)] = cb;
|
|
li.push(cb);
|
|
return cb.next ? cb : body
|
|
}
|
|
}
|
|
|
|
function once(type, callback){
|
|
return body.on(type, callback, true)
|
|
}
|
|
|
|
function remove(li, cb) {
|
|
var i = li.length;
|
|
while (~--i)
|
|
if (cb == li[i] || cb == li[i].fn || !cb)
|
|
li.splice(i, 1);
|
|
}
|
|
|
|
function off(type, cb) {
|
|
remove((body.on[type] || []), cb);
|
|
if (cb && cb.ns) delete body.on[type]['$'+cb.ns];
|
|
return body
|
|
}
|
|
|
|
function observable(parent, opts) {
|
|
opts = opts || {};
|
|
var o = emitterify(opts.base || promise_1());
|
|
o.i = 0;
|
|
o.li = [];
|
|
o.fn = opts.fn;
|
|
o.parent = parent;
|
|
o.source = opts.fn ? o.parent.source : o;
|
|
|
|
o.on('stop', function(reason){
|
|
return o.type
|
|
? o.parent.off(o.type, o)
|
|
: o.parent.off(o)
|
|
});
|
|
|
|
o.each = function(fn) {
|
|
var n = fn.next ? fn : observable(o, { fn: fn });
|
|
o.li.push(n);
|
|
return n
|
|
};
|
|
|
|
o.pipe = function(fn) {
|
|
return fn(o)
|
|
};
|
|
|
|
o.map = function(fn){
|
|
return o.each(function(d, i, n){ return n.next(fn(d, i, n)) })
|
|
};
|
|
|
|
o.filter = function(fn){
|
|
return o.each(function(d, i, n){ return fn(d, i, n) && n.next(d) })
|
|
};
|
|
|
|
o.reduce = function(fn, acc) {
|
|
return o.each(function(d, i, n){ return n.next(acc = fn(acc, d, i, n)) })
|
|
};
|
|
|
|
o.unpromise = function(){
|
|
var n = observable(o, { base: {}, fn: function(d){ return n.next(d) } });
|
|
o.li.push(n);
|
|
return n
|
|
};
|
|
|
|
o.next = function(value) {
|
|
o.resolve && o.resolve(value);
|
|
return o.li.length
|
|
? o.li.map(function(n){ return n.fn(value, n.i++, n) })
|
|
: value
|
|
};
|
|
|
|
o.until = function(stop){
|
|
stop.each(function(){ o.source.emit('stop'); });
|
|
return o
|
|
};
|
|
|
|
o.off = function(fn){
|
|
return remove(o.li, fn), o
|
|
};
|
|
|
|
o[Symbol.asyncIterator] = function(){ return {
|
|
next: () => (o.wait = new Promise(resolve => {
|
|
o.wait = true;
|
|
o.map((d, i, n) => {
|
|
delete o.wait;
|
|
o.off(n);
|
|
resolve({ value: d, done: false });
|
|
});
|
|
|
|
o.emit('pull', o);
|
|
}))
|
|
}};
|
|
|
|
return o
|
|
}
|
|
};
|
|
|
|
var nanosocket = function(url = location.href.replace('http', 'ws')){
|
|
const io = emitterify({ attempt: 0 });
|
|
io.ready = io.once('connected');
|
|
io.connect = connect(io, url);
|
|
io.connect();
|
|
io.send = data => io.ready.then(socket => socket.send(data));
|
|
return io
|
|
};
|
|
|
|
const { min, pow } = Math;
|
|
|
|
const connect = (io, url) => () => {
|
|
const { WebSocket, location, setTimeout } = window
|
|
, socket = new WebSocket(url);
|
|
socket.onopen = d => io.emit('connected', socket);
|
|
socket.onmessage = d => io.emit('recv', d.data);
|
|
socket.onclose = d => {
|
|
io.ready = io.once('connected');
|
|
io.emit('disconnected');
|
|
setTimeout(io.connect, backoff(++io.attempt));
|
|
};
|
|
};
|
|
|
|
const backoff = (attempt, base = 100, cap = 10000) =>
|
|
min(cap, base * pow(2, attempt));
|
|
|
|
return nanosocket;
|
|
|
|
}());
|