The rule engine can expose rules and expressions as a structured render tree, then turn that tree into formats such as HTML or Mermaid diagrams.
Rendering is read-only. It does not execute rules, mutate context, or change how rules are evaluated.
Core engine APIs and the shared Renderable shape come from the main package, while renderer-specific classes come from the optional @samatawy/rules/render entry point.
import { type Renderable, RuleParser, Workspace } from '@samatawy/rules';
import { HtmlRenderer, MermaidRenderer } from '@samatawy/rules/render';
This keeps rendering and visualization helpers out of the default package surface for consumers that do not need them.
toJson() methodEvery parsed expression and rule exposes toJson() and returns a Renderable object.
Expressions return nodes such as LiteralExpression, VariableExpression, FunctionExpression, ComparisonExpression, LogicalExpression, TernaryExpression, SwitchExpression, and LambdaExpression.
Rules return higher-level shapes such as IfThenRule, IfThenElseRule, OutputRule, CompositeAction, and CommandExecutable.
At a high level, the render tree uses these fields:
type identifies the node.name and value carry literal names and values.operator, left, and right represent binary expressions.arguments and elements represent functions, commands, arrays, and grouped actions.condition, trueExpression, and falseExpression represent rule branches and ternaries.output and expression represent assignment targets.cases and defaultCase represent switch expressions.Example:
import { RuleParser, type Renderable, Workspace } from '@samatawy/rules';
const space = new Workspace();
const parser = new RuleParser({ workspace: space });
const rule = parser.parse('IF total > 100 THEN discount = 0.1');
const ruleJson: Renderable | undefined = rule?.toJson();
const conditionJson = rule?.getExpression().toJson();
The rule-level output is shaped like this:
{
"type": "IfThenRule",
"condition": {
"type": "ComparisonExpression",
"operator": ">",
"left": {
"type": "VariableExpression",
"name": "total"
},
"right": {
"type": "LiteralExpression",
"value": 100
}
},
"trueExpression": {
"type": "OutputAction",
"output": "discount",
"expression": {
"type": "LiteralExpression",
"value": 0.1
}
}
}
This JSON tree is the common input used by the built-in renderers and any custom renderer you write.
The package currently includes two renderers:
Both renderers accept either a full rule or an expression.
IF, THEN, ELSE, SET, and command structure.Use toJson() directly when you want to:
If you need a custom output format, see Contributing for guidance on creating a custom renderer.