@edgerules/web
EdgeRules decision service for the browser. Ships two builds:
| Export | Description |
|---|---|
@edgerules/web | Production build — execution only (DecisionService) |
@edgerules/web/mutable | Development build — execution + CRUD (MutableDecisionService) |
The browser package is API-identical to @edgerules/node; only the
underlying WASM loader differs (browser fetch vs Node.js fs). Choose this package for Vite, webpack, and other
browser bundler setups.
Installation
npm install @edgerules/web @edgerules/portable
ESM only. The WASM binary is loaded asynchronously on first use.
Production Usage
Load from an EdgeRules DSL string
import {DecisionService} from '@edgerules/web';
const service = new DecisionService(`{
applicant: {
age: <number, required: true>
income: <number, default: 0>
}
isEligible: applicant.age >= 18 and applicant.income >= 1000
}`);
// Execute the whole model against a request
const result = service.execute('*', {applicant: {age: 25, income: 2500}});
// { applicant: { age: 25, income: 2500 }, isEligible: true }
Load from a Portable JSON model
import {DecisionService} from '@edgerules/web';
import type {PortableContext} from '@edgerules/portable';
const model: PortableContext = {
'@kind': 'context',
fields: {
minAge: 18,
minIncome: 1000,
applicant: {
'@kind': 'context',
fields: {age: {'@kind': 'placeholder', type: 'number'}, income: {'@kind': 'placeholder', type: 'number'}},
},
isEligible: 'applicant.age >= minAge and applicant.income >= minIncome',
},
};
const service = new DecisionService(model);
const result = service.execute('isEligible', {applicant: {age: 30, income: 3000}});
// true
Error handling
import type {PortableError} from '@edgerules/portable';
try {
service.execute('nonExistentField');
} catch (err) {
const error = err as PortableError;
console.error(error.type); // "EntryNotFound"
console.error(error.message); // human-readable, safe to surface in UI
}
Mutable / Development Usage
Use the ./mutable subpath for rule editors, visual builders, and test tooling. Do not use this build in
production.
import {Kinds, MutableDecisionService} from '@edgerules/web/mutable';
const service = new MutableDecisionService(initialModel);
// Inspect a field with inferred type information
const node = service.get('applicant.age');
// { "@kind": "placeholder", "type": "number", "required": true, "writeOnly": true, "linked": true }
// Hot-update a rule
service.set('minAge', 21);
// Add a new typed input
service.set('applicant.creditScore', {'@kind': 'placeholder', type: 'number', default: 0});
// Remove a field
service.remove('applicant.creditScore');
// Read the full model snapshot
const snapshot = service.get('*');
// Read the method signatures only
const signatures = service.get('*', Kinds.METHOD_INTERFACES);
// Read/write a node as DSL source text instead of Portable JSON
const code = service.getCode('minAge'); // '21'
service.setCode('minAge', '18'); // returns a PortableNode, not code text
API Reference
DecisionService
| Method | Description |
|---|---|
new DecisionService(model) | Create from a DSL string or a root PortableContext |
execute(method, args?) | Evaluate method (field path, function, or "*") against optional request bindings |
execute details
method: "*"— evaluates every top-level field and returns the full model result.method: "person.isAdult"— evaluates and returns that single field.method: "validateApplicant"— calls a named function; supply its parameters throughargs.args— a model-shaped object whose entries are bound as external inputs. Nested typed holes follow the model shape (e.g.{ applicant: { age: 30 } }forapplicant: { age: <number> }).
MutableDecisionService (dev build)
Inherits execute and adds:
| Method | Description |
|---|---|
get(path, kinds?) | Read a node, filtered by @kind (see Kinds); linked tells if the model links |
set(path, value) | Write an expression, placeholder, context, method, or type |
getCode(path) | Read a node as EdgeRules DSL source text |
setCode(path, code) | Write a node from EdgeRules DSL source text; returns a PortableNode, not code text |
remove(path) | Delete an entry at the given path |
rename(oldPath, newPath) | Rename an entry within its context |
Related packages
@edgerules/node— same API for Node.js@edgerules/portable— Portable JSON type definitions