Comparing version 0.0.10 to 0.0.11-11bca60dc2e3e6c42592c194492636b865039e52
@@ -0,10 +1,6 @@ | ||
import { create, parse, set, struct, subscribe } from 'brisky-struct'; | ||
import bs from 'brisky-stamp'; | ||
import hash from 'string-hash'; | ||
import { c, create, parse, set, struct, subscribe } from 'brisky-struct'; | ||
import bs from 'brisky-stamp'; | ||
import ua from 'vigour-ua'; | ||
const uniq = global.navigator.userAgent + | ||
global.navigator.userLanguage + | ||
global.navigator.language; | ||
var id = hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
const next = typeof window === 'undefined' | ||
@@ -14,19 +10,8 @@ ? process.nextTick | ||
const parse$1 = (stamp, hub, t) => { | ||
const src = bs.src(stamp); | ||
if (!src) { | ||
return bs.create(bs.type(stamp), hub.id, bs.val(stamp)) | ||
} else { | ||
const val = bs.val(stamp); | ||
if (!t[1]) t[1] = {}; | ||
const meta = t[1]; | ||
if (!meta.resolve) meta.resolve = {}; | ||
const resolve = meta.resolve[src]; | ||
if (!resolve || val < resolve) meta.resolve[src] = val; | ||
return stamp | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
if (!struct$$1.isHub || struct$$1.key === 'clients' || (struct$$1._p && struct$$1._p.key === 'clients')) { | ||
return | ||
} | ||
}; | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
const path = struct$$1.path(); | ||
const path = struct$$1.path(); // cached version (later) | ||
const len = path.length; | ||
@@ -47,3 +32,3 @@ | ||
s.stamp = parse$1(struct$$1.stamp, hub, t); | ||
s.stamp = struct$$1.stamp; | ||
@@ -58,5 +43,9 @@ if (val === null) { | ||
} else if (struct$$1.val && struct$$1.val.inherits) { | ||
// make a bit more secure... | ||
// if (!s.val) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
// if allrdy serialized stop it! | ||
serialize(hub, t, struct$$1.val, val, level); | ||
// } | ||
} else if (struct$$1.val !== void 0) { | ||
@@ -69,29 +58,37 @@ s.val = struct$$1.val; | ||
const meta = hub => { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
store[1].context = hub.clientContext; | ||
store[1].id = hub.id; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
if (!hub.receiveOnly) { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
if (hub.context) { | ||
if (hub.context.keys().length > 0) { | ||
store[1].context = hub.context.compute() ? hub.context.serialize() : false; | ||
} else { | ||
store[1].context = hub.context.compute() || false; | ||
} | ||
} | ||
store[1].id = hub.client.key; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
} | ||
}; | ||
const send = (val, stamp, struct$$1) => { | ||
if (bs.type(stamp) !== 'upstream') { | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p.url && !p._c) { hub = p; } | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly && struct$$1.key !== 'clients') { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.id) { | ||
return | ||
} | ||
// -1 means upsteam (floats for extra speed) | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p._url_ && !p._c) hub = p; | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly) { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.client.key) { | ||
return | ||
} | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} | ||
@@ -137,6 +134,7 @@ }; | ||
const parse$2 = (struct$$1, obj, key, root) => { | ||
const parse$1 = (struct$$1, obj, key, root) => { | ||
const result = {}; | ||
if (!root) { root = result; } | ||
if (obj.type) result.type = obj.type; // need to be done before the rest of subs to sync correctly | ||
// need to be done before the rest of subs to sync correctly | ||
if (obj.type) result.type = parse$1(struct$$1, obj.type, 'type'); | ||
for (let i in obj) { | ||
@@ -148,3 +146,3 @@ if (i !== '_' && i !== 'type') { | ||
// console.log('CLIENT NEED TO HANDLE MORE SPECIAL THEN JUST ROOT') | ||
// let id = state.id | ||
// let id = state._uid_ | ||
// if (!root.clients) { root.clients = {} } | ||
@@ -178,3 +176,3 @@ // if (!root.clients[id]) { root.clients[id] = {} } | ||
// empty objects are very uninteresetting maybe just skip them | ||
let parsed = parse$2(struct$$1, obj[i], i, root); | ||
let parsed = parse$1(struct$$1, obj[i], i, root); | ||
@@ -197,10 +195,19 @@ // if (i === 'root' || i === 'parent') { | ||
const uniq = global.navigator.userAgent + | ||
global.navigator.userLanguage + | ||
global.navigator.language; | ||
var uid = () => hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
var createClient = (t, val, stamp, useragent, id) => { | ||
if (!id) id = t._uid_ || uid(); | ||
ua(useragent, val); | ||
t.set({ clients: { [id]: val } }, stamp); | ||
return t.clients[id] | ||
}; | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new WebSocket(url); | ||
const id = hub.id; | ||
// t, val, stamp, useragent, id | ||
const client = hub.client || createClient(hub, {}, false); | ||
hub.set({ clients: { [id]: { } } }, false); | ||
const client = hub.clients[id]; | ||
hub.set({ client }, false); | ||
@@ -211,7 +218,7 @@ | ||
const close = () => { | ||
const stamp = bs.create('disconnect', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = false; | ||
hub.set({ connected: false }, stamp); | ||
bs.close(); | ||
if (!socket.blockReconnect && hub.url) { | ||
if (!socket.blockReconnect && hub._url_) { | ||
reconnect = Math.min((reconnect * 1.5), 2000); | ||
@@ -224,12 +231,12 @@ hub.reconnect = setTimeout(connect, reconnect, hub, url, reconnect); | ||
socket.onerror = () => { | ||
if (typeof window === 'undefined') { | ||
close(); | ||
} else { | ||
socket.close(); | ||
} | ||
}; | ||
if (typeof window === 'undefined') { | ||
socket.hackyOnClose = close; | ||
} | ||
socket.onerror = typeof window === 'undefined' | ||
? close | ||
: () => socket.close(); | ||
socket.onopen = () => { | ||
const stamp = bs.create('connected', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = socket; | ||
@@ -241,7 +248,13 @@ meta(hub); | ||
socket.onmessage = ({ data }) => { | ||
const stamp = bs.create('upstream'); | ||
// console.log(JSON.stringify(JSON.parse(data), false, 2)) | ||
hub.set(JSON.parse(data), stamp); | ||
bs.close(stamp); | ||
socket.onmessage = (data) => { | ||
data = data.data; | ||
// console.warn('INCOMING\n', JSON.parse(data)) | ||
if (!hub.receiveOnly) { | ||
hub.receiveOnly = true; | ||
hub.set(JSON.parse(data), false); | ||
hub.receiveOnly = null; | ||
} else { | ||
hub.set(JSON.parse(data), false); | ||
} | ||
bs.close(); | ||
}; | ||
@@ -251,4 +264,3 @@ }; | ||
const removeUrl = hub => { | ||
hub.url = null; | ||
hub.urlIndex = null; | ||
hub.url = hub._url_ = hub.urlIndex = null; | ||
hub.emitters.set({ data: { url$: null } }, false); | ||
@@ -264,7 +276,14 @@ }; | ||
hub.socket.blockReconnect = true; | ||
hub.socket.close(); | ||
console.log('GO GO GOREMOVE', hub.socket._readyState); | ||
if (hub.connected.compute() === false || !hub.socket._readyState) { | ||
console.log('hacky!'); | ||
hub.socket.hackyOnClose(); | ||
} else { | ||
hub.socket.close(); | ||
} | ||
} | ||
// hub.socket = false | ||
}; | ||
const url = (hub, val, stamp) => { | ||
const url = (hub, val, key, stamp) => { | ||
hub.on((val, stamp, t) => { | ||
@@ -277,15 +296,34 @@ if (val === null && !t._c && t === hub) { | ||
}, 'url$'); | ||
if (!val) val = null; | ||
if (val !== hub.url) { | ||
if ((!hub.url && val) || (hub.url.compute() !== val)) { | ||
removeSocket(hub); | ||
hub.set({ connected: false }, stamp); | ||
if (!val) { | ||
removeUrl(hub); | ||
hub.set({ connected: false }, stamp); | ||
hub._url_ = null; | ||
if (hub.url) hub.url.set(null, stamp); | ||
} else { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; | ||
hub.url = val; | ||
connect(hub, val, 50); | ||
if (!hub.url) { | ||
create({ | ||
on: { | ||
data: { | ||
url: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
hub.set({ connected: false }, stamp); | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; // use this for checks | ||
hub._url_ = val; | ||
connect(hub, val, 50); | ||
} else { | ||
hub._url_ = null; | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, struct, hub, key); | ||
} | ||
hub.url.set(val, stamp); | ||
} | ||
@@ -295,27 +333,69 @@ } | ||
// very context as well | ||
// const clients => (val, stamp) { | ||
// const hub = this.cParent() | ||
// if (this.compute() === false && hub.upstream) { | ||
// // put this in clients (the file) | ||
// const clients = hub.clients | ||
// if (clients && clients.keys().length > 1) { | ||
// clients.each((client) => { | ||
// if ( | ||
// client.val !== null && | ||
// !client.socket && | ||
// client.key != hub.id // eslint-disable-line | ||
// ) { | ||
// client.remove(stamp) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
// } | ||
const removeClients = (hub, stamp) => { | ||
const clients = hub.clients; | ||
if (clients && clients.keys().length > 1) { | ||
clients.forEach((client, key) => { | ||
if ( | ||
client.val !== null && | ||
client !== hub.client | ||
) { | ||
client.set(null, stamp); | ||
delete clients[key]; | ||
} | ||
}); | ||
} | ||
}; | ||
const connected = { type: 'struct' }; | ||
const connected = { | ||
type: 'struct', | ||
on: { | ||
data: { | ||
removeClients: (val, stamp, t) => { | ||
if (t.compute() === false) { | ||
// all instances! -- fix this | ||
removeClients(t._p, stamp); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
const context = (hub, val) => { | ||
if (val !== hub.clientContext) { | ||
hub.clientContext = val; | ||
const contextStruct = struct.create({ | ||
props: { | ||
default: { | ||
on: { | ||
data: { | ||
updateParent: (val, stamp, t) => { | ||
console.log('👻 GO UPDATE PARENT!!! 👻'); | ||
t.parent().emit('data', val, stamp); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
const contextIsNotEqual = (val, context) => { | ||
if (val && typeof val === 'object') { | ||
for (let field in val) { | ||
if (!context[field] || val[field] !== context[field].compute()) { | ||
console.log('😜', field); | ||
return true | ||
} | ||
} | ||
} else { | ||
console.log('😜 ?????'); | ||
return val !== context.compute() | ||
} | ||
}; | ||
const context = (hub, val, key, stamp) => { | ||
if (!hub.context || contextIsNotEqual(val, hub.context)) { | ||
console.log('⚽️ fire fire fire FLAME context ⚽️', val, stamp); | ||
if (!hub.context) { | ||
create(val, stamp, contextStruct, hub, key); | ||
} else { | ||
removeClients(hub, stamp); | ||
hub.context.set(val, stamp); | ||
} | ||
if (hub.connected && hub.connected.compute() === true) meta(hub); | ||
@@ -341,11 +421,13 @@ } | ||
if (!raw) subs = parse(subs); | ||
const parsed = parse$2(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
if (!this.receiveOnly) { | ||
const parsed = parse$1(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
} | ||
} | ||
@@ -375,12 +457,24 @@ } | ||
const props$1 = { contextKey: true }; | ||
var context$1 = { | ||
props: { | ||
contextKey: true, | ||
getContext: (t, fn) => { | ||
t.set({ | ||
define: { | ||
getContext (key, socket) { | ||
return fn(key, (key) => createContext(this, key), this, socket) | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
getContext: (key, context) => context() | ||
}; | ||
const define$1 = { | ||
getContext (val) { | ||
var result = find(this, val); | ||
if (!result) { | ||
result = this.create({ contextKey: val }, false); | ||
} | ||
return result | ||
const createContext = (hub, val) => { | ||
var result = find(hub, val); | ||
if (!result) { | ||
result = hub.create({ contextKey: val }, false); | ||
} | ||
return result | ||
}; | ||
@@ -393,6 +487,3 @@ | ||
while (i--) { | ||
if (instances[i].contextKey === val) { | ||
// console.log('found context --->', val, instances[i].clients.keys()) | ||
return instances[i] | ||
} | ||
if (instances[i].contextKey === val) return instances[i] | ||
} | ||
@@ -402,8 +493,2 @@ } | ||
var context$1 = Object.freeze({ | ||
props: props$1, | ||
define: define$1 | ||
}); | ||
const types = struct.props.types; | ||
@@ -417,6 +502,7 @@ | ||
default: 'self', | ||
id: (t, val) => { t.set({ define: { id: val } }); }, | ||
_uid_: (t, val) => { t.set({ define: { _uid_: val } }); }, | ||
// why nto call this client id -- thats what it is | ||
clients: (t, val, key, stamp) => { | ||
if (!t.clients) { | ||
t.clients = c(clients, val, stamp, t, key); | ||
t.clients = create(val, stamp, clients, t, key); | ||
} else { | ||
@@ -429,13 +515,12 @@ set(t.clients, val, stamp); | ||
client: true | ||
}, | ||
id | ||
} | ||
}); | ||
hub.props.types.struct = c(hub, { | ||
hub.props.types.struct = hub.create({ | ||
props: { default: types.struct.props.default.bind() } | ||
}); | ||
}, false); | ||
hub.props.types.struct.props.default.struct = hub.props.type.struct = hub; | ||
hub.set({ types: { hub: 'self' }, inject: [ server, context$1, client ] }, false); | ||
hub.set({ types: { hub: 'self' }, inject: [ server, client, context$1 ] }, false); | ||
@@ -454,21 +539,13 @@ hub.types._ks = void 0; | ||
} | ||
}) | ||
}, false) | ||
} | ||
}); | ||
}, false); | ||
// import bs from 'brisky-stamp' | ||
console.log('hub.js:', __dirname); | ||
var index = (val, stamp) => { | ||
if (stamp === void 0) { | ||
const r = hub.create(val, bs.create()); | ||
bs.close(); | ||
return r | ||
} else { | ||
return hub.create(val, stamp) | ||
} | ||
}; | ||
const fn = (val, stamp) => hub.create(val, stamp); | ||
// add uids to stamps else it sucks -- dont compromise for tests think of that as an after thought | ||
export default index; | ||
//# sourceMappingURL=browser.es.js.map | ||
export default fn; |
@@ -5,11 +5,7 @@ 'use strict'; | ||
var hash = _interopDefault(require('string-hash')); | ||
var briskyStruct = require('brisky-struct'); | ||
var bs = _interopDefault(require('brisky-stamp')); | ||
var hash = _interopDefault(require('string-hash')); | ||
var ua = _interopDefault(require('vigour-ua')); | ||
const uniq = global.navigator.userAgent + | ||
global.navigator.userLanguage + | ||
global.navigator.language; | ||
var id = hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
const next = typeof window === 'undefined' | ||
@@ -19,19 +15,8 @@ ? process.nextTick | ||
const parse$1 = (stamp, hub, t) => { | ||
const src = bs.src(stamp); | ||
if (!src) { | ||
return bs.create(bs.type(stamp), hub.id, bs.val(stamp)) | ||
} else { | ||
const val = bs.val(stamp); | ||
if (!t[1]) t[1] = {}; | ||
const meta = t[1]; | ||
if (!meta.resolve) meta.resolve = {}; | ||
const resolve = meta.resolve[src]; | ||
if (!resolve || val < resolve) meta.resolve[src] = val; | ||
return stamp | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
if (!struct$$1.isHub || struct$$1.key === 'clients' || (struct$$1._p && struct$$1._p.key === 'clients')) { | ||
return | ||
} | ||
}; | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
const path = struct$$1.path(); | ||
const path = struct$$1.path(); // cached version (later) | ||
const len = path.length; | ||
@@ -52,3 +37,3 @@ | ||
s.stamp = parse$1(struct$$1.stamp, hub, t); | ||
s.stamp = struct$$1.stamp; | ||
@@ -63,5 +48,9 @@ if (val === null) { | ||
} else if (struct$$1.val && struct$$1.val.inherits) { | ||
// make a bit more secure... | ||
// if (!s.val) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
// if allrdy serialized stop it! | ||
serialize(hub, t, struct$$1.val, val, level); | ||
// } | ||
} else if (struct$$1.val !== void 0) { | ||
@@ -74,29 +63,37 @@ s.val = struct$$1.val; | ||
const meta = hub => { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
store[1].context = hub.clientContext; | ||
store[1].id = hub.id; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
if (!hub.receiveOnly) { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
if (hub.context) { | ||
if (hub.context.keys().length > 0) { | ||
store[1].context = hub.context.compute() ? hub.context.serialize() : false; | ||
} else { | ||
store[1].context = hub.context.compute() || false; | ||
} | ||
} | ||
store[1].id = hub.client.key; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
} | ||
}; | ||
const send = (val, stamp, struct$$1) => { | ||
if (bs.type(stamp) !== 'upstream') { | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p.url && !p._c) { hub = p; } | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly && struct$$1.key !== 'clients') { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.id) { | ||
return | ||
} | ||
// -1 means upsteam (floats for extra speed) | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p._url_ && !p._c) hub = p; | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly) { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.client.key) { | ||
return | ||
} | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} | ||
@@ -142,6 +139,7 @@ }; | ||
const parse$2 = (struct$$1, obj, key, root) => { | ||
const parse$1 = (struct$$1, obj, key, root) => { | ||
const result = {}; | ||
if (!root) { root = result; } | ||
if (obj.type) result.type = obj.type; // need to be done before the rest of subs to sync correctly | ||
// need to be done before the rest of subs to sync correctly | ||
if (obj.type) result.type = parse$1(struct$$1, obj.type, 'type'); | ||
for (let i in obj) { | ||
@@ -153,3 +151,3 @@ if (i !== '_' && i !== 'type') { | ||
// console.log('CLIENT NEED TO HANDLE MORE SPECIAL THEN JUST ROOT') | ||
// let id = state.id | ||
// let id = state._uid_ | ||
// if (!root.clients) { root.clients = {} } | ||
@@ -183,3 +181,3 @@ // if (!root.clients[id]) { root.clients[id] = {} } | ||
// empty objects are very uninteresetting maybe just skip them | ||
let parsed = parse$2(struct$$1, obj[i], i, root); | ||
let parsed = parse$1(struct$$1, obj[i], i, root); | ||
@@ -202,10 +200,19 @@ // if (i === 'root' || i === 'parent') { | ||
const uniq = global.navigator.userAgent + | ||
global.navigator.userLanguage + | ||
global.navigator.language; | ||
var uid = () => hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
var createClient = (t, val, stamp, useragent, id) => { | ||
if (!id) id = t._uid_ || uid(); | ||
ua(useragent, val); | ||
t.set({ clients: { [id]: val } }, stamp); | ||
return t.clients[id] | ||
}; | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new WebSocket(url); | ||
const id = hub.id; | ||
// t, val, stamp, useragent, id | ||
const client = hub.client || createClient(hub, {}, false); | ||
hub.set({ clients: { [id]: { } } }, false); | ||
const client = hub.clients[id]; | ||
hub.set({ client }, false); | ||
@@ -216,7 +223,7 @@ | ||
const close = () => { | ||
const stamp = bs.create('disconnect', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = false; | ||
hub.set({ connected: false }, stamp); | ||
bs.close(); | ||
if (!socket.blockReconnect && hub.url) { | ||
if (!socket.blockReconnect && hub._url_) { | ||
reconnect = Math.min((reconnect * 1.5), 2000); | ||
@@ -229,12 +236,12 @@ hub.reconnect = setTimeout(connect, reconnect, hub, url, reconnect); | ||
socket.onerror = () => { | ||
if (typeof window === 'undefined') { | ||
close(); | ||
} else { | ||
socket.close(); | ||
} | ||
}; | ||
if (typeof window === 'undefined') { | ||
socket.hackyOnClose = close; | ||
} | ||
socket.onerror = typeof window === 'undefined' | ||
? close | ||
: () => socket.close(); | ||
socket.onopen = () => { | ||
const stamp = bs.create('connected', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = socket; | ||
@@ -246,7 +253,13 @@ meta(hub); | ||
socket.onmessage = ({ data }) => { | ||
const stamp = bs.create('upstream'); | ||
// console.log(JSON.stringify(JSON.parse(data), false, 2)) | ||
hub.set(JSON.parse(data), stamp); | ||
bs.close(stamp); | ||
socket.onmessage = (data) => { | ||
data = data.data; | ||
// console.warn('INCOMING\n', JSON.parse(data)) | ||
if (!hub.receiveOnly) { | ||
hub.receiveOnly = true; | ||
hub.set(JSON.parse(data), false); | ||
hub.receiveOnly = null; | ||
} else { | ||
hub.set(JSON.parse(data), false); | ||
} | ||
bs.close(); | ||
}; | ||
@@ -256,4 +269,3 @@ }; | ||
const removeUrl = hub => { | ||
hub.url = null; | ||
hub.urlIndex = null; | ||
hub.url = hub._url_ = hub.urlIndex = null; | ||
hub.emitters.set({ data: { url$: null } }, false); | ||
@@ -269,7 +281,14 @@ }; | ||
hub.socket.blockReconnect = true; | ||
hub.socket.close(); | ||
console.log('GO GO GOREMOVE', hub.socket._readyState); | ||
if (hub.connected.compute() === false || !hub.socket._readyState) { | ||
console.log('hacky!'); | ||
hub.socket.hackyOnClose(); | ||
} else { | ||
hub.socket.close(); | ||
} | ||
} | ||
// hub.socket = false | ||
}; | ||
const url = (hub, val, stamp) => { | ||
const url = (hub, val, key, stamp) => { | ||
hub.on((val, stamp, t) => { | ||
@@ -282,15 +301,34 @@ if (val === null && !t._c && t === hub) { | ||
}, 'url$'); | ||
if (!val) val = null; | ||
if (val !== hub.url) { | ||
if ((!hub.url && val) || (hub.url.compute() !== val)) { | ||
removeSocket(hub); | ||
hub.set({ connected: false }, stamp); | ||
if (!val) { | ||
removeUrl(hub); | ||
hub.set({ connected: false }, stamp); | ||
hub._url_ = null; | ||
if (hub.url) hub.url.set(null, stamp); | ||
} else { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; | ||
hub.url = val; | ||
connect(hub, val, 50); | ||
if (!hub.url) { | ||
briskyStruct.create({ | ||
on: { | ||
data: { | ||
url: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
hub.set({ connected: false }, stamp); | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; // use this for checks | ||
hub._url_ = val; | ||
connect(hub, val, 50); | ||
} else { | ||
hub._url_ = null; | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, briskyStruct.struct, hub, key); | ||
} | ||
hub.url.set(val, stamp); | ||
} | ||
@@ -300,27 +338,69 @@ } | ||
// very context as well | ||
// const clients => (val, stamp) { | ||
// const hub = this.cParent() | ||
// if (this.compute() === false && hub.upstream) { | ||
// // put this in clients (the file) | ||
// const clients = hub.clients | ||
// if (clients && clients.keys().length > 1) { | ||
// clients.each((client) => { | ||
// if ( | ||
// client.val !== null && | ||
// !client.socket && | ||
// client.key != hub.id // eslint-disable-line | ||
// ) { | ||
// client.remove(stamp) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
// } | ||
const removeClients = (hub, stamp) => { | ||
const clients = hub.clients; | ||
if (clients && clients.keys().length > 1) { | ||
clients.forEach((client, key) => { | ||
if ( | ||
client.val !== null && | ||
client !== hub.client | ||
) { | ||
client.set(null, stamp); | ||
delete clients[key]; | ||
} | ||
}); | ||
} | ||
}; | ||
const connected = { type: 'struct' }; | ||
const connected = { | ||
type: 'struct', | ||
on: { | ||
data: { | ||
removeClients: (val, stamp, t) => { | ||
if (t.compute() === false) { | ||
// all instances! -- fix this | ||
removeClients(t._p, stamp); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
const context = (hub, val) => { | ||
if (val !== hub.clientContext) { | ||
hub.clientContext = val; | ||
const contextStruct = briskyStruct.struct.create({ | ||
props: { | ||
default: { | ||
on: { | ||
data: { | ||
updateParent: (val, stamp, t) => { | ||
console.log('👻 GO UPDATE PARENT!!! 👻'); | ||
t.parent().emit('data', val, stamp); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
const contextIsNotEqual = (val, context) => { | ||
if (val && typeof val === 'object') { | ||
for (let field in val) { | ||
if (!context[field] || val[field] !== context[field].compute()) { | ||
console.log('😜', field); | ||
return true | ||
} | ||
} | ||
} else { | ||
console.log('😜 ?????'); | ||
return val !== context.compute() | ||
} | ||
}; | ||
const context = (hub, val, key, stamp) => { | ||
if (!hub.context || contextIsNotEqual(val, hub.context)) { | ||
console.log('⚽️ fire fire fire FLAME context ⚽️', val, stamp); | ||
if (!hub.context) { | ||
briskyStruct.create(val, stamp, contextStruct, hub, key); | ||
} else { | ||
removeClients(hub, stamp); | ||
hub.context.set(val, stamp); | ||
} | ||
if (hub.connected && hub.connected.compute() === true) meta(hub); | ||
@@ -346,11 +426,13 @@ } | ||
if (!raw) subs = briskyStruct.parse(subs); | ||
const parsed = parse$2(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
if (!this.receiveOnly) { | ||
const parsed = parse$1(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
} | ||
} | ||
@@ -380,12 +462,24 @@ } | ||
const props$1 = { contextKey: true }; | ||
var context$1 = { | ||
props: { | ||
contextKey: true, | ||
getContext: (t, fn) => { | ||
t.set({ | ||
define: { | ||
getContext (key, socket) { | ||
return fn(key, (key) => createContext(this, key), this, socket) | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
getContext: (key, context) => context() | ||
}; | ||
const define$1 = { | ||
getContext (val) { | ||
var result = find(this, val); | ||
if (!result) { | ||
result = this.create({ contextKey: val }, false); | ||
} | ||
return result | ||
const createContext = (hub, val) => { | ||
var result = find(hub, val); | ||
if (!result) { | ||
result = hub.create({ contextKey: val }, false); | ||
} | ||
return result | ||
}; | ||
@@ -398,6 +492,3 @@ | ||
while (i--) { | ||
if (instances[i].contextKey === val) { | ||
// console.log('found context --->', val, instances[i].clients.keys()) | ||
return instances[i] | ||
} | ||
if (instances[i].contextKey === val) return instances[i] | ||
} | ||
@@ -407,8 +498,2 @@ } | ||
var context$1 = Object.freeze({ | ||
props: props$1, | ||
define: define$1 | ||
}); | ||
const types = briskyStruct.struct.props.types; | ||
@@ -422,6 +507,7 @@ | ||
default: 'self', | ||
id: (t, val) => { t.set({ define: { id: val } }); }, | ||
_uid_: (t, val) => { t.set({ define: { _uid_: val } }); }, | ||
// why nto call this client id -- thats what it is | ||
clients: (t, val, key, stamp) => { | ||
if (!t.clients) { | ||
t.clients = briskyStruct.c(clients, val, stamp, t, key); | ||
t.clients = briskyStruct.create(val, stamp, clients, t, key); | ||
} else { | ||
@@ -434,13 +520,12 @@ briskyStruct.set(t.clients, val, stamp); | ||
client: true | ||
}, | ||
id | ||
} | ||
}); | ||
hub.props.types.struct = briskyStruct.c(hub, { | ||
hub.props.types.struct = hub.create({ | ||
props: { default: types.struct.props.default.bind() } | ||
}); | ||
}, false); | ||
hub.props.types.struct.props.default.struct = hub.props.type.struct = hub; | ||
hub.set({ types: { hub: 'self' }, inject: [ server, context$1, client ] }, false); | ||
hub.set({ types: { hub: 'self' }, inject: [ server, client, context$1 ] }, false); | ||
@@ -459,21 +544,13 @@ hub.types._ks = void 0; | ||
} | ||
}) | ||
}, false) | ||
} | ||
}); | ||
}, false); | ||
// import bs from 'brisky-stamp' | ||
console.log('hub.js:', __dirname); | ||
var index = (val, stamp) => { | ||
if (stamp === void 0) { | ||
const r = hub.create(val, bs.create()); | ||
bs.close(); | ||
return r | ||
} else { | ||
return hub.create(val, stamp) | ||
} | ||
}; | ||
const fn = (val, stamp) => hub.create(val, stamp); | ||
// add uids to stamps else it sucks -- dont compromise for tests think of that as an after thought | ||
module.exports = index; | ||
//# sourceMappingURL=browser.js.map | ||
module.exports = fn; |
@@ -0,9 +1,8 @@ | ||
import { create, get, getKeys, getType, getVal, parse, puid, set, struct, subscribe } from 'brisky-struct'; | ||
import bs from 'brisky-stamp'; | ||
import { w3cwebsocket } from 'websocket'; | ||
import hash from 'string-hash'; | ||
import { c, create, get, getKeys, getType, parse, set, struct, subscribe } from 'brisky-struct'; | ||
import bs from 'brisky-stamp'; | ||
import WebSocket from 'uws'; | ||
import ua from 'vigour-ua'; | ||
import uws from 'uws'; | ||
const uniq = process.pid; | ||
var id = hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
const next = typeof window === 'undefined' | ||
@@ -13,19 +12,8 @@ ? process.nextTick | ||
const parse$1 = (stamp, hub, t) => { | ||
const src = bs.src(stamp); | ||
if (!src) { | ||
return bs.create(bs.type(stamp), hub.id, bs.val(stamp)) | ||
} else { | ||
const val = bs.val(stamp); | ||
if (!t[1]) t[1] = {}; | ||
const meta = t[1]; | ||
if (!meta.resolve) meta.resolve = {}; | ||
const resolve = meta.resolve[src]; | ||
if (!resolve || val < resolve) meta.resolve[src] = val; | ||
return stamp | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
if (!struct$$1.isHub || struct$$1.key === 'clients' || (struct$$1._p && struct$$1._p.key === 'clients')) { | ||
return | ||
} | ||
}; | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
const path = struct$$1.path(); | ||
const path = struct$$1.path(); // cached version (later) | ||
const len = path.length; | ||
@@ -46,3 +34,3 @@ | ||
s.stamp = parse$1(struct$$1.stamp, hub, t); | ||
s.stamp = struct$$1.stamp; | ||
@@ -57,5 +45,9 @@ if (val === null) { | ||
} else if (struct$$1.val && struct$$1.val.inherits) { | ||
// make a bit more secure... | ||
// if (!s.val) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
// if allrdy serialized stop it! | ||
serialize(hub, t, struct$$1.val, val, level); | ||
// } | ||
} else if (struct$$1.val !== void 0) { | ||
@@ -68,29 +60,37 @@ s.val = struct$$1.val; | ||
const meta = hub => { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
store[1].context = hub.clientContext; | ||
store[1].id = hub.id; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
if (!hub.receiveOnly) { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
if (hub.context) { | ||
if (hub.context.keys().length > 0) { | ||
store[1].context = hub.context.compute() ? hub.context.serialize() : false; | ||
} else { | ||
store[1].context = hub.context.compute() || false; | ||
} | ||
} | ||
store[1].id = hub.client.key; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
} | ||
}; | ||
const send = (val, stamp, struct$$1) => { | ||
if (bs.type(stamp) !== 'upstream') { | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p.url && !p._c) { hub = p; } | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly && struct$$1.key !== 'clients') { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.id) { | ||
return | ||
} | ||
// -1 means upsteam (floats for extra speed) | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p._url_ && !p._c) hub = p; | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly) { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.client.key) { | ||
return | ||
} | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} | ||
@@ -118,2 +118,5 @@ }; | ||
// import WebSocket from 'uws' | ||
// export default WebSocket | ||
const isEmpty = t => { | ||
@@ -134,6 +137,7 @@ for (let i in t) { return false } | ||
const parse$2 = (struct$$1, obj, key, root) => { | ||
const parse$1 = (struct$$1, obj, key, root) => { | ||
const result = {}; | ||
if (!root) { root = result; } | ||
if (obj.type) result.type = obj.type; // need to be done before the rest of subs to sync correctly | ||
// need to be done before the rest of subs to sync correctly | ||
if (obj.type) result.type = parse$1(struct$$1, obj.type, 'type'); | ||
for (let i in obj) { | ||
@@ -145,3 +149,3 @@ if (i !== '_' && i !== 'type') { | ||
// console.log('CLIENT NEED TO HANDLE MORE SPECIAL THEN JUST ROOT') | ||
// let id = state.id | ||
// let id = state._uid_ | ||
// if (!root.clients) { root.clients = {} } | ||
@@ -175,3 +179,3 @@ // if (!root.clients[id]) { root.clients[id] = {} } | ||
// empty objects are very uninteresetting maybe just skip them | ||
let parsed = parse$2(struct$$1, obj[i], i, root); | ||
let parsed = parse$1(struct$$1, obj[i], i, root); | ||
@@ -194,9 +198,16 @@ // if (i === 'root' || i === 'parent') { | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new WebSocket(url); | ||
const id = hub.id; | ||
const uniq = process.pid; | ||
var uid = () => hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
hub.set({ clients: { [id]: { } } }, false); | ||
var createClient = (t, val, stamp, useragent, id) => { | ||
if (!id) id = t._uid_ || uid(); | ||
ua(useragent, val); | ||
t.set({ clients: { [id]: val } }, stamp); | ||
return t.clients[id] | ||
}; | ||
const client = hub.clients[id]; | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new w3cwebsocket(url); | ||
// t, val, stamp, useragent, id | ||
const client = hub.client || createClient(hub, {}, false); | ||
@@ -208,7 +219,7 @@ hub.set({ client }, false); | ||
const close = () => { | ||
const stamp = bs.create('disconnect', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = false; | ||
hub.set({ connected: false }, stamp); | ||
bs.close(); | ||
if (!socket.blockReconnect && hub.url) { | ||
if (!socket.blockReconnect && hub._url_) { | ||
reconnect = Math.min((reconnect * 1.5), 2000); | ||
@@ -221,12 +232,12 @@ hub.reconnect = setTimeout(connect, reconnect, hub, url, reconnect); | ||
socket.onerror = () => { | ||
if (typeof window === 'undefined') { | ||
close(); | ||
} else { | ||
socket.close(); | ||
} | ||
}; | ||
if (typeof window === 'undefined') { | ||
socket.hackyOnClose = close; | ||
} | ||
socket.onerror = typeof window === 'undefined' | ||
? close | ||
: () => socket.close(); | ||
socket.onopen = () => { | ||
const stamp = bs.create('connected', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = socket; | ||
@@ -238,7 +249,13 @@ meta(hub); | ||
socket.onmessage = ({ data }) => { | ||
const stamp = bs.create('upstream'); | ||
// console.log(JSON.stringify(JSON.parse(data), false, 2)) | ||
hub.set(JSON.parse(data), stamp); | ||
bs.close(stamp); | ||
socket.onmessage = (data) => { | ||
data = data.data; | ||
// console.warn('INCOMING\n', JSON.parse(data)) | ||
if (!hub.receiveOnly) { | ||
hub.receiveOnly = true; | ||
hub.set(JSON.parse(data), false); | ||
hub.receiveOnly = null; | ||
} else { | ||
hub.set(JSON.parse(data), false); | ||
} | ||
bs.close(); | ||
}; | ||
@@ -248,4 +265,3 @@ }; | ||
const removeUrl = hub => { | ||
hub.url = null; | ||
hub.urlIndex = null; | ||
hub.url = hub._url_ = hub.urlIndex = null; | ||
hub.emitters.set({ data: { url$: null } }, false); | ||
@@ -261,7 +277,14 @@ }; | ||
hub.socket.blockReconnect = true; | ||
hub.socket.close(); | ||
console.log('GO GO GOREMOVE', hub.socket._readyState); | ||
if (hub.connected.compute() === false || !hub.socket._readyState) { | ||
console.log('hacky!'); | ||
hub.socket.hackyOnClose(); | ||
} else { | ||
hub.socket.close(); | ||
} | ||
} | ||
// hub.socket = false | ||
}; | ||
const url = (hub, val, stamp) => { | ||
const url = (hub, val, key, stamp) => { | ||
hub.on((val, stamp, t) => { | ||
@@ -274,15 +297,34 @@ if (val === null && !t._c && t === hub) { | ||
}, 'url$'); | ||
if (!val) val = null; | ||
if (val !== hub.url) { | ||
if ((!hub.url && val) || (hub.url.compute() !== val)) { | ||
removeSocket(hub); | ||
hub.set({ connected: false }, stamp); | ||
if (!val) { | ||
removeUrl(hub); | ||
hub.set({ connected: false }, stamp); | ||
hub._url_ = null; | ||
if (hub.url) hub.url.set(null, stamp); | ||
} else { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; | ||
hub.url = val; | ||
connect(hub, val, 50); | ||
if (!hub.url) { | ||
create({ | ||
on: { | ||
data: { | ||
url: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
hub.set({ connected: false }, stamp); | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; // use this for checks | ||
hub._url_ = val; | ||
connect(hub, val, 50); | ||
} else { | ||
hub._url_ = null; | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, struct, hub, key); | ||
} | ||
hub.url.set(val, stamp); | ||
} | ||
@@ -292,27 +334,69 @@ } | ||
// very context as well | ||
// const clients => (val, stamp) { | ||
// const hub = this.cParent() | ||
// if (this.compute() === false && hub.upstream) { | ||
// // put this in clients (the file) | ||
// const clients = hub.clients | ||
// if (clients && clients.keys().length > 1) { | ||
// clients.each((client) => { | ||
// if ( | ||
// client.val !== null && | ||
// !client.socket && | ||
// client.key != hub.id // eslint-disable-line | ||
// ) { | ||
// client.remove(stamp) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
// } | ||
const removeClients = (hub, stamp) => { | ||
const clients = hub.clients; | ||
if (clients && clients.keys().length > 1) { | ||
clients.forEach((client, key) => { | ||
if ( | ||
client.val !== null && | ||
client !== hub.client | ||
) { | ||
client.set(null, stamp); | ||
delete clients[key]; | ||
} | ||
}); | ||
} | ||
}; | ||
const connected = { type: 'struct' }; | ||
const connected = { | ||
type: 'struct', | ||
on: { | ||
data: { | ||
removeClients: (val, stamp, t) => { | ||
if (t.compute() === false) { | ||
// all instances! -- fix this | ||
removeClients(t._p, stamp); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
const context = (hub, val) => { | ||
if (val !== hub.clientContext) { | ||
hub.clientContext = val; | ||
const contextStruct = struct.create({ | ||
props: { | ||
default: { | ||
on: { | ||
data: { | ||
updateParent: (val, stamp, t) => { | ||
console.log('👻 GO UPDATE PARENT!!! 👻'); | ||
t.parent().emit('data', val, stamp); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
const contextIsNotEqual = (val, context) => { | ||
if (val && typeof val === 'object') { | ||
for (let field in val) { | ||
if (!context[field] || val[field] !== context[field].compute()) { | ||
console.log('😜', field); | ||
return true | ||
} | ||
} | ||
} else { | ||
console.log('😜 ?????'); | ||
return val !== context.compute() | ||
} | ||
}; | ||
const context = (hub, val, key, stamp) => { | ||
if (!hub.context || contextIsNotEqual(val, hub.context)) { | ||
console.log('⚽️ fire fire fire FLAME context ⚽️', val, stamp); | ||
if (!hub.context) { | ||
create(val, stamp, contextStruct, hub, key); | ||
} else { | ||
removeClients(hub, stamp); | ||
hub.context.set(val, stamp); | ||
} | ||
if (hub.connected && hub.connected.compute() === true) meta(hub); | ||
@@ -338,11 +422,13 @@ } | ||
if (!raw) subs = parse(subs); | ||
const parsed = parse$2(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
if (!this.receiveOnly) { | ||
const parsed = parse$1(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
} | ||
} | ||
@@ -399,3 +485,3 @@ } | ||
const parse$3 = (obj, state, key) => { | ||
const parse$2 = (obj, state, key) => { | ||
const result = {}; | ||
@@ -421,7 +507,7 @@ for (let i in obj) { | ||
let msg; | ||
if (!pass) { | ||
msg = `cannot parse function ${key}.exec\n${val}`; | ||
} else { | ||
msg = `cannot run function ${key}.exec\n${val}`; | ||
} | ||
// if (!pass) { | ||
msg = `cannot parse function ${key}.exec\n${val}`; | ||
// } else { | ||
// msg = `cannot run function ${key}.exec\n${val}` | ||
// } | ||
state.emit('error', new Error(msg)); | ||
@@ -434,3 +520,3 @@ obj[i] = dummy; | ||
} else { | ||
result[i] = parse$3(obj[i], state, i); | ||
result[i] = parse$2(obj[i], state, i); | ||
} | ||
@@ -441,2 +527,17 @@ } | ||
const cache = (client, struct$$1, stamp) => { | ||
if (!client.cache) client.cache = {}; | ||
client.cache[puid(struct$$1)] = stamp; | ||
}; | ||
const isCached = (client, struct$$1, stamp) => client.cache && | ||
client.cache[puid(struct$$1)] === stamp; | ||
const isEmpty$1 = obj => { | ||
for (let i in obj) { //eslint-disable-line | ||
return false | ||
} | ||
return true | ||
}; | ||
const progress = (client) => { | ||
@@ -447,11 +548,7 @@ if (!client.inProgress) { | ||
if (client.val !== null) { | ||
var isEmpty = true; | ||
for (let i in client.inProgress) { //eslint-disable-line | ||
isEmpty = false; | ||
break | ||
} | ||
if (!isEmpty) { | ||
// bit hacky... | ||
if (!isEmpty$1(client.inProgress)) { | ||
if (client.inProgress.types) { | ||
for (let i in client.inProgress) { | ||
// order is still important since settign types after the facts is still broken | ||
// this will be a big update | ||
if (i === 'types') { | ||
@@ -475,134 +572,96 @@ break | ||
const send$1 = (hub, client, t, type, subs, tree) => { | ||
var val; | ||
if (type === 'remove') { | ||
if (!t._p[t.key]) { | ||
val = null; | ||
if (bs.src(t._p.tStamp) === client.key) { | ||
return | ||
const send$1 = (hub, client, struct$$1, type, subs, tree) => { | ||
if (struct$$1.isHub && client.val !== null) { | ||
let isRemoved; | ||
if (type === 'remove') { | ||
if (!struct$$1._p[struct$$1.key]) isRemoved = true; | ||
} else if (type === 'update' && tree.$t !== struct$$1) { | ||
if (tree.$t && tree.$t._p && !tree.$t._p[tree.$t.key]) { | ||
let previous = tree.$t; | ||
let prop = previous; | ||
while (previous) { | ||
if (previous._p && previous._p[previous.key]) { | ||
// think of something fast for level... | ||
serialize$2(client, progress(client), subs, prop, get(hub, 'serverIndex'), true); | ||
} | ||
prop = previous; | ||
previous = previous._p; | ||
} | ||
} | ||
} | ||
} else if (type === 'update' && tree.$t !== t) { | ||
if (tree.$t && tree.$t._p && !tree.$t._p[tree.$t.key]) { | ||
serialize$2(hub.id, client, progress(client), subs, tree.$t, null, get(hub, 'serverIndex'), tree); | ||
} | ||
serialize$2(client, progress(client), subs, struct$$1, get(hub, 'serverIndex'), isRemoved); | ||
} | ||
if (t.val !== void 0 || val === null || subs.val === true) { | ||
// opt this line (the get) just use a define or something | ||
serialize$2(hub.id, client, progress(client), subs, t, val, get(hub, 'serverIndex'), tree); | ||
} | ||
}; | ||
const cache = (client, struct$$1, stamp, level, val) => { | ||
if (!client.cache) client.cache = {}; | ||
client.cache[struct$$1.uid()] = stamp[0]; | ||
}; | ||
const serialize$2 = (client, t, subs, struct$$1, level, isRemoved) => { | ||
const stamp = get(struct$$1, 'stamp') || 1; // remove the need for this default (feels wrong) | ||
const val = isRemoved ? null : getVal(struct$$1); | ||
const isCached = (client, struct$$1, stamp) => { | ||
return client.cache && client.cache[struct$$1.uid()] === stamp[0] | ||
}; | ||
const setStamp = (s, stamp, src, struct$$1, id, client, level) => { | ||
cache(client, struct$$1, stamp, level); | ||
s.stamp = !src | ||
? bs.create(bs.type(stamp), id, bs.val(stamp)) | ||
: stamp; | ||
}; | ||
// clean the cached up a bit | ||
const serialize$2 = (id, client, t, subs, struct$$1, val, level) => { | ||
const stamp = get(struct$$1, 'stamp'); | ||
var cached, isType; | ||
if (stamp && (val === null || !(cached = isCached(client, struct$$1, stamp))) || subs.val === true) { | ||
const src = bs.src(stamp); | ||
if ( | ||
src !== client.key && bs.src(t.tStamp) !== client.key || | ||
(isType = struct$$1.key === 'type') | ||
) { | ||
if ( | ||
client.resolve && | ||
client.resolve[src] && | ||
bs.val(stamp) >= client.resolve[src] | ||
) { | ||
if (val !== null) { | ||
if (struct$$1.val !== void 0) cache(client, struct$$1, stamp, level); | ||
if (subs.val === true) { | ||
const keys = getKeys(struct$$1); | ||
if (keys) deepSerialize(keys, id, client, t, subs, struct$$1, val, level); | ||
} | ||
} | ||
if (val !== void 0 && stamp && !isCached(client, struct$$1, stamp)) { | ||
// val === null -- double chck if this is nessecary | ||
const path = struct$$1.path(); | ||
const len = path.length; | ||
let s = t; | ||
for (let i = level; i < len; i++) { | ||
let tt = s[path[i]]; | ||
if (!tt) { | ||
s = s[path[i]] = {}; | ||
} else { | ||
if (subs.type) { | ||
// simple but will make it better need more checks | ||
var p = struct$$1; | ||
while (p) { | ||
if (p.key === 'types') { | ||
return | ||
} | ||
p = p._p; | ||
} | ||
} | ||
s = tt; | ||
if (s.val === null) return | ||
} | ||
} | ||
if (isType) { // means its blocked otherwise (could be a set form own client) | ||
typeSerialize(id, client, t, subs, struct$$1, val, level); | ||
} else if (!cached && (struct$$1.val !== void 0 || val === null)) { | ||
const path = struct$$1.path(); | ||
const len = path.length; | ||
var s = t; | ||
for (let i = level; i < len; i++) { | ||
let tt = s[path[i]]; | ||
if (!tt) { | ||
s = s[path[i]] = {}; | ||
} else { | ||
s = tt; | ||
if (s.val === null) return | ||
} | ||
} | ||
if (val === null) { | ||
setStamp(s, stamp, src, struct$$1, id, client, level, val); | ||
s.val = null; | ||
} else { | ||
if (struct$$1.key === 'type') { | ||
typeSerialize(id, client, t, subs, struct$$1, val, level); | ||
} | ||
setStamp(s, stamp, src, struct$$1, id, client, level); | ||
if (struct$$1.val && struct$$1.val.inherits) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
serialize$2(id, client, t, subs, struct$$1.val, val, level); | ||
} else if (struct$$1.val !== void 0) { | ||
s.val = struct$$1.val; | ||
} | ||
} | ||
if (isRemoved) { | ||
cache(client, struct$$1, stamp); | ||
s.stamp = stamp; | ||
s.val = val; | ||
} else { | ||
if (subs.type) { | ||
const type = get(struct$$1, 'type'); // make getType (fast) | ||
if (getVal(type) !== 'hub') { | ||
serialize$2(client, t, subs.type, type, level); | ||
} | ||
} | ||
if (subs.val === true) { | ||
const keys = getKeys(struct$$1); | ||
if (keys) deepSerialize(keys, id, client, t, subs, struct$$1, val, level); | ||
} | ||
cache(client, struct$$1, stamp); | ||
s.stamp = stamp; | ||
if (struct$$1.key === 'type') { | ||
if (val === 'hub') return | ||
serialize$2(client, t, subs, getType(struct$$1.parent(2), val), level); | ||
// allways need a stamp! | ||
} | ||
if (typeof val === 'object' && val.inherits) { | ||
s.val = val.path(); | ||
s.val.unshift('@', 'root'); | ||
serialize$2(client, t, subs, val, level); | ||
} else if (val !== void 0) { | ||
s.val = val; | ||
} | ||
} | ||
} else if (val && typeof val === 'object' && val.inherits) { | ||
// can send a bit too much data when val: true and overlapping keys | ||
serialize$2(client, t, subs, val, level); | ||
} | ||
}; | ||
const typeSerialize = (id, client, t, subs, struct$$1, val, level) => { | ||
serialize$2(id, client, t, subs, getType(struct$$1.parent(2), struct$$1.compute()), val, level); | ||
if (subs.val === true && !isRemoved) { | ||
deepSerialize(getKeys(struct$$1), client, t, subs, struct$$1, level); | ||
} | ||
}; | ||
const deepSerialize = (keys, id, client, t, subs, struct$$1, val, level) => { | ||
const deepSerialize = (keys, client, t, subs, struct$$1, level) => { | ||
if (struct$$1.get('type') && struct$$1.get('type').compute() !== 'hub') { | ||
serialize$2(client, t, subs, struct$$1.get('type'), level); | ||
} | ||
if (keys) { | ||
for (let i = 0, len = keys.length; i < len; i++) { | ||
let prop = get(struct$$1, keys[i]); | ||
if (prop && prop.isHub) serialize$2(id, client, t, subs, prop, val, level); | ||
if (prop && prop.isHub) serialize$2(client, t, subs, prop, level); | ||
} | ||
} | ||
// feels really shacky /w context :/ needs tests | ||
if (struct$$1._removed) { | ||
for (let i = 0, len = struct$$1._removed.length; i < len; i++) { | ||
let prop = struct$$1._removed[i]; | ||
if (prop && prop.isHub) serialize$2(id, client, t, subs, prop, null, level); | ||
serialize$2(client, t, subs, prop, level, true); | ||
} | ||
@@ -612,2 +671,28 @@ } | ||
const removeSubscriptions = (t, id) => { | ||
if (t.subscriptions) { | ||
let i = t.subscriptions.length; | ||
while (i--) { // clean this up with unsubscribe in struct | ||
if (t.subscriptions[i]._uid_ == id) { //eslint-disable-line | ||
t.subscriptions.splice(i, 1); | ||
} | ||
} | ||
} | ||
}; | ||
const removeClient = (client) => { | ||
const id = client.key; | ||
client.val = null; | ||
if (client.socket) { | ||
client.socket.client = null; | ||
client.socket = null; | ||
} | ||
const t = client.parent(2); | ||
removeSubscriptions(t, id); | ||
client.set(null); | ||
// if (client.context && t.clients.keys().length === (t.url ? 1 : 0)) { | ||
// t.set(null, stamp) | ||
// } | ||
}; | ||
var incoming = (hub, socket, data) => { | ||
@@ -617,45 +702,74 @@ const payload = data[0]; | ||
var client = socket.client; | ||
var t; | ||
if (meta) { | ||
let t; | ||
if (client) { | ||
t = hub; | ||
if (client.context != meta.context) { // eslint-disable-line | ||
client.set(null); | ||
t = create$2(hub, socket, meta); | ||
client = socket.client; | ||
if ('context' in meta && client.context != meta.context) { // eslint-disable-line | ||
removeClient(client); | ||
create$1(hub, socket, meta, payload); | ||
} else if (meta.subscriptions) { | ||
incomingSubscriptions(t, client, meta, client.id); | ||
if (payload) setPayload(t, payload, client); | ||
incomingSubscriptions(t, client, meta, client.key); | ||
bs.close(); | ||
} | ||
} else { | ||
t = create$2(hub, socket, meta); | ||
client = socket.client; | ||
create$1(hub, socket, meta, payload); | ||
} | ||
} else { | ||
t = client.parent(2); | ||
setPayload(client.parent(2), payload, client); | ||
bs.close(); | ||
} | ||
}; | ||
if (payload) { | ||
if (meta && meta.resolve) { | ||
client.resolve = meta.resolve; | ||
t.set(payload, false); | ||
bs.on(() => { client.resolve = false; }); | ||
} else { | ||
t.set(payload, false); | ||
const addToCache = (client, hub, payload) => { | ||
if (typeof payload === 'object' && payload) { | ||
for (let key in payload) { | ||
if (key !== 'val' && key !== 'stamp') { | ||
let struct$$1 = hub[key]; | ||
if (struct$$1 && struct$$1.isHub) { | ||
addToCache(client, hub[key], payload[key]); | ||
} | ||
} | ||
} | ||
bs.close(); | ||
if (payload.val !== void 0 && payload.stamp) { | ||
cache(client, hub, payload.stamp); | ||
} | ||
} | ||
}; | ||
const create$2 = (hub, socket, meta) => { | ||
const stamp = bs.create('connect'); | ||
const setPayload = (hub, payload, client) => { | ||
hub.set(payload, false); | ||
addToCache(client, hub, payload); | ||
}; | ||
const set$1 = (meta, socket, t, payload) => { | ||
const stamp = bs.create(); | ||
const id = meta.id; | ||
const t = meta.context ? hub.getContext(meta.context) : hub; | ||
t.set({ clients: { [id]: { socket, context: meta.context } } }, stamp); | ||
const client = socket.client = t.clients[id]; | ||
const context = meta.context; | ||
// const ip = socket._socket.remoteAddress | ||
const client = socket.client = createClient( | ||
t, { socket, context }, stamp, socket.useragent, id | ||
); | ||
if (payload) setPayload(t, payload, client); | ||
if (meta.subscriptions) incomingSubscriptions(t, client, meta, id); | ||
bs.close(stamp); | ||
return t | ||
bs.close(); | ||
}; | ||
const create$1 = (hub, socket, meta, payload) => { | ||
const t = meta.context ? hub.getContext(meta.context, socket) : hub; | ||
if (!t.inherits && t.then) { | ||
t.then((t) => { | ||
if (socket.external !== null) { | ||
console.log('client connected and found informations'); | ||
set$1(meta, socket, t, payload); | ||
} else { | ||
console.log('client discconected when logging in'); | ||
} | ||
}).catch(err => hub.emit('error', err)); | ||
} else { | ||
set$1(meta, socket, t, payload); | ||
} | ||
}; | ||
const incomingSubscriptions = (hub, client, meta, id) => { | ||
@@ -667,6 +781,6 @@ const update = (t, type, subs, tree) => send$1(hub, client, t, type, subs, tree); | ||
if (!client.upstreamSubscriptions[uid]) { | ||
let subs = parse$3(meta.subscriptions[key], hub); | ||
let subs = parse$2(meta.subscriptions[key], hub); | ||
client.upstreamSubscriptions[uid] = subs; | ||
subscribe(hub, subs, update); | ||
hub.subscriptions[hub.subscriptions.length - 1].id = id; | ||
hub.subscriptions[hub.subscriptions.length - 1]._uid_ = id; | ||
} | ||
@@ -676,9 +790,35 @@ } | ||
const Server = WebSocket.Server; | ||
const removeSubscriptions = (t, id) => { | ||
if (t.subscriptions) { | ||
let i = t.subscriptions.length; | ||
while (i--) { // clean this up with unsubscribe in struct | ||
if (t.subscriptions[i].id === id) t.subscriptions.splice(i, 1); | ||
var removedInProgress; | ||
const on$1 = { | ||
data: { | ||
remove$: (val, stamp, struct$$1) => { | ||
// just do a diff with the payload rly the best way for now... | ||
if (val === null && (!struct$$1._c || struct$$1._cLevel === 1)) { | ||
let p = struct$$1; | ||
let hub; | ||
while (p) { | ||
if (p.port && !p._c) { hub = p; } | ||
p = p.parent(); | ||
} | ||
if (hub) { | ||
// probably not working correctly with context | ||
const target = struct$$1.parent(); | ||
if (target) { | ||
if (!target._removed) { | ||
target._removed = []; | ||
if (!removedInProgress) { | ||
removedInProgress = []; | ||
bs.on(() => { | ||
let i = removedInProgress.length; | ||
while (i--) { | ||
delete removedInProgress[i]._removed; | ||
} | ||
}); | ||
} | ||
removedInProgress.push(target); | ||
} | ||
target._removed.push(struct$$1); | ||
} | ||
} | ||
} | ||
} | ||
@@ -688,5 +828,11 @@ } | ||
const create$1 = (hub, port) => { | ||
const Server = uws.Server; | ||
const createServer = (hub, port) => { | ||
const server = new Server({ port }); | ||
server.on('connection', (socket) => { | ||
console.log(`💫 hub listening on ${port} 💫`); | ||
server.on('connection', socket => { | ||
socket.useragent = socket.upgradeReq && socket.upgradeReq.headers['user-agent']; | ||
// need to remove when done -- its the best thing todo (mem!!!) | ||
socket.on('message', (data) => { | ||
@@ -698,14 +844,3 @@ data = JSON.parse(data); | ||
const close = () => { | ||
const client = socket.client; | ||
if (client) { | ||
const stamp = bs.create('disconnect'); | ||
const id = client.key; | ||
const t = client.parent(2); | ||
removeSubscriptions(t, id); | ||
client.set(null, stamp); | ||
if (client.context && t.clients.keys().length === (t.url ? 1 : 0)) { | ||
t.set(null, stamp); | ||
} | ||
bs.close(); | ||
} | ||
if (socket.client) removeClient(socket.client); | ||
}; | ||
@@ -720,3 +855,3 @@ | ||
const removeServer = hub => { | ||
const server = hub.server; | ||
const server = hub._server_; | ||
const instances = hub.instances; | ||
@@ -727,5 +862,6 @@ closeConnections(hub); | ||
} | ||
server.httpServer.close(); | ||
// remove all clients subscriptions | ||
hub.server = null; | ||
hub._server_ = null; | ||
}; | ||
@@ -735,3 +871,3 @@ | ||
const clients = hub.clients; | ||
const id = hub.id; // to exclude the client (not nessecary) | ||
const id = hub._uid_; // to exclude the client (not nessecary) | ||
if (clients) { | ||
@@ -754,3 +890,4 @@ clients.forEach(client => { | ||
const port = (hub, val) => { | ||
const port = (hub, val, key, stamp) => { | ||
// use remove | ||
hub.on((val, stamp, t) => { | ||
@@ -763,15 +900,29 @@ if (val === null && !t._c && t === hub) { | ||
if (!val) val = null; | ||
if (val !== hub.port) { | ||
if (hub.server) { | ||
if ((!hub.port && val) || (hub.port.compute() !== val)) { | ||
if (hub._server_) { | ||
removeServer(hub); | ||
} | ||
if (!val) { | ||
if (hub.port) hub.port.set(null, stamp); | ||
removePort(hub); | ||
} else { | ||
hub.port = val; | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.serverIndex = i; | ||
hub.server = create$1(hub, val); | ||
if (!hub.port) { | ||
create({ | ||
on: { | ||
data: { | ||
port: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.serverIndex = i; | ||
hub._server_ = createServer(hub, val); | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, struct, hub, key); | ||
} | ||
hub.port.set(val, stamp); | ||
} | ||
@@ -782,3 +933,3 @@ } | ||
const props$1 = { | ||
server: true, | ||
_server_: true, | ||
serverIndex: true, | ||
@@ -788,40 +939,5 @@ port | ||
var removedInProgress; | ||
const on$1 = { | ||
data: { | ||
remove$: (val, stamp, struct$$1) => { | ||
if (val === null && (!struct$$1._c || struct$$1._cLevel === 1)) { | ||
let p = struct$$1; | ||
let hub; | ||
while (p) { | ||
if (p.port && !p._c) { hub = p; } | ||
p = p.parent(); | ||
} | ||
if (hub) { | ||
const target = struct$$1.parent(); | ||
if (target) { | ||
if (!target._removed) { | ||
target._removed = []; | ||
if (!removedInProgress) { | ||
removedInProgress = []; | ||
bs.on(() => { | ||
let i = removedInProgress.length; | ||
while (i--) { | ||
delete removedInProgress[i]._removed; | ||
} | ||
}); | ||
} | ||
removedInProgress.push(target); | ||
} | ||
struct$$1._p._removed.push(struct$$1); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var server = Object.freeze({ | ||
@@ -832,12 +948,24 @@ props: props$1, | ||
const props$2 = { contextKey: true }; | ||
var context$1 = { | ||
props: { | ||
contextKey: true, | ||
getContext: (t, fn) => { | ||
t.set({ | ||
define: { | ||
getContext (key, socket) { | ||
return fn(key, (key) => createContext(this, key), this, socket) | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
getContext: (key, context) => context() | ||
}; | ||
const define$1 = { | ||
getContext (val) { | ||
var result = find(this, val); | ||
if (!result) { | ||
result = this.create({ contextKey: val }, false); | ||
} | ||
return result | ||
const createContext = (hub, val) => { | ||
var result = find(hub, val); | ||
if (!result) { | ||
result = hub.create({ contextKey: val }, false); | ||
} | ||
return result | ||
}; | ||
@@ -850,6 +978,3 @@ | ||
while (i--) { | ||
if (instances[i].contextKey === val) { | ||
// console.log('found context --->', val, instances[i].clients.keys()) | ||
return instances[i] | ||
} | ||
if (instances[i].contextKey === val) return instances[i] | ||
} | ||
@@ -859,8 +984,2 @@ } | ||
var context$1 = Object.freeze({ | ||
props: props$2, | ||
define: define$1 | ||
}); | ||
const types = struct.props.types; | ||
@@ -874,6 +993,7 @@ | ||
default: 'self', | ||
id: (t, val) => { t.set({ define: { id: val } }); }, | ||
_uid_: (t, val) => { t.set({ define: { _uid_: val } }); }, | ||
// why nto call this client id -- thats what it is | ||
clients: (t, val, key, stamp) => { | ||
if (!t.clients) { | ||
t.clients = c(clients, val, stamp, t, key); | ||
t.clients = create(val, stamp, clients, t, key); | ||
} else { | ||
@@ -886,13 +1006,12 @@ set(t.clients, val, stamp); | ||
client: true | ||
}, | ||
id | ||
} | ||
}); | ||
hub.props.types.struct = c(hub, { | ||
hub.props.types.struct = hub.create({ | ||
props: { default: types.struct.props.default.bind() } | ||
}); | ||
}, false); | ||
hub.props.types.struct.props.default.struct = hub.props.type.struct = hub; | ||
hub.set({ types: { hub: 'self' }, inject: [ server, context$1, client ] }, false); | ||
hub.set({ types: { hub: 'self' }, inject: [ server, client, context$1 ] }, false); | ||
@@ -911,21 +1030,13 @@ hub.types._ks = void 0; | ||
} | ||
}) | ||
}, false) | ||
} | ||
}); | ||
}, false); | ||
// import bs from 'brisky-stamp' | ||
console.log('hub.js:', __dirname); | ||
var index = (val, stamp) => { | ||
if (stamp === void 0) { | ||
const r = hub.create(val, bs.create()); | ||
bs.close(); | ||
return r | ||
} else { | ||
return hub.create(val, stamp) | ||
} | ||
}; | ||
const fn = (val, stamp) => hub.create(val, stamp); | ||
// add uids to stamps else it sucks -- dont compromise for tests think of that as an after thought | ||
export default index; | ||
//# sourceMappingURL=index.es.js.map | ||
export default fn; |
@@ -5,10 +5,9 @@ 'use strict'; | ||
var hash = _interopDefault(require('string-hash')); | ||
var briskyStruct = require('brisky-struct'); | ||
var bs = _interopDefault(require('brisky-stamp')); | ||
var WebSocket = _interopDefault(require('uws')); | ||
var websocket = require('websocket'); | ||
var hash = _interopDefault(require('string-hash')); | ||
var ua = _interopDefault(require('vigour-ua')); | ||
var uws = _interopDefault(require('uws')); | ||
const uniq = process.pid; | ||
var id = hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
const next = typeof window === 'undefined' | ||
@@ -18,19 +17,8 @@ ? process.nextTick | ||
const parse$1 = (stamp, hub, t) => { | ||
const src = bs.src(stamp); | ||
if (!src) { | ||
return bs.create(bs.type(stamp), hub.id, bs.val(stamp)) | ||
} else { | ||
const val = bs.val(stamp); | ||
if (!t[1]) t[1] = {}; | ||
const meta = t[1]; | ||
if (!meta.resolve) meta.resolve = {}; | ||
const resolve = meta.resolve[src]; | ||
if (!resolve || val < resolve) meta.resolve[src] = val; | ||
return stamp | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
if (!struct$$1.isHub || struct$$1.key === 'clients' || (struct$$1._p && struct$$1._p.key === 'clients')) { | ||
return | ||
} | ||
}; | ||
const serialize = (hub, t, struct$$1, val, level) => { | ||
const path = struct$$1.path(); | ||
const path = struct$$1.path(); // cached version (later) | ||
const len = path.length; | ||
@@ -51,3 +39,3 @@ | ||
s.stamp = parse$1(struct$$1.stamp, hub, t); | ||
s.stamp = struct$$1.stamp; | ||
@@ -62,5 +50,9 @@ if (val === null) { | ||
} else if (struct$$1.val && struct$$1.val.inherits) { | ||
// make a bit more secure... | ||
// if (!s.val) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
// if allrdy serialized stop it! | ||
serialize(hub, t, struct$$1.val, val, level); | ||
// } | ||
} else if (struct$$1.val !== void 0) { | ||
@@ -73,29 +65,37 @@ s.val = struct$$1.val; | ||
const meta = hub => { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
store[1].context = hub.clientContext; | ||
store[1].id = hub.id; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
if (!hub.receiveOnly) { | ||
const store = inProgress(hub, bs.inProgress ? bs.on : next); | ||
if (!store[1]) store[1] = {}; | ||
if (hub.context) { | ||
if (hub.context.keys().length > 0) { | ||
store[1].context = hub.context.compute() ? hub.context.serialize() : false; | ||
} else { | ||
store[1].context = hub.context.compute() || false; | ||
} | ||
} | ||
store[1].id = hub.client.key; | ||
store[1].subscriptions = hub.upstreamSubscriptions; | ||
} | ||
}; | ||
const send = (val, stamp, struct$$1) => { | ||
if (bs.type(stamp) !== 'upstream') { | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p.url && !p._c) { hub = p; } | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly && struct$$1.key !== 'clients') { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.id) { | ||
return | ||
} | ||
// -1 means upsteam (floats for extra speed) | ||
let hub; | ||
let p = struct$$1; | ||
while (p) { | ||
if (p._url_ && !p._c) hub = p; | ||
p = p.parent(); // needs to walk over context (for multi server) | ||
} | ||
if (hub && !hub.receiveOnly) { | ||
if (struct$$1 === hub) { | ||
if (val === null) { | ||
return | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} else if (struct$$1._p.key === 'clients') { | ||
if (struct$$1.key !== hub.client.key) { | ||
return | ||
} | ||
} | ||
serialize(hub, inProgress(hub, bs.on), struct$$1, val, hub.urlIndex); | ||
} | ||
@@ -123,2 +123,5 @@ }; | ||
// import WebSocket from 'uws' | ||
// export default WebSocket | ||
const isEmpty = t => { | ||
@@ -139,6 +142,7 @@ for (let i in t) { return false } | ||
const parse$2 = (struct$$1, obj, key, root) => { | ||
const parse$1 = (struct$$1, obj, key, root) => { | ||
const result = {}; | ||
if (!root) { root = result; } | ||
if (obj.type) result.type = obj.type; // need to be done before the rest of subs to sync correctly | ||
// need to be done before the rest of subs to sync correctly | ||
if (obj.type) result.type = parse$1(struct$$1, obj.type, 'type'); | ||
for (let i in obj) { | ||
@@ -150,3 +154,3 @@ if (i !== '_' && i !== 'type') { | ||
// console.log('CLIENT NEED TO HANDLE MORE SPECIAL THEN JUST ROOT') | ||
// let id = state.id | ||
// let id = state._uid_ | ||
// if (!root.clients) { root.clients = {} } | ||
@@ -180,3 +184,3 @@ // if (!root.clients[id]) { root.clients[id] = {} } | ||
// empty objects are very uninteresetting maybe just skip them | ||
let parsed = parse$2(struct$$1, obj[i], i, root); | ||
let parsed = parse$1(struct$$1, obj[i], i, root); | ||
@@ -199,9 +203,16 @@ // if (i === 'root' || i === 'parent') { | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new WebSocket(url); | ||
const id = hub.id; | ||
const uniq = process.pid; | ||
var uid = () => hash(`b-${Date.now()}-${(Math.random() * 10000) | 0}-${uniq}`); | ||
hub.set({ clients: { [id]: { } } }, false); | ||
var createClient = (t, val, stamp, useragent, id) => { | ||
if (!id) id = t._uid_ || uid(); | ||
ua(useragent, val); | ||
t.set({ clients: { [id]: val } }, stamp); | ||
return t.clients[id] | ||
}; | ||
const client = hub.clients[id]; | ||
const connect = (hub, url, reconnect) => { | ||
const socket = new websocket.w3cwebsocket(url); | ||
// t, val, stamp, useragent, id | ||
const client = hub.client || createClient(hub, {}, false); | ||
@@ -213,7 +224,7 @@ hub.set({ client }, false); | ||
const close = () => { | ||
const stamp = bs.create('disconnect', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = false; | ||
hub.set({ connected: false }, stamp); | ||
bs.close(); | ||
if (!socket.blockReconnect && hub.url) { | ||
if (!socket.blockReconnect && hub._url_) { | ||
reconnect = Math.min((reconnect * 1.5), 2000); | ||
@@ -226,12 +237,12 @@ hub.reconnect = setTimeout(connect, reconnect, hub, url, reconnect); | ||
socket.onerror = () => { | ||
if (typeof window === 'undefined') { | ||
close(); | ||
} else { | ||
socket.close(); | ||
} | ||
}; | ||
if (typeof window === 'undefined') { | ||
socket.hackyOnClose = close; | ||
} | ||
socket.onerror = typeof window === 'undefined' | ||
? close | ||
: () => socket.close(); | ||
socket.onopen = () => { | ||
const stamp = bs.create('connected', hub.id); | ||
const stamp = bs.create(); | ||
hub.socket = socket; | ||
@@ -243,7 +254,13 @@ meta(hub); | ||
socket.onmessage = ({ data }) => { | ||
const stamp = bs.create('upstream'); | ||
// console.log(JSON.stringify(JSON.parse(data), false, 2)) | ||
hub.set(JSON.parse(data), stamp); | ||
bs.close(stamp); | ||
socket.onmessage = (data) => { | ||
data = data.data; | ||
// console.warn('INCOMING\n', JSON.parse(data)) | ||
if (!hub.receiveOnly) { | ||
hub.receiveOnly = true; | ||
hub.set(JSON.parse(data), false); | ||
hub.receiveOnly = null; | ||
} else { | ||
hub.set(JSON.parse(data), false); | ||
} | ||
bs.close(); | ||
}; | ||
@@ -253,4 +270,3 @@ }; | ||
const removeUrl = hub => { | ||
hub.url = null; | ||
hub.urlIndex = null; | ||
hub.url = hub._url_ = hub.urlIndex = null; | ||
hub.emitters.set({ data: { url$: null } }, false); | ||
@@ -266,7 +282,14 @@ }; | ||
hub.socket.blockReconnect = true; | ||
hub.socket.close(); | ||
console.log('GO GO GOREMOVE', hub.socket._readyState); | ||
if (hub.connected.compute() === false || !hub.socket._readyState) { | ||
console.log('hacky!'); | ||
hub.socket.hackyOnClose(); | ||
} else { | ||
hub.socket.close(); | ||
} | ||
} | ||
// hub.socket = false | ||
}; | ||
const url = (hub, val, stamp) => { | ||
const url = (hub, val, key, stamp) => { | ||
hub.on((val, stamp, t) => { | ||
@@ -279,15 +302,34 @@ if (val === null && !t._c && t === hub) { | ||
}, 'url$'); | ||
if (!val) val = null; | ||
if (val !== hub.url) { | ||
if ((!hub.url && val) || (hub.url.compute() !== val)) { | ||
removeSocket(hub); | ||
hub.set({ connected: false }, stamp); | ||
if (!val) { | ||
removeUrl(hub); | ||
hub.set({ connected: false }, stamp); | ||
hub._url_ = null; | ||
if (hub.url) hub.url.set(null, stamp); | ||
} else { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; | ||
hub.url = val; | ||
connect(hub, val, 50); | ||
if (!hub.url) { | ||
briskyStruct.create({ | ||
on: { | ||
data: { | ||
url: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
hub.set({ connected: false }, stamp); | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.urlIndex = i; // use this for checks | ||
hub._url_ = val; | ||
connect(hub, val, 50); | ||
} else { | ||
hub._url_ = null; | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, briskyStruct.struct, hub, key); | ||
} | ||
hub.url.set(val, stamp); | ||
} | ||
@@ -297,27 +339,69 @@ } | ||
// very context as well | ||
// const clients => (val, stamp) { | ||
// const hub = this.cParent() | ||
// if (this.compute() === false && hub.upstream) { | ||
// // put this in clients (the file) | ||
// const clients = hub.clients | ||
// if (clients && clients.keys().length > 1) { | ||
// clients.each((client) => { | ||
// if ( | ||
// client.val !== null && | ||
// !client.socket && | ||
// client.key != hub.id // eslint-disable-line | ||
// ) { | ||
// client.remove(stamp) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
// } | ||
const removeClients = (hub, stamp) => { | ||
const clients = hub.clients; | ||
if (clients && clients.keys().length > 1) { | ||
clients.forEach((client, key) => { | ||
if ( | ||
client.val !== null && | ||
client !== hub.client | ||
) { | ||
client.set(null, stamp); | ||
delete clients[key]; | ||
} | ||
}); | ||
} | ||
}; | ||
const connected = { type: 'struct' }; | ||
const connected = { | ||
type: 'struct', | ||
on: { | ||
data: { | ||
removeClients: (val, stamp, t) => { | ||
if (t.compute() === false) { | ||
// all instances! -- fix this | ||
removeClients(t._p, stamp); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
const context = (hub, val) => { | ||
if (val !== hub.clientContext) { | ||
hub.clientContext = val; | ||
const contextStruct = briskyStruct.struct.create({ | ||
props: { | ||
default: { | ||
on: { | ||
data: { | ||
updateParent: (val, stamp, t) => { | ||
console.log('👻 GO UPDATE PARENT!!! 👻'); | ||
t.parent().emit('data', val, stamp); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
const contextIsNotEqual = (val, context) => { | ||
if (val && typeof val === 'object') { | ||
for (let field in val) { | ||
if (!context[field] || val[field] !== context[field].compute()) { | ||
console.log('😜', field); | ||
return true | ||
} | ||
} | ||
} else { | ||
console.log('😜 ?????'); | ||
return val !== context.compute() | ||
} | ||
}; | ||
const context = (hub, val, key, stamp) => { | ||
if (!hub.context || contextIsNotEqual(val, hub.context)) { | ||
console.log('⚽️ fire fire fire FLAME context ⚽️', val, stamp); | ||
if (!hub.context) { | ||
briskyStruct.create(val, stamp, contextStruct, hub, key); | ||
} else { | ||
removeClients(hub, stamp); | ||
hub.context.set(val, stamp); | ||
} | ||
if (hub.connected && hub.connected.compute() === true) meta(hub); | ||
@@ -343,11 +427,13 @@ } | ||
if (!raw) subs = briskyStruct.parse(subs); | ||
const parsed = parse$2(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
if (!this.receiveOnly) { | ||
const parsed = parse$1(this, subs); | ||
if (parsed) { | ||
const key = hash(JSON.stringify(parsed)); | ||
if (!this.upstreamSubscriptions) { | ||
this.upstreamSubscriptions = { [key]: parsed }; | ||
if (this.url) meta(this); | ||
} else if (!this.upstreamSubscriptions[key]) { | ||
this.upstreamSubscriptions[key] = parsed; | ||
if (this.url) meta(this); | ||
} | ||
} | ||
@@ -404,3 +490,3 @@ } | ||
const parse$3 = (obj, state, key) => { | ||
const parse$2 = (obj, state, key) => { | ||
const result = {}; | ||
@@ -426,7 +512,7 @@ for (let i in obj) { | ||
let msg; | ||
if (!pass) { | ||
msg = `cannot parse function ${key}.exec\n${val}`; | ||
} else { | ||
msg = `cannot run function ${key}.exec\n${val}`; | ||
} | ||
// if (!pass) { | ||
msg = `cannot parse function ${key}.exec\n${val}`; | ||
// } else { | ||
// msg = `cannot run function ${key}.exec\n${val}` | ||
// } | ||
state.emit('error', new Error(msg)); | ||
@@ -439,3 +525,3 @@ obj[i] = dummy; | ||
} else { | ||
result[i] = parse$3(obj[i], state, i); | ||
result[i] = parse$2(obj[i], state, i); | ||
} | ||
@@ -446,2 +532,17 @@ } | ||
const cache = (client, struct$$1, stamp) => { | ||
if (!client.cache) client.cache = {}; | ||
client.cache[briskyStruct.puid(struct$$1)] = stamp; | ||
}; | ||
const isCached = (client, struct$$1, stamp) => client.cache && | ||
client.cache[briskyStruct.puid(struct$$1)] === stamp; | ||
const isEmpty$1 = obj => { | ||
for (let i in obj) { //eslint-disable-line | ||
return false | ||
} | ||
return true | ||
}; | ||
const progress = (client) => { | ||
@@ -452,11 +553,7 @@ if (!client.inProgress) { | ||
if (client.val !== null) { | ||
var isEmpty = true; | ||
for (let i in client.inProgress) { //eslint-disable-line | ||
isEmpty = false; | ||
break | ||
} | ||
if (!isEmpty) { | ||
// bit hacky... | ||
if (!isEmpty$1(client.inProgress)) { | ||
if (client.inProgress.types) { | ||
for (let i in client.inProgress) { | ||
// order is still important since settign types after the facts is still broken | ||
// this will be a big update | ||
if (i === 'types') { | ||
@@ -480,134 +577,96 @@ break | ||
const send$1 = (hub, client, t, type, subs, tree) => { | ||
var val; | ||
if (type === 'remove') { | ||
if (!t._p[t.key]) { | ||
val = null; | ||
if (bs.src(t._p.tStamp) === client.key) { | ||
return | ||
const send$1 = (hub, client, struct$$1, type, subs, tree) => { | ||
if (struct$$1.isHub && client.val !== null) { | ||
let isRemoved; | ||
if (type === 'remove') { | ||
if (!struct$$1._p[struct$$1.key]) isRemoved = true; | ||
} else if (type === 'update' && tree.$t !== struct$$1) { | ||
if (tree.$t && tree.$t._p && !tree.$t._p[tree.$t.key]) { | ||
let previous = tree.$t; | ||
let prop = previous; | ||
while (previous) { | ||
if (previous._p && previous._p[previous.key]) { | ||
// think of something fast for level... | ||
serialize$2(client, progress(client), subs, prop, briskyStruct.get(hub, 'serverIndex'), true); | ||
} | ||
prop = previous; | ||
previous = previous._p; | ||
} | ||
} | ||
} | ||
} else if (type === 'update' && tree.$t !== t) { | ||
if (tree.$t && tree.$t._p && !tree.$t._p[tree.$t.key]) { | ||
serialize$2(hub.id, client, progress(client), subs, tree.$t, null, briskyStruct.get(hub, 'serverIndex'), tree); | ||
} | ||
serialize$2(client, progress(client), subs, struct$$1, briskyStruct.get(hub, 'serverIndex'), isRemoved); | ||
} | ||
if (t.val !== void 0 || val === null || subs.val === true) { | ||
// opt this line (the get) just use a define or something | ||
serialize$2(hub.id, client, progress(client), subs, t, val, briskyStruct.get(hub, 'serverIndex'), tree); | ||
} | ||
}; | ||
const cache = (client, struct$$1, stamp, level, val) => { | ||
if (!client.cache) client.cache = {}; | ||
client.cache[struct$$1.uid()] = stamp[0]; | ||
}; | ||
const serialize$2 = (client, t, subs, struct$$1, level, isRemoved) => { | ||
const stamp = briskyStruct.get(struct$$1, 'stamp') || 1; // remove the need for this default (feels wrong) | ||
const val = isRemoved ? null : briskyStruct.getVal(struct$$1); | ||
const isCached = (client, struct$$1, stamp) => { | ||
return client.cache && client.cache[struct$$1.uid()] === stamp[0] | ||
}; | ||
const setStamp = (s, stamp, src, struct$$1, id, client, level) => { | ||
cache(client, struct$$1, stamp, level); | ||
s.stamp = !src | ||
? bs.create(bs.type(stamp), id, bs.val(stamp)) | ||
: stamp; | ||
}; | ||
// clean the cached up a bit | ||
const serialize$2 = (id, client, t, subs, struct$$1, val, level) => { | ||
const stamp = briskyStruct.get(struct$$1, 'stamp'); | ||
var cached, isType; | ||
if (stamp && (val === null || !(cached = isCached(client, struct$$1, stamp))) || subs.val === true) { | ||
const src = bs.src(stamp); | ||
if ( | ||
src !== client.key && bs.src(t.tStamp) !== client.key || | ||
(isType = struct$$1.key === 'type') | ||
) { | ||
if ( | ||
client.resolve && | ||
client.resolve[src] && | ||
bs.val(stamp) >= client.resolve[src] | ||
) { | ||
if (val !== null) { | ||
if (struct$$1.val !== void 0) cache(client, struct$$1, stamp, level); | ||
if (subs.val === true) { | ||
const keys = briskyStruct.getKeys(struct$$1); | ||
if (keys) deepSerialize(keys, id, client, t, subs, struct$$1, val, level); | ||
} | ||
} | ||
if (val !== void 0 && stamp && !isCached(client, struct$$1, stamp)) { | ||
// val === null -- double chck if this is nessecary | ||
const path = struct$$1.path(); | ||
const len = path.length; | ||
let s = t; | ||
for (let i = level; i < len; i++) { | ||
let tt = s[path[i]]; | ||
if (!tt) { | ||
s = s[path[i]] = {}; | ||
} else { | ||
if (subs.type) { | ||
// simple but will make it better need more checks | ||
var p = struct$$1; | ||
while (p) { | ||
if (p.key === 'types') { | ||
return | ||
} | ||
p = p._p; | ||
} | ||
} | ||
s = tt; | ||
if (s.val === null) return | ||
} | ||
} | ||
if (isType) { // means its blocked otherwise (could be a set form own client) | ||
typeSerialize(id, client, t, subs, struct$$1, val, level); | ||
} else if (!cached && (struct$$1.val !== void 0 || val === null)) { | ||
const path = struct$$1.path(); | ||
const len = path.length; | ||
var s = t; | ||
for (let i = level; i < len; i++) { | ||
let tt = s[path[i]]; | ||
if (!tt) { | ||
s = s[path[i]] = {}; | ||
} else { | ||
s = tt; | ||
if (s.val === null) return | ||
} | ||
} | ||
if (val === null) { | ||
setStamp(s, stamp, src, struct$$1, id, client, level, val); | ||
s.val = null; | ||
} else { | ||
if (struct$$1.key === 'type') { | ||
typeSerialize(id, client, t, subs, struct$$1, val, level); | ||
} | ||
setStamp(s, stamp, src, struct$$1, id, client, level); | ||
if (struct$$1.val && struct$$1.val.inherits) { | ||
s.val = struct$$1.val.path(); | ||
s.val.unshift('@', 'root'); | ||
serialize$2(id, client, t, subs, struct$$1.val, val, level); | ||
} else if (struct$$1.val !== void 0) { | ||
s.val = struct$$1.val; | ||
} | ||
} | ||
if (isRemoved) { | ||
cache(client, struct$$1, stamp); | ||
s.stamp = stamp; | ||
s.val = val; | ||
} else { | ||
if (subs.type) { | ||
const type = briskyStruct.get(struct$$1, 'type'); // make getType (fast) | ||
if (briskyStruct.getVal(type) !== 'hub') { | ||
serialize$2(client, t, subs.type, type, level); | ||
} | ||
} | ||
if (subs.val === true) { | ||
const keys = briskyStruct.getKeys(struct$$1); | ||
if (keys) deepSerialize(keys, id, client, t, subs, struct$$1, val, level); | ||
} | ||
cache(client, struct$$1, stamp); | ||
s.stamp = stamp; | ||
if (struct$$1.key === 'type') { | ||
if (val === 'hub') return | ||
serialize$2(client, t, subs, briskyStruct.getType(struct$$1.parent(2), val), level); | ||
// allways need a stamp! | ||
} | ||
if (typeof val === 'object' && val.inherits) { | ||
s.val = val.path(); | ||
s.val.unshift('@', 'root'); | ||
serialize$2(client, t, subs, val, level); | ||
} else if (val !== void 0) { | ||
s.val = val; | ||
} | ||
} | ||
} else if (val && typeof val === 'object' && val.inherits) { | ||
// can send a bit too much data when val: true and overlapping keys | ||
serialize$2(client, t, subs, val, level); | ||
} | ||
}; | ||
const typeSerialize = (id, client, t, subs, struct$$1, val, level) => { | ||
serialize$2(id, client, t, subs, briskyStruct.getType(struct$$1.parent(2), struct$$1.compute()), val, level); | ||
if (subs.val === true && !isRemoved) { | ||
deepSerialize(briskyStruct.getKeys(struct$$1), client, t, subs, struct$$1, level); | ||
} | ||
}; | ||
const deepSerialize = (keys, id, client, t, subs, struct$$1, val, level) => { | ||
const deepSerialize = (keys, client, t, subs, struct$$1, level) => { | ||
if (struct$$1.get('type') && struct$$1.get('type').compute() !== 'hub') { | ||
serialize$2(client, t, subs, struct$$1.get('type'), level); | ||
} | ||
if (keys) { | ||
for (let i = 0, len = keys.length; i < len; i++) { | ||
let prop = briskyStruct.get(struct$$1, keys[i]); | ||
if (prop && prop.isHub) serialize$2(id, client, t, subs, prop, val, level); | ||
if (prop && prop.isHub) serialize$2(client, t, subs, prop, level); | ||
} | ||
} | ||
// feels really shacky /w context :/ needs tests | ||
if (struct$$1._removed) { | ||
for (let i = 0, len = struct$$1._removed.length; i < len; i++) { | ||
let prop = struct$$1._removed[i]; | ||
if (prop && prop.isHub) serialize$2(id, client, t, subs, prop, null, level); | ||
serialize$2(client, t, subs, prop, level, true); | ||
} | ||
@@ -617,2 +676,28 @@ } | ||
const removeSubscriptions = (t, id) => { | ||
if (t.subscriptions) { | ||
let i = t.subscriptions.length; | ||
while (i--) { // clean this up with unsubscribe in struct | ||
if (t.subscriptions[i]._uid_ == id) { //eslint-disable-line | ||
t.subscriptions.splice(i, 1); | ||
} | ||
} | ||
} | ||
}; | ||
const removeClient = (client) => { | ||
const id = client.key; | ||
client.val = null; | ||
if (client.socket) { | ||
client.socket.client = null; | ||
client.socket = null; | ||
} | ||
const t = client.parent(2); | ||
removeSubscriptions(t, id); | ||
client.set(null); | ||
// if (client.context && t.clients.keys().length === (t.url ? 1 : 0)) { | ||
// t.set(null, stamp) | ||
// } | ||
}; | ||
var incoming = (hub, socket, data) => { | ||
@@ -622,45 +707,74 @@ const payload = data[0]; | ||
var client = socket.client; | ||
var t; | ||
if (meta) { | ||
let t; | ||
if (client) { | ||
t = hub; | ||
if (client.context != meta.context) { // eslint-disable-line | ||
client.set(null); | ||
t = create$2(hub, socket, meta); | ||
client = socket.client; | ||
if ('context' in meta && client.context != meta.context) { // eslint-disable-line | ||
removeClient(client); | ||
create$1(hub, socket, meta, payload); | ||
} else if (meta.subscriptions) { | ||
incomingSubscriptions(t, client, meta, client.id); | ||
if (payload) setPayload(t, payload, client); | ||
incomingSubscriptions(t, client, meta, client.key); | ||
bs.close(); | ||
} | ||
} else { | ||
t = create$2(hub, socket, meta); | ||
client = socket.client; | ||
create$1(hub, socket, meta, payload); | ||
} | ||
} else { | ||
t = client.parent(2); | ||
setPayload(client.parent(2), payload, client); | ||
bs.close(); | ||
} | ||
}; | ||
if (payload) { | ||
if (meta && meta.resolve) { | ||
client.resolve = meta.resolve; | ||
t.set(payload, false); | ||
bs.on(() => { client.resolve = false; }); | ||
} else { | ||
t.set(payload, false); | ||
const addToCache = (client, hub, payload) => { | ||
if (typeof payload === 'object' && payload) { | ||
for (let key in payload) { | ||
if (key !== 'val' && key !== 'stamp') { | ||
let struct$$1 = hub[key]; | ||
if (struct$$1 && struct$$1.isHub) { | ||
addToCache(client, hub[key], payload[key]); | ||
} | ||
} | ||
} | ||
bs.close(); | ||
if (payload.val !== void 0 && payload.stamp) { | ||
cache(client, hub, payload.stamp); | ||
} | ||
} | ||
}; | ||
const create$2 = (hub, socket, meta) => { | ||
const stamp = bs.create('connect'); | ||
const setPayload = (hub, payload, client) => { | ||
hub.set(payload, false); | ||
addToCache(client, hub, payload); | ||
}; | ||
const set$1 = (meta, socket, t, payload) => { | ||
const stamp = bs.create(); | ||
const id = meta.id; | ||
const t = meta.context ? hub.getContext(meta.context) : hub; | ||
t.set({ clients: { [id]: { socket, context: meta.context } } }, stamp); | ||
const client = socket.client = t.clients[id]; | ||
const context = meta.context; | ||
// const ip = socket._socket.remoteAddress | ||
const client = socket.client = createClient( | ||
t, { socket, context }, stamp, socket.useragent, id | ||
); | ||
if (payload) setPayload(t, payload, client); | ||
if (meta.subscriptions) incomingSubscriptions(t, client, meta, id); | ||
bs.close(stamp); | ||
return t | ||
bs.close(); | ||
}; | ||
const create$1 = (hub, socket, meta, payload) => { | ||
const t = meta.context ? hub.getContext(meta.context, socket) : hub; | ||
if (!t.inherits && t.then) { | ||
t.then((t) => { | ||
if (socket.external !== null) { | ||
console.log('client connected and found informations'); | ||
set$1(meta, socket, t, payload); | ||
} else { | ||
console.log('client discconected when logging in'); | ||
} | ||
}).catch(err => hub.emit('error', err)); | ||
} else { | ||
set$1(meta, socket, t, payload); | ||
} | ||
}; | ||
const incomingSubscriptions = (hub, client, meta, id) => { | ||
@@ -672,6 +786,6 @@ const update = (t, type, subs, tree) => send$1(hub, client, t, type, subs, tree); | ||
if (!client.upstreamSubscriptions[uid]) { | ||
let subs = parse$3(meta.subscriptions[key], hub); | ||
let subs = parse$2(meta.subscriptions[key], hub); | ||
client.upstreamSubscriptions[uid] = subs; | ||
briskyStruct.subscribe(hub, subs, update); | ||
hub.subscriptions[hub.subscriptions.length - 1].id = id; | ||
hub.subscriptions[hub.subscriptions.length - 1]._uid_ = id; | ||
} | ||
@@ -681,9 +795,35 @@ } | ||
const Server = WebSocket.Server; | ||
const removeSubscriptions = (t, id) => { | ||
if (t.subscriptions) { | ||
let i = t.subscriptions.length; | ||
while (i--) { // clean this up with unsubscribe in struct | ||
if (t.subscriptions[i].id === id) t.subscriptions.splice(i, 1); | ||
var removedInProgress; | ||
const on$1 = { | ||
data: { | ||
remove$: (val, stamp, struct$$1) => { | ||
// just do a diff with the payload rly the best way for now... | ||
if (val === null && (!struct$$1._c || struct$$1._cLevel === 1)) { | ||
let p = struct$$1; | ||
let hub; | ||
while (p) { | ||
if (p.port && !p._c) { hub = p; } | ||
p = p.parent(); | ||
} | ||
if (hub) { | ||
// probably not working correctly with context | ||
const target = struct$$1.parent(); | ||
if (target) { | ||
if (!target._removed) { | ||
target._removed = []; | ||
if (!removedInProgress) { | ||
removedInProgress = []; | ||
bs.on(() => { | ||
let i = removedInProgress.length; | ||
while (i--) { | ||
delete removedInProgress[i]._removed; | ||
} | ||
}); | ||
} | ||
removedInProgress.push(target); | ||
} | ||
target._removed.push(struct$$1); | ||
} | ||
} | ||
} | ||
} | ||
@@ -693,5 +833,11 @@ } | ||
const create$1 = (hub, port) => { | ||
const Server = uws.Server; | ||
const createServer = (hub, port) => { | ||
const server = new Server({ port }); | ||
server.on('connection', (socket) => { | ||
console.log(`💫 hub listening on ${port} 💫`); | ||
server.on('connection', socket => { | ||
socket.useragent = socket.upgradeReq && socket.upgradeReq.headers['user-agent']; | ||
// need to remove when done -- its the best thing todo (mem!!!) | ||
socket.on('message', (data) => { | ||
@@ -703,14 +849,3 @@ data = JSON.parse(data); | ||
const close = () => { | ||
const client = socket.client; | ||
if (client) { | ||
const stamp = bs.create('disconnect'); | ||
const id = client.key; | ||
const t = client.parent(2); | ||
removeSubscriptions(t, id); | ||
client.set(null, stamp); | ||
if (client.context && t.clients.keys().length === (t.url ? 1 : 0)) { | ||
t.set(null, stamp); | ||
} | ||
bs.close(); | ||
} | ||
if (socket.client) removeClient(socket.client); | ||
}; | ||
@@ -725,3 +860,3 @@ | ||
const removeServer = hub => { | ||
const server = hub.server; | ||
const server = hub._server_; | ||
const instances = hub.instances; | ||
@@ -732,5 +867,6 @@ closeConnections(hub); | ||
} | ||
server.httpServer.close(); | ||
// remove all clients subscriptions | ||
hub.server = null; | ||
hub._server_ = null; | ||
}; | ||
@@ -740,3 +876,3 @@ | ||
const clients = hub.clients; | ||
const id = hub.id; // to exclude the client (not nessecary) | ||
const id = hub._uid_; // to exclude the client (not nessecary) | ||
if (clients) { | ||
@@ -759,3 +895,4 @@ clients.forEach(client => { | ||
const port = (hub, val) => { | ||
const port = (hub, val, key, stamp) => { | ||
// use remove | ||
hub.on((val, stamp, t) => { | ||
@@ -768,15 +905,29 @@ if (val === null && !t._c && t === hub) { | ||
if (!val) val = null; | ||
if (val !== hub.port) { | ||
if (hub.server) { | ||
if ((!hub.port && val) || (hub.port.compute() !== val)) { | ||
if (hub._server_) { | ||
removeServer(hub); | ||
} | ||
if (!val) { | ||
if (hub.port) hub.port.set(null, stamp); | ||
removePort(hub); | ||
} else { | ||
hub.port = val; | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.serverIndex = i; | ||
hub.server = create$1(hub, val); | ||
if (!hub.port) { | ||
briskyStruct.create({ | ||
on: { | ||
data: { | ||
port: (val, stamp, struct$$1) => { | ||
val = struct$$1.compute(); | ||
if (val) { | ||
let i = -1; | ||
if (hub.key) i++; | ||
hub.parent(() => { i++; }); | ||
hub.serverIndex = i; | ||
hub._server_ = createServer(hub, val); | ||
} | ||
} | ||
} | ||
} | ||
}, stamp, briskyStruct.struct, hub, key); | ||
} | ||
hub.port.set(val, stamp); | ||
} | ||
@@ -787,3 +938,3 @@ } | ||
const props$1 = { | ||
server: true, | ||
_server_: true, | ||
serverIndex: true, | ||
@@ -793,40 +944,5 @@ port | ||
var removedInProgress; | ||
const on$1 = { | ||
data: { | ||
remove$: (val, stamp, struct$$1) => { | ||
if (val === null && (!struct$$1._c || struct$$1._cLevel === 1)) { | ||
let p = struct$$1; | ||
let hub; | ||
while (p) { | ||
if (p.port && !p._c) { hub = p; } | ||
p = p.parent(); | ||
} | ||
if (hub) { | ||
const target = struct$$1.parent(); | ||
if (target) { | ||
if (!target._removed) { | ||
target._removed = []; | ||
if (!removedInProgress) { | ||
removedInProgress = []; | ||
bs.on(() => { | ||
let i = removedInProgress.length; | ||
while (i--) { | ||
delete removedInProgress[i]._removed; | ||
} | ||
}); | ||
} | ||
removedInProgress.push(target); | ||
} | ||
struct$$1._p._removed.push(struct$$1); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var server = Object.freeze({ | ||
@@ -837,12 +953,24 @@ props: props$1, | ||
const props$2 = { contextKey: true }; | ||
var context$1 = { | ||
props: { | ||
contextKey: true, | ||
getContext: (t, fn) => { | ||
t.set({ | ||
define: { | ||
getContext (key, socket) { | ||
return fn(key, (key) => createContext(this, key), this, socket) | ||
} | ||
} | ||
}); | ||
} | ||
}, | ||
getContext: (key, context) => context() | ||
}; | ||
const define$1 = { | ||
getContext (val) { | ||
var result = find(this, val); | ||
if (!result) { | ||
result = this.create({ contextKey: val }, false); | ||
} | ||
return result | ||
const createContext = (hub, val) => { | ||
var result = find(hub, val); | ||
if (!result) { | ||
result = hub.create({ contextKey: val }, false); | ||
} | ||
return result | ||
}; | ||
@@ -855,6 +983,3 @@ | ||
while (i--) { | ||
if (instances[i].contextKey === val) { | ||
// console.log('found context --->', val, instances[i].clients.keys()) | ||
return instances[i] | ||
} | ||
if (instances[i].contextKey === val) return instances[i] | ||
} | ||
@@ -864,8 +989,2 @@ } | ||
var context$1 = Object.freeze({ | ||
props: props$2, | ||
define: define$1 | ||
}); | ||
const types = briskyStruct.struct.props.types; | ||
@@ -879,6 +998,7 @@ | ||
default: 'self', | ||
id: (t, val) => { t.set({ define: { id: val } }); }, | ||
_uid_: (t, val) => { t.set({ define: { _uid_: val } }); }, | ||
// why nto call this client id -- thats what it is | ||
clients: (t, val, key, stamp) => { | ||
if (!t.clients) { | ||
t.clients = briskyStruct.c(clients, val, stamp, t, key); | ||
t.clients = briskyStruct.create(val, stamp, clients, t, key); | ||
} else { | ||
@@ -891,13 +1011,12 @@ briskyStruct.set(t.clients, val, stamp); | ||
client: true | ||
}, | ||
id | ||
} | ||
}); | ||
hub.props.types.struct = briskyStruct.c(hub, { | ||
hub.props.types.struct = hub.create({ | ||
props: { default: types.struct.props.default.bind() } | ||
}); | ||
}, false); | ||
hub.props.types.struct.props.default.struct = hub.props.type.struct = hub; | ||
hub.set({ types: { hub: 'self' }, inject: [ server, context$1, client ] }, false); | ||
hub.set({ types: { hub: 'self' }, inject: [ server, client, context$1 ] }, false); | ||
@@ -916,21 +1035,13 @@ hub.types._ks = void 0; | ||
} | ||
}) | ||
}, false) | ||
} | ||
}); | ||
}, false); | ||
// import bs from 'brisky-stamp' | ||
console.log('hub.js:', __dirname); | ||
var index = (val, stamp) => { | ||
if (stamp === void 0) { | ||
const r = hub.create(val, bs.create()); | ||
bs.close(); | ||
return r | ||
} else { | ||
return hub.create(val, stamp) | ||
} | ||
}; | ||
const fn = (val, stamp) => hub.create(val, stamp); | ||
// add uids to stamps else it sucks -- dont compromise for tests think of that as an after thought | ||
module.exports = index; | ||
//# sourceMappingURL=index.js.map | ||
module.exports = fn; |
{ | ||
"name": "hub.js", | ||
"description": "Seamless realtime communcation", | ||
"version": "0.0.10", | ||
"version": "0.0.11-11bca60dc2e3e6c42592c194492636b865039e52", | ||
"main": "dist/index.js", | ||
@@ -11,5 +11,6 @@ "module": "dist/index.es.js", | ||
"./dist/index.es.js": "./dist/browser.es.js", | ||
"./lib/uid/index.js": "./lib/uid/browser.js", | ||
"./lib/server/index.js": "./lib/server/browser.js", | ||
"./lib/client/websocket/index.js": "./lib/client/websocket/browser.js" | ||
"./src/client/uid/index.js": "./src/client/uid/browser.js", | ||
"./src/server/index.js": "./src/server/browser.js", | ||
"./src/client/websocket/index.js": "./src/client/websocket/browser.js", | ||
"source-map-support": false | ||
}, | ||
@@ -19,5 +20,6 @@ "scripts": { | ||
"pretest": "npm run build && standard", | ||
"watch": "node rollup/watch", | ||
"version-commit": "npm --no-git-tag-version version $(node -pe \"require('./package.json').version.split('-')[0]\")-$(git log -n 1 --pretty=format:'%H')", | ||
"publish-branch": "npm run version-commit && npm publish --tag $(git rev-parse --abbrev-ref HEAD | sed 's/\\//-/g')", | ||
"prepublish": "npm run build", | ||
"watch": "node rollup/watch", | ||
"postinstall": "[ -d dist ] || npm run build || ( mkdir dist && yarn && npm run build )", | ||
"test": "node test/index.js", | ||
@@ -45,7 +47,8 @@ "dev": "node rollup/watch & nodemon --harmony-async-await test/index.js", | ||
"dependencies": { | ||
"brisky-stamp": "^3.0.12", | ||
"brisky-struct": "^1.1.7", | ||
"brisky-stamp": "^4.0.0", | ||
"brisky-struct": "feature-enhancements", | ||
"string-hash": "^1.1.0", | ||
"uws": "0.12.0", | ||
"vigour-ua": "^2.2.3" | ||
"vigour-ua": "^3.0.0", | ||
"websocket": "^1.0.24" | ||
}, | ||
@@ -60,6 +63,5 @@ "nyc": { | ||
"devDependencies": { | ||
"source-map-support": "^0.4.7", | ||
"buble": "0.15.1", | ||
"coveralls": "^2.11.9", | ||
"nodemon": "^1.11.0", | ||
"coveralls": "^2.11.9", | ||
"nyc": "^10.0.0", | ||
@@ -66,0 +68,0 @@ "pre-commit": "^1.1.3", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
361824
12
2726
0
6
+ Addedwebsocket@^1.0.24
+ Addedbrisky-stamp@4.0.1(transitive)
+ Addedbrisky-struct@1.1.7-b279c9343194043e5d005a7946bae1f4cdf5f2bc(transitive)
+ Addedbufferutil@4.0.9(transitive)
+ Addedd@1.0.2(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addedes5-ext@0.10.64(transitive)
+ Addedes6-iterator@2.0.3(transitive)
+ Addedes6-symbol@3.1.4(transitive)
+ Addedesniff@2.0.1(transitive)
+ Addedevent-emitter@0.3.5(transitive)
+ Addedext@1.7.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedms@2.0.0(transitive)
+ Addednext-tick@1.1.0(transitive)
+ Addednode-gyp-build@4.8.4(transitive)
+ Addedtype@2.7.3(transitive)
+ Addedtypedarray-to-buffer@3.1.5(transitive)
+ Addedutf-8-validate@5.0.10(transitive)
+ Addedvigour-ua@3.1.6(transitive)
+ Addedwebsocket@1.0.35(transitive)
+ Addedyaeti@0.0.6(transitive)
- Removedbrisky-stamp@3.0.12(transitive)
- Removedbrisky-struct@1.10.13(transitive)
- Removeddom-walk@0.1.2(transitive)
- Removedglobal@4.4.0(transitive)
- Removedmin-document@2.19.0(transitive)
- Removedprocess@0.11.10(transitive)
- Removedstamp@4.0.2(transitive)
- Removedvigour-ua@2.2.3(transitive)
Updatedbrisky-stamp@^4.0.0
Updatedvigour-ua@^3.0.0