Skip to content

Commit

Permalink
Merge pull request #127 from mithunsatheesh/8.0.0
Browse files Browse the repository at this point in the history
8.0.0
  • Loading branch information
nikollatesla authored Feb 24, 2023
2 parents 96d7c91 + e653b28 commit eefafb0
Show file tree
Hide file tree
Showing 19 changed files with 1,914 additions and 2,161 deletions.
47 changes: 25 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ A rule will consist of a condition and its corresponding consequence. You can fi

``` js
{
"condition" : function(R) {
R.when(this.transactionTotal < 500);
"condition" : (R, fact) => {
R.when(fact.transactionTotal < 500);
},
"consequence" : function(R) {
this.result = false;
"consequence" : (R, fact) => {
fact.result = false;
R.stop();
}
}
Expand All @@ -56,32 +56,33 @@ Facts are those input json values on which the rule engine applies its rule to o

A sample Fact may look like

{
"name":"user4",
"application":"MOB2",
"transactionTotal":400,
"cardType":"Credit Card",
}
``` json
{
"name":"user4",
"application":"MOB2",
"transactionTotal":400,
"cardType":"Credit Card",
}
````

###### 3. Using the Rule Engine

The example below shows how to use the rule engine to apply a sample rule on a specific fact. Rules can be fed into the rule engine as Array of rules or as an individual rule object.

``` js
var RuleEngine = require("node-rules");
import RuleEngine from "node-rules";

/* Creating Rule Engine instance */
var R = new RuleEngine();
const R = new RuleEngine();

/* Add a rule */
var rule = {
"condition": function(R) {
console.log(this);
R.when(this.transactionTotal < 500);
const rule = {
"condition": (R, fact) => {
R.when(fact.transactionTotal < 500);
},
"consequence": function(R) {
this.result = false;
this.reason = "The transaction was blocked as it was less than 500";
"consequence": (R, fact) => {
fact.result = false;
fact.reason = "The transaction was blocked as it was less than 500";
R.stop();
}
};
Expand All @@ -90,20 +91,22 @@ var rule = {
R.register(rule);

/* Add a Fact with less than 500 as transaction, and this should be blocked */
var fact = {
let fact = {
"name": "user4",
"application": "MOB2",
"transactionTotal": 400,
"cardType": "Credit Card"
};

/* Check if the engine blocks it! */
R.execute(fact, function (data) {
if (data.result) {
R.execute(fact, (data) => {

if (data.result !== false) {
console.log("Valid transaction");
} else {
console.log("Blocked Reason:" + data.reason);
}

});
```

Expand Down
7 changes: 4 additions & 3 deletions __tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../index');
import RuleEngine from '../';

describe("Rules", function() {
describe(".init()", function() {
it("should empty the existing rule array", function() {
Expand Down Expand Up @@ -251,10 +252,10 @@ describe("Rules", function() {

it("should support fact as optional second parameter for es6 compatibility", function() {
var rule = {
"condition": function(R, fact) {
"condition": (R, fact) => {
R.when(fact && (fact.transactionTotal < 500));
},
"consequence": function(R, fact) {
"consequence": (R, fact) => {
fact.result = false;
R.stop();
}
Expand Down
2 changes: 1 addition & 1 deletion dist/node-rules.min.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/Dynamic-Control.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,24 @@ The above `prioritize` call will give priority to Rule with id "one" over all th
##### 3. `RuleEngine.register(<rules>)`
We know that we can pass Rules as parameter into the Rule Engine constructor while we create the Rule Engine object like below.

var RuleEngine = new RuleEngine(rules);
const RuleEngine = new RuleEngine(rules);

Where `rules` can be either an array of rule objects or a single array. But what if we need to add some rules later to the Rule Engine. Register can be used any time to append new rules into the Rule Engine. It can be used like.

var RuleEngine = new RuleEngine();
const RuleEngine = new RuleEngine();
RuleEngine.register(newrule);
RuleEngine.register(newrule);


##### 4. `RuleEngine.findRules(<filter>)`
This function is used to retrieve the Rules which are registered on the Rule engine which matches the filter we pass as its parameter. A sample usage can be like below.

var rules = RuleEngine.findRules({"id": "one"});
const rules = RuleEngine.findRules({"id": "one"});

##### 5. `RuleEngine.init()`
This function is used to remove all the rules registered on the Rule Engine. This is mostly used for rule clean up purposes by internal functions. A sample usage can be like below.

var RuleEngine = new RuleEngine();
const RuleEngine = new RuleEngine();
RuleEngine.register(badrule);
RuleEngine.init();//removes the bad rule and cleans up
RuleEngine.register(newrule);
Expand Down
18 changes: 9 additions & 9 deletions docs/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ The example below shows how to use the rule engine to apply a sample rule on a s

``` js
//import the package
var RuleEngine = require('node-rules');
import RuleEngine from 'node-rules';

//define the rules
var rules = [{
"condition": function(R) {
R.when(this && (this.transactionTotal < 500));
const rules = [{
"condition": (R, fact) => {
R.when(fact && (fact.transactionTotal < 500));
},
"consequence": function(R) {
this.result = false;
"consequence": (R, fact) => {
fact.result = false;
R.stop();
}
}];
/*as you can see above we removed the priority
and on properties for this example as they are optional.*/

//sample fact to run the rules on
var fact = {
let fact = {
"userIP": "27.3.4.5",
"name":"user4",
"application":"MOB2",
Expand All @@ -28,10 +28,10 @@ var fact = {
};

//initialize the rule engine
var R = new RuleEngine(rules);
const R = new RuleEngine(rules);

//Now pass the fact on to the rule engine for results
R.execute(fact,function(result){
R.execute(fact, (result) => {

if(result.result)
console.log("\n-----Payment Accepted----\n");
Expand Down
80 changes: 0 additions & 80 deletions docs/Exporting-and-Importing-Rules.md

This file was deleted.

19 changes: 10 additions & 9 deletions docs/Rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ Lets see how a sample rule will look like and then proceed to explain the differ
"name": "transaction minimum",
"priority": 3,
"on" : true,
"condition": function(R) {
R.when(this.transactionTotal < 500);
"condition": (R, fact) => {
R.when(fact.transactionTotal < 500);
},
"consequence": function(R) {
this.result = false;
"consequence": (R, fact) => {
fact.result = false;
R.stop();
}
}

Above is a sample rule which has mandatory as well as optional parameters. You can choose to use which all attributes you need to use while defining your rule. Now lets look into the attributes one by one.

###### 1. condition
Condition is a function where the user can do the checks on the fact provided. The fact variable will be available in `this` context of the condition function. Lets see a sample condition below.
Condition is a function where the user can do the checks on the fact provided. The fact variable will be available in `this` context of the condition function or as second function argument incase you are using arrow functions. Lets see a sample condition below.

"condition": function(R) {
"condition": (R, fact) => {
R.when(this.transactionTotal < 500);
}

Expand All @@ -29,12 +29,13 @@ As you can see, the we have to pass an expression on to the `R.when` function wh
Its mandatory to have this field.

###### 2. consequence
The consequence is the part where we define what happens when the condition evaluates to true for a particular fact. Just like in condition, fact variable will be available in `this` context. You may utilize it to add extra result attributes if needed.
The consequence is the part where we define what happens when the condition evaluates to true for a particular fact. Just like in condition, fact variable will be available in `this` context or as second function argument incase you are using arrow functions. You may utilize it to add extra result attributes if needed.

"consequence": function(R) {
this.result = false;
"consequence": (R, fact) {
fact.result = false;
R.stop();
}

In the above example we use an additional parameter `result` to communicate to the code outside the rule engine that the fact has succeeded. Also the Rule API provides a number of functions here to control the flow of the rule engine. They are `R.stop()`, `R.restart()` and `R.next()`. Stop refers to stop processing the rule engine. Restart tells the rule engine to start applying all the rules again to the fact. Next is to instruct the rule engine to continue applying the rest of the rules to the fact before stopping. Check [Flow Control API](https://github.com/mithunsatheesh/node-rules/wiki/Flow-Control-API) in wiki to read more about this.

You can read more about flow control API here.
Expand Down
1 change: 0 additions & 1 deletion docs/_Sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
* [Facts](https://github.com/mithunsatheesh/node-rules/wiki/Facts)
* [Flow Control API](https://github.com/mithunsatheesh/node-rules/wiki/Flow-Control-API)
* [Dynamic control](https://github.com/mithunsatheesh/node-rules/wiki/Dynamic-Control)
* [Export/Import Rules](https://github.com/mithunsatheesh/node-rules/wiki/Exporting-and-Importing-Rules)
* [Examples](https://github.com/mithunsatheesh/node-rules/wiki/Examples)
3 changes: 2 additions & 1 deletion examples/node.js/1.SimpleRule.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../../index');
import RuleEngine from '../../lib/node-rules.js';

/* Sample Rule to block a transaction if its below 500 */
var rule = {
"condition": function(R) {
Expand Down
3 changes: 2 additions & 1 deletion examples/node.js/2.MultipleRules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../../index');
import RuleEngine from '../../lib/node-rules.js';

/* Set of Rules to be applied
First blocks a transaction if less than 500
Second blocks a debit card transaction.*/
Expand Down
3 changes: 2 additions & 1 deletion examples/node.js/3.CascadingRules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../../index');
import RuleEngine from '../../lib/node-rules.js';

/* Here we can see a rule which upon matching its condition,
does some processing and passes it to other rules for processing */
var rules = [{
Expand Down
3 changes: 2 additions & 1 deletion examples/node.js/4.PrioritizedRules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../../index');
import RuleEngine from '../../lib/node-rules.js';

/* Set of Rules to be applied */
var rules = [{
"priority": 4,
Expand Down
3 changes: 2 additions & 1 deletion examples/node.js/5.RecurssionWithRules.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var RuleEngine = require('../../index');
import RuleEngine from '../../lib/node-rules.js';

/* Sample Rule to block a transaction if its below 500 */
var rule = {
"condition": function(R) {
Expand Down
Loading

0 comments on commit eefafb0

Please sign in to comment.