ADYSRE

ビゞネスルヌル゚ンゞン

フレヌムワヌク非䟝存、プラグむン方匏のルヌル゚ンゞン。ASTが唯䞀の真実であり、ビルダヌが線集し、実行゚ンゞンが蟿り、レンダラヌが説明し、デバッガヌが解き明かしたす。有料API、クラりドサヌビス、倖郚゚ンゞンは䞀切䜿いたせん。

パッケヌゞ
11
挔算子
27
関数
23
ルヌルの皮類
7

取り蟌める圢匏 ADYSRE AST, jsonLogic, json-rules-engine, MongoDB query filters.

できるこず

  • A JSON tree

    Rules are plain JSON. Storable, diffable, versionable, and readable by anything.

  • Everything is a plugin

    Operators, functions, actions, fields, storage, renderers. Add one without touching the engine.

  • Runs anywhere

    Synchronous, pure, zero dependencies. The same rule evaluates on a server, in a browser or in a test.

  • Says what it means

    Every rule renders as a sentence, generated from the tree and never parsed back into it.

  • Shows its reasoning

    Which row decided the verdict, what the operator received, and what short-circuiting hid.

  • Edits itself

    A visual builder with undo, per-row validation and a live preview, driven entirely by the plugin metadata.

  • Takes what you have

    Converts other rule formats, warning where an equivalent is near rather than exact.

  • Keeps its history

    Versioning, restore and querying behind one contract every adapter is checked against.

詊す

条件を線集するず、文章も刀定も説明も同時に倉わりたす。

As documented: matched

A nested group, a date function, and two outcomes on one rule.

Saved

When

Then

Otherwise

In words

Matched

Large orders from new customers need approval

Why this answer

Why this answer

MatchedTook 1ms

every condition contributed, so no single one decided

1 branches never ran

  • Matchedall of these are true0.81ms
  • MatchedgreaterThan0.44ms

    The operator received: 2400, 1000

  • Matchedany of these are true0.19ms
  • Matchedequals0.09ms

    The operator received: "new", "new"

  • Never ranbefore

The rule, as JSON

ビゞネスルヌル゚ンゞンの䜿い方

プロゞェクトにルヌルを組み蟌むために必芁なすべお。導入、蚘述、実行、説明、拡匵、そしお線集の提䟛たで。以䞋のコヌドはそのたた動きたす。

  1. 01

    むンストヌル

    必芁なものだけを導入したす。゚ンゞンず型定矩はランタむム䟝存れロ。ビルダヌが別パッケヌゞなのは、ルヌルを評䟡するだけのサヌバヌにReact゚ディタを送る必芁がないからです。

    terminal
    # the engine and its vocabulary
    pnpm add @adysre/rules-core @adysre/rules-types
    
    # the visual builder, when you want one
    pnpm add @adysre/rules-ui @adysre/rules-react @adysre/rules-theme
  2. 02

    ルヌルを曞く

    ルヌルはただのJSONです。ビルダヌがIDず時刻を扱いたすが、手で曞いおも、保存しおも、レビュヌで差分を取っおも構いたせん。

    rules/large-orders.ts
    import { all, condition, field, literal, rule } from '@adysre/rules-core';
    
    // A rule is plain JSON. The builders exist so ids and timestamps are handled
    // for you, but nothing stops you writing the object by hand.
    const largeOrders = rule({
      name: 'Large orders from new customers need approval',
      kind: 'validation',
      when: all([
        condition({
          left: field('order.total'),
          operator: 'greaterThan',
          args: [literal(1000)],
        }),
      ]),
      then: [{ id: 'a_hold', type: 'requireApproval' }],
    });
  3. 03

    実行する

    同期的で玔粋。レゞストリが空から始たるのは、ルヌルに䜕を蚱すかがあなたの遞択だからです。結果には刀定、アクション、トレヌスが含たれたす。

    rules/run.ts
    import { builtinPlugins, createContext, createRegistry, evaluateRule } from '@adysre/rules-core';
    
    // The registry starts EMPTY: what rules may do is your choice. Pass the
    // built-ins for the usual twenty-seven operators and twenty-three functions.
    const registry = createRegistry(builtinPlugins);
    
    const outcome = evaluateRule(registry, largeOrders, createContext(order));
    
    outcome.verdict;      // 'matched' | 'unmatched' | 'skipped' | 'errored'
    outcome.actions;      // what to do — the engine never does it for you
    outcome.trace;        // every node that ran, and what it concluded
  4. 04

    読み返す

    すべおのルヌルは文章になりたす。ツリヌから生成され、決しお逆方向に解析されたせん。たず構造、次に文字列です。

    rules/explain.ts
    import { describeRule } from '@adysre/rules-renderer';
    
    describeRule(largeOrders, { plugins: registry }).text;
    // When order total is greater than 1,000
    // Then require approval
    
    // Structure first, text second: `.lines` gives typed segments, so a UI can
    // highlight the field being edited or colour the condition that decided it.
  5. 05

    独自の挔算子を足す

    ゚ンゞンができるこずはすべおプラグむンです。登録すればビルダヌが提瀺し、デバッガヌが説明し、ルヌルはJSONのたたです。

    rules/registry.ts
    import { createRegistry, builtinPlugins, RuleError } from '@adysre/rules-core';
    import type { OperatorPlugin } from '@adysre/rules-types';
    
    // Your own operator. The builder picks it up, the debugger explains it, and
    // your rules stay plain JSON — no change to the engine.
    const withinBusinessHours: OperatorPlugin = {
      id: 'withinBusinessHours',
      labelKey: 'operators.withinBusinessHours',
      arity: 0,
      accepts: ['date'],
      evaluate: (left) => {
        if (typeof left !== 'string') {
          // Not `false`: a broken comparison must not look like a failed one.
          throw new RuleError('type_mismatch', 'withinBusinessHours needs a date.');
        }
        const hour = new Date(left).getHours();
        return hour >= 9 && hour < 17;
      },
    };
    
    const registry = createRegistry(builtinPlugins, { operators: [withinBusinessHours] });
  6. 06

    線集できるようにする

    ビゞュアルビルダヌはプラグむンのメタデヌタだけで動きたす。arityが入力欄の数を、acceptsが提瀺する挔算子を決めたす。

    app/editor.tsx
    'use client';
    
    import { RuleBuilder } from '@adysre/rules-ui';
    
    export function Editor({ rule, onChange }) {
      return (
        <RuleBuilder
          rule={rule}
          registry={registry}
          sample={sampleOrder}   // runs the rule as you type
          onChange={onChange}
        />
      );
    }
  7. 07

    理由を知る

    デバッガヌは刀定を決めた行を瀺し、短絡評䟡を切っおもう䞀床実行し、速い経路が飛ばした䞍具合を明らかにしたす。

    rules/debug.ts
    import { debugRule } from '@adysre/rules-devtools';
    
    const session = debugRule(registry, largeOrders, createContext(order));
    
    session.decision;                  // which row decided, or that several did
    session.comparison.hiddenErrors;   // faults a short circuit stepped over
  8. 08

    保存する

    バヌゞョン管理ず埩元を備えた単䞀のストレヌゞ契玄。埩元は巻き戻しではなく新しいバヌゞョンを曞きたす。

    rules/storage.ts
    import { createMemoryStorage, runStorageConformance } from '@adysre/rules-storage';
    
    const storage = createMemoryStorage();
    await storage.save(largeOrders);          // version 1
    await storage.restore(largeOrders.id, 1); // a NEW version holding version 1
    
    // Writing your own adapter? Check it against the same contract:
    const results = await runStorageConformance(() => createMyAdapter());

パッケヌゞ構成

各パッケヌゞは必芁になった段階で远加されたす。䜿うものだけ導入しおください。

  • The vocabulary
    @adysre/rules-types

    Type vocabulary for the ADYSRE Business Rules Engine: the rule AST, execution contracts and plugin interfaces.

    v0.1.0
  • The engine
    @adysre/rules-core

    Framework-agnostic core of the ADYSRE Business Rules Engine: AST builders, traversal and validation. No runtime dependencies.

    v0.1.0
  • Importers
    @adysre/rules-parser

    Imports rules into the ADYSRE AST from JSON, jsonLogic, json-rules-engine and MongoDB-style queries.

    v0.1.0
  • Natural language
    @adysre/rules-renderer

    Turns an ADYSRE rule AST into readable language. Generated from the tree, never parsed back into it.

    v0.1.0
  • Persistence
    @adysre/rules-storage

    Where rules live: the storage contract, versioning, querying, and a reference adapter every other one has to match.

    v0.1.0
  • Builder state
    @adysre/rules-react

    Headless state for a rule builder: an immutable store with history, plus the React bindings.

    v0.1.0
  • The visual builder
    @adysre/rules-ui

    The visual rule builder: React components over @adysre/rules-react, styled with design tokens.

    v0.1.0
  • The debugger
    @adysre/rules-devtools

    The execution debugger: why a rule answered what it answered, and what short-circuiting hid.

    v0.1.0
  • Over HTTP
    @adysre/rules-next

    Rules over HTTP: route handlers and server actions on the Web standard, so they run in Next.js and anywhere else.

    v0.1.0
  • Design tokens
    @adysre/rules-theme

    Design tokens for the rule builder, and a contrast audit that proves a theme is readable.

    v0.1.0
  • Sandbox and examples
    @adysre/rules-playground

    A runnable sandbox and the worked examples, each verified against the engine that runs it.

    v0.1.0

知っおおきたい蚭蚈刀断

  • The AST is the only source of truth

    Everything else is a projection of it. Prose is generated from the tree and never parsed back, so the two can never disagree.

  • An error is not a false

    A condition that cannot be evaluated is errored, and so is the rule. A broken comparison never looks like a failed one.

  • Actions are intent, never performed

    The engine reports what should happen and the host decides. That is what lets a rule be run twice, in a preview, or in a test.

  • The registry cannot be mutated

    Extending it returns a new one, so two tenants can hold different capabilities without one leaking into the other.

  • Every answer carries its reasoning

    Each node records what it saw and what it concluded, so somebody can be shown the condition that decided it.

  • No language to learn

    There is no text format to hand-author, so there is no second system to keep in step with the tree.