@loydjs/graph
v1.1.0
Published
Loyd graph — field dependency DAG
Maintainers
Readme
Overview
@loydjs/graph enables incremental revalidation by tracking field dependencies as a directed acyclic graph (DAG). When a field changes, only that field and its dependents are revalidated — not the entire schema.
This is particularly useful in large forms where validating all fields on every keystroke would be expensive. It is also the foundation for @loydjs/react's useForm hook.
Installation
npm install @loydjs/graphRequires
@loydjs/core·@loydjs/schema· Node.js ≥ 20 · TypeScript ≥ 5.4
API
buildDag(schema, dependencies)
Builds a dependency graph from a schema and an explicit dependency map.
import { buildDag } from "@loydjs/graph";
import { object, string, number } from "@loydjs/schema";
const CheckoutSchema = object({
country: string(),
state: string(), // depends on country
zipCode: string(), // depends on country + state
totalPrice: number(),
discount: number(), // depends on totalPrice
finalPrice: number(), // depends on totalPrice + discount
});
const dag = buildDag(CheckoutSchema, {
state: ["country"],
zipCode: ["country", "state"],
discount: ["totalPrice"],
finalPrice: ["totalPrice", "discount"],
});validateIncremental(dag, changedFields, values)
Revalidates only the changed fields and their dependents.
import { validateIncremental } from "@loydjs/graph";
// User changes the country field
const result = validateIncremental(dag, ["country"], {
country: "FR",
state: "IDF",
zipCode: "75001",
totalPrice: 99.99,
discount: 10,
finalPrice: 89.99,
});
// Only country, state, and zipCode were revalidated
// totalPrice, discount, finalPrice were skipped
console.log(result.revalidated); // ["country", "state", "zipCode"]
console.log(result.issues); // LoydIssue[]markDirty(dag, changedFields)
Marks fields as dirty without revalidating — useful for tracking touched state in forms.
import { markDirty, getDirtyFields } from "@loydjs/graph";
markDirty(dag, ["email", "name"]);
getDirtyFields(dag); // ["email", "name"]getDependents(dag, field)
Returns all fields that depend on a given field (direct and transitive).
import { getDependents } from "@loydjs/graph";
getDependents(dag, "country"); // ["state", "zipCode"]
getDependents(dag, "totalPrice"); // ["discount", "finalPrice"]Use with React
@loydjs/graph powers @loydjs/react — the DAG is built automatically from your schema and dependency map when you call useForm.
import { useForm } from "@loydjs/react";
const { register, handleSubmit } = useForm({
schema: CheckoutSchema,
dependencies: {
state: ["country"],
zipCode: ["country", "state"],
},
mode: "onChange",
});Dependencies
| Package | Role |
|:---|:---|
| @loydjs/core | LoydSchema, LoydIssue types |
| @loydjs/schema | Schema traversal for DAG construction |
Documentation
License
MIT © b3nito404
