rulit 1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/condition.ts","../src/field.ts","../src/op.ts","../src/trace.ts","../src/registry.ts","../src/ruleset.ts","../src/zod.ts","../src/otel.ts"],"sourcesContent":["import { condition as conditionFn } from \"./condition\";\nimport { field as fieldFn } from \"./field\";\nimport { op as opObj } from \"./op\";\nimport { ruleset as rulesetFn } from \"./ruleset\";\nimport { zodEffects as zodEffectsFn, zodFacts as zodFactsFn } from \"./zod\";\nimport { registry as registryObj } from \"./registry\";\nimport { createOtelAdapter } from \"./otel\";\n\nexport const Rules = {\n ruleset: rulesetFn,\n condition: conditionFn,\n field: fieldFn,\n op: opObj,\n registry: registryObj,\n zodFacts: zodFactsFn,\n zodEffects: zodEffectsFn,\n otel: {\n createAdapter: createOtelAdapter,\n },\n};\n\nexport {\n rulesetFn as ruleset,\n conditionFn as condition,\n fieldFn as field,\n opObj as op,\n registryObj as registry,\n zodFactsFn as zodFacts,\n zodEffectsFn as zodEffects,\n};\nexport { createOtelAdapter } from \"./otel\";\n\nexport type ActionContext<Facts, Effects> = import(\"./types\").ActionContext<Facts, Effects>;\nexport type Condition<Facts> = import(\"./types\").Condition<Facts>;\nexport type ConditionMeta<Facts> = import(\"./types\").ConditionMeta<Facts>;\nexport type ConditionTrace = import(\"./types\").ConditionTrace;\nexport type EffectsMode = import(\"./types\").EffectsMode;\nexport type MergeStrategy = import(\"./types\").MergeStrategy;\nexport type RuleActivation = import(\"./types\").RuleActivation;\nexport type RuleMeta = import(\"./types\").RuleMeta;\nexport type RulesetGraph = import(\"./types\").RulesetGraph;\nexport type GraphNode = import(\"./types\").GraphNode;\nexport type GraphEdge = import(\"./types\").GraphEdge;\nexport type RuleTrace = import(\"./types\").RuleTrace;\nexport type RunOptions = import(\"./types\").RunOptions;\nexport type RunResult<Effects> = import(\"./types\").RunResult<Effects>;\nexport type TraceRun = import(\"./types\").TraceRun;\nexport type TelemetryAdapter = import(\"./types\").TelemetryAdapter;\nexport type TelemetryAttributes = import(\"./types\").TelemetryAttributes;\nexport type Field<T, P extends import(\"./field\").Path<T>> = import(\"./field\").Field<T, P>;\nexport type Path<T> = import(\"./field\").Path<T>;\nexport type PathValue<T, P extends import(\"./field\").Path<T>> = import(\"./field\").PathValue<T, P>;\n","import type { Condition, ConditionMeta, ConditionTrace } from \"./types\";\n\ntype ConditionDetails<Facts> = (facts: Facts) => Pick<ConditionTrace, \"left\" | \"op\" | \"right\">;\ntype ConditionOptions<Facts> = {\n details?: ConditionDetails<Facts>;\n reasonCode?: string;\n};\n\n/**\n * Create a condition with optional trace details and a reason code.\n *\n * @example\n * ```ts\n * const isAdult = Rules.condition(\"is adult\", (facts: Facts) => facts.user.age >= 18, {\n * details: (facts) => ({ left: facts.user.age, op: \">=\", right: 18 }),\n * reasonCode: \"AGE_18\",\n * });\n * ```\n */\nexport function condition<Facts>(\n label: string,\n test: (facts: Facts) => boolean,\n options?: ConditionDetails<Facts> | ConditionOptions<Facts>,\n): Condition<Facts> {\n const meta: ConditionMeta<Facts> = {\n label,\n reasonCode: typeof options === \"object\" ? options?.reasonCode : undefined,\n kind: \"atomic\",\n };\n\n const cond = (facts: Facts) => {\n const result = test(facts);\n const details = typeof options === \"function\" ? options : options?.details;\n const info = details ? details(facts) : undefined;\n return {\n label,\n result,\n left: info?.left,\n op: info?.op,\n right: info?.right,\n reasonCode: meta.reasonCode,\n };\n };\n cond.meta = meta;\n return cond;\n}\n","import { condition } from \"./condition\";\nimport type { Condition } from \"./types\";\n\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined;\n\ntype DotPrefix<T extends string> = T extends \"\" ? \"\" : `.${T}`;\n\ntype PathImpl<T, Key extends keyof T> = Key extends string\n ? T[Key] extends Primitive\n ? Key\n : T[Key] extends Array<unknown>\n ? Key\n : T[Key] extends Date\n ? Key\n : Key | `${Key}${DotPrefix<Path<T[Key]>>}`\n : never;\n\nexport type Path<T> = T extends object ? { [K in keyof T]-?: PathImpl<T, K> }[keyof T] : never;\n\nexport type PathValue<T, P extends Path<T>> = P extends `${infer Key}.${infer Rest}`\n ? Key extends keyof T\n ? Rest extends Path<T[Key]>\n ? PathValue<T[Key], Rest>\n : never\n : never\n : P extends keyof T\n ? T[P]\n : never;\n\ntype FieldOperators<T, P extends Path<T>> =\n PathValue<T, P> extends number\n ? NumberOperators<T, P>\n : PathValue<T, P> extends string\n ? StringOperators<T, P>\n : PathValue<T, P> extends boolean\n ? BooleanOperators<T, P>\n : PathValue<T, P> extends Date\n ? DateOperators<T, P>\n : PathValue<T, P> extends Array<infer U>\n ? ArrayOperators<T, P, U>\n : BaseOperators<T, P>;\n\ntype BaseOperators<T, P extends Path<T>> = {\n eq: (value: PathValue<T, P>) => Condition<T>;\n in: (values: PathValue<T, P>[]) => Condition<T>;\n};\n\ntype NumberOperators<T, P extends Path<T>> = BaseOperators<T, P> & {\n gt: (value: number) => Condition<T>;\n gte: (value: number) => Condition<T>;\n lt: (value: number) => Condition<T>;\n lte: (value: number) => Condition<T>;\n between: (min: number, max: number) => Condition<T>;\n};\n\ntype StringOperators<T, P extends Path<T>> = BaseOperators<T, P> & {\n contains: (value: string) => Condition<T>;\n startsWith: (value: string) => Condition<T>;\n matches: (value: RegExp) => Condition<T>;\n};\n\ntype BooleanOperators<T, P extends Path<T>> = BaseOperators<T, P> & {\n isTrue: () => Condition<T>;\n isFalse: () => Condition<T>;\n};\n\ntype DateOperators<T, P extends Path<T>> = BaseOperators<T, P> & {\n before: (value: Date) => Condition<T>;\n after: (value: Date) => Condition<T>;\n};\n\ntype ArrayOperators<T, P extends Path<T>, U> = BaseOperators<T, P> & {\n contains: (value: U) => Condition<T>;\n any: (predicate: (item: U) => boolean, label?: string) => Condition<T>;\n all: (predicate: (item: U) => boolean, label?: string) => Condition<T>;\n};\n\nexport type Field<T, P extends Path<T>> = {\n path: P;\n get: (facts: T) => PathValue<T, P>;\n} & FieldOperators<T, P>;\n\n/**\n * Create a typed field accessor for a facts model.\n *\n * @example\n * ```ts\n * const factsField = Rules.field<Facts>();\n * const isAdult = factsField(\"user.age\").gte(18);\n * ```\n */\nexport function field<T>(): <P extends Path<T>>(path: P) => Field<T, P>;\n/**\n * Create a typed field accessor for a specific path.\n *\n * @example\n * ```ts\n * const isVip = Rules.field<Facts>()(\"user.tags\").contains(\"vip\");\n * ```\n */\nexport function field<T, P extends Path<T>>(path: P): Field<T, P>;\nexport function field<T, P extends Path<T>>(path?: P) {\n if (path === undefined) {\n return (nextPath: P) => createField<T, P>(nextPath);\n }\n return createField<T, P>(path);\n}\n\nfunction createField<T, P extends Path<T>>(path: P): Field<T, P> {\n const getter = (facts: T) => getPathValue(facts, path) as PathValue<T, P>;\n\n const base = {\n path,\n get: getter,\n eq: (value: PathValue<T, P>) =>\n condition<T>(\n `${path} == ${String(value)}`,\n (facts) => getter(facts) === value,\n (facts) => ({\n left: getter(facts),\n op: \"==\",\n right: value,\n }),\n ),\n in: (values: PathValue<T, P>[]) =>\n condition<T>(\n `${path} in [${values.length}]`,\n (facts) => values.includes(getter(facts)),\n (facts) => ({\n left: getter(facts),\n op: \"in\",\n right: values,\n }),\n ),\n } as unknown as Field<T, P>;\n\n return addOperators(base);\n}\n\nfunction addOperators<T, P extends Path<T>>(base: Field<T, P>): Field<T, P> {\n const anyBase = base as Field<T, P> & Record<string, unknown>;\n\n anyBase.gt = (value: number) =>\n condition<T>(\n `${base.path} > ${value}`,\n (facts) => Number(base.get(facts)) > value,\n (facts) => ({\n left: base.get(facts),\n op: \">\",\n right: value,\n }),\n );\n\n anyBase.gte = (value: number) =>\n condition<T>(\n `${base.path} >= ${value}`,\n (facts) => Number(base.get(facts)) >= value,\n (facts) => ({\n left: base.get(facts),\n op: \">=\",\n right: value,\n }),\n );\n\n anyBase.lt = (value: number) =>\n condition<T>(\n `${base.path} < ${value}`,\n (facts) => Number(base.get(facts)) < value,\n (facts) => ({\n left: base.get(facts),\n op: \"<\",\n right: value,\n }),\n );\n\n anyBase.lte = (value: number) =>\n condition<T>(\n `${base.path} <= ${value}`,\n (facts) => Number(base.get(facts)) <= value,\n (facts) => ({\n left: base.get(facts),\n op: \"<=\",\n right: value,\n }),\n );\n\n anyBase.between = (min: number, max: number) =>\n condition<T>(\n `${base.path} between ${min} and ${max}`,\n (facts) => {\n const value = Number(base.get(facts));\n return value >= min && value <= max;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"between\",\n right: [min, max],\n }),\n );\n\n anyBase.contains = (value: unknown) =>\n condition<T>(\n `${base.path} contains ${String(value)}`,\n (facts) => {\n const current = base.get(facts) as unknown;\n if (typeof current === \"string\") {\n return current.includes(String(value));\n }\n if (Array.isArray(current)) {\n return current.includes(value);\n }\n return false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"contains\",\n right: value,\n }),\n );\n\n anyBase.startsWith = (value: string) =>\n condition<T>(\n `${base.path} startsWith ${value}`,\n (facts) => {\n const current = base.get(facts);\n return typeof current === \"string\" ? current.startsWith(value) : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"startsWith\",\n right: value,\n }),\n );\n\n anyBase.matches = (value: RegExp) =>\n condition<T>(\n `${base.path} matches ${value.toString()}`,\n (facts) => {\n const current = base.get(facts);\n return typeof current === \"string\" ? value.test(current) : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"matches\",\n right: value.toString(),\n }),\n );\n\n anyBase.isTrue = () =>\n condition<T>(\n `${base.path} is true`,\n (facts) => base.get(facts) === true,\n (facts) => ({\n left: base.get(facts),\n op: \"is\",\n right: true,\n }),\n );\n\n anyBase.isFalse = () =>\n condition<T>(\n `${base.path} is false`,\n (facts) => base.get(facts) === false,\n (facts) => ({\n left: base.get(facts),\n op: \"is\",\n right: false,\n }),\n );\n\n anyBase.before = (value: Date) =>\n condition<T>(\n `${base.path} before ${value.toISOString()}`,\n (facts) => {\n const current = base.get(facts);\n return current instanceof Date ? current.getTime() < value.getTime() : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"before\",\n right: value.toISOString(),\n }),\n );\n\n anyBase.after = (value: Date) =>\n condition<T>(\n `${base.path} after ${value.toISOString()}`,\n (facts) => {\n const current = base.get(facts);\n return current instanceof Date ? current.getTime() > value.getTime() : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"after\",\n right: value.toISOString(),\n }),\n );\n\n anyBase.any = (predicate: (item: unknown) => boolean, label = `${base.path} any`) =>\n condition<T>(\n label,\n (facts) => {\n const current = base.get(facts);\n return Array.isArray(current) ? current.some(predicate) : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"any\",\n right: \"predicate\",\n }),\n );\n\n anyBase.all = (predicate: (item: unknown) => boolean, label = `${base.path} all`) =>\n condition<T>(\n label,\n (facts) => {\n const current = base.get(facts);\n return Array.isArray(current) ? current.every(predicate) : false;\n },\n (facts) => ({\n left: base.get(facts),\n op: \"all\",\n right: \"predicate\",\n }),\n );\n\n return base;\n}\n\nfunction getPathValue<T, P extends Path<T>>(facts: T, path: P): unknown {\n const parts = String(path).split(\".\");\n let current: unknown = facts;\n\n for (const part of parts) {\n if (current && typeof current === \"object\") {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n\n return current;\n}\n","import { condition } from \"./condition\";\nimport type { Condition, ConditionMeta, ConditionTrace } from \"./types\";\n\ntype ConditionLabel = string | { label: string };\n\nfunction resolveLabel(defaultLabel: string, label?: ConditionLabel): string {\n if (!label) {\n return defaultLabel;\n }\n return typeof label === \"string\" ? label : label.label;\n}\n\n/**\n * Boolean and extensibility operators for composing conditions.\n */\nexport const op = { and, or, not, custom, register, use, has, list };\n\ntype OperatorFactory<Facts, Args extends unknown[]> = (...args: Args) => Condition<Facts>;\n\nconst registry: Record<string, OperatorFactory<unknown, unknown[]>> = {};\n\n/**\n * Combine conditions with logical AND.\n *\n * @example\n * ```ts\n * const combined = Rules.op.and(isAdult, isVip);\n * ```\n */\nfunction and<Facts>(...conditions: Condition<Facts>[]): Condition<Facts>;\nfunction and<Facts>(label: ConditionLabel, ...conditions: Condition<Facts>[]): Condition<Facts>;\nfunction and<Facts>(...args: Array<Condition<Facts> | ConditionLabel>): Condition<Facts> {\n const { label, conditions } = splitArgs<Facts>(\"and\", args);\n const meta: ConditionMeta<Facts> = { label, kind: \"and\", children: conditions };\n const cond = (facts: Facts) => {\n const children = conditions.map((cond) => cond(facts));\n const result = children.every((child) => child.result);\n return {\n label,\n result,\n op: \"and\",\n left: children.map((child) => child.label),\n right: undefined,\n children,\n };\n };\n cond.meta = meta;\n return cond;\n}\n\n/**\n * Combine conditions with logical OR.\n *\n * @example\n * ```ts\n * const combined = Rules.op.or(isAdult, isVip);\n * ```\n */\nfunction or<Facts>(...conditions: Condition<Facts>[]): Condition<Facts>;\nfunction or<Facts>(label: ConditionLabel, ...conditions: Condition<Facts>[]): Condition<Facts>;\nfunction or<Facts>(...args: Array<Condition<Facts> | ConditionLabel>): Condition<Facts> {\n const { label, conditions } = splitArgs<Facts>(\"or\", args);\n const meta: ConditionMeta<Facts> = { label, kind: \"or\", children: conditions };\n const cond = (facts: Facts) => {\n const children = conditions.map((cond) => cond(facts));\n const result = children.some((child) => child.result);\n return {\n label,\n result,\n op: \"or\",\n left: children.map((child) => child.label),\n right: undefined,\n children,\n };\n };\n cond.meta = meta;\n return cond;\n}\n\n/**\n * Negate a condition.\n *\n * @example\n * ```ts\n * const notVip = Rules.op.not(isVip);\n * ```\n */\nfunction not<Facts>(conditionToNegate: Condition<Facts>): Condition<Facts>;\nfunction not<Facts>(label: ConditionLabel, conditionToNegate: Condition<Facts>): Condition<Facts>;\nfunction not<Facts>(\n labelOrCondition: ConditionLabel | Condition<Facts>,\n maybeCondition?: Condition<Facts>,\n): Condition<Facts> {\n const label = resolveLabel(\n \"not\",\n typeof labelOrCondition === \"function\" ? undefined : labelOrCondition,\n );\n const conditionToNegate =\n typeof labelOrCondition === \"function\"\n ? labelOrCondition\n : (maybeCondition as Condition<Facts>);\n\n const meta: ConditionMeta<Facts> = {\n label,\n kind: \"not\",\n children: [conditionToNegate],\n };\n const cond = (facts: Facts) => {\n const child = conditionToNegate(facts);\n return {\n label,\n result: !child.result,\n op: \"not\",\n left: child.label,\n right: undefined,\n children: [child],\n };\n };\n cond.meta = meta;\n return cond;\n}\n\n/**\n * Create a custom condition with an optional reason code and trace details.\n *\n * @example\n * ```ts\n * const isEven = Rules.op.custom(\"is-even\", (facts: { value: number }) => facts.value % 2 === 0);\n * ```\n */\nfunction custom<Facts>(\n label: string,\n test: (facts: Facts) => boolean,\n options?:\n | ((facts: Facts) => Pick<ConditionTrace, \"left\" | \"op\" | \"right\">)\n | {\n details?: (facts: Facts) => Pick<ConditionTrace, \"left\" | \"op\" | \"right\">;\n reasonCode?: string;\n },\n): Condition<Facts> {\n return condition(label, test, options);\n}\n\n/**\n * Register a custom operator factory by name.\n *\n * @example\n * ```ts\n * Rules.op.register(\"positive\", () => Rules.condition(\"positive\", (facts: { value: number }) => facts.value > 0));\n * ```\n */\nfunction register<Facts, Args extends unknown[]>(\n name: string,\n factory: OperatorFactory<Facts, Args>,\n): void {\n if (registry[name]) {\n throw new Error(`Operator \"${name}\" is already registered.`);\n }\n registry[name] = factory as OperatorFactory<unknown, unknown[]>;\n}\n\n/**\n * Create a condition using a registered operator.\n *\n * @example\n * ```ts\n * const positive = Rules.op.use<{ value: number }, []>(\"positive\");\n * ```\n */\nfunction use<Facts, Args extends unknown[]>(name: string, ...args: Args): Condition<Facts> {\n const factory = registry[name];\n if (!factory) {\n throw new Error(`Operator \"${name}\" is not registered.`);\n }\n return factory(...args) as Condition<Facts>;\n}\n\n/**\n * Check if a custom operator name is registered.\n *\n * @example\n * ```ts\n * if (!Rules.op.has(\"positive\")) { ... }\n * ```\n */\nfunction has(name: string): boolean {\n return Boolean(registry[name]);\n}\n\n/**\n * List registered operator names.\n *\n * @example\n * ```ts\n * const names = Rules.op.list();\n * ```\n */\nfunction list(): string[] {\n return Object.keys(registry).sort();\n}\n\nfunction splitArgs<Facts>(\n defaultLabel: string,\n args: Array<Condition<Facts> | ConditionLabel>,\n): { label: string; conditions: Condition<Facts>[] } {\n if (args.length === 0) {\n return { label: defaultLabel, conditions: [] };\n }\n\n const [first, ...rest] = args;\n if (typeof first === \"function\") {\n return { label: defaultLabel, conditions: args as Condition<Facts>[] };\n }\n\n const conditions = rest as Condition<Facts>[];\n return {\n label: resolveLabel(defaultLabel, first),\n conditions,\n };\n}\n","import type { ConditionTrace, RuleTrace } from \"./types\";\n\nexport function explainTrace(trace: RuleTrace[], name?: string): string {\n const header = name ? `Ruleset ${name}` : \"Ruleset\";\n const lines = [header];\n\n for (const rule of trace) {\n const tags = rule.meta?.tags?.length ? ` [tags: ${rule.meta.tags.join(\", \")}]` : \"\";\n const reason = rule.meta?.reasonCode ? ` [reason: ${rule.meta.reasonCode}]` : \"\";\n const skipped = rule.skippedReason ? ` (skipped: ${rule.skippedReason})` : \"\";\n lines.push(\n `- Rule ${rule.ruleId}: ${rule.matched ? \"matched\" : \"skipped\"}${skipped}${tags}${reason}`,\n );\n for (const condition of rule.conditions) {\n lines.push(...renderCondition(condition, 2));\n }\n for (const note of rule.notes) {\n lines.push(` - note: ${note}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatCondition(condition: ConditionTrace): string {\n const parts = [`[${condition.result ? \"true\" : \"false\"}]`, condition.label];\n if (condition.reasonCode) {\n parts.push(`{reason: ${condition.reasonCode}}`);\n }\n if (condition.op) {\n const left = formatValue(condition.left);\n const right = formatValue(condition.right);\n parts.push(`(${left} ${condition.op} ${right})`);\n }\n return parts.join(\" \");\n}\n\nfunction renderCondition(condition: ConditionTrace, indent: number): string[] {\n const pad = \" \".repeat(indent);\n const lines = [`${pad}- ${formatCondition(condition)}`];\n if (condition.children && condition.children.length > 0) {\n for (const child of condition.children) {\n lines.push(...renderCondition(child, indent + 2));\n }\n }\n return lines;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === \"string\") {\n return `\"${value}\"`;\n }\n return String(value);\n}\n","import type { RuleTrace, RulesetGraph, TraceRun } from \"./types\";\n\ntype GraphSource = {\n graph: () => RulesetGraph;\n toMermaid: () => string;\n};\n\ntype RegistryEntry = {\n id: string;\n name?: string;\n createdAt: number;\n source: GraphSource;\n traces: TraceRun[];\n};\n\ntype RegistryListItem = {\n id: string;\n name?: string;\n createdAt: number;\n};\n\nconst entries = new Map<string, RegistryEntry>();\nconst nameIndex = new Map<string, string>();\nlet counter = 0;\nlet traceCounter = 0;\nconst traceLimit = 25;\n\nfunction makeId() {\n return `ruleset-${counter++}`;\n}\n\n/**\n * In-memory registry of rulesets created in this process.\n */\nexport const registry = {\n /**\n * Register a ruleset in the global registry.\n *\n * @example\n * ```ts\n * const rs = Rules.ruleset<Facts, Effects>(\"eligibility\");\n * Rules.registry.list();\n * ```\n */\n register(source: GraphSource, name?: string): string {\n const id = makeId();\n entries.set(id, { id, name, createdAt: Date.now(), source, traces: [] });\n if (name) {\n nameIndex.set(name, id);\n }\n return id;\n },\n\n /**\n * List all registered rulesets.\n *\n * @example\n * ```ts\n * const list = Rules.registry.list();\n * ```\n */\n list(): RegistryListItem[] {\n return Array.from(entries.values()).map(({ id, name, createdAt }) => ({\n id,\n name,\n createdAt,\n }));\n },\n\n /**\n * Get a graph by id or ruleset name.\n *\n * @example\n * ```ts\n * const graph = Rules.registry.getGraph(\"eligibility\");\n * ```\n */\n getGraph(idOrName: string): RulesetGraph | undefined {\n const entry = getEntry(idOrName);\n return entry?.source.graph();\n },\n\n /**\n * Get Mermaid output by id or ruleset name.\n *\n * @example\n * ```ts\n * const mermaid = Rules.registry.getMermaid(\"eligibility\");\n * ```\n */\n getMermaid(idOrName: string): string | undefined {\n const entry = getEntry(idOrName);\n return entry?.source.toMermaid();\n },\n\n /**\n * Record a trace run for a ruleset. Keeps a rolling window of traces.\n *\n * @example\n * ```ts\n * Rules.registry.recordTrace(\"eligibility\", trace, fired);\n * ```\n */\n recordTrace(\n idOrName: string,\n trace: RuleTrace[],\n fired: string[],\n facts: unknown,\n ): TraceRun | undefined {\n const entry = getEntry(idOrName);\n if (!entry) {\n return undefined;\n }\n const run: TraceRun = {\n id: `trace-${traceCounter++}`,\n createdAt: Date.now(),\n facts,\n fired,\n trace,\n };\n entry.traces.push(run);\n if (entry.traces.length > traceLimit) {\n entry.traces.splice(0, entry.traces.length - traceLimit);\n }\n return run;\n },\n\n /**\n * List trace runs for a ruleset.\n *\n * @example\n * ```ts\n * const traces = Rules.registry.listTraces(\"eligibility\");\n * ```\n */\n listTraces(idOrName: string): TraceRun[] {\n const entry = getEntry(idOrName);\n return entry ? [...entry.traces] : [];\n },\n\n /**\n * Get a trace by id for a ruleset.\n *\n * @example\n * ```ts\n * const trace = Rules.registry.getTrace(\"eligibility\", \"trace-0\");\n * ```\n */\n getTrace(idOrName: string, traceId: string): TraceRun | undefined {\n const entry = getEntry(idOrName);\n return entry?.traces.find((run) => run.id === traceId);\n },\n\n /**\n * Clear the registry (useful in tests).\n *\n * @example\n * ```ts\n * Rules.registry.clear();\n * ```\n */\n clear(): void {\n entries.clear();\n nameIndex.clear();\n traceCounter = 0;\n },\n};\n\nfunction getEntry(idOrName: string): RegistryEntry | undefined {\n const byId = entries.get(idOrName);\n if (byId) {\n return byId;\n }\n const id = nameIndex.get(idOrName);\n return id ? entries.get(id) : undefined;\n}\n","import type {\n ActionContext,\n Condition,\n GraphEdge,\n GraphNode,\n RulesetGraph,\n MergeStrategy,\n RuleMeta,\n RunOptions,\n RunResult,\n RuleTrace,\n ActionResult,\n AsyncActionResult,\n TelemetryAdapter,\n TelemetryAttributes,\n} from \"./types\";\nimport { field as fieldFactory } from \"./field\";\nimport { explainTrace } from \"./trace\";\nimport { registry } from \"./registry\";\n\ntype Rule<Facts, Effects> = {\n id: string;\n priority: number;\n order: number;\n conditions: Condition<Facts>[];\n action: (ctx: ActionContext<Facts, Effects>) => AsyncActionResult<Effects>;\n meta?: RuleMeta;\n};\n\ntype DefaultEffectsFactory<Effects> = () => Effects;\n\ntype Engine<Facts, Effects> = {\n run: (input: { facts: Facts } & RunOptions) => RunResult<Effects>;\n runAsync: (input: { facts: Facts } & RunOptions) => Promise<RunResult<Effects>>;\n};\n\ntype RulesetBuilderWithDefaults<Facts, Effects> = RulesetBuilderImpl<Facts, Effects, true>;\n\ntype RulesetBuilder<Facts, Effects, HasDefaults extends boolean> = Omit<\n RulesetBuilderImpl<Facts, Effects, HasDefaults>,\n \"compile\"\n> &\n (HasDefaults extends true ? { compile(): Engine<Facts, Effects> } : { compile: never });\n\ntype RuleBuilder<Facts, Effects, HasDefaults extends boolean, HasThen extends boolean> = Omit<\n RuleBuilderImpl<Facts, Effects, HasDefaults, HasThen>,\n \"end\"\n> &\n (HasThen extends true ? { end(): RulesetBuilder<Facts, Effects, HasDefaults> } : { end: never });\n\nclass RulesetBuilderImpl<Facts, Effects, HasDefaults extends boolean> {\n private readonly name?: string;\n private readonly rules: Rule<Facts, Effects>[] = [];\n private defaultEffectsFactory?: DefaultEffectsFactory<Effects>;\n private validateFactsFn?: (facts: Facts) => void;\n private validateEffectsFn?: (effects: Effects) => void;\n private nextOrder = 0;\n private registryId?: string;\n private telemetryAdapter?: TelemetryAdapter;\n\n constructor(name?: string) {\n this.name = name;\n }\n\n /**\n * Set the default effects factory. Required before compile().\n *\n * @example\n * ```ts\n * const rs = Rules.ruleset<Facts, Effects>(\"rs\")\n * .defaultEffects(() => ({ flags: [] }));\n * ```\n */\n defaultEffects(factory: DefaultEffectsFactory<Effects>): RulesetBuilder<Facts, Effects, true> {\n this.defaultEffectsFactory = factory;\n return this as unknown as RulesetBuilder<Facts, Effects, true>;\n }\n\n /**\n * Provide a validation function for facts. Called before each run.\n *\n * @example\n * ```ts\n * const rs = Rules.ruleset<Facts, Effects>(\"validate\")\n * .validateFacts((facts) => {\n * if (!facts.user) throw new Error(\"missing user\");\n * });\n * ```\n */\n validateFacts(validator: (facts: Facts) => void): RulesetBuilder<Facts, Effects, HasDefaults> {\n this.validateFactsFn = validator;\n return this as unknown as RulesetBuilder<Facts, Effects, HasDefaults>;\n }\n\n /**\n * Provide a validation function for effects. Called after default effects creation\n * and after each run completes.\n *\n * @example\n * ```ts\n * const rs = Rules.ruleset<Facts, Effects>(\"validate\")\n * .validateEffects((effects) => {\n * if (!Array.isArray(effects.flags)) throw new Error(\"invalid effects\");\n * });\n * ```\n */\n validateEffects(\n validator: (effects: Effects) => void,\n ): RulesetBuilder<Facts, Effects, HasDefaults> {\n this.validateEffectsFn = validator;\n return this as unknown as RulesetBuilder<Facts, Effects, HasDefaults>;\n }\n\n /**\n * Attach telemetry adapter (OpenTelemetry-compatible).\n *\n * @example\n * ```ts\n * const adapter = Rules.otel.createAdapter(trace.getTracer(\"rulit\"));\n * Rules.ruleset(\"rs\").telemetry(adapter);\n * ```\n */\n telemetry(adapter: TelemetryAdapter): RulesetBuilder<Facts, Effects, HasDefaults> {\n this.telemetryAdapter = adapter;\n return this as unknown as RulesetBuilder<Facts, Effects, HasDefaults>;\n }\n\n _setRegistryId(id: string): void {\n this.registryId = id;\n }\n\n /**\n * Add a new rule to the ruleset.\n *\n * @example\n * ```ts\n * Rules.ruleset<Facts, Effects>(\"rs\")\n * .defaultEffects(() => ({ flags: [] }))\n * .rule(\"vip\")\n * .when(factsField(\"user.tags\").contains(\"vip\"))\n * .then(({ effects }) => effects.flags.push(\"vip\"))\n * .end();\n * ```\n */\n rule(id: string): RuleBuilder<Facts, Effects, HasDefaults, false> {\n return new RuleBuilderImpl(this, id) as unknown as RuleBuilder<\n Facts,\n Effects,\n HasDefaults,\n false\n >;\n }\n\n /**\n * Create a typed field helper bound to the facts type.\n *\n * @example\n * ```ts\n * const factsField = Rules.ruleset<Facts, Effects>(\"rs\").field();\n * const isAdult = factsField(\"user.age\").gte(18);\n * ```\n */\n field() {\n return fieldFactory<Facts>();\n }\n\n _addRule(rule: Rule<Facts, Effects>): void {\n this.rules.push(rule);\n }\n\n _nextOrder(): number {\n const order = this.nextOrder;\n this.nextOrder += 1;\n return order;\n }\n\n /**\n * Export a graph representation of the ruleset.\n *\n * @example\n * ```ts\n * const graph = ruleset.graph();\n * ```\n */\n graph(): RulesetGraph {\n const nodes: GraphNode[] = [];\n const edges: GraphEdge[] = [];\n const rulesetId = `ruleset:${this.name ?? \"ruleset\"}`;\n\n nodes.push({\n id: rulesetId,\n type: \"ruleset\",\n label: this.name ?? \"ruleset\",\n });\n\n let conditionCounter = 0;\n\n const visitCondition = (condition: Condition<Facts>, parentId: string) => {\n const meta = condition.meta;\n const conditionId = `condition:${conditionCounter++}`;\n nodes.push({\n id: conditionId,\n type: \"condition\",\n label: meta?.label ?? \"condition\",\n reasonCode: meta?.reasonCode,\n });\n edges.push({ from: parentId, to: conditionId });\n\n if (meta?.children && meta.children.length > 0) {\n for (const child of meta.children) {\n visitCondition(child, conditionId);\n }\n }\n };\n\n for (const rule of this.rules) {\n const ruleId = `rule:${rule.id}`;\n nodes.push({\n id: ruleId,\n type: \"rule\",\n label: rule.id,\n reasonCode: rule.meta?.reasonCode,\n tags: rule.meta?.tags,\n description: rule.meta?.description,\n version: rule.meta?.version,\n });\n edges.push({ from: rulesetId, to: ruleId });\n\n for (const condition of rule.conditions) {\n visitCondition(condition, ruleId);\n }\n }\n\n return { nodes, edges };\n }\n\n /**\n * Export a Mermaid flowchart for visualization.\n *\n * @example\n * ```ts\n * const mermaid = ruleset.toMermaid();\n * ```\n */\n toMermaid(): string {\n const graph = this.graph();\n const idMap = new Map<string, string>();\n let counter = 0;\n\n for (const node of graph.nodes) {\n idMap.set(node.id, `n${counter++}`);\n }\n\n const lines: string[] = [\"flowchart TD\"];\n\n for (const node of graph.nodes) {\n const id = idMap.get(node.id);\n if (!id) {\n continue;\n }\n const reason = node.reasonCode ? ` [reason: ${node.reasonCode}]` : \"\";\n const tags = node.tags?.length ? ` [tags: ${node.tags.join(\", \")}]` : \"\";\n const label = `${capitalize(node.type)}: ${node.label}${tags}${reason}`;\n lines.push(` ${id}[\"${label}\"]`);\n }\n\n for (const edge of graph.edges) {\n const from = idMap.get(edge.from);\n const to = idMap.get(edge.to);\n if (from && to) {\n lines.push(` ${from} --> ${to}`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Compile the ruleset into an engine.\n *\n * @example\n * ```ts\n * const engine = Rules.ruleset<Facts, Effects>(\"rs\")\n * .defaultEffects(() => ({ flags: [] }))\n * .compile();\n * ```\n */\n compile(this: RulesetBuilderWithDefaults<Facts, Effects>): Engine<Facts, Effects> {\n const defaultEffectsFactory = this.defaultEffectsFactory;\n if (!defaultEffectsFactory) {\n throw new Error(\"defaultEffects() is required before compile().\");\n }\n\n const sortedRules = [...this.rules].sort((a, b) => {\n if (a.priority !== b.priority) {\n return b.priority - a.priority;\n }\n return a.order - b.order;\n });\n\n return {\n run: ({\n facts,\n activation = \"all\",\n effectsMode = \"mutable\",\n mergeStrategy = \"assign\",\n rollbackOnError = false,\n includeTags,\n excludeTags,\n }) => {\n return runWithSpan(\n this.telemetryAdapter,\n \"rulit.run\",\n rulesetSpanAttrs(this.name, this.registryId),\n () =>\n runSync({\n facts,\n activation,\n effectsMode,\n mergeStrategy,\n rollbackOnError,\n includeTags,\n excludeTags,\n rules: sortedRules,\n defaultEffectsFactory,\n validateFactsFn: this.validateFactsFn,\n validateEffectsFn: this.validateEffectsFn,\n registryId: this.registryId,\n rulesetName: this.name,\n telemetryAdapter: this.telemetryAdapter,\n }),\n );\n },\n runAsync: async ({\n facts,\n activation = \"all\",\n effectsMode = \"mutable\",\n mergeStrategy = \"assign\",\n rollbackOnError = false,\n includeTags,\n excludeTags,\n }) => {\n return runWithSpanAsync(\n this.telemetryAdapter,\n \"rulit.run\",\n rulesetSpanAttrs(this.name, this.registryId),\n () =>\n runAsync({\n facts,\n activation,\n effectsMode,\n mergeStrategy,\n rollbackOnError,\n includeTags,\n excludeTags,\n rules: sortedRules,\n defaultEffectsFactory,\n validateFactsFn: this.validateFactsFn,\n validateEffectsFn: this.validateEffectsFn,\n registryId: this.registryId,\n rulesetName: this.name,\n telemetryAdapter: this.telemetryAdapter,\n }),\n );\n },\n };\n }\n}\n\nclass RuleBuilderImpl<Facts, Effects, HasDefaults extends boolean, HasThen extends boolean> {\n private readonly ruleset: RulesetBuilderImpl<Facts, Effects, HasDefaults>;\n private readonly id: string;\n private priorityValue = 0;\n private conditions: Condition<Facts>[] = [];\n private action?: (ctx: ActionContext<Facts, Effects>) => AsyncActionResult<Effects>;\n private metaValue: RuleMeta = {};\n\n constructor(ruleset: RulesetBuilderImpl<Facts, Effects, HasDefaults>, id: string) {\n this.ruleset = ruleset;\n this.id = id;\n }\n\n /**\n * Set rule priority. Higher runs first.\n *\n * @example\n * ```ts\n * rule.priority(100);\n * ```\n */\n priority(value: number): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.priorityValue = value;\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Add conditions to a rule.\n *\n * @example\n * ```ts\n * rule.when(factsField(\"user.age\").gte(18), factsField(\"user.tags\").contains(\"vip\"));\n * ```\n */\n when(...conditions: Condition<Facts>[]): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.conditions = conditions;\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set rule metadata in one call.\n *\n * @example\n * ```ts\n * rule.meta({ tags: [\"vip\"], version: \"1.0.0\", reasonCode: \"VIP_RULE\" });\n * ```\n */\n meta(meta: RuleMeta): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n const tags = meta.tags ?? this.metaValue.tags;\n this.metaValue = { ...this.metaValue, ...meta, tags };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set rule tags used for filtering.\n *\n * @example\n * ```ts\n * rule.tags(\"vip\", \"adult\");\n * ```\n */\n tags(...tags: string[]): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.metaValue = { ...this.metaValue, tags };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set a human-readable description.\n *\n * @example\n * ```ts\n * rule.description(\"VIP adult rule\");\n * ```\n */\n description(description: string): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.metaValue = { ...this.metaValue, description };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set a rule version string.\n *\n * @example\n * ```ts\n * rule.version(\"1.2.3\");\n * ```\n */\n version(version: string): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.metaValue = { ...this.metaValue, version };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set a reason code for audit/explain output.\n *\n * @example\n * ```ts\n * rule.reasonCode(\"VIP_ADULT\");\n * ```\n */\n reasonCode(reasonCode: string): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.metaValue = { ...this.metaValue, reasonCode };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Enable or disable a rule.\n *\n * @example\n * ```ts\n * rule.enabled(false);\n * ```\n */\n enabled(enabled: boolean): RuleBuilder<Facts, Effects, HasDefaults, HasThen> {\n this.metaValue = { ...this.metaValue, enabled };\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, HasThen>;\n }\n\n /**\n * Set the rule action. Returning a partial effects object applies a patch.\n *\n * @example\n * ```ts\n * rule.then(({ effects }) => {\n * effects.flags.push(\"vip\");\n * });\n * ```\n */\n then(\n action: (ctx: ActionContext<Facts, Effects>) => ActionResult<Effects>,\n ): RuleBuilder<Facts, Effects, HasDefaults, true> {\n this.action = action;\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, true>;\n }\n\n /**\n * Set an async rule action. Returning a partial effects object applies a patch.\n *\n * @example\n * ```ts\n * rule.thenAsync(async ({ effects }) => {\n * effects.flags.push(\"vip\");\n * });\n * ```\n */\n thenAsync(\n action: (ctx: ActionContext<Facts, Effects>) => Promise<ActionResult<Effects>>,\n ): RuleBuilder<Facts, Effects, HasDefaults, true> {\n this.action = action;\n return this as unknown as RuleBuilder<Facts, Effects, HasDefaults, true>;\n }\n\n /**\n * Finalize the rule and return to the ruleset builder.\n *\n * @example\n * ```ts\n * ruleset.rule(\"vip\").then(() => undefined).end();\n * ```\n */\n end(\n this: RuleBuilderImpl<Facts, Effects, HasDefaults, true>,\n ): RulesetBuilder<Facts, Effects, HasDefaults> {\n if (!this.action) {\n throw new Error(\"then() is required before end().\");\n }\n\n const rule: Rule<Facts, Effects> = {\n id: this.id,\n priority: this.priorityValue,\n order: this.ruleset._nextOrder(),\n conditions: this.conditions,\n action: this.action,\n meta: Object.keys(this.metaValue).length ? this.metaValue : undefined,\n };\n this.ruleset._addRule(rule);\n return this.ruleset as unknown as RulesetBuilder<Facts, Effects, HasDefaults>;\n }\n}\n\n/**\n * Create a new ruleset builder.\n *\n * @example\n * ```ts\n * const rs = Rules.ruleset<Facts, Effects>(\"eligibility\");\n * ```\n */\nexport function ruleset<Facts, Effects>(name?: string): RulesetBuilder<Facts, Effects, false> {\n const builder = new RulesetBuilderImpl<Facts, Effects, false>(name);\n const registryId = registry.register(builder, name);\n builder._setRegistryId(registryId);\n return builder as unknown as RulesetBuilder<Facts, Effects, false>;\n}\n\nfunction getSkipReason(\n meta: RuleMeta | undefined,\n includeTags?: string[],\n excludeTags?: string[],\n): string | undefined {\n if (meta?.enabled === false) {\n return \"disabled\";\n }\n const tags = meta?.tags ?? [];\n if (includeTags && includeTags.length > 0 && !includeTags.some((tag) => tags.includes(tag))) {\n return \"tag-filtered\";\n }\n if (excludeTags && excludeTags.length > 0 && excludeTags.some((tag) => tags.includes(tag))) {\n return \"tag-excluded\";\n }\n return undefined;\n}\n\nfunction mergeEffects<Effects>(\n target: Effects,\n patch: Partial<Effects>,\n strategy: MergeStrategy,\n): void {\n if (strategy === \"assign\") {\n Object.assign(target as Record<string, unknown>, patch as Record<string, unknown>);\n return;\n }\n deepMerge(target as Record<string, unknown>, patch as Record<string, unknown>);\n}\n\nfunction deepMerge(target: Record<string, unknown>, patch: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(patch)) {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const current = target[key];\n if (!current || typeof current !== \"object\" || Array.isArray(current)) {\n target[key] = {};\n }\n deepMerge(target[key] as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n target[key] = value;\n }\n }\n}\n\nfunction cloneEffects<Effects>(effects: Effects): Effects {\n if (typeof structuredClone === \"function\") {\n return structuredClone(effects);\n }\n return JSON.parse(JSON.stringify(effects)) as Effects;\n}\n\ntype RunInput<Facts, Effects> = {\n facts: Facts;\n activation: \"all\" | \"first\";\n effectsMode: \"mutable\" | \"immutable\";\n mergeStrategy: MergeStrategy;\n rollbackOnError: boolean;\n includeTags?: string[];\n excludeTags?: string[];\n rules: Rule<Facts, Effects>[];\n defaultEffectsFactory: DefaultEffectsFactory<Effects>;\n validateFactsFn?: (facts: Facts) => void;\n validateEffectsFn?: (effects: Effects) => void;\n registryId?: string;\n rulesetName?: string;\n telemetryAdapter?: TelemetryAdapter;\n};\n\nfunction runSync<Facts, Effects>({\n facts,\n activation,\n effectsMode,\n mergeStrategy,\n rollbackOnError,\n includeTags,\n excludeTags,\n rules,\n defaultEffectsFactory,\n validateFactsFn,\n validateEffectsFn,\n registryId,\n rulesetName,\n telemetryAdapter,\n}: RunInput<Facts, Effects>): RunResult<Effects> {\n validateFactsFn?.(facts);\n let effects = defaultEffectsFactory();\n validateEffectsFn?.(effects);\n const trace: RuleTrace[] = [];\n const fired: string[] = [];\n\n for (const rule of rules) {\n const start = Date.now();\n const ruleTrace: RuleTrace = {\n ruleId: rule.id,\n matched: false,\n conditions: [],\n notes: [],\n meta: rule.meta,\n };\n\n const skipReason = getSkipReason(rule.meta, includeTags, excludeTags);\n if (skipReason) {\n ruleTrace.skippedReason = skipReason;\n ruleTrace.durationMs = Date.now() - start;\n trace.push(ruleTrace);\n continue;\n }\n\n let matched = true;\n for (const condition of rule.conditions) {\n const conditionTrace = runWithSpan(\n telemetryAdapter,\n \"rulit.condition\",\n conditionSpanAttrs(rulesetName, rule, condition),\n () => condition(facts),\n );\n ruleTrace.conditions.push(conditionTrace);\n if (!conditionTrace.result) {\n matched = false;\n break;\n }\n }\n\n ruleTrace.matched = matched;\n if (matched) {\n const workingEffects =\n effectsMode === \"immutable\" ? cloneEffects(effects) : (effects as Effects);\n const ctx: ActionContext<Facts, Effects> = {\n facts,\n effects: workingEffects,\n trace: {\n note: (message: string) => {\n ruleTrace.notes.push(message);\n },\n },\n };\n try {\n const patch = runWithSpan(\n telemetryAdapter,\n \"rulit.rule\",\n ruleSpanAttrs(rulesetName, rule),\n () => rule.action(ctx),\n );\n if (isPromise(patch)) {\n throw new Error(\"Async rule action detected. Use runAsync().\");\n }\n if (patch && typeof patch === \"object\") {\n mergeEffects(workingEffects, patch, mergeStrategy);\n }\n if (effectsMode === \"immutable\") {\n effects = workingEffects;\n }\n } catch (error) {\n ruleTrace.error = String(error);\n ruleTrace.notes.push(`error: ${String(error)}`);\n if (!rollbackOnError) {\n throw error;\n }\n if (effectsMode === \"immutable\") {\n effects = effects;\n }\n }\n fired.push(rule.id);\n }\n\n ruleTrace.durationMs = Date.now() - start;\n trace.push(ruleTrace);\n\n if (matched && activation === \"first\") {\n break;\n }\n }\n\n validateEffectsFn?.(effects);\n if (registryId) {\n registry.recordTrace(registryId, trace, fired, facts);\n }\n return {\n effects,\n fired,\n trace,\n explain: () => explainTrace(trace, rulesetName),\n };\n}\n\nasync function runAsync<Facts, Effects>({\n facts,\n activation,\n effectsMode,\n mergeStrategy,\n rollbackOnError,\n includeTags,\n excludeTags,\n rules,\n defaultEffectsFactory,\n validateFactsFn,\n validateEffectsFn,\n registryId,\n rulesetName,\n telemetryAdapter,\n}: RunInput<Facts, Effects>): Promise<RunResult<Effects>> {\n validateFactsFn?.(facts);\n let effects = defaultEffectsFactory();\n validateEffectsFn?.(effects);\n const trace: RuleTrace[] = [];\n const fired: string[] = [];\n\n for (const rule of rules) {\n const start = Date.now();\n const ruleTrace: RuleTrace = {\n ruleId: rule.id,\n matched: false,\n conditions: [],\n notes: [],\n meta: rule.meta,\n };\n\n const skipReason = getSkipReason(rule.meta, includeTags, excludeTags);\n if (skipReason) {\n ruleTrace.skippedReason = skipReason;\n ruleTrace.durationMs = Date.now() - start;\n trace.push(ruleTrace);\n continue;\n }\n\n let matched = true;\n for (const condition of rule.conditions) {\n const conditionTrace = runWithSpan(\n telemetryAdapter,\n \"rulit.condition\",\n conditionSpanAttrs(rulesetName, rule, condition),\n () => condition(facts),\n );\n ruleTrace.conditions.push(conditionTrace);\n if (!conditionTrace.result) {\n matched = false;\n break;\n }\n }\n\n ruleTrace.matched = matched;\n if (matched) {\n const workingEffects =\n effectsMode === \"immutable\" ? cloneEffects(effects) : (effects as Effects);\n const ctx: ActionContext<Facts, Effects> = {\n facts,\n effects: workingEffects,\n trace: {\n note: (message: string) => {\n ruleTrace.notes.push(message);\n },\n },\n };\n try {\n const patch = await runWithSpanAsync(\n telemetryAdapter,\n \"rulit.rule\",\n ruleSpanAttrs(rulesetName, rule),\n () => rule.action(ctx),\n );\n if (patch && typeof patch === \"object\") {\n mergeEffects(workingEffects, patch, mergeStrategy);\n }\n if (effectsMode === \"immutable\") {\n effects = workingEffects;\n }\n } catch (error) {\n ruleTrace.error = String(error);\n ruleTrace.notes.push(`error: ${String(error)}`);\n if (!rollbackOnError) {\n throw error;\n }\n if (effectsMode === \"immutable\") {\n effects = effects;\n }\n }\n fired.push(rule.id);\n }\n\n ruleTrace.durationMs = Date.now() - start;\n trace.push(ruleTrace);\n\n if (matched && activation === \"first\") {\n break;\n }\n }\n\n validateEffectsFn?.(effects);\n if (registryId) {\n registry.recordTrace(registryId, trace, fired, facts);\n }\n return {\n effects,\n fired,\n trace,\n explain: () => explainTrace(trace, rulesetName),\n };\n}\n\nfunction isPromise(value: unknown): value is Promise<unknown> {\n return Boolean(value) && typeof (value as Promise<unknown>).then === \"function\";\n}\n\nfunction runWithSpan<T>(\n adapter: TelemetryAdapter | undefined,\n name: string,\n attributes: TelemetryAttributes,\n fn: () => T,\n): T {\n if (!adapter) {\n return fn();\n }\n const span = adapter.startSpan(name, attributes);\n try {\n const result = fn();\n span.end();\n return result;\n } catch (error) {\n span.recordException?.(error);\n span.end();\n throw error;\n }\n}\n\nasync function runWithSpanAsync<T>(\n adapter: TelemetryAdapter | undefined,\n name: string,\n attributes: TelemetryAttributes,\n fn: () => Promise<T> | T,\n): Promise<T> {\n if (!adapter) {\n return await fn();\n }\n const span = adapter.startSpan(name, attributes);\n try {\n const result = await fn();\n span.end();\n return result;\n } catch (error) {\n span.recordException?.(error);\n span.end();\n throw error;\n }\n}\n\nfunction rulesetSpanAttrs(name?: string, registryId?: string): TelemetryAttributes {\n return {\n \"rulit.ruleset\": name ?? registryId ?? \"ruleset\",\n };\n}\n\nfunction ruleSpanAttrs<Facts, Effects>(\n rulesetName: string | undefined,\n rule: Rule<Facts, Effects>,\n): TelemetryAttributes {\n return {\n \"rulit.ruleset\": rulesetName ?? \"ruleset\",\n \"rulit.rule_id\": rule.id,\n };\n}\n\nfunction conditionSpanAttrs<Facts, Effects>(\n rulesetName: string | undefined,\n rule: Rule<Facts, Effects>,\n condition: Condition<Facts>,\n): TelemetryAttributes {\n return {\n \"rulit.ruleset\": rulesetName ?? \"ruleset\",\n \"rulit.rule_id\": rule.id,\n \"rulit.condition\": condition.meta?.label ?? \"condition\",\n };\n}\n\nfunction capitalize(value: string): string {\n return value.length > 0 ? value[0].toUpperCase() + value.slice(1) : value;\n}\n","import type { ZodType } from \"zod\";\n\n/**\n * Create a facts validator using a Zod schema.\n *\n * @example\n * ```ts\n * const factsSchema = z.object({ user: z.object({ age: z.number() }) });\n * const rs = Rules.ruleset<Facts, Effects>(\"rs\").validateFacts(Rules.zodFacts(factsSchema));\n * ```\n */\nexport function zodFacts<Facts>(schema: ZodType<Facts>) {\n return (facts: Facts) => {\n schema.parse(facts);\n };\n}\n\n/**\n * Create an effects validator using a Zod schema.\n *\n * @example\n * ```ts\n * const effectsSchema = z.object({ flags: z.array(z.string()) });\n * const rs = Rules.ruleset<Facts, Effects>(\"rs\").validateEffects(Rules.zodEffects(effectsSchema));\n * ```\n */\nexport function zodEffects<Effects>(schema: ZodType<Effects>) {\n return (effects: Effects) => {\n schema.parse(effects);\n };\n}\n","import type { TelemetryAdapter, TelemetryAttributes, TelemetrySpan } from \"./types\";\n\ntype OtelSpanLike = {\n end: () => void;\n recordException?: (error: unknown) => void;\n setAttribute?: (key: string, value: unknown) => void;\n setAttributes?: (attributes: Record<string, unknown>) => void;\n};\n\ntype OtelTracerLike = {\n startSpan: (name: string, options?: { attributes?: Record<string, unknown> }) => OtelSpanLike;\n};\n\n/**\n * Create a telemetry adapter from an OpenTelemetry tracer.\n *\n * @example\n * ```ts\n * import { trace } from \"@opentelemetry/api\";\n * const adapter = Rules.otel.createAdapter(trace.getTracer(\"rulit\"));\n * Rules.ruleset(\"rs\").telemetry(adapter);\n * ```\n */\nexport function createOtelAdapter(tracer: OtelTracerLike): TelemetryAdapter {\n return {\n startSpan(name: string, attributes?: TelemetryAttributes): TelemetrySpan {\n const span = tracer.startSpan(name, { attributes });\n if (attributes) {\n span.setAttributes?.(attributes);\n }\n return span;\n },\n };\n}\n"],"mappings":"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","names":["registry","cond","condition","registry","condition","counter","ruleset","registry","registry"]}