Constructor
Create a stateful engine that tracks state changes and emits events.
import { createRuleEngine , StatefulRuleEngine } from 'rule-engine-js' ;
const baseEngine = createRuleEngine ();
const statefulEngine = new StatefulRuleEngine ( baseEngine , options );
Parameters
Base rule engine instance
Trigger on every state change (default: only false → true)
evaluate()
Evaluate rule with state tracking and event emission.
const result = statefulEngine . evaluate ( ruleId , rule , context , options );
Parameters
Unique identifier for this rule
Returns
{
success : boolean ; // Rule passed/failed
triggered : boolean ; // Whether event was triggered
hasChangeOperator : boolean ; // Rule contains change operators
stateChange : string | null ; // 'triggered', 'untriggered', null
value ?: any ; // Evaluation result
error ?: string ; // Error if failed
}
Example
const rule = {
and: [
{ gte: [ 'temperature' , 25 ] },
{ increased: [ 'temperature' ] }
]
};
// First evaluation
statefulEngine . evaluate ( 'temp-rule' , rule , { temperature: 20 });
// { success: false, triggered: false }
// Second evaluation
statefulEngine . evaluate ( 'temp-rule' , rule , { temperature: 26 });
// { success: true, triggered: true }
// Emits 'triggered' event
evaluateBatch()
Evaluate multiple rules at once.
const results = statefulEngine . evaluateBatch ( rules , context , options );
Parameters
Object mapping rule IDs to rule expressions
Returns
Object with results for each rule.
Example
const rules = {
'temp-high' : { gte: [ 'temperature' , 30 ] },
'temp-changed' : { changed: [ 'temperature' ] },
'temp-increased' : { increased: [ 'temperature' ] }
};
const results = statefulEngine . evaluateBatch ( rules , { temperature: 28 });
// {
// 'temp-high': { success: false, triggered: false },
// 'temp-changed': { success: true, triggered: true },
// 'temp-increased': { success: true, triggered: true }
// }
Event System
on()
Register event listener.
statefulEngine . on ( event , callback );
Events:
'triggered' - Rule changed from false → true
'untriggered' - Rule changed from true → false
'changed' - Any state change
'evaluated' - Every evaluation
Example
statefulEngine . on ( 'triggered' , ( event ) => {
console . log ( `Rule ${ event . ruleId } triggered!` );
console . log ( 'Current:' , event . context );
console . log ( 'Previous:' , event . previousContext );
});
statefulEngine . on ( 'changed' , ( event ) => {
console . log ( `Rule ${ event . ruleId } state changed` );
});
statefulEngine . on ( 'evaluated' , ( event ) => {
console . log ( `Rule ${ event . ruleId } evaluated:` , event . result );
});
Event Data
{
ruleId : string ;
rule : object ;
context : object ;
previousContext : object | null ;
result : object ;
previousResult : object | null ;
triggered : boolean ;
timestamp : string ; // ISO 8601
}
off()
Remove event listener.
const handler = ( event ) => { /* ... */ };
statefulEngine . on ( 'triggered' , handler );
statefulEngine . off ( 'triggered' , handler );
getHistory()
Get evaluation history for a rule.
const history = statefulEngine . getHistory ( ruleId );
Parameters
Rule ID to get history for
Returns
Array of evaluation events (if storeHistory: true).
Example
// Enable history
const engine = new StatefulRuleEngine ( baseEngine , {
storeHistory: true ,
maxHistorySize: 50
});
// After some evaluations
const history = engine . getHistory ( 'temp-rule' );
console . log ( ` ${ history . length } evaluations found` );
clearState()
Clear stored state.
// Clear specific rule
statefulEngine . clearState ( 'temp-rule' );
// Clear all rules
statefulEngine . clearState ();
Complete Example
import { createRuleEngine , StatefulRuleEngine } from 'rule-engine-js' ;
// Create engines
const baseEngine = createRuleEngine ();
const statefulEngine = new StatefulRuleEngine ( baseEngine , {
triggerOnEveryChange: false ,
storeHistory: true ,
maxHistorySize: 100
});
// Setup event listeners
statefulEngine . on ( 'triggered' , ( event ) => {
console . log ( `🔥 Alert: ${ event . ruleId } ` );
sendAlert ( event . context );
});
statefulEngine . on ( 'changed' , ( event ) => {
console . log ( `📊 State changed: ${ event . ruleId } ` );
logChange ( event );
});
// Define rules
const rules = {
'temp-critical' : {
and: [
{ gte: [ 'temperature' , 30 ] },
{ increased: [ 'temperature' ] }
]
},
'inventory-low' : {
and: [
{ decreased: [ 'stock' ] },
{ lte: [ 'stock' , 10 ] }
]
},
'price-drop' : {
and: [
{ decreased: [ 'price' ] },
{ changedBy: [ 'price' , 5 ] }
]
}
};
// Evaluate batch
const results = statefulEngine . evaluateBatch ( rules , {
temperature: 31 ,
stock: 8 ,
price: 45
});
// Check history
const tempHistory = statefulEngine . getHistory ( 'temp-critical' );
console . log ( `History: ${ tempHistory . length } entries` );
// Clear state when needed
statefulEngine . clearState ( 'temp-critical' );
Triggering Modes
Default Mode (false → true)
const engine = new StatefulRuleEngine ( baseEngine , {
triggerOnEveryChange: false // default
});
// Only triggers when state changes from false to true
Every Change Mode
const engine = new StatefulRuleEngine ( baseEngine , {
triggerOnEveryChange: true
});
// Triggers on any state change (true ↔ false)
Use Cases
Temperature Monitoring
Order Status Tracking
Price Drop Alerts
statefulEngine . on ( 'triggered' , ( event ) => {
if ( event . ruleId === 'temp-high' ) {
sendAlert ( 'Temperature exceeded threshold' );
}
});
const rule = {
and: [
{ gte: [ 'temperature' , 30 ] },
{ increased: [ 'temperature' ] }
]
};
statefulEngine . evaluate ( 'temp-high' , rule , sensorData );
TypeScript
import { StatefulRuleEngine } from 'rule-engine-js' ;
import type { StatefulEngineOptions , EventData } from 'rule-engine-js' ;
const options : StatefulEngineOptions = {
triggerOnEveryChange: false ,
storeHistory: true ,
maxHistorySize: 100
};
const engine = new StatefulRuleEngine ( baseEngine , options );
engine . on ( 'triggered' , ( event : EventData ) => {
console . log ( event . ruleId );
});