@f-o-t/rules-engine 1.0.0 → 2.0.0

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @f-o-t/rules-engine
2
2
 
3
- A fully type-safe, functional, enterprise-grade rules orchestration engine for TypeScript. Built on top of `@f-o-t/condition-evaluator` for condition evaluation.
3
+ A fully type-safe, functional, rules orchestration engine for TypeScript. Built on top of `@f-o-t/condition-evaluator` for condition evaluation.
4
4
 
5
5
  ## Features
6
6
 
@@ -219,17 +219,72 @@ const engine = createEngine({
219
219
  // Performance monitoring
220
220
  slowRuleThresholdMs: 100,
221
221
 
222
+ // Hook timeout (prevents slow hooks from blocking)
223
+ hookTimeoutMs: 5000, // 5 second timeout
224
+
222
225
  // Lifecycle hooks
223
226
  hooks: {
224
- onBeforeEvaluation: async (context, rules) => {},
225
- onAfterEvaluation: async (result) => {},
227
+ beforeEvaluation: async (context, rules) => {},
228
+ afterEvaluation: async (result) => {},
226
229
  onRuleMatch: async (rule, context) => {},
227
230
  onRuleError: async (rule, error) => {},
228
231
  onCacheHit: async (key, result) => {},
232
+ onSlowRule: async (rule, timeMs, threshold) => {},
233
+ // Error handler for hook failures
234
+ onHookError: (hookName, error) => {
235
+ console.error(`Hook ${hookName} failed:`, error);
236
+ },
229
237
  },
230
238
  });
231
239
  ```
232
240
 
241
+ ## Zod Schemas
242
+
243
+ All configuration types are built from Zod schemas, enabling runtime validation and type inference:
244
+
245
+ ```typescript
246
+ import {
247
+ // Config schemas
248
+ CacheConfigSchema,
249
+ ValidationConfigSchema,
250
+ VersioningConfigSchema,
251
+ LogLevelSchema,
252
+
253
+ // Evaluation schemas
254
+ ConflictResolutionStrategySchema,
255
+ EvaluateOptionsSchema,
256
+
257
+ // State schemas
258
+ RuleStatsSchema,
259
+ CacheStatsSchema,
260
+ EngineStatsSchema,
261
+
262
+ // Validation schemas
263
+ ValidationErrorSchema,
264
+ ValidationResultSchema,
265
+ ValidationOptionsSchema,
266
+
267
+ // Helper functions
268
+ getDefaultCacheConfig,
269
+ getDefaultValidationConfig,
270
+ parseCacheConfig,
271
+ } from "@f-o-t/rules-engine";
272
+
273
+ // Parse and validate config with defaults
274
+ const cacheConfig = parseCacheConfig({ ttl: 30000 });
275
+ // Result: { enabled: true, ttl: 30000, maxSize: 1000 }
276
+
277
+ // Get default config
278
+ const defaults = getDefaultCacheConfig();
279
+ // Result: { enabled: true, ttl: 60000, maxSize: 1000 }
280
+
281
+ // Use schemas for custom validation
282
+ const result = CacheConfigSchema.safeParse(userInput);
283
+ if (!result.success) {
284
+ console.error(result.error.issues);
285
+ }
286
+ ```
287
+
233
288
  ## Validation
234
289
 
235
290
  ```typescript
@@ -360,11 +415,26 @@ import {
360
415
  } from "@f-o-t/rules-engine";
361
416
 
362
417
  // Export/Import
363
- const json = exportToJson(rules);
364
- const { success, rules: imported } = importFromJson(json, {
418
+ const json = exportToJson(rules, ruleSets);
419
+ const result = importFromJson(json, {
365
420
  generateNewIds: true, // Generate new IDs on import
366
421
  });
367
422
 
423
+ if (result.success) {
424
+ console.log("Imported rules:", result.rules);
425
+ console.log("Imported ruleSets:", result.ruleSets);
426
+ }
427
+
428
+ // Check for orphaned references (ruleSets referencing missing rules)
429
+ if (result.orphanedReferences.length > 0) {
430
+ for (const orphan of result.orphanedReferences) {
431
+ console.warn(
432
+ `RuleSet "${orphan.ruleSetName}" references missing rules:`,
433
+ orphan.missingRuleIds
434
+ );
435
+ }
436
+ }
437
+
368
438
  // Clone rule
369
439
  const cloned = cloneRule(rule, { generateNewId: true });
370
440
 
@@ -431,15 +501,9 @@ import {
431
501
  generateId,
432
502
  hashContext,
433
503
  hashRules,
434
- pipe,
435
- compose,
436
- identity,
437
- always,
438
- tap,
439
504
  measureTime,
440
505
  measureTimeAsync,
441
506
  withTimeout,
442
- delay,
443
507
  } from "@f-o-t/rules-engine";
444
508
 
445
509
  // Generate unique IDs
@@ -448,13 +512,6 @@ const id = generateId();
448
512
  // Hash context for caching
449
513
  const hash = hashContext({ amount: 100 });
450
514
 
451
- // Functional composition
452
- const process = pipe(
453
- (rules) => filterRules(rules, { enabled: true }),
454
- (rules) => sortByPriority(rules, "desc"),
455
- (rules) => rules.slice(0, 10)
456
- );
457
-
458
515
  // Measure execution time
459
516
  const { result, durationMs } = measureTime(() => expensiveOperation());
460
517
 
@@ -465,8 +522,9 @@ const { result: asyncResult, durationMs: asyncTime } = await measureTimeAsync(
465
522
 
466
523
  // Timeout wrapper
467
524
  const resultWithTimeout = await withTimeout(
468
- () => slowOperation(),
469
- 5000 // 5 second timeout
525
+ slowOperationPromise,
526
+ 5000, // 5 second timeout
527
+ "Operation timed out" // optional error message
470
528
  );
471
529
  ```
472
530