UNPKG

verdict-rules

Version:

A small, zero-dependency, async-native rule-evaluation engine. Compose conditions into one explainable pass/fail verdict, with sequential evaluation and real short-circuiting as a guarantee.

132 lines (111 loc) • 6.69 kB
# Changelog Release history for the `verdict-rules` JS/TS package. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows [semantic versioning](https://semver.org/), scoped to this package — it releases independently of the other language SDKs and of the AI-agent skill. ## [0.3.1] - 2026-09-18 - Every doc comment and inline comment in the package's own source trimmed to state current behavior only -- design rationale, alternatives-considered framing, and cross-references to the deeper docs for "the full reasoning" cut, not relocated. ## [0.3.0] - 2026-09-18 - `Rule<TContext>` is now generic over the context it reads from, along with `FunctionRule`, `AndRule`, `OrRule`, and `RulesEngine` — no default type parameter. Dict-context is `Rule<Context>`, written out explicitly. `TContext` is inferred from a predicate's own parameter type. - `docs/architecture/js.md` gained a "Generic context, concretely" section. ## [0.0.7] - 2026-09-17 - **The CDN section no longer hardcodes a version+hash pair for the pinned `<script>` example** — the exact problem the `0.0.6` fix itself only patched, not removed (this same pin went stale twice now). The ESM import switches to `@latest`, which never needed the integrity hash in the first place (documented in the same section: the CDN's on-the-fly transform has no stable bytes to hash, so there was nothing for a hash to protect there). The pinned `<script>` + `integrity` example is now an explicit placeholder pointing at [jsdelivr's own package page](https://www.jsdelivr.com/package/npm/verdict-rules), which generates the exact tag with the correct hash for whichever version is picked — a static value here would only ever be correct for the version that existed when it was written. - **unpkg and esm.sh are now linked directly**, alongside jsdelivr, rather than named without a link. ## [0.0.6] - 2026-09-16 - **`## Install` now also shows the bare import statement** (`import { AndRule, FunctionRule, RulesEngine } from "verdict-rules"`), matching the Python package page's own Install section -- previously the import only appeared inside the first-example code block further down the page. - **The first-example heading is now "A first rule"**, not the generic "Use" -- the shared package-README template explicitly names a generic "Usage"-style heading as the thing to avoid, and Python's own page already used the correct idiom. - **Fixed the CDN example's stale version pin**: `verdict-rules@0.0.2` in both the `<script src>` and the `+esm` import -- three releases behind the package's actual current version. The integrity hash was already correct (verified against the live CDN for real): every release between `0.0.2` and `0.0.5` was documentation/metadata-only, so the bundle's own bytes never changed, only the version number needed updating. ## [0.0.5] - 2026-09-16 - **The structural-typing example swaps `overEighteen`/`age` for `isBusinessHours`/`hour`** -- kept distinct from the main example's own `age` field, which already lives on the same page. - **`docs/quickstart.md`'s complete example now nests a composite** (`AndRule` containing an `OrRule`, one branch of which is itself a further `AndRule`) and demonstrates `runGroup` alongside a passing and a failing call, rather than repeating the same flat two-rule `AndRule` + `runNamed` shape the package README's own first example already covers. Package identical to `0.0.4` otherwise. ## [0.0.4] - 2026-09-15 - **`keywords` drops `policy` and adds `decision-engine` and `async`**, now `rules-engine`, `rule-evaluation`, `eligibility`, `decision`, `decision-engine`, `async`. `policy` names a rule together with what happens when it's enforced -- this package only ever evaluates and never acts on the result, so a "policy" keyword invited a search for something this package doesn't do. `decision` stays: it's this package's own output, a judgment reached, not an act of enforcing anything. Package identical to `0.0.3` otherwise. ## [0.0.3] - 2026-09-15 - **Drops the "Where to go next" row pointing back at the top-level `README.md`.** `docs/architecture/` is already linked in the same table and already covers "why it's shaped this way," in more depth than a narrative pointer would — a second row saying the same thing again was dead weight, not a different fact. ## [0.0.2] - 2026-09-15 - **The npm landing page's first example now demonstrates `RulesEngine`**, wrapping the rule and running it by name instead of stopping at the composite's own `.evaluate()` — `RulesEngine` is one of the five named primitives, and the first example is meant to show all of them. `package-readmes.md`'s own authoring template now mandates this for every language's first example and `docs/quickstart.md`'s worked example alike, so the two never demonstrate a different subset of the API from each other. - **Drops the `## Development` section.** It duplicated a subset of `CONTRIBUTING.md`'s own JS/TS section on a page a consumer landed on to install the package, not to change it — `package-readmes.md` no longer mandates this section for any language. - **Cuts the blockquote to a single fact.** The second sentence pointed to the top-level `README.md` while narrating what this file itself was for — the document talking about itself, the same failure `package-readmes.md` already names for every other doc in this repo. That pointer moves to `## Where to go next`'s own first row instead. ## [0.0.1] - 2026-09-14 Initial publish. - `Rule` (a structural `interface`), `FunctionRule`, `AndRule`, `OrRule`, `RulesEngine`, `RuleResult`, `RunResult`. - Sequential, never concurrent evaluation, so short-circuiting is a real contract rather than a best-effort optimisation. - Vacuous-truth polarity decided per composite: `AndRule([])` passes, `OrRule([])` fails. - Unknown rule names and unknown groups throw rather than returning a vacuous pass — emptiness folds to an identity, absence is an error. - `RulesEngine.tryRunNamed` / `tryRunGroup`, returning `undefined` rather than throwing when nothing matches — the primitives the throwing forms are built on. `undefined` means absent, never failed. - `RulesEngine.ruleNames` / `groupNames` for enumerating an engine. - `UnknownLookupError`, carrying `kind` and `key`, so an unknown lookup is catchable by type rather than by matching message text. - Ships as ESM, CommonJS, and an ES2019 global bundle for a plain `<script>` tag or a CDN URL. Node 18+, zero runtime dependencies, types included.