decision
Version:
Decision System Based on Event System and Alleyway Grammer
122 lines (111 loc) • 3.47 kB
JavaScript
let makeDecisions = (decisions, marmoset, alleyway) => {
for (let i = 0; i < decisions.length; i++) {
let decision = decisions[i];
makeDecision(decision, marmoset, alleyway);
}
}
let makeDecision = (decision, marmoset, alleyway) => {
decision.end(function(queueInfo) {
let {
when, actionType, dataRule, name, filter
} = fetchData(queueInfo);
createDecisionEndEvent(marmoset, name);
listen(when, marmoset, (e) => {
if (filter) {
let filterResult = getAction(alleyway, filter).call(undefined, e.data);
if (!filterResult) return;
}
let actionResult = getAction(alleyway, actionType).
apply(undefined, getActionData(e.data, dataRule));
waitResult(actionResult, res => {
// TODO trigger decision end event
marmoset.trigger("system", "decisionEnd", {
name,
res,
when,
actionType
});
}, err => {
throw new Error(err);
});
});
});
}
let waitResult = (actionResult, cb, fail) => {
if (actionResult && typeof actionResult.then === "function") {
actionResult.then(res => {
cb && cb(res);
}).catch(err => fail(err));
} else {
cb && cb(actionResult);
}
}
let getAction = (alleyway, actionType) => {
if (typeof actionType === "function") {
var action = actionType;
} else if (typeof actionType === "string") {
var action = alleyway.translate(actionType);
}
return action;
}
let getActionData = (data, dataRule) => {
if (dataRule) {
data = dataRule(data);
if (!isArray(data)) {
data = [data];
}
} else {
data = [data];
}
return data;
}
let createDecisionEndEvent = (marmoset, name) => {
if (!name) return;
marmoset.createEventByRoute((m) => {
m().happen("system", "decisionEnd").
inCase(e => e.data.name === name).
trigger("system", name).data(e => e.data.res);
});
}
let fetchData = (queueInfo) => {
let map = queueInfo.getMap();
let when = map["when"].args[0];
let actionType = map["then"].args[0];
let dataRule = map["data"] && map["data"].args[0];
let name = map["named"] && map["named"].args[0];
let filter = map["filter"] && map["filter"].args[0];
return {
when, actionType, dataRule, name, filter
};
}
let isArray = v => v && typeof v === "object" && typeof v.length === "number";
let listen = (when, marmoset, callback) => {
let res = splitWhen(when);
if (res.ctxs.length === 1) {
marmoset.on(res.ctxs[0], res.types.join(";"), (e) => {
callback && callback(e);
});
} else if (res.ctxs.length > 1) {
marmoset.onGroup(res.ctxs, res.types.join(";"), (e) => {
callback && callback(e);
});
}
}
let splitWhen = (when) => {
let sentences = when.split(";");
let ctxs = [],
types = [];
for (let i = 0; i < sentences.length; i++) {
let sentence = sentences[i];
let parts = sentence.split("::");
let channel = parts[0];
let eventType = parts[1];
ctxs.push(channel);
types.push(eventType);
}
return {
ctxs,
types
};
}
export default makeDecisions;