Skip to content

Rules ​

Rules are the core building blocks of the Standard Rule Engine. They define the logic that processes facts and updates context.

Creating Rules ​

Rules are created using the rule() method on an engine:

ts
const engine = new Engine().rule("example", (facts, { context }) => {
  // Rule logic here
});

Rule Structure ​

Each rule consists of:

  1. A unique name
  2. A handler function
  3. Optional schema validation
ts
const 
engine
= new
Engine
().
context
("processed", false).
rule
(
"process-user", // Rule name (
facts
, {
context
}) => {
// Handler function
context
.
processed
= true;
}, { // Optional schema
schema
:
z
.
object
({
id
:
z
.
string
(),
name
:
z
.
string
(),
}), }, );

Rule Handlers ​

Rule handlers receive two parameters:

  1. facts: The data to process
  2. options: An object containing context and helpers
ts
const 
engine
= new
Engine
()
.
context
("count", 0)
.
helper
("increment", (
context
) => {
context
.
count
++;
}) .
rule
(
"example", (
facts
, {
context
,
helpers
}) => {
helpers
.
increment
();
console
.
log
(`Processing ${
facts
.
id
}`);
}, {
schema
:
type
({
id
: "string" }),
}, );

Priority ​

Rules can be given a priority to control the order they are executed in. Rules with a lower priority number are executed first. The default priority is 1.

ts
const 
engine
= new
Engine
()
.
rule
(
"alwaysRunFirst", (
_
, {
context
}) => {
console
.
log
("im first");
}, {
priority
: 0,
}, ) .
rule
(
"alwaysRunLast", (
_
, {
context
}) => {
console
.
log
("im last");
}, {
priority
: 100,
}, ); const
session
=
engine
.
createSession
().
insert
({}).
fire
();
// Output: // im first // im last

Schema Validation ​

Rules can specify a schema to validate facts. The schema property can take any schema validation library that implements the Standard Schema.

ts
const 
engine
= new
Engine
().
context
({
isValid
: false }).
rule
(
"validate-user", (
user
, {
context
}) => {
context
.
isValid
= true;
}, {
schema
:
z
.
object
({
id
:
z
.
string
(),
email
:
z
.
string
().
email
(),
age
:
z
.
number
().
min
(18),
}), }, );

Example: User Validation ​

ts
import { 
Engine
} from "standard-rule-engine";
import {
z
} from "zod";
const
userSchema
=
z
.
object
({
id
:
z
.
string
(),
email
:
z
.
string
().
email
(),
age
:
z
.
number
(),
password
:
z
.
string
().
min
(8),
}); const
engine
= new
Engine
()
.
context
({
isValid
: false,
errors
: [] as string[],
}) .
helper
("addError", (
context
,
error
: string) => {
context
.
errors
.
push
(
error
);
}) .
rule
(
"validate-age", (
user
, {
context
,
helpers
}) => {
if (
user
.
age
< 18) {
helpers
.
addError
("User must be at least 18 years old");
} }, {
schema
:
userSchema
},
) .
rule
(
"validate-password", (
user
, {
context
,
helpers
}) => {
if (!/[A-Z]/.
test
(
user
.
password
)) {
helpers
.
addError
("Password must contain at least one uppercase letter");
} if (!/[0-9]/.
test
(
user
.
password
)) {
helpers
.
addError
("Password must contain at least one number");
} }, {
schema
:
userSchema
},
) .
rule
("final-validation", (
_
, {
context
}) => {
context
.
isValid
=
context
.
errors
.
length
=== 0;
}); const
session
=
engine
.
createSession
();
session
.
insert
({
id
: "123",
email
: "user@example.com",
age
: 16,
password
: "weak",
});
session
.
fire
();
console
.
log
(
session
.
context
);
// { // isValid: false, // errors: [ // "User must be at least 18 years old", // "Password must contain at least one uppercase letter", // "Password must contain at least one number" // ] // }