npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rulesengineedited

v0.0.5

Published

Business Rules Engine

Downloads

18

Readme

Since it was trowing some weired issue I have recreated this repositories in my system

BizRez Rules - JavaScript Condition Event Engine

A small functional Rule Engine - simple maybe an understatement...

Intro

Simplicity is elegance. This rule engine is NOT forward chaining, backward chaining, nor is this an inference engine. What it is, is a pragmatic reactive engine. Simply stated, when there is a condition, execute an action -- most assuredly in a stateless manner.

Prime directives, and ables ...

  • Stateless
  • Simple input, output, and process
  • Asynchronous non-blocking invocations
  • Rules to be self contained and serializable to a database (persistable)
  • Rules to be versioned (versionable)
  • Rules to be inventoried and stored in a library (sharable)
  • Rules can be modified on-the-fly (adaptable)
  • Rules can be unit tested independently (testable)
  • Crazy fast

#####Martin Fowler on Rule Engines

// Rule Abilities 
{ables: [persistable, versionable, shareable, adaptable, testable, chainable, reusable, extensible]}

Dependencies

  • Underscore.js for Mapreduce Decision Tables
  • Async.js for asynchronous hooks and behavior
  • Mocha.js for for test infecting the code (good infection)
  • Require.js for the module loader

A few Use Cases for Usage

  • Validations
  • Mappings
  • Calculations
  • Batch processing
  • Automated business rules - decision engine
  • Automation of sequential events and process
  • Home security, sprinkler systems, and darn maybe your car...

Benefits

  • Repository of rules
  • Traceability
  • Modify the rule not the code
  • Dynamic changeability - conditions change so do the execution
  • Easy to understand and modify
  • Extensible
  • Maintainable
  • Reusable
  • Chainable
  • Micro foot print and scalable

Design - IPO (Input Process Output)

// Input - Example Greetings (rules.js - not functional but a conceptual demo)

facts = {
          input: { hour: 10 },
          output: {greeting:''}
         }

// Process - Example Decision Table
rule =  {

                "id": "GREETING",
                "description": "Show correct greeting based on time",
                "condition": function (facts) {
                    // We will calculate the results regardless
                    return true;
                },
                "action": function (facts) {

                    var decisionTable
                        = [
                        {from: 0, to: 11, greeting: 'Good Morning'},
                        {from: 12, to: 17, greeting: 'Good Afternoon'},
                        {from: 18, to: 22, greetings: 'Good Evening'},
                        {from: 23, to: 24, greetings: 'Good Night'}
                    ];

                    var resultArray;

                    // MAP
                    resultArray = _.map(decisionTable, function (row) {
                        var result = "";
                        if (facts.input.hour >= row.from && facts.input.hour <= row.to) {
                            result = row.greeting;
                        }
                        return result;
                    });
                    // Reduce
                    var result = _.reduce(resultArray, function (memory, element) {
                        if (element !== "") {
                            memory = element;
                        }
                        return  memory;
                    });
                    facts.output.greeting = result;

                }
            }
// Output - Example result

facts = {
          input: { hour: 10 },
          output: {greeting:'Good Morning'}
         }

Validation Rules

Setup Example

// Set Up Validate Functions to be used by the validation engine
const _validate = new validate();
const _isDecimal3 = _validate.isDecimal(3);
const _isDecimal4 = _validate.isDecimal(4);
const _isDecimal5 = _validate.isDecimal(5);
const _range5_10 = _validate.range(5, 10);
const _phoneType = _validate.inGroup(['home', 'business']);
const _membership = _validate.inGroup(['Gold', 'Silver', 'Bronze']);

// Setup Phone validation rules
const validationRulesPersonPhones = [
    {key: 'type',   validate: _.isString, error: 'phone.type is not a valid string type'},
    {key: 'type',   validate: _phoneType, error: 'phone.type is not in phone type group'},
    {key: 'number', validate: _.isString, error: 'phone.number invalid'}
];

// Setup Person validation rules
const validationRulesPerson = [

    {key: 'person.firstName', validate: _.isString,  error: 'person.firstName not a string'},
    {key: 'person.lastName',  validate: _.isString , error: 'person.lastName not a string'},
    {key: 'person.DOB',       validate: _.isDate,    error: 'person.DOB invalid'},
    {key: 'person.secret.id', validate: _.isString,   error: 'person.secret.id not a string'},
    {key: 'person.secret.pwd',validate: _.isString,   error: 'person.secret.pwd not a string'},
    {key: 'person.email',     validate: _validate.isEmail,      error: 'person.email is invalid'},
    {key: 'id',               validate: _.isNumber,  error: 'id is not a number'},
    {key: 'dec3',             validate: _isDecimal3, error: 'dec3 is not three decimals'},
    {key: 'dec4',             validate: _isDecimal4, error: 'dec4 is not three decimals'},
    {key: 'dec5',             validate: _isDecimal5, error: 'dec5 is not three decimals'},
    {key: 'num_1',            validate: _range5_10,  error: 'Number is not within range of 5-10'},
    {key: 'membership',       validate: _membership, error: 'Invalid membership'}

];

function getFacts() {
    let obj = {};
    obj.person = {};
    obj.person.firstName = 'Bill';
    obj.person.lastName = 'Joy';
    obj.person.DOB = new Date();
    obj.person.secret = {};
    obj.person.secret.id = 'myId_isSecret';
    obj.person.secret.pwd = 'secret';
    obj.person.phones = [{type: 'home', number: '8675309'}, {type: 'business', number: '8675309'}];
    obj.person.email = '[email protected]';
    obj.id = 12345;
    obj.dec3 = '1.233';
    obj.dec4 = '1.2333';
    obj.dec5 = '1.23333';
    obj.num_1 = 5;
    obj.membership = 'Gold';
    return obj;
}

    // Run Example from testValidate.js
    let errorResults = [];
    // Run validation rules on Person
    errorResults.push(_validate.run(validationRulesPerson, getFacts()));
    // Run validation rules on Persons Phone numbers
    getFacts().person.phones.forEach(function(elem) {
        errorResults.push(_validate.run(validationRulesPersonPhones, elem));
    });
    // Will contain all errors found
    errorResults = _.flatten(errorResults);

Download

The source is available for download from GitHub.

Alternatively, you can install using Node Package Manager npm:

mocha lib/test

mocha lib/test/testValidate.js