@bimetal/calendar-rules
v0.13.0
Published
Calendar-domain rule pack: noOverlap, workingHoursOnly, min/maxDuration, domainRule, withRules store integration. Built on @bimetal/rule-engine.
Maintainers
Readme
@bimetal/calendar-rules
Calendar-domain rule pack: concrete rules, the domainRule factory, and withRules store integration. Built on @bimetal/rule-engine + @bimetal/calendar-data.
Installation
npm install @bimetal/calendar-rulesBuilt-in Rules
noOverlap(options?)— rejects overlapping eventswarnOnOverlap(options?)— same check, but warning instead of errorworkingHoursOnly— rejects events outsideconfig.workingHoursminDuration(minutes),maxDuration(minutes)— duration guardsminGranularityDuration— derives min duration fromconfig.granularitydomainRule({ id, description, domainKey, appliesTo?, evaluate })— factory for rules that target events carrying a specific domain model
Store Integration
withRules(store, engine, config, caller?)— wraps aCalendarStoreso every dispatch evaluates rules first; throwsRuleViolationErroron error-severity resultsRuleAwareStore—CalendarStorepluslastWarningsfor the most recent dispatchRuleViolationError— thrown when a rule'sevaluatereturns{ passed: false, severity: 'error' }
Calendar-flavored Types
CalendarRule— extendsRule<CalendarCommand, RuleContext>with optionaldomainKeyCalendarRuleResult— alias of the genericRuleResultRuleContext— pinned toCalendarReadModel,CoreConfig,CalendarDateTimeRuleEngine—RuleEngine<CalendarCommand, RuleContext>
Convenience
createRuleEngine is re-exported from @bimetal/rule-engine so calendar consumers don't need a second import.
Example
import { createCalendarStore, createEvent } from '@bimetal/calendar-data';
import {
createRuleEngine,
noOverlap,
workingHoursOnly,
withRules,
} from '@bimetal/calendar-rules';
import { defaultConfig } from '@bimetal/core';
const store = createCalendarStore();
const engine = createRuleEngine([noOverlap(), workingHoursOnly]);
const guarded = withRules(store, engine, defaultConfig);
await guarded.dispatch(createEvent(/* ... */)); // throws RuleViolationError on conflictNote on Domain Filtering
CalendarRule.domainKey is an opaque hint. The generic engine does not filter rules by it (that would couple @bimetal/rule-engine to the calendar event shape). Instead, domainRule() checks the target event's domains[domainKey] inside its own evaluate and returns PASS when the domain is absent — same behavior as before, but cleanly decoupled.
Replaces
This package contains the calendar-specific portion of the (removed) @bimetal/rules. The generic engine lives in @bimetal/rule-engine.
License
PolyForm Noncommercial License 1.0.0
