mvdom
Version:
deprecated - Moved to dom-native package
247 lines • 7.63 kB
JavaScript
import { ensureArray, splitAndTrim } from './utils';
;
export function addHubEvents(target, source) {
const t = (target == null) ? [] : (target instanceof Array) ? target : [target];
(source instanceof Array) ? t.push(...source) : t.push(source);
return t;
}
export function bindHubEvents(bindings, opts) {
const bindingList = (bindings instanceof Array) ? bindings : [bindings];
for (const bindings of bindingList) {
const infoList = listHubInfos(bindings);
infoList.forEach(function (info) {
info.hub.sub(info.topics, info.labels, info.fun, opts);
});
}
}
export function unbindHubEvents(bindings, nsObject) {
const bindingList = (bindings instanceof Array) ? bindings : [bindings];
bindingList.forEach(function (hubEvents) {
const infoList = listHubInfos(hubEvents);
infoList.forEach(function (info) {
info.hub.unsub(nsObject);
});
});
}
function listHubInfos(hubEvents) {
const infoList = [];
for (const key in hubEvents) {
const val = hubEvents[key];
if (val instanceof Function) {
infoList.push(getHubInfo(key, null, val));
}
else {
const _hub = hub(key);
for (const key2 in val) {
infoList.push(getHubInfo(key2, _hub, val[key2]));
}
}
}
return infoList;
}
function getHubInfo(str, _hub, fun) {
const a = splitAndTrim(str, ";");
const topicIdx = (_hub) ? 0 : 1;
_hub = (!_hub) ? hub(a[0]) : _hub;
const info = {
topics: a[topicIdx],
fun: fun,
hub: _hub
};
if (a.length > topicIdx + 1) {
info.labels = a[topicIdx + 1];
}
return info;
}
export function hub(name) {
if (name == null) {
throw new Error('MVDOM INVALID API CALLS: mvdom.hub(name) require a name (no name was given).');
}
let hub = hubDic.get(name);
if (hub === undefined) {
hub = new HubImpl(name);
hubDic.set(name, hub);
hubDataDic.set(name, new HubData(name));
}
return hub;
}
const hubDic = new Map();
const hubDataDic = new Map();
class HubImpl {
constructor(name) {
this.name = name;
}
sub(topics, labels_or_handler, handler_or_opts, opts) {
let labels;
let handler;
if (labels_or_handler instanceof Function) {
labels = null;
handler = labels_or_handler;
opts = handler_or_opts;
}
else {
labels = labels_or_handler;
handler = handler_or_opts;
}
const topicArray = splitAndTrim(topics, ",");
const labelArray = (labels != null) ? splitAndTrim(labels, ",") : null;
opts = makeOpts(opts);
const hubData = hubDataDic.get(this.name);
hubData.addEvent(topicArray, labelArray, handler, opts);
}
unsub(ns) {
const hubData = hubDataDic.get(this.name);
hubData.removeRefsForNs(ns.ns);
}
pub(topics, labels, data) {
if (typeof data === "undefined") {
data = labels;
labels = null;
}
const topicArray = splitAndTrim(topics, ",");
const labelArray = (labels != null) ? splitAndTrim(labels, ",") : null;
const hubData = hubDataDic.get(this.name);
const hasLabels = (labels != null && labels.length > 0);
if (hasLabels) {
hubData.getRefs(topicArray, labelArray).forEach(function (ref) {
invokeRef(ref, data);
});
}
hubData.getRefs(topicArray, null).forEach(function (ref) {
if (hasLabels) {
labelArray.forEach(function (label) {
invokeRef(ref, data, label);
});
}
else {
invokeRef(ref, data);
}
});
}
deleteHub() {
hubDic.delete(this.name);
hubDataDic.delete(this.name);
}
}
class HubData {
constructor(name) {
this.refsByNs = new Map();
this.refsByTopic = new Map();
this.refsByTopicLabel = new Map();
this.name = name;
}
addEvent(topics, labels, fun, opts) {
const refs = buildRefs(topics, labels, fun, opts);
const refsByNs = this.refsByNs;
const refsByTopic = this.refsByTopic;
const refsByTopicLabel = this.refsByTopicLabel;
refs.forEach(function (ref) {
if (ref.ns != null) {
ensureArray(refsByNs, ref.ns).push(ref);
}
if (ref.label != null) {
ensureArray(refsByTopicLabel, buildTopicLabelKey(ref.topic, ref.label)).push(ref);
}
else {
ensureArray(refsByTopic, ref.topic).push(ref);
}
});
}
;
getRefs(topics, labels) {
const refs = [];
const refsByTopic = this.refsByTopic;
const refsByTopicLabel = this.refsByTopicLabel;
topics.forEach(function (topic) {
if (labels == null || labels.length === 0) {
const topicRefs = refsByTopic.get(topic);
if (topicRefs) {
refs.push.apply(refs, topicRefs);
}
}
else {
labels.forEach(function (label) {
const topicLabelRefs = refsByTopicLabel.get(buildTopicLabelKey(topic, label));
if (topicLabelRefs) {
refs.push.apply(refs, topicLabelRefs);
}
});
}
});
return refs;
}
;
removeRefsForNs(ns) {
const refsByTopic = this.refsByTopic;
const refsByTopicLabel = this.refsByTopicLabel;
const refsByNs = this.refsByNs;
const refs = this.refsByNs.get(ns);
if (refs != null) {
refs.forEach(function (ref) {
let refList;
if (ref.label != null) {
const topicLabelKey = buildTopicLabelKey(ref.topic, ref.label);
refList = refsByTopicLabel.get(topicLabelKey);
}
else {
refList = refsByTopic.get(ref.topic);
}
let idx;
while ((idx = refList.indexOf(ref)) !== -1) {
refList.splice(idx, 1);
}
});
refsByNs.delete(ns);
}
}
;
}
function buildRefs(topics, labels, fun, opts) {
let refs = [];
topics.forEach(function (topic) {
if (labels == null || labels.length === 0) {
refs.push({
topic: topic,
fun: fun,
ns: opts.ns,
ctx: opts.ctx
});
}
else {
labels.forEach(function (label) {
refs.push({
topic: topic,
label: label,
fun: fun,
ns: opts.ns,
ctx: opts.ctx
});
});
}
});
return refs;
}
const emptyOpts = {};
function makeOpts(opts) {
if (opts == null) {
opts = emptyOpts;
}
else {
if (typeof opts === "string") {
opts = { ns: opts };
}
}
return opts;
}
function buildTopicLabelKey(topic, label) {
return topic + "-!-" + label;
}
function invokeRef(ref, data, label) {
const info = {
topic: ref.topic,
label: ref.label || label,
ns: ref.ns
};
ref.fun.call(ref.ctx, data, info);
}
//# sourceMappingURL=hub.js.map