Picorules Compiler JS Core
raw JSON → 1.1.1 verified Fri May 01 auth: no javascript
Pure JavaScript/TypeScript compiler and runtime evaluator for the Picorules clinical decision support language. Compiles ruleblocks to optimized SQL (Oracle, SQL Server, PostgreSQL) or evaluates directly in JavaScript for single-patient use (browser, Node.js, edge). v1.1.1 – production-ready, zero runtime dependencies (Zod only for input validation), full type safety, tree-shakeable ESM/CJS, 406 tests. Unique: dual execution mode (SQL batch vs in-memory), pluggable data adapters (EADV built-in), automatic cross-ruleblock dependency resolution.
Common errors
error TypeError: Cannot read properties of undefined (reading 'lastdv') ↓
cause Data adapter not properly initialized or empty data array.
fix
Ensure EadvDataAdapter receives an array of EADV observations. At minimum: [{ eid: 1, att: 'some_att', dt: '2024-01-01', val: 123 }]
error Error: Ruleblock 'X' imports unknown symbol 'Y' ↓
cause Cross-ruleblock reference to a symbol that does not exist in any parsed ruleblock.
fix
Check that all referenced ruleblocks are included in the array passed to
parse() and that spelling matches. error SyntaxError: Unexpected token '#' in JSON at position 0 ↓
cause Mistakenly tried to parse a `.prb` file as JSON instead of raw text.
fix
Read the .prb file as a string (e.g., using fs.readFileSync) and pass the text to
parse(). error Module not found: Error: Can't resolve 'picorules-compiler-js-core' in '/path' ↓
cause Package not installed or import path incorrect in bundler environment.
fix
Run
npm install picorules-compiler-js-core. Ensure your bundler resolves ESM (set "type": "module" in package.json or use .mjs extension). Warnings
breaking v1.1.0 changed the `compile` return type: `.sql` is now an array of strings indexed by ruleblock order, not an object keyed by ruleblock name. ↓
fix Access result.sql[index] instead of result.sql[ruleblockName].
breaking v1.0 required Node.js >= 14; v1.1+ requires Node.js >= 16 due to ES2021 features. ↓
fix Upgrade Node.js to >= 16.
deprecated The `evaluate` function's second parameter `adapter` formerly accepted plain objects; now requires an `EadvDataAdapter` instance. ↓
fix Wrap data with `new EadvDataAdapter(data)` before passing to `evaluate`.
gotcha Ruleblock names must be unique; duplicate names cause silent overwrite. ↓
fix Ensure each ruleblock has a distinct `name` field.
gotcha The `evaluate` mode does NOT support all SQL dialects; it only works with EADV data adapter. For other data sources, compile to SQL and execute externally. ↓
fix Use `compile()` for non-EADV databases.
gotcha TypeScript users: `Dialect` enum values are strings; ensure you use `Dialect.ORACLE`, not raw strings like `'oracle'`. ↓
fix Always import and use the `Dialect` enum.
Install
npm install picorules-compiler-js-core yarn add picorules-compiler-js-core pnpm add picorules-compiler-js-core Imports
- compile wrong
const { compile } = require('picorules-compiler-js-core')correctimport { compile } from 'picorules-compiler-js-core' - parse wrong
import parse from 'picorules-compiler-js-core'correctimport { parse } from 'picorules-compiler-js-core' - evaluate wrong
import { evaluate } from 'picorules-compiler-js-core/evaluate'correctimport { evaluate } from 'picorules-compiler-js-core' - EadvDataAdapter wrong
import { EADVDataAdapter } from 'picorules-compiler-js-core'correctimport { EadvDataAdapter } from 'picorules-compiler-js-core' - Dialect wrong
import Dialect from 'picorules-compiler-js-core'correctimport { Dialect } from 'picorules-compiler-js-core' - evaluateAll wrong
import { evaluateAll } from 'picorules-compiler-js-core/runtime'correctimport { evaluateAll } from 'picorules-compiler-js-core'
Quickstart
import { parse, evaluate, EadvDataAdapter } from 'picorules-compiler-js-core';
const prbSource = `
#define_ruleblock(cd_obesity, {
description: "BMI assessment",
is_active: 2
});
ht => eadv.obs_height.val.lastdv();
wt => eadv.obs_weight.val.lastdv();
bmi : { ht_val!? and wt_val!? => round(wt_val / power(ht_val / 100, 2), 1) };
is_obese : { bmi > 30 => 1 }, { => 0 };
`;
const parsed = parse([{ name: 'cd_obesity', text: prbSource, isActive: true }]);
const adapter = new EadvDataAdapter([
{ eid: 1, att: 'obs_height', dt: '2024-06-01', val: 170 },
{ eid: 1, att: 'obs_weight', dt: '2024-06-01', val: 95 },
]);
const result = evaluate(parsed[0], adapter);
console.log(result);
// { ht_val: 170, ht_dt: Date, wt_val: 95, wt_dt: Date, bmi: 32.9, is_obese: 1 }