@edgerules/web 0.0.0-alpha.202607061032 → 0.0.0-alpha.202607061957
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.
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# @edgerules/web
|
|
2
|
+
|
|
3
|
+
[](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)
|
|
4
|
+
[](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)
|
|
5
|
+
[](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)
|
|
6
|
+
[](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)
|
|
7
|
+
[](https://sonarcloud.io/summary/new_code?id=rimvydasb_edgerules)
|
|
8
|
+
|
|
9
|
+
EdgeRules decision service for the **browser**. Ships two builds:
|
|
10
|
+
|
|
11
|
+
| Export | Description |
|
|
12
|
+
|--------------------------|-----------------------------------------------------------------|
|
|
13
|
+
| `@edgerules/web` | Production build — execution only (`DecisionService`) |
|
|
14
|
+
| `@edgerules/web/mutable` | Development build — execution + CRUD (`MutableDecisionService`) |
|
|
15
|
+
|
|
16
|
+
The browser package is API-identical to [`@edgerules/node`](https://www.npmjs.com/package/@edgerules/node); only the
|
|
17
|
+
underlying WASM loader differs (browser `fetch` vs Node.js `fs`). Choose this package for Vite, webpack, and other
|
|
18
|
+
browser bundler setups.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm install @edgerules/web @edgerules/portable
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> ESM only. The WASM binary is loaded asynchronously on first use.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Production Usage
|
|
33
|
+
|
|
34
|
+
### Load from an EdgeRules DSL string
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import {DecisionService} from '@edgerules/web';
|
|
38
|
+
|
|
39
|
+
const service = new DecisionService(`{
|
|
40
|
+
applicant: {
|
|
41
|
+
age: <number, required: true>
|
|
42
|
+
income: <number, default: 0>
|
|
43
|
+
}
|
|
44
|
+
isEligible: applicant.age >= 18 and applicant.income >= 1000
|
|
45
|
+
}`);
|
|
46
|
+
|
|
47
|
+
// Execute the whole model against a request
|
|
48
|
+
const result = service.execute('*', {applicant: {age: 25, income: 2500}});
|
|
49
|
+
// { applicant: { age: 25, income: 2500 }, isEligible: true }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Load from a Portable JSON model
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import {DecisionService} from '@edgerules/web';
|
|
56
|
+
import type {PortableRootContext} from '@edgerules/portable';
|
|
57
|
+
|
|
58
|
+
const model: PortableRootContext = {
|
|
59
|
+
'@version': '1.0',
|
|
60
|
+
'@model-name': 'Loan Eligibility',
|
|
61
|
+
minAge: 18,
|
|
62
|
+
minIncome: 1000,
|
|
63
|
+
isEligible: 'applicant.age >= minAge and applicant.income >= minIncome',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const service = new DecisionService(model);
|
|
67
|
+
|
|
68
|
+
const result = service.execute('isEligible', {applicant: {age: 30, income: 3000}});
|
|
69
|
+
// true
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Error handling
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import type {PortableError} from '@edgerules/portable';
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
service.execute('nonExistentField');
|
|
79
|
+
} catch (err) {
|
|
80
|
+
const error = err as PortableError;
|
|
81
|
+
console.error(error.type); // "EntryNotFound"
|
|
82
|
+
console.error(error.message); // human-readable, safe to surface in UI
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Mutable / Development Usage
|
|
89
|
+
|
|
90
|
+
Use the `./mutable` subpath for rule editors, visual builders, and test tooling. **Do not use this build in
|
|
91
|
+
production.**
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import {MutableDecisionService} from '@edgerules/web/mutable';
|
|
95
|
+
|
|
96
|
+
const service = new MutableDecisionService(initialModel);
|
|
97
|
+
|
|
98
|
+
// Inspect a field with inferred type information
|
|
99
|
+
const node = service.get('applicant.age');
|
|
100
|
+
// { "@kind": "type", "type": "number", "required": true, "writeOnly": true }
|
|
101
|
+
|
|
102
|
+
// Hot-update a rule
|
|
103
|
+
service.set('minAge', 21);
|
|
104
|
+
|
|
105
|
+
// Add a new typed input
|
|
106
|
+
service.set('applicant.creditScore', {'@kind': 'type', type: 'number', default: 0});
|
|
107
|
+
|
|
108
|
+
// Remove a field
|
|
109
|
+
service.remove('applicant.creditScore');
|
|
110
|
+
|
|
111
|
+
// Read the full model snapshot
|
|
112
|
+
const snapshot = service.get('*', 'ALL');
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## API Reference
|
|
118
|
+
|
|
119
|
+
### `DecisionService`
|
|
120
|
+
|
|
121
|
+
| Method | Description |
|
|
122
|
+
|------------------------------|--------------------------------------------------------------------------------------|
|
|
123
|
+
| `new DecisionService(model)` | Create from a DSL string or `PortableRootContext` |
|
|
124
|
+
| `execute(method, args?)` | Evaluate `method` (field path, function, or `"*"`) against optional request bindings |
|
|
125
|
+
|
|
126
|
+
#### `execute` details
|
|
127
|
+
|
|
128
|
+
- `method: "*"` — evaluates every top-level field and returns the full model result.
|
|
129
|
+
- `method: "person.isAdult"` — evaluates and returns that single field.
|
|
130
|
+
- `method: "validateApplicant"` — calls a named function; supply its parameters through `args`.
|
|
131
|
+
- `args` — a model-shaped object whose entries are bound as external inputs. Nested typed holes follow the model shape
|
|
132
|
+
(e.g. `{ applicant: { age: 30 } }` for `applicant: { age: <number> }`).
|
|
133
|
+
|
|
134
|
+
### `MutableDecisionService` (dev build)
|
|
135
|
+
|
|
136
|
+
Inherits `execute` and adds:
|
|
137
|
+
|
|
138
|
+
| Method | Description |
|
|
139
|
+
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
140
|
+
| `get(path, filter?)` | Read a node enriched with inferred types; `filter` selects the view (`"FIELDS"` \| `"TYPE_DEFINITIONS"` \| `"FUNCTION_DEFINITIONS"` \| `"ALL"`) |
|
|
141
|
+
| `set(path, node)` | Write an expression, typed hole, context, function definition, or type definition |
|
|
142
|
+
| `remove(path)` | Delete an entry at the given path |
|
|
143
|
+
| `rename(oldPath, newPath)` | Rename an entry within its context |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Related packages
|
|
148
|
+
|
|
149
|
+
- [`@edgerules/node`](https://www.npmjs.com/package/@edgerules/node) — same API for Node.js
|
|
150
|
+
- [`@edgerules/portable`](https://www.npmjs.com/package/@edgerules/portable) — Portable JSON type definitions
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgerules/web",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.202607061957",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "EdgeRules decision service for the browser.",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@edgerules/portable": "0.0.0-alpha.
|
|
7
|
+
"@edgerules/portable": "0.0.0-alpha.202607061957"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@edgerules/core": "*",
|