Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Evaluation Interface #401

chris-pardy started this conversation in Ideas
Discussion options

Thinking about a next version of this library and I think there needs to be a single type to encapsulate all the things rules and conditions can do. There are 2 potential versions of that.

Almanac on Steroids
This is an interface that encapsulates all the things we know the system can do:

interface Evaluation{
 compare(operator: string, lhs: unknown, rhs: unknown): boolean;
 realizeCondition(condition: string): Promise<ConditionResult>;
 factValue(factName: string, params?: Record<string, unknown>): Promise<unknown>;
 getValue(value: unknown): Promise<unknown>;
 emitEvent(event: Event): void;
}

This approach allows for fairly simple condition classes that read pretty clearly.

async evaluate(evaluation: Evaluation): Promise<ConditionResult> {
 const [factResult, valueResult ] = await Promsei.all([
 evaluation.factValue(this.fact, this.params),
 evaluate.getValue(this.value)
 ]);
 const result = evaluation.compare(this.operator, factResult, valueResult);
 return {
 result,
 fact: this.fact,
 params: this.params,
 factResult,
 operation: this.operator,
 value: this.value,
 valueResult
 }
}

Hyper Generic
If we really wanted to open up the rules engine to extension we could build it on a much more skeletal framework and allow anyone to extend it this could look something like this.

interface EvaluationTarget<TResult, TArgs extends any[]> {
 evaluate(evaluation: Evaluation, ...args: TArgs): TResult;
}
interface Evaluation {
 evaluate<TTarget extends EvaluationTarget<any, any[]>(
 target: TTarget,
 ...args: TTarget extends EvaluationTarget<any, infer TArgs> ? TArgs : never[]
 ): TTarget extends EvaluationTarget<infer TResult, any[]> ? TResult : never;
}

Writing the condition would then be slightly more verbose.

// Evaluation Targets act like plugins
import { factValue, getValue } from 'json-rules-engine/almanac';
import { comparison } from 'json-rules-engine/operator';
// Condition Class
async evaluate(evaluation: Evaluation): Promise<ConditionResult> {
 const [ factResult, valueResult ] = await Promise.all([
 evaluation.evaluate(factValue, this.fact, this.params),
 evaluation.evaluate(getValue, this.value)
 ]);
 const result = evaluation.evaluate(comparison, this.operator, factResult, valueResult);
 return {
 result,
 fact: this.fact,
 params: this.params,
 factResult,
 operation: this.operator,
 value: this.value,
 valueResult
 }
}
You must be logged in to vote

Replies: 1 comment

Comment options

chris-pardy
Nov 18, 2024
Collaborator Author

@emilefokkemanavara core idea for a totally new version

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /