"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); var xml_js_1 = require("xml-js"); var index_1 = require("./index"); var utils_1 = require("./utils"); var actions = require("./actions"); function getAttribute(element, attribute) { return element.attributes ? element.attributes[attribute] : undefined; } function indexedRecord(items, identifier) { var record = {}; var identifierFn = utils_1.isString(identifier) ? function (item) { return item[identifier]; } : identifier; items.forEach(function (item) { var key = identifierFn(item); record[key] = item; }); return record; } function indexedAggregateRecord(items, identifier) { var record = {}; var identifierFn = utils_1.isString(identifier) ? function (item) { return item[identifier]; } : identifier; items.forEach(function (item) { var key = identifierFn(item); (record[key] = record[key] || []).push(item); }); return record; } function executableContent(elements) { var transition = { actions: mapActions(elements) }; return transition; } function getTargets(targetAttr) { // return targetAttr ? [`#${targetAttr}`] : undefined; return targetAttr ? ("" + targetAttr).split(/\s+/).map(function (target) { return "#" + target; }) : undefined; } function mapActions(elements) { return elements.map(function (element) { switch (element.name) { case 'raise': return actions.raise(element.attributes .event); case 'assign': return actions.assign(function (xs) { var literalKeyExprs = xs ? utils_1.keys(xs) .map(function (key) { return "const " + key + " = xs['" + key + "'];"; }) .join('\n') : ''; var fnStr = "\n const xs = arguments[0];\n " + literalKeyExprs + ";\n return {'" + element.attributes.location + "': " + element.attributes.expr + "};\n "; var fn = new Function(fnStr); return fn(xs); }); case 'send': var delay_1 = element.attributes.delay; var numberDelay = delay_1 ? typeof delay_1 === 'number' ? delay_1 : /(\d+)ms/.test(delay_1) ? +/(\d+)ms/.exec(delay_1)[1] : 0 : 0; return actions.send(element.attributes.event, { delay: numberDelay }); default: return { type: 'not-implemented' }; } }); } function toConfig(nodeJson, id, options, extState) { var evalCond = options.evalCond; var parallel = nodeJson.name === 'parallel'; var initial = parallel ? undefined : nodeJson.attributes.initial; var states; var on; var elements = nodeJson.elements; switch (nodeJson.name) { case 'history': { if (!elements) { return { id: id, history: nodeJson.attributes.type || 'shallow' }; } var _a = __read(elements.filter(function (element) { return element.name === 'transition'; }), 1), transitionElement = _a[0]; var target = getAttribute(transitionElement, 'target'); var history_1 = getAttribute(nodeJson, 'type') || 'shallow'; return { id: id, history: history_1, target: target ? "#" + target : undefined }; } case 'final': { return __assign({}, nodeJson.attributes, { type: 'final' }); } default: break; } if (nodeJson.elements) { var stateElements = nodeJson.elements.filter(function (element) { return element.name === 'state' || element.name === 'parallel' || element.name === 'final' || element.name === 'history'; }); var transitionElements = nodeJson.elements.filter(function (element) { return element.name === 'transition'; }); var onEntryElement = nodeJson.elements.find(function (element) { return element.name === 'onentry'; }); var onExitElement = nodeJson.elements.find(function (element) { return element.name === 'onexit'; }); states = indexedRecord(stateElements, function (item) { return "" + item.attributes.id; }); var initialElement = !initial ? nodeJson.elements.find(function (element) { return element.name === 'initial'; }) : undefined; if (initialElement && initialElement.elements.length) { initial = initialElement.elements.find(function (element) { return element.name === 'transition'; }).attributes.target; } else if (!initialElement && stateElements.length) { initial = stateElements[0].attributes.id; } on = utils_1.mapValues(indexedAggregateRecord(transitionElements, function (item) { return (item.attributes ? item.attributes.event || '' : ''); }), function (values) { return values.map(function (value) { var targets = getAttribute(value, 'target'); return __assign({ target: getTargets(targets) }, (value.elements ? executableContent(value.elements) : undefined), (value.attributes && value.attributes.cond ? { cond: evalCond(value.attributes.cond, extState) } : undefined)); }); }); var onEntry = onEntryElement ? mapActions(onEntryElement.elements) : undefined; var onExit = onExitElement ? mapActions(onExitElement.elements) : undefined; return __assign({ id: id }, (initial ? { initial: initial } : undefined), (parallel ? { type: 'parallel' } : undefined), (stateElements.length ? { states: utils_1.mapValues(states, function (state, key) { return toConfig(state, key, options, extState); }) } : undefined), (transitionElements.length ? { on: on } : undefined), (onEntry ? { onEntry: onEntry } : undefined), (onExit ? { onExit: onExit } : undefined)); } return { id: id }; } function toMachine(xml, options) { var json = xml_js_1.xml2js(xml); var machineElement = json.elements.filter(function (element) { return element.name === 'scxml'; })[0]; var dataModelEl = machineElement.elements.filter(function (element) { return element.name === 'datamodel'; })[0]; var extState = dataModelEl ? dataModelEl.elements.reduce(function (acc, element) { acc[element.attributes.id] = element.attributes.expr ? JSON.parse(element.attributes.expr) : undefined; return acc; }, {}) : undefined; return index_1.Machine(__assign({}, toConfig(machineElement, '(machine)', options, extState), { delimiter: options.delimiter }), undefined, extState); } exports.toMachine = toMachine; //# sourceMappingURL=scxml.js.map