UNPKG

@o3r/rules-engine

Version:

This module provides a rule engine that can be executed on your Otter application to customize your application (translations, placeholders and configs) based on a json file generated by your CMS.

1,222 lines (1,198 loc) 71.2 kB
import * as i0 from '@angular/core'; import { PipeTransform, ModuleWithProviders, InjectionToken } from '@angular/core'; import * as rxjs from 'rxjs'; import { Observable, BehaviorSubject } from 'rxjs'; import * as _o3r_core from '@o3r/core'; import { RulesEngineAction, ItemIdentifier, Logger, DevtoolsCommonOptions, OtterMessageContent, MessageDataTypes, ConnectContentMessage, RequestMessagesContentMessage, DevtoolsServiceInterface, AsyncStoreItem, SetActionPayload, UpdateActionPayload, AsyncRequest, SetAsyncStoreItemEntitiesActionPayload, FailAsyncStoreItemEntitiesActionPayload, FromApiActionPayload, Serializer, RulesEngineActionHandler } from '@o3r/core'; import * as _o3r_rules_engine from '@o3r/rules-engine'; import * as i3 from '@o3r/logger'; import { Logger as Logger$1 } from '@o3r/logger'; import * as i1 from '@angular/common'; import * as _ngrx_store from '@ngrx/store'; import { ActionReducer, Action, ReducerTypes, ActionCreator, Store } from '@ngrx/store'; import * as _ngrx_entity from '@ngrx/entity'; import { EntityState } from '@ngrx/entity'; import * as _ngrx_effects from '@ngrx/effects'; import { Actions } from '@ngrx/effects'; /** Represents all the supported facts types TOCHECK utils.Date vs Date */ type Facts = string | number | boolean | null | Date | Record<string, unknown> | unknown[]; /** Fact basic value type */ type FactBasicValues = number | boolean | string | string[] | boolean[] | number[] | undefined; /** Map of fact name / type pairs */ interface FactDefinitions { [factName: string]: unknown; } /** Return type of a fact factory */ type FactFactoryReturn<T> = Observable<T> | Promise<T> | T; /** Set of facts */ type FactSet<T extends FactDefinitions> = { [P in keyof T]: FactFactoryReturn<T[P] | undefined | null>; }; /** Fact stream type */ type FactValueStream<T = unknown> = Observable<T | undefined>; /** Fact stream */ interface Fact<T = unknown> { /** Fact ID */ id: string; /** Stream of the fact fact value */ value$: FactValueStream<T>; } /** * Rule Engine operator */ interface Operator<LeftExposed = unknown, RightExposed = unknown, LeftSupported = LeftExposed, RightSupported = RightExposed> { /** Operator name to use in condition */ name: string; /** Priority in the dropdown display */ orderingWeight?: number; /** Left Hand Value validator function */ validateLhs?: unknown extends LeftSupported ? (operand: unknown) => boolean : (operand: unknown) => operand is LeftSupported; /** Right Hand Value validator function */ validateRhs?: unknown extends RightSupported ? (operand: unknown) => boolean : (operand: unknown) => operand is RightSupported; /** Evaluate the values */ evaluator: (lhs: LeftSupported, rhs: RightSupported, operatorFactValues?: Record<string, Facts>) => boolean; /** List of facts names that the operator can depend on */ factImplicitDependencies?: string[]; } /** * Rule Engine unary operator */ interface UnaryOperator<L = unknown> { /** Operator name to use in condition */ name: string; /** Left Hand Value validator function */ validateLhs?: unknown extends L ? (operand: unknown) => boolean : (operand: unknown) => operand is L; /** Evaluate the values */ evaluator: (lhs: L) => boolean; } /** * Alias for supported simple types in AEM to be used in the operators to avoid repetition of the * (string | boolean | Date | number) * This type reference is specifically handled by the rule operator extractor. */ type SupportedSimpleTypes = string | boolean | Date | number | null | undefined; /** * Any input that can be used as single parameter for Date constructor (Date, string, number) */ type DateInput = Date | string | number; /** * Execute Operator * @param lhs Left hand side * @param rhs Right hand side * @param operator Operator to compare values * @param operatorFacts Facts that operator can depend on */ declare function executeOperator<L = unknown, R = unknown>(lhs: L, rhs: R, operator: Operator<L, R>, operatorFacts?: Record<string, Facts | undefined>): boolean; /** * Validate a number operand * @param operand value of one of the operands */ declare function numberValidator(operand: unknown): operand is number | string; /** * Validate an operand is a range of numbers * @param operatorInput value of one of the operands */ declare function isRangeNumber(operatorInput: unknown): operatorInput is [number | string, number | string]; /** * Verifies if the parameter is a valid date for the operator (getTime function available returning a number) * @param operatorInput */ declare const isValidDate: (operatorInput: any) => operatorInput is Date; /** * Verifies if the parameter is a valid input for Date constructor (new Date returns a valid date) * @param operatorInput */ declare const isValidDateInput: (operatorInput: any) => operatorInput is DateInput; /** * Verifies if the parameter is a valid date range * @param operatorInput */ declare const isValidDateRange: (operatorInput: any) => operatorInput is [DateInput, DateInput]; /** * Verifies if the parameter is a valid time input * @param operatorInput */ declare const isValidTimeInput: (operatorInput: any) => operatorInput is string; /** * Verifies if the parameter is a valid time range * @param operatorInput */ declare const isValidTimeRange: (operatorInput: any) => operatorInput is [string, string]; /** * Validate that a value is a supported simple type * @param value value to validate */ declare function isSupportedSimpleTypes(value: unknown): value is SupportedSimpleTypes; /** * Validate that a value is a string * @param value */ declare function isString(value: unknown): value is string; /** * Parse input to return RegExp * @param inputRegExp */ declare function parseRegExp(inputRegExp: string): RegExp; /** * Check if any of the variable's value is equal to a specific value * @title contains */ declare const arrayContains: Operator<SupportedSimpleTypes[], SupportedSimpleTypes>; /** * Check if the specified text value is included in the text variable * @title contains */ declare const stringContains: Operator<string, string>; /** * Check if every value of the variable is different from a specific value * @title does not contain */ declare const notArrayContains: Operator<SupportedSimpleTypes[], SupportedSimpleTypes>; /** * Check if the specified text value is not included in the text variable * @title does not contain */ declare const notStringContains: Operator<string, string>; /** * Check if every value of the variable equals a specific value * @title all equal to */ declare const allEqual: Operator<SupportedSimpleTypes[], SupportedSimpleTypes>; /** * Check if every numerical value of the variable is greater than a specific value * @title all > */ declare const allGreater: Operator<SupportedSimpleTypes[], number | string>; /** * Check if every value of the variable is in a specific list * @title all in */ declare const allIn: Operator<SupportedSimpleTypes[], SupportedSimpleTypes[]>; /** * Check if every value of the variable is not in a specific list * @title none in */ declare const allNotIn: Operator<SupportedSimpleTypes[], SupportedSimpleTypes[]>; /** * Check if every numerical value of the variable is lower than a specific value * @title all < */ declare const allLower: Operator<number[], number | string>; /** * Check if every string value of the variable matches a specific pattern * @title all match */ declare const allMatch: Operator<string[], string>; /** * Check if every value of the variable is included in a specified range * @title all between */ declare const allRangeNumber: Operator<number[], [number | string, number | string]>; /** * Check if at least one of the values of the variable equals a specific value * @title one equal to */ declare const oneEquals: Operator<SupportedSimpleTypes[], SupportedSimpleTypes>; /** * Check if one of the values of the variable is greater than a specific value * @title one > */ declare const oneGreater: Operator<number[], number | string>; /** * Check if at least one of the values of the variable is equal to one in a specified list * @title one in */ declare const oneIn: Operator<SupportedSimpleTypes[], SupportedSimpleTypes[]>; /** * Check if one of the values of the variable is lower than a specific value * @title one < */ declare const oneLower: Operator<number[], number | string>; /** * Check if one of the values of the variable matches a specific pattern * @title one matches */ declare const oneMatches: Operator<string[], string>; /** * Check if one of the values of the variable is included in a specified range * @title one between */ declare const oneRangeNumber: Operator<number[], [number | string, number | string]>; /** * Check if the number of values of the variable is equal to a specific value * @title number of = */ declare const lengthEquals: Operator<any[], number | string>; /** * Check if the number of values of the variable is different from a specific value * @title number of ≠ */ declare const lengthNotEquals: Operator<any[], number | string>; /** * Check if the number of values of the variable is lower or equal to a specific value * @title number of ≤ */ declare const lengthLessThanOrEquals: Operator<any[], number | string>; /** * Check if the number of values of the variable is lower than a specific value * @title number of < */ declare const lengthLessThan: Operator<any[], number | string>; /** * Check if the number of values of the variable is greater or equal to a specific value * @title number of ≥ */ declare const lengthGreaterThanOrEquals: Operator<any[], number | string>; /** * Check if the number of values of the variable is greater than a specific value * @title number of > */ declare const lengthGreaterThan: Operator<any[], number | string>; /** List of all default array operators */ declare const arrayBasedOperators: (Operator<SupportedSimpleTypes[], SupportedSimpleTypes, SupportedSimpleTypes[], SupportedSimpleTypes> | Operator<string, string, string, string> | Operator<SupportedSimpleTypes[], string | number, SupportedSimpleTypes[], string | number> | Operator<SupportedSimpleTypes[], SupportedSimpleTypes[], SupportedSimpleTypes[], SupportedSimpleTypes[]> | Operator<number[], string | number, number[], string | number> | Operator<string[], string, string[], string> | Operator<number[], [string | number, string | number], number[], [string | number, string | number]> | Operator<any[], string | number, any[], string | number>)[]; /** * Check if a variable is equal to a specific value * @title is equal to */ declare const equals: Operator; /** * Check if a variable is different from a specific value * @title is not equal to */ declare const notEquals: Operator; /** * Check if the variable's value is included in a specified list * @title is in */ declare const inArray: Operator<SupportedSimpleTypes, SupportedSimpleTypes[]>; /** * Check if the variable's value is not included in the value list * @title is not in */ declare const notInArray: Operator<SupportedSimpleTypes, SupportedSimpleTypes[]>; /** * Check if the text variable is part of the specified value * @title within */ declare const inString: Operator<string, string>; /** * Check if the text variable is not part of the specified value * @title not within */ declare const notInString: Operator<string, string>; /** * Check if the variable and its value are defined * @title is defined */ declare const isDefined: UnaryOperator<any>; /** * Check if the variable and its value are undefined * @title is not defined */ declare const isUndefined: UnaryOperator<any>; /** * Check if the text variable matches the specified RegExp pattern * @title matches the pattern */ declare const matchesPattern: Operator<string, string>; /** List of all default basic operators */ declare const basicOperators: (Operator<string, string, string, string> | Operator<unknown, unknown, unknown, unknown> | Operator<SupportedSimpleTypes, SupportedSimpleTypes[], SupportedSimpleTypes, SupportedSimpleTypes[]> | UnaryOperator<any>)[]; /** * Check if a date variable is in a specified date range * @title is between */ declare const inRangeDate: Operator<Date, [DateInput, DateInput], DateInput>; /** * Check if the value of the variable is in the next x minutes * @title is in next minutes * @returns false for dates before `now` and for dates after `now` + `nextMinutes`, true for dates between `now` and `now` + `nextMinutes` */ declare const dateInNextMinutes: Operator<Date, number, DateInput, string | number>; /** * Check if the value of the variable is not in the next x minutes * @title is not in next minutes * @returns false for dates before `now` and for dates between `now` and `now` + `nextMinutes`, true for dates after `now` + `nextMinutes` */ declare const dateNotInNextMinutes: Operator<Date, number, DateInput, string | number>; /** * Check if a date variable is prior than a specified date * @title is before */ declare const dateBefore: Operator<Date, DateInput, DateInput>; /** * Check if a date variable is posterior than a specified date * @title is after */ declare const dateAfter: Operator<Date, DateInput, DateInput>; /** * Check if a date variable is the same as a specified date * @title is equal to */ declare const dateEquals: Operator<Date, DateInput, DateInput>; /** * Check if a date variable is different from a specified date * @title is not equal */ declare const dateNotEquals: Operator<Date, DateInput, DateInput>; declare const dateBasedOperators: (Operator<Date, [DateInput, DateInput], DateInput, [DateInput, DateInput]> | Operator<Date, number, DateInput, string | number> | Operator<Date, DateInput, DateInput, DateInput>)[]; /** * Check if the number variable is greater or equal to a specific value * @title ≥ */ declare const greaterThanOrEqual: Operator<number, number, number | string, number | string>; /** * Check if the number variable is greater than a specific value * @title > */ declare const greaterThan: Operator<number, number, number | string, number | string>; /** * Check if the number variable is lower or equal to a specific value * @title ≤ */ declare const lessOrEqual: Operator<number, number, number | string, number | string>; /** * Check if the number variable is lower than a specific value * @title < */ declare const lessThan: Operator<number, number, number | string, number | string>; /** List of all default number based operators */ declare const numberBasedOperators: Operator<number, number, string | number, string | number>[]; declare const operatorList: (_o3r_rules_engine.Operator<_o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes, _o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes> | _o3r_rules_engine.Operator<string, string, string, string> | _o3r_rules_engine.Operator<_o3r_rules_engine.SupportedSimpleTypes[], string | number, _o3r_rules_engine.SupportedSimpleTypes[], string | number> | _o3r_rules_engine.Operator<_o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes[]> | _o3r_rules_engine.Operator<number[], string | number, number[], string | number> | _o3r_rules_engine.Operator<string[], string, string[], string> | _o3r_rules_engine.Operator<number[], [string | number, string | number], number[], [string | number, string | number]> | _o3r_rules_engine.Operator<any[], string | number, any[], string | number> | _o3r_rules_engine.Operator<unknown, unknown, unknown, unknown> | _o3r_rules_engine.Operator<_o3r_rules_engine.SupportedSimpleTypes, _o3r_rules_engine.SupportedSimpleTypes[], _o3r_rules_engine.SupportedSimpleTypes, _o3r_rules_engine.SupportedSimpleTypes[]> | _o3r_rules_engine.UnaryOperator<any> | _o3r_rules_engine.Operator<Date, [_o3r_rules_engine.DateInput, _o3r_rules_engine.DateInput], _o3r_rules_engine.DateInput, [_o3r_rules_engine.DateInput, _o3r_rules_engine.DateInput]> | _o3r_rules_engine.Operator<Date, number, _o3r_rules_engine.DateInput, string | number> | _o3r_rules_engine.Operator<Date, _o3r_rules_engine.DateInput, _o3r_rules_engine.DateInput, _o3r_rules_engine.DateInput> | _o3r_rules_engine.Operator<number, number, string | number, string | number>)[]; type NativeTypes = string | boolean | number; /** Generic operand */ interface Operand<T extends string, U extends NativeTypes = NativeTypes> { /** Operand type */ type: T; /** Static value */ value: U; } /** Operand based on fact */ interface OperandFact extends Operand<'FACT', string> { /** JSONPath to deep read the fact value */ path?: string; } /** Condition available operand types */ type GenericOperand = OperandFact | Operand<'RUNTIME_FACT', string> | Operand<'LITERAL'>; /** Condition object interface with unary operator */ interface UnaryOperation { /** Left Hand Side */ lhs: GenericOperand; /** Operator */ operator: string; } /** Condition object interface */ interface BinaryOperation { /** Left Hand Side */ lhs: GenericOperand; /** Right Hand Side */ rhs: GenericOperand; /** Operator */ operator: string; } /** Nested Condition */ type NestedCondition = UnaryOperation | BinaryOperation | TopLevelCondition; /** All Condition */ type AllConditions = { all: NestedCondition[]; any?: never; not?: never; }; /** Any Condition */ type AnyConditions = { any: NestedCondition[]; all?: never; not?: never; }; /** Not Condition */ type NotCondition = { not: NestedCondition; all?: never; any?: never; }; /** Top level Condition in the rule definition */ type TopLevelCondition = AllConditions | AnyConditions | NotCondition | UnaryOperation | BinaryOperation; /** Event emitted in case the rule condition is passed */ interface RuleEvent { /** Type (or name) of the event */ type: string; /** list of parameter associated to the event */ params?: Record<string, any>; } /** Base for the Rule definition */ interface Rule { /** Unique id associated to a rule*/ id: string; /** Runtime facts that are needed for the rule execution (sent by the CMS) */ inputRuntimeFacts: string[]; /** Runtime facts that are created/updated by the rule*/ outputRuntimeFacts: string[]; /** Name of the rule*/ name: string; /** rootElement of the rule, that contains either a block, either an action list */ rootElement: AllBlock; } /** * List of possible types of actions resulted as output of a rule execution * @deprecated the actions are now depending of executing modules */ type ActionTypes = 'SET_FACT' | 'UPDATE_CONFIG' | 'UPDATE_ASSET' | 'UPDATE_LOCALISATION' | 'UPDATE_PLACEHOLDER'; /** Types associated to the condition blocks that are supported */ type ConditionBlockTypes = 'IF_ELSE'; /** Interface common to all elements */ interface RuleElement { /** Type of the element*/ elementType: string; } /** Interface common to all actions */ interface ActionBlock extends RuleElement, RulesEngineAction { elementType: 'ACTION'; actionType: string; value: any; } /** Interface of action that sets or updates a temporary fact */ interface ActionSetTemporaryFactBlock extends ActionBlock { actionType: 'SET_FACT'; fact: string; } /** Interface of block Rule */ interface RuleBlock extends RuleElement { elementType: 'RULE_BLOCK'; blockType: ConditionBlockTypes; } /** All supported blocks (supporting nested structure) */ type AllBlock = IfElseBlock | (ActionBlock & Record<string, any>); /** Block representing an 'if else' condition. If no condition specified it will execute success elements only */ interface IfElseBlock extends RuleBlock { blockType: 'IF_ELSE'; successElements: AllBlock[]; failureElements: AllBlock[]; condition?: TopLevelCondition; } /** Interface of a ruleset as it's specified in the json file */ interface Ruleset { /** Unique id of the ruleset*/ id: string; /** Name of the ruleset */ name: string; /** Optional ruleset description */ description?: string; /** List of rules associated to the ruleset */ rules: Rule[]; /** Optional date range where the ruleset will be executed*/ validityRange?: { from?: string; to?: string; }; /** * Components linked to the ruleset. If present the ruleset will not be active by default. * 'or' condition: If at least one component has subscribed, the ruleset will become active. */ linkedComponents?: { or: ItemIdentifier[]; }; } /** Performance object supporting NodeJs Performance and Web Performance reporting */ type CrossPlatformPerformance = { /** @see Performance.mark */ mark: (...x: Parameters<Performance['mark']>) => ReturnType<Performance['mark']> | void; /** @see Performance.measure */ measure: (measureName: string, startOrMeasureOptions?: string, endMark?: string) => ReturnType<Performance['measure']> | void; }; /** Fact stream object to handle fact reference change */ interface FactObject<T> { /** Subject of fact stream */ subject: BehaviorSubject<Observable<T> | undefined>; /** Stream of the fact value */ value$: Observable<T | undefined>; } /** Rule Engine constructor options */ interface RulesEngineOptions { /** List of facts */ facts?: Fact<Facts>[]; /** List of rules */ rules?: Ruleset[]; /** List of custom operators */ operators?: Operator<any, any>[]; /** Delay before fact stream defaulting value */ factDefaultDelay?: number; /** * Skip the rule and fact circular dependency checks * Turn to true to increase the speed of the upsert of a rule */ skipCircularDependencyChecks?: boolean; /** * Provide debugger instance to the rules engine */ debugger?: EngineDebugger; /** * Instance of the performance reporter to use for performance measurements. * @default window.performance on browser only, undefined on node */ performance?: CrossPlatformPerformance; /** * Name of the rules engine instance * @default RulesEngine */ rulesEngineInstanceName?: string; /** * Client to log the warning and error message */ logger?: Logger; } /** Rule as stored in the rules engine */ interface EngineRule extends Rule { /** stream of the rule conditions result */ result$: BehaviorSubject<ActionBlock[]>; } /** Rule as stored in the rules engine */ interface EngineRuleset { /** Optional date range where the ruleset will be executed, it supports a dateString or a timestamp as number, more info on javascript Date() documentation */ validityRange?: { from?: string | number; to?: string | number; }; /** * Components linked to the ruleset. If present the ruleset will not be active by default. * 'or' condition: If at least one component has subscribed, the ruleset will become active. */ linkedComponents?: { or: ItemIdentifier[]; }; /** Unique id of the ruleset*/ id: string; /** Stores the result of each rules from the ruleset */ rulesResultsSubject$: Observable<ActionBlock[]>; } /** Timestamp of a rules engine output event */ interface TimedEvent { /** Timestamp value when the event occurs */ timestamp: number; /** Duration of the execution */ duration?: number; } /** Fact change triggering the evaluation of a rule/execution of a ruleset */ interface EvaluationReason { /** Name of the fact that changed */ factName: string; /** New value of the fact */ newValue?: Facts; /** Old value of the fact */ oldValue?: Facts; } /** Result object resulted at the end of a rule evaluation */ interface RuleEvaluation extends TimedEvent { /** Identifier of the evaluation (ruleset name + rule name) */ id: string; /** Evaluated rule identifier */ rule: Pick<Rule, 'id' | 'name'>; /** Actions outputted by the rule evaluation */ outputActions: ActionBlock[] | undefined; /** Map containing the facts changes triggering the rule evaluation */ triggers: Record<string, Record<string, EvaluationReason>>; /** Error object in case of rule evaluation failure */ error?: any; /** Runtime facts with values at the end of rule evaluation */ temporaryFacts?: Record<string, Facts>; /** Flag to notify if the rules evaluation comes from an old ruleset execution */ cached?: boolean; } /** Wrapped rule evaluation output */ interface RuleEvaluationOutput { /** Actions emitted at the end of rule evaluation */ actions: ActionBlock[] | undefined; /** Rule evaluation output object */ evaluation?: RuleEvaluation; /** Error object emitted at the end of rule evaluation, if any */ error?: any; } /** Base object resulted at the end of a ruleset execution */ interface BaseRulesetExecution { /** Id of the ruleset execution */ executionId: string; /** Id of the ruleset which was executed */ rulesetId: string; /** Name of the executed ruleset */ rulesetName: string; /** Counter of executions for the ruleset */ executionCounter: number; /** All input facts affecting the ruleset */ inputFacts: { factName: string; value: Facts; }[]; /** Runtime facts used across the ruleset */ temporaryFacts?: Record<string, Facts>; /** Facts changes that triggered the execution of the ruleset */ triggers: Record<string, Record<string, EvaluationReason>>; /** List of evaluated rules accros ruleset execution */ rulesEvaluations: RuleEvaluation[]; } /** Debug event emitted in case of successful ruleset execution */ interface RulesetExecutionEvent extends BaseRulesetExecution, TimedEvent { /** Event type */ type: 'RulesetExecution'; /** List of the actions emitted at the end of ruleset execution */ outputActions: ActionBlock[]; } /** Debug event emitted in case of ruleset execution failure */ interface RulesetExecutionErrorEvent extends BaseRulesetExecution, TimedEvent { /** Event type */ type: 'RulesetExecutionError'; /** List of rules causing the execution error*/ rulesCausingTheError: Pick<Rule, 'name' | 'id'>[]; /** List of outputted errors */ errors: any[]; } /** Debug event emitted when active rulesets are changing */ interface ActiveRulesetsEvent extends TimedEvent { /** Event type */ type: 'ActiveRulesets'; /** List of active rulesets */ rulesets: Pick<Ruleset, 'name' | 'id'>[]; } /** Debug event emitted each time the Rules Engine outputs a list of actions */ interface AllActionsEvent extends TimedEvent { /** event type */ type: 'AllActions'; /** List of emitted actions */ actions: ActionBlock[]; } /** Debug event emitted when rulesets are registered to the rules engine */ interface AvailableRulesets extends TimedEvent { /** Event type */ type: 'AvailableRulesets'; /** Registered rulesets list */ availableRulesets: Pick<Ruleset, 'name' | 'id'>[]; } /** Debug event emitted when facts are updated */ interface AvailableFactsSnapshot extends TimedEvent { /** Event type */ type: 'AvailableFactsSnapshot'; /** List of all facts */ facts: { factName: string; value: Facts; }[]; } /** Type of possible debug events emitted by Rules Engine */ type DebugEvent = RulesetExecutionEvent | RulesetExecutionErrorEvent | ActiveRulesetsEvent | AllActionsEvent | AvailableRulesets | AvailableFactsSnapshot; /** Rules engine */ declare class RulesEngine { /** Map of registered fact stream, this map is mutated by the ruleset executors */ private readonly factMap; /** Subject containing the rulesets and the results stream*/ private readonly rulesetMapSubject; /** Map of available operators */ operators: Record<string, Operator<unknown, unknown>>; /** List of events for the current state of the rules engine */ readonly events$: Observable<ActionBlock[]>; /** Delay before fact stream defaulting value */ factDefaultDelay?: number; /** * Instance of engine debug object; Undefined if debugMode is not active */ readonly engineDebug?: EngineDebugger; /** Name of the rules engine instance */ readonly rulesEngineInstanceName: string; /** * Performance reporter to use for performance measurements. * @default window.performance on browser only, undefined on node */ readonly performance: _o3r_rules_engine.CrossPlatformPerformance | undefined; /** * Log the engine errors */ readonly logger?: Logger$1; /** * Flag to check if the run is in debug mode or not */ get debugMode(): boolean; /** * Rules engine * @param options rules engine options */ constructor(options?: RulesEngineOptions); /** * Attach debug events to actions stream if debug engine is activated */ private handleActionsStreamOutput; /** * Create the actions stream event based on provided active rulesets ids; Handle debug too * @param ruleSets */ private prepareActionsStream; /** * Create or retrieve a fact stream * The fact stream created will be registered in the engine * @param id ID of the fact to retrieve * @param factValue$ Value stream for the fact */ retrieveOrCreateFactStream<T = Facts>(id: string, factValue$?: Observable<T>): Observable<T | undefined>; /** * Retrieve the promise of the latest value of a fact. * Return undefined if the fact is not defined. * @param id ID of the fact to retrieve */ retrieveFactValue<T = unknown>(id: string): Promise<T | undefined> | undefined; /** * Update or insert fact in rules engine * @param facts fact list to add / update */ upsertFacts<T = unknown>(facts: Fact<T> | Fact<T>[]): void; /** * Update or insert rule in rules engine * @param rulesets */ upsertRulesets(rulesets: Ruleset[]): void; /** * Update or insert operator in rules engine * @param operators operator list to add / update */ upsertOperators(operators: (Operator<any, any> | UnaryOperator<any>)[]): void; /** * Operator to apply on a stream of rulesets ids * Returns a stream of actions outputted by the rules engine, corresponding to the rulesetsIds */ getEventStream<T extends ActionBlock = ActionBlock>(): (rulesetsIds$: Observable<string[] | undefined>) => Observable<T[]>; /** Get the list of registered facts names */ getRegisteredFactsNames(): string[]; } declare class RulesetExecutor { /** retrieveFactFunc */ protected readonly rulesEngine: RulesEngine; /** Map of available operators */ protected readonly operators: Record<string, Operator<unknown, unknown>>; /** Delay before fact stream defaulting value */ readonly factDefaultDelay?: number; /** Ruleset associated to the current executor*/ readonly ruleset: Ruleset; /** Ruleset plugged to the fact stream, that contains actions stream result */ readonly engineRuleset: EngineRuleset; private executionCounter; /** * Create a new ruleset executor * @param ruleset Ruleset to evaluate * @param rulesEngine Instance of the rules engine */ constructor(ruleset: Ruleset, rulesEngine: RulesEngine); /** * Recursively explores a rule to identify and collect input facts. * Input facts are identified based on the 'FACT' type and operator-specific implicit dependencies. * @param currentObject The current object being explored. * @param ruleInputFacts A set to store the identified input facts for the rule. */ private collectRuleInputFacts; /** * Report performance mark for a rule run * @param rule Rule to measure * @param status status of the rule evaluation */ protected performanceMark(rule: Rule, status: 'start' | 'end'): void; /** * Get operand value stream according to its type * @param operand operand of the condition * @param factsValue * @param runtimeFactValues */ protected getOperandValue(operand: GenericOperand | undefined, factsValue: Record<string, Facts | undefined>, runtimeFactValues: Record<string, Facts>): unknown; /** * Process a root rule from a ruleset, and return the associated actions to be processed * Will also update the runtimeFactValues map that is ruleset wise * Note that runtimeFactValues will be mutated by all the runtime facts actions executed * @param rule * @param factsValue * @param runtimeFactValues * @protected */ protected evaluateRule(rule: Rule, factsValue: Record<string, Facts | undefined>, runtimeFactValues: Record<string, Facts>): ActionBlock[]; /** * Recursively process a block to extract all the actions keeping the order * Note that runtimeFactValues will be mutated by all the runtime facts actions executed * @param element * @param factsValue * @param runtimeFactValues This runtime fact map will be mutated by all the runtime facts actions executed * @param actions * @protected */ protected evaluateBlock(element: AllBlock, factsValue: Record<string, Facts | undefined>, runtimeFactValues: Record<string, Facts>, actions?: ActionBlock[]): ActionBlock[]; /** * Returns true if the element is a IfElse block * @param element * @protected */ protected isIfElseBlock(element: AllBlock): element is IfElseBlock; /** * Returns true if the element is an action block * @param element * @protected */ protected isActionBlock(element: AllBlock): element is ActionBlock; /** * Returns true if the action sets a temporary fact * @param element * @protected */ protected isActionSetTemporaryFactBlock(element: ActionBlock): element is ActionSetTemporaryFactBlock; /** * Evaluate a condition block * @param nestedCondition * @param factsValue * @param runtimeFactValues * @protected */ protected evaluateCondition(nestedCondition: NestedCondition, factsValue: Record<string, Facts | undefined>, runtimeFactValues: Record<string, Facts>): boolean; /** * Find rule input facts * @param obj */ protected readonly findRuleInputFacts: (obj: AllBlock) => string[]; /** * Plug ruleset to fact streams and trigger a first evaluation */ protected plugRuleset(): EngineRuleset; } interface EngineDebuggerOptions { /** * Limit of events to keep in the stack before subscribing to the debugEvents$ stream. * @default undefined no limit */ eventsStackLimit?: number; } /** * Rules engine debugger object to emit debug events */ declare class EngineDebugger { private registeredRuleEngine?; private registeredRulesets; private readonly debugEventsSubject$; private performanceMeasures$; private readonly requestFactsSnapshot; /** Stream emitting a debug event when is fired; timeline is kept */ readonly debugEvents$: Observable<DebugEvent>; /** Retrieved the rules engine plugged to the debugger */ get rulesEngine(): RulesEngine | undefined; /** * Instantiate a rules engine debugger * @param options Options to configure the debugger */ constructor(options?: EngineDebuggerOptions); private initializePerformanceObserver; private createBaseExecutionOutputObject; private rulesetExecution; private rulesetExecutionError; /** * Plug the debugger to a Rule Engine * @param rulesEngine */ registerRuleEngine(rulesEngine: RulesEngine): void; /** * Handle ruleset execution debug info * @param currRes * @param prevRes * @param allExecutionsValid * @param rulesetInputFacts * @param runtimeFactValues * @param executionCounter * @param ruleset */ handleDebugRulesetExecutionInfo(currRes: RuleEvaluationOutput[], prevRes: RuleEvaluationOutput[] | undefined, allExecutionsValid: boolean, rulesetInputFacts: string[], runtimeFactValues: Record<string, Facts>, executionCounter: number, ruleset: Ruleset): { executionCounter: number; rulesetOutputExecution: RuleEvaluation[]; allExecutionsValid: boolean; rulesetTriggers: Record<string, Record<string, EvaluationReason>>; }; /** * Emits an 'AvailableRulesets' debug event when rulesets are registered to the rules engine * @param rulesets */ addAvailableRulesets(rulesets: Ruleset[]): void; /** * Computes and emits an 'ActiveRulesets' debug event when the active rulesets are changing * @param ruleSetExecutorMap map off all rulesets executors * @param restrictiveRuleSets ids of the rulesets to activate; if not provided all registered rulesets will be considered as active */ activeRulesetsChange(ruleSetExecutorMap: Record<string, RulesetExecutor>, restrictiveRuleSets?: string[]): void; /** * Emits an 'AllActions' debug event each time the rules engine outputs the list of actions * @param actions list of outputted actions */ allActionsChange(actions: ActionBlock[]): void; /** * Emits a 'RulesetExecution' debug event at the output of a successful ruleset execution * @param ruleset * @param executionCounter * @param rulesetInputFacts * @param allOutputActions * @param runtimeFactValues * @param rulesetTriggers * @param rulesExecutions */ addRulesetExecutionEvent(ruleset: Ruleset, executionCounter: number, rulesetInputFacts: string[], allOutputActions: ActionBlock[], runtimeFactValues: Record<string, Facts>, rulesetTriggers: Record<string, Record<string, EvaluationReason>>, rulesExecutions: RuleEvaluation[]): void; /** * Emits a 'RulesetExecutionError' debug event at the output of a failing ruleset execution * @param ruleset * @param rulesetInputFacts * @param executionCounter * @param runtimeFactValues * @param rulesetTriggers * @param rulesExecutions */ addRulesetExecutionErrorEvent(ruleset: Ruleset, rulesetInputFacts: string[], executionCounter: number, runtimeFactValues: Record<string, Facts>, rulesetTriggers: Record<string, Record<string, EvaluationReason>>, rulesExecutions: RuleEvaluation[]): void; /** * Emits a 'AvailableFactsSnapshot' debug event when a fact value is updated * @param _id * @param factValue$ */ addAvailableFactsSnapshotEvent(_id: string, factValue$: Observable<any>): void; /** * Returns a list of fact name and value pairs * @param factsNames List of facts names to get the value for */ getFactsSnapshot(factsNames: string[]): Promise<{ factName: string; value: any; }[]>; } /** * Determine if the condition is a properties condition * @param condition Condition to analyze */ declare function isConditionProperties(condition: any): condition is BinaryOperation | UnaryOperation; /** * Determine if the given operand is a Fact operand * @param operand Operand to analyze */ declare function isOperandFact(operand: any): operand is OperandFact; /** * Determine if the given operand is a Inner Fact operand * @param operand Operand to analyze */ declare function isOperandRuntimeFact(operand: any): operand is Operand<'RUNTIME_FACT', string>; /** * Determine if the given operand is a Static Value operand * @param operand Operand to analyze */ declare function isOperandLiteral(operand: any): operand is Operand<'LITERAL'>; /** * Determine if the given condition is All based child conditions * @param condition Condition node */ declare function isAllConditions(condition: any): condition is AllConditions; /** * Determine if the given condition is Any based child conditions * @param condition Condition node */ declare function isAnyConditions(condition: any): condition is AnyConditions; /** * Determine if the given condition is Not based child conditions * @param condition Condition node */ declare function isNotCondition(condition: any): condition is NotCondition; declare class FactsSnapshotComponent { /** * Full list of available facts with their current value */ readonly facts: i0.InputSignal<{ factName: string; value: Facts; }[]>; /** * Search terms */ readonly search: i0.WritableSignal<string>; /** * Filtered list of facts using search terms */ readonly filteredFacts: i0.Signal<{ factName: string; value: Facts; }[]>; static ɵfac: i0.ɵɵFactoryDeclaration<FactsSnapshotComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<FactsSnapshotComponent, "o3r-facts-snapshot", never, { "facts": { "alias": "facts"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>; } type RulesetExecutionStatus = 'Error' | 'Active' | 'Deactivated' | 'NoEffect'; /** * Model of a RulesetExecution with more information for debug purpose */ type RulesetExecutionDebug = (RulesetExecutionEvent | RulesetExecutionErrorEvent) & { isActive: boolean; status: RulesetExecutionStatus; rulesetInformation: Ruleset | undefined; }; declare class RulesetHistoryPresComponent { private readonly cd; /** * Reflects the state of each ruleset expanded elements. * Each ruleset entry contains a list of subpanel that can be collapsed or expanded. * Ruleset whole panel status is store the 'ruleset' entry. * @example * Expanded ruleset with rule overview collapsed: * {'rulesetId': {'ruleset' : true, 'ruleOverview': false}} * @note Collapsing a ruleset will not reset the subpanel expansion status */ expansionStatus: { [key: string]: { [subpanel: string]: boolean; }; }; rulesetExecutions: RulesetExecutionDebug[]; executionDurationFormat: string; /** * Toggle a ruleset subpanel * @param ruleId * @param subpanel element to collapse. 'ruleset' will toggle the whole panel but won't reset the subpanels states. */ toggleExpansion(ruleId: string, subpanel: string): void; static ɵfac: i0.ɵɵFactoryDeclaration<RulesetHistoryPresComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<RulesetHistoryPresComponent, "o3r-ruleset-history-pres", never, { "rulesetExecutions": { "alias": "rulesetExecutions"; "required": false; }; "executionDurationFormat": { "alias": "executionDurationFormat"; "required": false; }; }, {}, never, never, true, never>; } declare class RuleConditionPresComponent { private _condition?; /** * Left hand operator as it will be displayed in the template. * In the case of a fact with a json path, will resolve the whole fact path, else will only display the value */ lhs: string; /** * Right hand operator as it will be displayed in the template. * In the case of a fact with a json path, will resolve the whole fact path, else will only display the value */ rhs: string | undefined; /** * Rule condition that will be flattened by the component setter */ set condition(condition: TopLevelCondition | undefined); get condition(): TopLevelCondition | undefined; private getOperandName; static ɵfac: i0.ɵɵFactoryDeclaration<RuleConditionPresComponent, never>; static ɵcmp: i0.ɵɵComponentDeclaration<RuleConditionPresComponent, "o3r-rule-condition-pres", never, { "condition": { "alias": "condition"; "required": false; }; }, {}, never, never, true, never>; } /** * @deprecated The Components and Pipes are now standalone, this module will be removed in v14 */ declare class RulesetHistoryPresModule { static ɵfac: i0.ɵɵFactoryDeclaration<RulesetHistoryPresModule, never>; static ɵmod: i0.ɵɵNgModuleDeclaration<RulesetHistoryPresModule, never, [typeof i1.JsonPipe, typeof RulesetHistoryPresComponent, typeof RuleConditionPresComponent], [typeof RulesetHistoryPresComponent]>; static ɵinj: i0.ɵɵInjectorDeclaration<RulesetHistoryPresModule>; } declare class O3rFallbackToPipe implements PipeTransform { transform<T>(value: T, fallback?: string): T | string; static ɵfac: i0.ɵɵFactoryDeclaration<O3rFallbackToPipe, never>; static ɵpipe: i0.ɵɵPipeDeclaration<O3rFallbackToPipe, "o3rFallbackTo", true>; } declare class O3rJsonOrStringPipe implements PipeTransform { /** * @inheritDoc */ transform(value: any): string; static ɵfac: i0.ɵɵFactoryDeclaration<O3rJsonOrStringPipe, never>; static ɵpipe: i0.ɵɵPipeDeclaration<O3rJsonOrStringPipe, "o3rJsonOrString", true>; } /** * Compute the status of the execution depending on its execution event type, the output and whether the execution * is still active * @param rulesetExecution * @param isActive */ declare const getStatus: (rulesetExecution: RulesetExecutionErrorEvent | RulesetExecutionEvent, isActive: boolean) => RulesetExecutionStatus; /** * Transform the output of the debug reports into the model for the ruleset history debug panel * @param events * @param rulesetMap */ declare const rulesetReportToHistory: (events: DebugEvent[], rulesetMap: Record<string, Ruleset>) => RulesetExecutionDebug[]; interface RulesEngineDevtoolsServiceOptions extends DevtoolsCommonOptions { /** Size of events list emitted by rules engine; When undefined all history will be kept */ rulesEngineStackLimit?: number; } /** Rules Engine debug event Message Content */ interface RulesEngineDebugEventsContentMessage extends OtterMessageContent<'rulesEngineEvents'> { /** Map of registered rulesets */ rulesetMap: Record<string, Ruleset>; /** List of event from the Rules Engine Debugger */ events: DebugEvent[]; } type RulesEngineMessageContents = RulesEngineDebugEventsContentMessage; /** List of possible DataTypes for RulesEngine messages */ type RulesEngineMessageDataTypes = MessageDataTypes<RulesEngineMessageContents>; /** List of all messages for configuration purpose */ type AvailableRulesEngineMessageContents = RulesEngineMessageContents | ConnectContentMessage | RequestMessagesContentMessage<RulesEngineMessageDataTypes>; declare const isRulesEngineMessage: (message: any) => message is AvailableRulesEngineMessageContents; declare class RulesEngineDevtoolsConsoleService implements DevtoolsServiceInterface { /** Name of the Window property to access to the devtools */ static readonly windowModuleName = "rulesEngine"; private readonly rulesEngineDevtools; private readonly options; constructor(); /** @inheritDoc */ activate(): void; /** Return the list of debug events emitted by rules engine */ getCurrentRulesEngineEventsStack(): Promise<void>; /** Returns the list of active rulesets (name and id) at the moment when the function is called */ getActiveRulesets(): Promise<void>; /** Returns the list of available rulesets (name and id) at the moment when the function is called */ getAvailableRulesets(): Promise<void>; /** Returns the list of output actions emitted by the rules engine at the moment when the function is called */ getAllOutputActions(): Promise<void>; /** * Get the list of executions for the given ruleset * @param rulesetId */ getRulesetExecutions(rulesetId: string): Promise<void>; /** * Check if the ruleset is activ in the moment when the function is called * @param rulesetId * @returns True if the ruleset is active; False if the ruleset is inactive or it does not exist */ isRulesetActive(rulesetId: string): Promise<void>; /** * Get the list of rules executed for the specified ruleset * @param rulesetId */ getRulesEvaluationsForRuleset(rulesetId: string): Promise<void>; /** * Get the list of input facts (name, current value) for the specified ruleset, at the moment when the function is called * @param rulesetId */ getInputFactsForRuleset(rulesetId: string): Promise<void>; /** * Get the list of triggers for the specified ruleset * @param rulesetId */ getTriggersForRuleset(rulesetId: string): Promise<void>; /** * Get the list of outputed actions emitted by the given ruleset, at the moment when the function is called * @param rulesetId */ getOutputActionsForRuleset(rulesetId: string): Promise<void>; /** Get the list of fact names and corresponding values */ getAllFactsSnapshot(): Promise<void>; /** * Retrieve the ruleset information (rules, linkedComponents, validity range etc.) for a ruleset id * @param rulesetId */ getRulesetInformation(rulesetId: string): Promise<void>; static ɵfac: i0.ɵɵFactoryDeclaration<RulesEngineDevtoolsConsoleService, never>; static ɵprov: i0.ɵɵInjectableDeclaration<RulesEngineDevtoolsConsoleService>; } declare class RulesEngineDevtoolsMessageService implements DevtoolsServiceInterface { private readonly rulesEngineDevtools; private readonly logger; private readonly options; private readonly forceEmitRulesEngineReport; private readonly sendMessage; private readonly destroyRef; constructor(); /** * Function to trigger a re-send a requested messages to the Otter Chrome DevTools extension * @param only restricted list of messages to re-send */ private handleReEmitRequest; /** * Function to handle the incoming messages from Otter Chrome DevTools extension * @param message */ private handleEvents; private readonly serializeError; /** * Serialize exceptions in a way that will display the error message after a JSON.stringify(