DMN decision and FEEL language interpreter written in JavaScript.
$ npm install imicros-feel-interpreter
const { Decision } = require("imicros-feel-interpreter");
const fs = require("fs");
const decision = new Decision();
let exampleFilePath = "./assets/Camunda/Credit limit.dmn" // Path to .dmn file (XML file)
let xmlData = fs.readFileSync(exampleFilePath).toString();
let success = decision.parse({ xml: xmlData });
if (success) {
decision.setAst(JSON.parse(JSON.stringify(decision.getAst()))); // you can store the parsed ast also in a database for faster execution
let result = decision.evaluate({ // parse your execution data as parameter
"Credit Score": 4.5,
"Turnover": 200000,
Customer: {
"Bonität": "well"
}
});
// {
// 'Credit Limit': 240000
// }
}
const { Decision } = require("imicros-feel-interpreter");
const fs = require("fs");
const util = require('util');
const decision = new Decision();
let exampleFilePath = "./assets/Camunda/Credit limit.dmn" // Path to .dmn file (XML file)
let xmlData = fs.readFileSync(exampleFilePath).toString();
let success = decision.parse({ xml: xmlData });
if (success) {
decision.setAst(JSON.parse(JSON.stringify(decision.getAst()))); // you can store the parsed ast also in a database for faster execution
let result = decision.analyse({ // parse your execution data as parameter
"Season": "Spring",
"Number of Guests": 3,
"Guests with children?": true
});
console.log(util.inspect(result.result, { showHidden: false, depth: null, colors: true }));
console.log(util.inspect(result.log, { showHidden: false, depth: null, colors: true })); // returns in addition a log of the execuition
/*
{
log: [
{ type: 'Input', name: 'Season', value: 'Spring' },
{ type: 'Input', name: 'Number of Guests', value: 3 },
{ type: 'Input', name: 'Guests with children?', value: true },
{
type: 'Rule',
decisionTable: 'Dish',
index: 0,
annotation: 'Default value',
steps: [
{
name: 'Season',
value: 'Spring',
expression: 'not("Fall", "Winter", "Spring", "Summer")',
result: false
},
{
name: 'How many guests',
value: 3,
expression: '>= 0',
result: true
}
],
result: false,
output: {}
},
{
type: 'Rule',
decisionTable: 'Dish',
index: 1,
annotation: '',
...
],
result: false,
output: {}
},
{
type: 'Decisiontable',
name: 'Beverages',
hitPolicy: 'Collect',
inputs: [
{ name: 'Dish', value: 'Dry Aged Gourmet Steak' },
{ name: 'Guests with children', value: true }
],
output: { beverages: [ 'Pinot Noir', 'Apple Juice' ] }
}
],
result: { beverages: [ 'Pinot Noir', 'Apple Juice' ] }
}
*/
}
const { Interpreter } = require("imicros-feel-interpreter");
const interpreter = new Interpreter();
/*** parse and evaluate in a single step ***/
let result = interpreter.evaluate("a/b**-c-d",{a:1,b:2,c:4,d:3});
// 13
/*** or in two steps: parse single evaluate multiple***/
let success = interpreter.parse("a/b**-c-d");
// true
let serialized = JSON.stringify(interpreter.ast);
interpreter.ast = JSON.parse(serialized);
// serialized ast can be stored somewhere and restored for multiple usage with different data sets
let result = interpreter.evaluate({a:1,b:2,c:4,d:3});
// 13
const { DMNParser, DMNConverter } = require("imicros-feel-interpreter");
const fs = require("fs");
const xmlData = fs.readFileSync(./assets/Sample.dmn).toString();
const expression = new DMNConverter().convert({ xml: xmlData });
- Complete support of DMN 1.4. Known restrictions see below.
- Provide build-in functions as listed in the examples.
- Additional name symbols ./-+* according rule 30. of the sepcification as well as keywords for,return,if,true,false,in,and,or,between,some,every,then,else,not,string,number,boolean,null,date,time,duration in names are not supported.
(The package uses nearley as parser and I didn't found a way to implement the ambiguity).
White spaces are allowed and normalized (doubled spaces will be replaced by just one space). Therefore expresssions like {"new example": 5}.new example as well as { "new example": 5}.new example will work.
Beside white spaces the special characters _?' which are not used as operators are allowed. - No external functions are supported.
In case of intensive usage with large number of data sets consider the pre-parsing possibility.
A simple expression if even(i) then (i*a) else (i*b)
with parsing and evaluation in one step evaluates 2.500 data sets per second and with a single parsing you can evaluate up to 200.000 data sets per second on an average hardware with single thread processing.
Camunda open source desktop editor https://camunda.com/de/download/modeler/
BPMN.iO open source embedded web-based modelling https://bpmn.io/
Redhat Visual Studio Code Extension https://marketplace.visualstudio.com/items?itemName=redhat.vscode-extension-dmn-editor