Skip to content

A JavaScript rule engine that models formal propositional logic. It allows you to separate conditional logic from source code and database triggers in a reusable package, where explicit rules can be independently defined and managed.

License

Notifications You must be signed in to change notification settings

commonality/archetypes-rules

Repository files navigation

archetypes-rules

banner

The MIT License NPM version FOSSA Status Known Vulnerabilities
Dependency Status
MacOS and Ubuntu build statuses Windows build status Coveralls test coverage Codacy code quality

Move conditional logic out of source code and database triggers and into a reusable package, where explicit rules can be independently defined and managed.

archetypes-rules models Boolean logic. Instead of writing conditionals like if / else if / else, you can instead create Rules that describe and evaluate Facts (aka, RuleContexts).

Table of Contents

1. Overview

Figure 1: Class diagram for the archetypes.rules namespace.

Figure 1: Class diagram for the archetypes.rules namespace

1.1. Rules

Rules are explicit constraints that govern actions. Rules evaluate Facts, or RuleContexts.

Rules are defined with⏤and stored as⏤JSON.

1.2. RuleElements

Rules contain one or more RuleElements. There are three types of RuleElements: Propositions, Operators, and Variables.

1.2.1. Propositions

Propositions are statements that are either, true, false, or null (unknown). Learn more...

1.2.2. Variables

Variables are symbols that represent the value of something. Learn more...

1.2.3. Operators

Operators: Boolean and quantifier operators.

1.3. RuleContexts (aka "facts")

RuleContexts are facts, stored as JSON in files, databases, etc.

1.4. Rules evaluate RuleContexts/Facts

Rules evaluate RuleContexts. During evaluation, we determine whether a RuleContext/Fact complies with a Rule.

returning a Proposition that tells us whether a given set of facts conform to the defined Rule.

RuleElements are evaluated using Reverse Polish Notation (RPN). See the examples below for details.

Back to Table of contents [toc]

2. Installation

npm install archetypes-rules

Back to Table of contents [toc]

3. Usage

3.1. Example 1: Is this customer eligible for a discount

Suppose we have a very simple rule that checks whether a customer is eligible for a discount. In order to be eligible, the customer simply needs to be a Gold Card holder.

const { Rule, RuleContext } = require('archetypes-rules')

// Create the rule
const rule = new Rule('eligibleForDiscount')

// Add a Proposition, i.e., a statement that has a value of true or false
rule.addProposition('customerIsGoldCardHolder', true)

// Create a RuleContext, i.e., a "Fact"
const ruleContext = RuleContext('eligibleForDiscountContext')

// Provide the truth statement as to whether the actual customer
// has a Gold Card
ruleContext.addProposition('customerIsGoldCardHolder', true)

// Evaluate
const result = rule.evaluate(ruleContext)

// Log the resulting Proposition

// Outputs
// Proposition statement = customerIsGoldCardHolder, value = true

3.2. Example 2: Group discount for six or more people

Say you provide a discount to a group of six or more people:

// Create the rule
const rule = Rule('eligible-for-group-discount')

// Declare a "placeholder" variable for the actual number of people
// (This value will be retrieved from the RuleContext)
rule.addVariable('actual-num-people', null)

// Declare the minimum number of people required for discount
rule.addVariable('min-num-people', 6)

// Compare the two, i.e.,
// actual-num-people >= min-num-people
rule.addOperator(Operator.GREATER_THAN_OR_EQUAL_TO)

// Create a RuleContext, i.e., a "Fact"
const ruleContext = RuleContext('eligible-for-group-discount-fact')

// How many people are there?
ruleContext.addVariable('actual-num-people', 5)

// Declare the "placeholder" minimun number of people required for discount
// (This value will be retrieved from the Rule)
ruleContext.addVariable('min-num-people', 'NULL_NUMBER_VARIABLE')

// Evaluate
const result = rule.evaluate(ruleContext)

// Log the resulting Proposition

// OUTPUT:
// Proposition statement =
// (actualNumPeople >= minNumPeople), value = false

3.3. Example 3: Is an airline passenger eligible for an upgrade?

In this example, we’re determining whether a given airline passenger is eligible to have their coach seat upgraded to a first-class seat. In order to be eligible, a passenger must:

  • Be in economy class now and either
    • Hold a Gold member card or
    • Hold a Silver member card and
  • Their carry-on luggage must be less than or equal to 15.0 pounds.

In order to determine this, we must compare a passenger’s facts with our rule.

const { Rule, RuleContext, RuleElement } = require('archetypes-rules')

// Create the rule
const rule = Rule('eligible-for-upgrade')

// Populate the rule using method chaining
rule
  .addProposition('passenger-is-economy', true)
  .addProposition('passenger-is-gold-card-holder', true)
  .addProposition('passenger-is-silver-card-holder', true)
  .addOperator('OR')
  .addOperator('AND')
  .addVariable('passenger-carry-on-baggage-weight', 'NULL_NUMBER_VARIABLE')
  .addVariable('passenger-carry-on-baggage-allowance', 15.0)
  .addOperator('LESS_THAN_OR_EQUAL_TO')
  .addOperator('AND')

// Create the RuleContext
const fact = RuleContext('eligibleForUpgradeFact')

// Load it with the facts about the passenger
fact
  .addProposition('passengerIsEconomy', true)
  .addProposition('passengerIsGoldCardHolder', true)
  .addProposition('passengerIsSilverCardHolder', false)
  .addVariable('passenger-carry-on-baggage-weight', 10.0)
  .addVariable('passenger-carry-on-baggage-allowance', 'NULL_NUMBER_VARIABLE')

// Log the resulting Proposition

// =>
// Proposition statement = (
//  (passengerIsEconomy AND
//    (passengerIsGoldCardHolder OR passengerIsSilverCardHolder)
//  ) AND (
//    passenger-carry-on-baggage-weight <= passenger-carry-on-baggage-allowance
//  )
// ), value = true

Back to Table of contents [toc]

4. Maintainers

@gregswindle

Information for Maintainers The Maintainer Guide describes how we develop and release archetype-rules (and has useful information for Maintainers and Trusted Committers).

Back to Table of contents [toc]

5. Contributions

GitHub Contributors GitHub GitHub Greenkeeper badge

Gratitude We gratefully accept Pull Requests. Here's what you need to know to get started.

Before submitting a Pull Request, please read our:

Back to Table of contents [toc]

6. License

MIT © 2019 Greg Swindle

Open Source Licenses View the latest detailed legal NOTICE report This link will take you to another Web site.

FOSSA Status

Back to Table of contents [toc]

About

A JavaScript rule engine that models formal propositional logic. It allows you to separate conditional logic from source code and database triggers in a reusable package, where explicit rules can be independently defined and managed.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published