@f-o-t/rules-engine 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/package.json +4 -1
  2. package/CHANGELOG.md +0 -168
  3. package/__tests__/builder.test.ts +0 -363
  4. package/__tests__/cache.test.ts +0 -130
  5. package/__tests__/config.test.ts +0 -35
  6. package/__tests__/engine.test.ts +0 -1213
  7. package/__tests__/evaluate.test.ts +0 -339
  8. package/__tests__/exports.test.ts +0 -30
  9. package/__tests__/filter-sort.test.ts +0 -303
  10. package/__tests__/integration.test.ts +0 -419
  11. package/__tests__/money-integration.test.ts +0 -149
  12. package/__tests__/validation.test.ts +0 -862
  13. package/biome.json +0 -39
  14. package/docs/MIGRATION-v3.md +0 -118
  15. package/fot.config.ts +0 -5
  16. package/src/analyzer/analysis.ts +0 -401
  17. package/src/builder/conditions.ts +0 -321
  18. package/src/builder/rule.ts +0 -192
  19. package/src/cache/cache.ts +0 -135
  20. package/src/cache/noop.ts +0 -20
  21. package/src/core/evaluate.ts +0 -185
  22. package/src/core/filter.ts +0 -85
  23. package/src/core/group.ts +0 -103
  24. package/src/core/sort.ts +0 -90
  25. package/src/engine/engine.ts +0 -462
  26. package/src/engine/hooks.ts +0 -235
  27. package/src/engine/state.ts +0 -322
  28. package/src/index.ts +0 -303
  29. package/src/optimizer/index-builder.ts +0 -381
  30. package/src/serialization/serializer.ts +0 -408
  31. package/src/simulation/simulator.ts +0 -359
  32. package/src/types/config.ts +0 -184
  33. package/src/types/consequence.ts +0 -38
  34. package/src/types/evaluation.ts +0 -87
  35. package/src/types/rule.ts +0 -112
  36. package/src/types/state.ts +0 -116
  37. package/src/utils/conditions.ts +0 -108
  38. package/src/utils/hash.ts +0 -30
  39. package/src/utils/id.ts +0 -6
  40. package/src/utils/time.ts +0 -42
  41. package/src/validation/conflicts.ts +0 -440
  42. package/src/validation/integrity.ts +0 -473
  43. package/src/validation/schema.ts +0 -386
  44. package/src/versioning/version-store.ts +0 -337
  45. package/tsconfig.json +0 -29
@@ -1,322 +0,0 @@
1
- import type {
2
- ConsequenceDefinitions,
3
- DefaultConsequences,
4
- } from "../types/consequence";
5
- import type {
6
- Rule,
7
- RuleFilters,
8
- RuleInput,
9
- RuleSet,
10
- RuleSetInput,
11
- } from "../types/rule";
12
- import type { MutableEngineState } from "../types/state";
13
- import { createInitialState } from "../types/state";
14
- import { generateId } from "../utils/id";
15
-
16
- export const addRule = <
17
- TContext = unknown,
18
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
19
- >(
20
- state: MutableEngineState<TContext, TConsequences>,
21
- input: RuleInput<TContext, TConsequences>,
22
- ): Rule<TContext, TConsequences> => {
23
- const now = new Date();
24
- const rule: Rule<TContext, TConsequences> = {
25
- id: input.id ?? generateId(),
26
- name: input.name,
27
- description: input.description,
28
- conditions: input.conditions,
29
- consequences: input.consequences.map((c) => ({
30
- type: c.type,
31
- payload: c.payload,
32
- })) as Rule<TContext, TConsequences>["consequences"],
33
- priority: input.priority ?? 0,
34
- enabled: input.enabled ?? true,
35
- stopOnMatch: input.stopOnMatch ?? false,
36
- tags: input.tags ?? [],
37
- category: input.category,
38
- metadata: input.metadata,
39
- createdAt: now,
40
- updatedAt: now,
41
- };
42
-
43
- state.rules.set(rule.id, rule);
44
-
45
- if (!state.ruleOrder.includes(rule.id)) {
46
- state.ruleOrder.push(rule.id);
47
- sortRuleOrder(state);
48
- }
49
-
50
- return rule;
51
- };
52
-
53
- export const addRules = <
54
- TContext = unknown,
55
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
56
- >(
57
- state: MutableEngineState<TContext, TConsequences>,
58
- inputs: RuleInput<TContext, TConsequences>[],
59
- ): Rule<TContext, TConsequences>[] => {
60
- return inputs.map((input) => addRule(state, input));
61
- };
62
-
63
- export const removeRule = <
64
- TContext = unknown,
65
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
66
- >(
67
- state: MutableEngineState<TContext, TConsequences>,
68
- ruleId: string,
69
- ): boolean => {
70
- const deleted = state.rules.delete(ruleId);
71
- if (deleted) {
72
- const index = state.ruleOrder.indexOf(ruleId);
73
- if (index !== -1) {
74
- state.ruleOrder.splice(index, 1);
75
- }
76
- }
77
- return deleted;
78
- };
79
-
80
- export const updateRule = <
81
- TContext = unknown,
82
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
83
- >(
84
- state: MutableEngineState<TContext, TConsequences>,
85
- ruleId: string,
86
- updates: Partial<RuleInput<TContext, TConsequences>>,
87
- ): Rule<TContext, TConsequences> | undefined => {
88
- const existing = state.rules.get(ruleId);
89
- if (!existing) return undefined;
90
-
91
- const updated: Rule<TContext, TConsequences> = {
92
- ...existing,
93
- ...(updates.name !== undefined && { name: updates.name }),
94
- ...(updates.description !== undefined && {
95
- description: updates.description,
96
- }),
97
- ...(updates.conditions !== undefined && {
98
- conditions: updates.conditions,
99
- }),
100
- ...(updates.consequences !== undefined && {
101
- consequences: updates.consequences.map((c) => ({
102
- type: c.type,
103
- payload: c.payload,
104
- })) as Rule<TContext, TConsequences>["consequences"],
105
- }),
106
- ...(updates.priority !== undefined && { priority: updates.priority }),
107
- ...(updates.enabled !== undefined && { enabled: updates.enabled }),
108
- ...(updates.stopOnMatch !== undefined && {
109
- stopOnMatch: updates.stopOnMatch,
110
- }),
111
- ...(updates.tags !== undefined && { tags: updates.tags }),
112
- ...(updates.category !== undefined && { category: updates.category }),
113
- ...(updates.metadata !== undefined && { metadata: updates.metadata }),
114
- updatedAt: new Date(),
115
- };
116
-
117
- state.rules.set(ruleId, updated);
118
-
119
- if (updates.priority !== undefined) {
120
- sortRuleOrder(state);
121
- }
122
-
123
- return updated;
124
- };
125
-
126
- export const getRule = <
127
- TContext = unknown,
128
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
129
- >(
130
- state: MutableEngineState<TContext, TConsequences>,
131
- ruleId: string,
132
- ): Rule<TContext, TConsequences> | undefined => {
133
- return state.rules.get(ruleId);
134
- };
135
-
136
- export const getRules = <
137
- TContext = unknown,
138
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
139
- >(
140
- state: MutableEngineState<TContext, TConsequences>,
141
- filters?: RuleFilters,
142
- ): ReadonlyArray<Rule<TContext, TConsequences>> => {
143
- const rules: Rule<TContext, TConsequences>[] = [];
144
-
145
- for (const id of state.ruleOrder) {
146
- const rule = state.rules.get(id);
147
- if (!rule) continue;
148
-
149
- if (filters) {
150
- if (
151
- filters.enabled !== undefined &&
152
- rule.enabled !== filters.enabled
153
- ) {
154
- continue;
155
- }
156
- if (filters.tags && filters.tags.length > 0) {
157
- const hasTag = filters.tags.some((tag) => rule.tags.includes(tag));
158
- if (!hasTag) continue;
159
- }
160
- if (
161
- filters.category !== undefined &&
162
- rule.category !== filters.category
163
- ) {
164
- continue;
165
- }
166
- if (
167
- filters.ids &&
168
- filters.ids.length > 0 &&
169
- !filters.ids.includes(rule.id)
170
- ) {
171
- continue;
172
- }
173
- }
174
-
175
- rules.push(rule);
176
- }
177
-
178
- return rules;
179
- };
180
-
181
- export const enableRule = <
182
- TContext = unknown,
183
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
184
- >(
185
- state: MutableEngineState<TContext, TConsequences>,
186
- ruleId: string,
187
- ): boolean => {
188
- const rule = state.rules.get(ruleId);
189
- if (!rule) return false;
190
-
191
- state.rules.set(ruleId, { ...rule, enabled: true, updatedAt: new Date() });
192
- return true;
193
- };
194
-
195
- export const disableRule = <
196
- TContext = unknown,
197
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
198
- >(
199
- state: MutableEngineState<TContext, TConsequences>,
200
- ruleId: string,
201
- ): boolean => {
202
- const rule = state.rules.get(ruleId);
203
- if (!rule) return false;
204
-
205
- state.rules.set(ruleId, { ...rule, enabled: false, updatedAt: new Date() });
206
- return true;
207
- };
208
-
209
- export const clearRules = <
210
- TContext = unknown,
211
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
212
- >(
213
- state: MutableEngineState<TContext, TConsequences>,
214
- ): void => {
215
- state.rules.clear();
216
- state.ruleOrder.length = 0;
217
- };
218
-
219
- export const addRuleSet = <
220
- TContext = unknown,
221
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
222
- >(
223
- state: MutableEngineState<TContext, TConsequences>,
224
- input: RuleSetInput,
225
- ): RuleSet => {
226
- const ruleSet: RuleSet = {
227
- id: input.id ?? generateId(),
228
- name: input.name,
229
- description: input.description,
230
- ruleIds: input.ruleIds,
231
- enabled: input.enabled ?? true,
232
- metadata: input.metadata,
233
- };
234
-
235
- state.ruleSets.set(ruleSet.id, ruleSet);
236
- return ruleSet;
237
- };
238
-
239
- export const getRuleSet = <
240
- TContext = unknown,
241
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
242
- >(
243
- state: MutableEngineState<TContext, TConsequences>,
244
- ruleSetId: string,
245
- ): RuleSet | undefined => {
246
- return state.ruleSets.get(ruleSetId);
247
- };
248
-
249
- export const getRuleSets = <
250
- TContext = unknown,
251
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
252
- >(
253
- state: MutableEngineState<TContext, TConsequences>,
254
- ): ReadonlyArray<RuleSet> => {
255
- return Array.from(state.ruleSets.values());
256
- };
257
-
258
- export const removeRuleSet = <
259
- TContext = unknown,
260
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
261
- >(
262
- state: MutableEngineState<TContext, TConsequences>,
263
- ruleSetId: string,
264
- ): boolean => {
265
- return state.ruleSets.delete(ruleSetId);
266
- };
267
-
268
- export const getRulesInSet = <
269
- TContext = unknown,
270
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
271
- >(
272
- state: MutableEngineState<TContext, TConsequences>,
273
- ruleSetId: string,
274
- ): ReadonlyArray<Rule<TContext, TConsequences>> => {
275
- const ruleSet = state.ruleSets.get(ruleSetId);
276
- if (!ruleSet || !ruleSet.enabled) return [];
277
-
278
- const rules: Rule<TContext, TConsequences>[] = [];
279
- for (const ruleId of ruleSet.ruleIds) {
280
- const rule = state.rules.get(ruleId);
281
- if (rule) {
282
- rules.push(rule);
283
- }
284
- }
285
-
286
- return rules;
287
- };
288
-
289
- const sortRuleOrder = <
290
- TContext = unknown,
291
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
292
- >(
293
- state: MutableEngineState<TContext, TConsequences>,
294
- ): void => {
295
- state.ruleOrder.sort((a, b) => {
296
- const ruleA = state.rules.get(a);
297
- const ruleB = state.rules.get(b);
298
- if (!ruleA || !ruleB) return 0;
299
- return ruleB.priority - ruleA.priority;
300
- });
301
- };
302
-
303
- export const cloneState = <
304
- TContext = unknown,
305
- TConsequences extends ConsequenceDefinitions = DefaultConsequences,
306
- >(
307
- state: MutableEngineState<TContext, TConsequences>,
308
- ): MutableEngineState<TContext, TConsequences> => {
309
- const newState = createInitialState<TContext, TConsequences>();
310
-
311
- for (const [id, rule] of state.rules) {
312
- newState.rules.set(id, { ...rule });
313
- }
314
-
315
- for (const [id, ruleSet] of state.ruleSets) {
316
- newState.ruleSets.set(id, { ...ruleSet, ruleIds: [...ruleSet.ruleIds] });
317
- }
318
-
319
- newState.ruleOrder.push(...state.ruleOrder);
320
-
321
- return newState;
322
- };
package/src/index.ts DELETED
@@ -1,303 +0,0 @@
1
- export type {
2
- ArrayCondition,
3
- ArrayOperator,
4
- BooleanCondition,
5
- BooleanOperator,
6
- Condition,
7
- ConditionGroup,
8
- CustomCondition,
9
- DateCondition,
10
- DateOperator,
11
- EvaluationResult,
12
- GroupEvaluationResult,
13
- LogicalOperator,
14
- NumberCondition,
15
- NumberOperator,
16
- StringCondition,
17
- StringOperator,
18
- } from "@f-o-t/condition-evaluator";
19
- export {
20
- ConditionGroup as ConditionGroupSchema,
21
- isConditionGroup,
22
- createEvaluator,
23
- createOperator,
24
- } from "@f-o-t/condition-evaluator";
25
- export {
26
- analyzeConsequenceUsage,
27
- analyzeFieldUsage,
28
- analyzeOperatorUsage,
29
- analyzeRuleComplexity,
30
- analyzeRuleSet,
31
- type ConsequenceUsage,
32
- type FieldUsage,
33
- findLeastUsedFields,
34
- findMostComplexRules,
35
- formatRuleSetAnalysis,
36
- type OperatorUsage,
37
- type RuleComplexity,
38
- type RuleSetAnalysis,
39
- } from "./analyzer/analysis";
40
- export {
41
- all,
42
- and,
43
- any,
44
- arr,
45
- bool,
46
- type ConditionBuilder,
47
- type ConditionBuilderState,
48
- conditions,
49
- date,
50
- num,
51
- or,
52
- resetBuilderIds,
53
- str,
54
- } from "./builder/conditions";
55
- export {
56
- createRule,
57
- type RuleBuilder,
58
- type RuleBuilderState,
59
- rule,
60
- } from "./builder/rule";
61
- export {
62
- type Cache,
63
- type CacheEntry,
64
- type CacheOptions,
65
- createCache,
66
- } from "./cache/cache";
67
- export { createNoopCache } from "./cache/noop";
68
- export {
69
- type EvaluateRuleOptions,
70
- type EvaluateRulesOptions,
71
- type EvaluateRulesResult,
72
- evaluateRule,
73
- evaluateRules,
74
- } from "./core/evaluate";
75
- export {
76
- filterByCategory,
77
- filterByEnabled,
78
- filterByIds,
79
- filterByTags,
80
- filterRules,
81
- } from "./core/filter";
82
- export {
83
- type GroupByField,
84
- type GroupedRules,
85
- groupByCategory,
86
- groupByCustom,
87
- groupByEnabled,
88
- groupByPriority,
89
- groupRules,
90
- } from "./core/group";
91
- export {
92
- type SortDirection,
93
- type SortField,
94
- type SortOptions,
95
- sortByCreatedAt,
96
- sortByName,
97
- sortByPriority,
98
- sortByUpdatedAt,
99
- sortRules,
100
- } from "./core/sort";
101
- export { createEngine, type Engine } from "./engine/engine";
102
- export {
103
- addRule,
104
- addRuleSet,
105
- addRules,
106
- clearRules,
107
- cloneState,
108
- disableRule,
109
- enableRule,
110
- getRule,
111
- getRuleSet,
112
- getRuleSets,
113
- getRules,
114
- getRulesInSet,
115
- removeRule,
116
- removeRuleSet,
117
- updateRule,
118
- } from "./engine/state";
119
- export {
120
- analyzeOptimizations,
121
- buildIndex,
122
- type CategoryIndex,
123
- type FieldIndex,
124
- filterRulesForContext,
125
- getIndexStats,
126
- getRuleById,
127
- getRulesByCategory,
128
- getRulesByField,
129
- getRulesByFields,
130
- getRulesByPriority,
131
- getRulesByPriorityRange,
132
- getRulesByTag,
133
- getRulesByTags,
134
- type IndexOptions,
135
- type OptimizationSuggestion,
136
- type PriorityIndex,
137
- type RuleIndex,
138
- type TagIndex,
139
- } from "./optimizer/index-builder";
140
- export {
141
- cloneRule,
142
- deserializeRule,
143
- deserializeRuleSet,
144
- diffRuleSets,
145
- type ExportFormat,
146
- exportRules,
147
- exportToJson,
148
- type ImportOptions,
149
- type ImportResult,
150
- importFromJson,
151
- importRules,
152
- mergeRuleSets,
153
- type OrphanedReference,
154
- type SerializedRule,
155
- type SerializedRuleSet,
156
- serializeRule,
157
- serializeRuleSet,
158
- } from "./serialization/serializer";
159
- export {
160
- type BatchSimulationResult,
161
- batchSimulate,
162
- findRulesAffectedByContextChange,
163
- formatSimulationResult,
164
- type SimulationContext,
165
- type SimulationResult,
166
- simulate,
167
- simulateSingleRule,
168
- type WhatIfResult,
169
- whatIf,
170
- } from "./simulation/simulator";
171
- export type {
172
- CacheConfig,
173
- EngineConfig,
174
- EngineHooks,
175
- Logger,
176
- LogLevel,
177
- ResolvedEngineConfig,
178
- ValidationConfig,
179
- VersioningConfig,
180
- } from "./types/config";
181
- export {
182
- CacheConfigSchema,
183
- getDefaultCacheConfig,
184
- getDefaultConflictResolution,
185
- getDefaultLogLevel,
186
- getDefaultValidationConfig,
187
- getDefaultVersioningConfig,
188
- LogLevelSchema,
189
- parseCacheConfig,
190
- parseValidationConfig,
191
- parseVersioningConfig,
192
- ValidationConfigSchema,
193
- VersioningConfigSchema,
194
- } from "./types/config";
195
- export type {
196
- AggregatedConsequence,
197
- Consequence,
198
- ConsequenceDefinitions,
199
- ConsequenceInput,
200
- DefaultConsequences,
201
- InferConsequencePayload,
202
- InferConsequenceType,
203
- } from "./types/consequence";
204
- export type {
205
- ConflictResolutionStrategy,
206
- EngineExecutionResult,
207
- EvaluateConfig,
208
- EvaluateOptions,
209
- EvaluationContext,
210
- RuleEvaluationResult,
211
- } from "./types/evaluation";
212
- export {
213
- ConflictResolutionStrategySchema,
214
- EvaluateConfigSchema,
215
- EvaluateOptionsSchema,
216
- } from "./types/evaluation";
217
- export type {
218
- Rule,
219
- RuleFilters,
220
- RuleInput,
221
- RuleSchemaType,
222
- RuleSet,
223
- RuleSetInput,
224
- RuleSetSchemaType,
225
- } from "./types/rule";
226
- export { RuleSchema, RuleSetSchema } from "./types/rule";
227
- export type {
228
- CacheStats,
229
- EngineState,
230
- EngineStats,
231
- OptimizerState,
232
- RuleStats,
233
- } from "./types/state";
234
- export {
235
- CacheStatsSchema,
236
- createInitialOptimizerState,
237
- createInitialRuleStats,
238
- createInitialState,
239
- EngineStatsSchema,
240
- RuleStatsSchema,
241
- } from "./types/state";
242
- export { hashContext, hashRules } from "./utils/hash";
243
- export { generateId } from "./utils/id";
244
- export {
245
- measureTime,
246
- measureTimeAsync,
247
- type TimingResult,
248
- withTimeout,
249
- } from "./utils/time";
250
- export {
251
- type Conflict,
252
- type ConflictDetectionOptions,
253
- type ConflictType,
254
- detectConflicts,
255
- formatConflicts,
256
- getConflictsBySeverity,
257
- getConflictsByType,
258
- hasConflicts,
259
- hasErrors,
260
- } from "./validation/conflicts";
261
- export {
262
- checkIntegrity,
263
- checkRuleFieldCoverage,
264
- formatIntegrityResult,
265
- getUsedFields,
266
- getUsedOperators,
267
- type IntegrityCheckOptions,
268
- type IntegrityCheckResult,
269
- type IntegrityIssue,
270
- } from "./validation/integrity";
271
- export {
272
- createRuleValidator,
273
- parseRule,
274
- type ResolvedValidationOptions,
275
- safeParseRule,
276
- type ValidationError,
277
- ValidationErrorSchema,
278
- type ValidationOptions,
279
- ValidationOptionsSchema,
280
- type ValidationResult,
281
- ValidationResultSchema,
282
- validateConditions,
283
- validateRule,
284
- validateRuleSet,
285
- validateRules,
286
- } from "./validation/schema";
287
- export {
288
- addVersion,
289
- compareVersions,
290
- createVersionStore,
291
- formatVersionHistory,
292
- getAllVersions,
293
- getHistory,
294
- getLatestVersion,
295
- getVersion,
296
- getVersionsByChangeType,
297
- getVersionsByDateRange,
298
- pruneOldVersions,
299
- type RuleVersion,
300
- rollbackToVersion,
301
- type VersionHistory,
302
- type VersionStore,
303
- } from "./versioning/version-store";