@arxo/law-engine

中文文档
0.5.6发布于 2026/10/21Apache-2.0TypeScriptES Module近 30 天下载 2265

Arxo Core compiler and evaluator SDK: WebAssembly, JavaScript and TypeScript for Node.js, browsers and workers.

原始使用文档
文档目录11 节
  1. Which package do you need?
  2. Quickstart
  3. Two modules
  4. Evaluate
  5. Run it anywhere
  6. API
  7. Compiler palette — full module
  8. Engine
  9. Failures
  10. Types
  11. Links

@arxo/law-engine

The Arxo Law engine as WebAssembly: compile .law packages, check them, and evaluate cases with byte-identical results in Node.js, browsers and workers. The modules have zero imports — no WASI, no clock, no environment — so the same request gives the same bytes anywhere.

npm node types wasm imports license

Which package do you need?

You want toUse
ask a published canon a question and get the answer with proof@arxo/law — it wraps this engine, assembles the case and projects the answer
check or compile .law sources in an editor, CI or the browser@arxo/law-engine, full module
evaluate already compiled packages (CLIR) with the smallest module@arxo/law-engine, core module
only the types of documents and diagnostics@arxo/law-types

Quickstart

npm install @arxo/law-engine

Check a package with a typo in it:

import { loadEngine } from '@arxo/law-engine/node';

const engine = await loadEngine();
const source = `language "law.core" version "0.2";
package demo.age version "0.1.0";
namespace "urn:example:demo-age";

pub entity Person;
pub relation age(p: Person, years: Integer) kind empirical;
pub relation adult(p: Person) kind institutional;

rule Adult(p: Person, y: Integer) strict {
  when aeg(p, y);
  when y >= 18;
  then adult(p);
}
`;
const { answer } = engine.call({ op: 'check', path: 'demo.law', files: { 'demo.law': source } });
answer.ok;                    // false
answer.diagnostics[0].code;   // 'LDC-E2102'
answer.diagnostics[0].message // 'predicate "aeg" is not declared as a relation in this file'
answer.diagnostics[0].primarySpan.start; // { line: 10, character: 8, offset: 284 }

Fix aeg → age and compile the package to its canonical intermediate representation:

const lowered = engine.call({ op: 'lower', path: 'demo.law', files: { 'demo.law': fixed } }).answer;
const ir = JSON.parse(lowered.bytes);
ir.semanticVersion;            // '0.2.5'
ir.artifactHash;               // 'sha256:e2c51767…'
engine.semanticHash(ir);       // the freshness fingerprint

Measured on a developer laptop (Node 20, 2026-10-02): loadEngine() 75 ms, check of this package 44 ms.

Two modules

ModuleSizeExportsUse it when
law_wasm.wasm (default)11.3 MBevaluator + compiler palette + verbalizeryou parse, check or lower .law sources
law_wasm_core.wasm5.4 MBevaluator, canonical form, semantic hash, program handlesyou evaluate compiled packages
law_binary_core.wasm5.9 MBevaluator over the compact binary envelopethe optional /binary entry

Both main modules answer an evaluation request with byte-identical documents. The core module has no compiler at all: the full wrapper refuses a core module at instantiation instead of failing on the first call.

Evaluate

import { loadCoreEngine, REQUEST_SCHEMA } from '@arxo/law-engine/core/node';

const core = await loadCoreEngine();
const program = core.load(ir);            // load once
const { document } = program.evaluate({   // evaluate many cases
  schemaVersion: REQUEST_SCHEMA,          // 'law.core.evaluation-request/0.2'
  semanticVersion: ir.semanticVersion,
  case: caseDocument,
  query,
});
program.dispose();

document is the evaluation document: results, proof graph, issues and hashes. The request envelope is closed — schemaVersion and semanticVersion are required, execution options live in case.options. Building caseDocument by hand is rarely needed: @arxo/law assembles it from plain facts and checks them against the package first.

Run it anywhere

Browser
import { LawEngine } from '@arxo/law-engine';

const wasmUrl = new URL('@arxo/law-engine/law_wasm.wasm', import.meta.url);
const engine = await LawEngine.instantiate(await fetch(wasmUrl));

The module instantiates with an empty import object; if that ever fails, the build is wrong — do not stub imports in. When you copy the files yourself, copy the complete dist directory, including composition.js.

Web worker — off the main thread
import { createWorkerEngine } from '@arxo/law-engine/worker';

const worker = new Worker(new URL('@arxo/law-engine/worker-entry', import.meta.url), { type: 'module' });
const engine = createWorkerEngine(worker, new URL('@arxo/law-engine/law_wasm.wasm', import.meta.url).href);
await engine.init();
const result = await engine.call({ op: 'features' });
worker.terminate();

For the core module: @arxo/law-engine/core/worker-entry and law_wasm_core.wasm.

Node worker thread
import { Worker } from 'node:worker_threads';
import { createRequire } from 'node:module';
import { createWorkerEngine } from '@arxo/law-engine/worker';

const resolve = createRequire(import.meta.url).resolve;
const worker = new Worker(resolve('@arxo/law-engine/worker-node-entry'));
const engine = createWorkerEngine(worker, resolve('@arxo/law-engine/law_wasm.wasm'));
await engine.init();
worker.terminate();

Node worker entries load wasm from a local path or file: URL as well as HTTP and data URLs.

A complete package tree — manifest, lock, cases, dependencies
const { answer } = engine.call({
  op: 'ask', path: 'pkg', files,
  args: {
    case: 'Main',
    evaluate: 'evaluate truth(demo.rules::eligible("Ada"));',
    queryId: 'urn:law:demo:case#case/Main/query/eligible',
  },
});

files maps paths to UTF-8 text or { base64: '…' } bytes: the manifest, law.lock, sources and cases, materialized dependencies and pinned resources. The engine never installs dependencies or reads the network on behalf of a compiler request.

API

Compiler palette — full module

engine.call(request) returns { answer, bytes }; bytes are the canonical form of answer.

opDoes
parsesyntax tree and syntax diagnostics
checkall static diagnostics: { ok, diagnostics }
lowerthe compiled package (CLIR)
layer, featuressemantic layer and features a package uses
expandthe package with templates expanded
explain, why-not, graphexplanation, blockers and dependency graph of a compiled package
testconformance vectors of a package
askevaluate a saved case of a complete package tree

Engine

MethodReturns
LawEngine.instantiate(source)an engine, from a fetch Response or bytes
engine.evaluate(request){ document, bytes } — one evaluation
engine.load(ir) / engine.loadBytes(bytes)a program handle: evaluate(request) without ir, then dispose()
engine.verbalize({ ir, pack, labels? }){ text, contentHash, gaps, blocks } — review text of a package under a template pack (full module)
engine.canon(document)canonical bytes of any JSON document
engine.semanticHash(document)the freshness fingerprint

Failures

Wherever the engine itself answers, a failure is a value: { error: { code, message } } or an envelope with ok: false. The wrapper throws only for misuse and for an explicit host failure, as HostAdapterError with code and message (preserved across workers). Match diagnostics on their stable code (LDC-E…), not on the message text. The loader refuses a module built for another ABI version.

Types

Every document and diagnostic is typed from the normative JSON schemas in @arxo/law-types, the package's only dependency, and re-exported here:

import type { EvaluationDocument, Diagnostic } from '@arxo/law-engine';

arxo.io · @arxo/law · Apache-2.0

版本与发布记录

@arxo/law-engine 共发布 27 个版本,首次发布于 2026/08/31;过去 12 个月发布了 27 个版本。

版本发布日期距今
0.5.6latest2026/10/2117 天前
0.5.52026/10/1622 天前
0.5.42026/10/1424 天前
0.5.32026/10/1425 天前
0.5.22026/10/1326 天前
0.5.12026/10/1226 天前

其他发布通道:next → 0.3.2。

关于 @arxo/law-engine 的常见问题

@arxo/law-engine 是什么?

Arxo Core compiler and evaluator SDK: WebAssembly, JavaScript and TypeScript for Node.js, browsers and workers.

如何安装 @arxo/law-engine?

在项目目录运行 npm install @arxo/law-engine,或使用 pnpm add / yarn add / bun add。

@arxo/law-engine 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@arxo/law-engine 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@arxo/law-engine 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@arxo/law-engine 可以商用吗?

@arxo/law-engine 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@arxo/law-engine 的下载量有多少?

根据 npm 官方下载统计,@arxo/law-engine 在 2026/10/07 – 2026/11/05 这 30 天内被下载 2,265 次,日均约 76 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arxo/law-engine 还在维护吗?

最新版本 0.5.6 发布于 2026/10/21(17 天前);至今共发布 27 个版本,其中过去 12 个月发布了 27 个;首次发布于 2026/08/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。