Skip to main content
This page is for contributors who want to understand or modify the source code.

Source Structure

src/
├── index.js                 # Public exports
├── core/
│   ├── RuleEngine.js        # Main engine
│   ├── PathResolver.js      # Path resolution
│   ├── StatefulRuleEngine.js
│   ├── concurrency/         # Queue management
│   ├── history/             # State history
│   └── recovery/            # Error handling
├── operators/               # All operators
├── helpers/                 # RuleHelpers fluent API
└── utils/                   # TypeUtils, errors

Layer Architecture


RuleEngine Internals

Operator Registry

Operators are stored in a Map:
// Registration
engine.operators.set('eq', {
  handler: (args, ctx) => { ... },
  options: { minArgs: 2 }
});

// Lookup
const op = engine.operators.get('eq');
op.handler(args, context);

Cache Key Generation

Context ID is derived from:
  1. Explicit _id field
  2. Explicit id field
  3. Hash of context values

Operator Execution

All operators follow this signature:
handler(args, context, evaluateExpr, depth) → boolean
ParamPurpose
argsOperator arguments from rule
contextData + _previous + _meta
evaluateExprCallback for nested rules
depthCurrent nesting level

Example: eq operator

function eq(args, context, evaluateExpr, depth) {
  const [left, right] = args;

  const leftVal = pathResolver.resolve(context, left);
  const rightVal = pathResolver.resolve(context, right);

  return leftVal === rightVal;
}

StatefulRuleEngine Pipeline


Concurrency Strategies

StrategyUse case
ParallelDefault, max throughput
SequentialOrder matters
Per-RuleIsolate rule execution

Error Recovery

Three components work together:

Circuit Breaker States

Retry Strategies

StrategyDelay pattern
Exponential100 → 200 → 400 → 800ms
Fixed100 → 100 → 100 → 100ms
Linear100 → 200 → 300 → 400ms

History Managers

Use PerRuleHistoryManager for production with multiple rules.

Security Checks

PathResolver blocks these patterns:
// Blocked paths
'__proto__'; // Prototype pollution
'constructor'; // Constructor access
'prototype'; // Prototype chain

// Blocked access
typeof value === 'function'; // No function calls
!obj.hasOwnProperty(key); // Only own properties

Depth & Complexity Limits

LimitDefaultPurpose
maxDepth10Prevent infinite nesting
maxOperators100Prevent DoS
maxCacheSize1000Memory limit

Design Patterns

PatternWhere
StrategyHistory, Concurrency, Retry managers
FactorycreateRuleEngine(), createRuleHelpers()
ObserverEvent system in StatefulRuleEngine
DecoratorStatefulRuleEngine wraps RuleEngine
Chain of ResponsibilityError recovery pipeline

Key Files

FileLinesResponsibility
RuleEngine.js~400Core evaluation
StatefulRuleEngine.js~600State + events
PathResolver.js~200Safe path access
ErrorRecoveryManager.js~300Recovery orchestration

Contributing