@mostajs/rules
v0.1.0
Published
Declarative rules / inference engine (ECA Condition) — pluggable backend, Prolog (tau-prolog) by default. Pure, bounded (no infinite loops), explainable. Composed by statemachine, trigger and rbac.
Downloads
86
Maintainers
Readme
@mostajs/rules
Moteur de règles déclaratif (la Condition d'Event-Condition-Action) — backend d'inférence pluggable, Prolog par défaut (via tau-prolog). Pur, borné (anti-boucle), explicable.
Auteur : Dr Hamid MADANI [email protected] · Licence : AGPL-3.0-or-later
@mostajs/rules est une primitive de l'écosystème @mostajs/*. Elle évalue des conditions/gardes déclaratives sur des faits — là où l'on disperserait sinon des if en dur. C'est la brique RULE du triptyque State · Rule · Trigger (inspiré des modules Drupal Workflow / Rules / Trigger) :
| Brique | Module |
|---|---|
| STATE | @mostajs/statemachine |
| RULE | @mostajs/rules (ce module) |
| TRIGGER | @mostajs/trigger |
| stack d'assemblage | @mostajs/workflow |
Installation
npm i @mostajs/rules tau-prologtau-prolog est une peer dependency optionnelle : c'est le moteur par défaut (pur-JS, navigateur + Node). Sans elle, l'usage lève RuleEngineUnavailableError (le paquet s'installe quand même). Backends optionnels prévus : swipl-wasm, json-logic-js.
Exemple minimal
import { createKnowledgeBase } from "@mostajs/rules";
const kb = createKnowledgeBase(); // moteur Prolog par défaut
await kb.consult(`
assignee(order(42), emp(7)).
peut_modifier_etat(Emp, Order) :- assignee(Order, Emp).
`);
await kb.holds("peut_modifier_etat(emp(7), order(42))"); // true
await kb.holds("peut_modifier_etat(emp(9), order(42))"); // false (deny-by-default)
const sols = await kb.query("assignee(order(42), X)");
// [{ bindings: { X: "emp(7)" } }]Cas d'usage dans l'écosystème
- Garde de transition (
@mostajs/statemachine/@mostajs/workflow) :transition_allowed(Order, Actor, From, To). - Autorisation d'instance (
@mostajs/rbac) : « l'employé ne modifie que ses commandes » —peut_modifier_etat(Emp, Order) :- assignee(Order, Emp). - Gating d'action (
@mostajs/trigger) : n'exécuter une action que si une condition tient. - Tarification / éligibilité / validation métier éditables sans redéploiement.
Règles nommées réutilisables
import { defineRule, createKnowledgeBase } from "@mostajs/rules";
defineRule("crm/transition_allowed", `transition_allowed(O, A, validee, terminee) :- ... .`);
const kb = createKnowledgeBase();
await kb.consult("crm/transition_allowed"); // chargé par son nomRéférence API
| Élément | Signature | Rôle |
|---|---|---|
| createKnowledgeBase(opts?) | → KnowledgeBase | crée une base (moteur Prolog par défaut) |
| kb.consult(progOuNom) | → Promise<this> | charge du Prolog brut ou une règle nommée |
| kb.assert(fact) / kb.retract(fact) | → Promise<this> | ajoute / retire un fait |
| kb.query(goal, opts?) | → Promise<Solution[]> | solutions (bindings) |
| kb.holds(goal, opts?) | → Promise<boolean> | garde booléenne (deny-by-default) |
| kb.explain(goal, opts?) | → Promise<DerivationNode> | arbre de dérivation (v0.2) |
| defineRule / getRule / listRules | — | règles nommées |
| createEngine(name?) | → RuleEngine | "prolog" (défaut) · "swi"/"jsonlogic" (v0.3) |
QueryOptions = { max?, steps?, timeoutMs? }. Limites par défaut : DEFAULT_LIMITS = { steps: 500000, timeoutMs: 1000 }.
Garde-fous (anti-boucle)
Toute requête est bornée par un nombre de pas de résolution (steps) et un plafond horloge (timeoutMs). Dépassement → RuleStepLimitError / RuleTimeoutError. Le moteur est pur (aucun I/O).
Statut
v0.0.1 — scaffold. Wiring fonctionnel consult/query/holds (Prolog). Feuille de route : docs/03-PLAN-DEV-RULES.md (0.1 tests, 0.2 explain, 0.3 backends optionnels, 1.0 = 14 livrables). Étude & décisions : docs/01-ETUDE-ETAT-ART-RULES-07062026.md, docs/02-AUDIT-EXISTANT-RULES.md.
