Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/historical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,44 @@ export function queryAndCountOrderedEvent(
return 0;
}
}

/**
* Queries a list of events and returns the index of the most recent event that occurred within a specified time range.
*
* @param events - Array of historical event conditions to check
* @param context - The context object containing the events history
* @param options - Rules engine options with event hash generation capability
* @param from - Optional timestamp (in milliseconds) marking the start of the time range (default: 0)
* @param to - Optional timestamp (in milliseconds) marking the end of the time range (default: Infinity)
* @returns the index of the most recent event. -1 if no event is found
*/
export function queryAndCountMostRecentEvent(
events: Array<HistoricalEvent>,
context: Context,
options: RulesEngineOptions,
from = 0,
to = Infinity,
) {
try {
return events.reduce(
(mostRecent, event, index) => {
const eventHash = options.generateEventHash(normalizeEvent(event));
const contextEvent = context.events[eventHash];
if (!contextEvent) {
return mostRecent;
}

const mostRecentTimestamp = contextEvent.timestamps
.filter((t: number) => t >= from && t <= to)
.pop();

return mostRecentTimestamp && mostRecentTimestamp > mostRecent.timestamp
? { index, timestamp: mostRecentTimestamp }
: mostRecent;
},
{ index: -1, timestamp: 0 },
).index;
} catch {
return -1;
}
}
11 changes: 10 additions & 1 deletion src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import {
checkForHistoricalMatcher,
queryAndCountAnyEvent,
queryAndCountMostRecentEvent,
queryAndCountOrderedEvent,
} from "./historical";

Expand Down Expand Up @@ -163,7 +164,15 @@ export function createHistoricalDefinition(
evaluate: (context, options) => {
let eventCount: number;

if (SearchType.ORDERED === searchType) {
if (SearchType.MOST_RECENT === searchType) {
eventCount = queryAndCountMostRecentEvent(
events,
context,
options,
from,
to,
);
} else if (SearchType.ORDERED === searchType) {
eventCount = queryAndCountOrderedEvent(
events,
context,
Expand Down
1 change: 1 addition & 0 deletions src/types/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const LogicType = {
export const SearchType = {
ANY: "any",
ORDERED: "ordered",
MOST_RECENT: "mostRecent",
};

export type SupportedCondition =
Expand Down
1 change: 1 addition & 0 deletions src/types/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface RuleSet {

export interface Rule {
key?: string;
meta?: object;
condition: GroupCondition | MatcherCondition | HistoricalCondition;
consequences: Array<Consequence>;
}
Expand Down
Loading