Library
Buckets
Declare named conditions over an item once, then declare buckets as boolean expressions over those conditions. Condition names, bucket names and the shape of the report are all inferred.
npm install @michaelrwalker/buckets // reference
One script, hover to learn it
Every highlighted token is real Buckets API — hover or tab to it for what it does.
import { BucketEngine } from "@michaelrwalker/buckets";
interface Package {
readonly id: string;
readonly weightKg: number;
readonly valueUsd: number;
readonly oversized: boolean;
readonly hazardous: boolean;
}
const dispatch = new BucketEngine()
.defineInput<Package>()
.defineCondition({ name: "isHeavy", checkFn: (p) => p.weightKg > 500 })
.defineCondition({ name: "isOversized", checkFn: (p) => p.oversized })
.defineCondition({ name: "isHighValue", checkFn: (p) => p.valueUsd > 10_000 })
.defineCondition({ name: "isHazardous", checkFn: (p) => p.hazardous })
.defineCondition({ name: "isLight", checkFn: (p) => p.weightKg <= 5 })
.defineComputedCondition({
name: "needsFreight",
checkFn: ({ OR }) => OR("isHeavy", "isOversized"),
})
.defineComputedCondition({
name: "needsSecurity",
checkFn: ({ OR }) => OR("isHighValue", "isHazardous"),
})
.defineBucket({ name: "armoredTruck", checkFn: () => "needsSecurity" })
.defineBucket({ name: "flatBed", checkFn: () => "needsFreight" })
.defineBucket({
name: "regularMail",
checkFn: ({ ONLY }) => ONLY("isLight"),
})
.defineBucket({
name: "cargoVan",
checkFn: ({ AND, NOT }) => AND(NOT("needsFreight"), NOT("needsSecurity")),
});
const report = await dispatch.process(shipment);
report.buckets.armoredTruck; // cash, jewelry, hazmat — highest priority
report.buckets.flatBed; // over 500kg or oversized
report.buckets.cargoVan; // everything else — the default lane
console.log("uncovered:", dispatch.missingCombinations());