Skip to content

Unwanted declaration merging #50

@pcafstockf

Description

@pcafstockf

What a great project!
When I stumbled upon it, I actually went looking for somewhere to use it. 🥇
The way you use JavaScript features to make the rules feel more natural, is very cool.

The premise merging feature is a great optimization... except when it's unwanted :-)
Disclaimer: I'm not an expert with rules engines, so feel free to point out if my thinking about this all wrong.

Consider a (somewhat contrived) example of a collection of rules which each ensure that a required section of a dynamic document are present:

requiredSections.forEach((clazz) => {
	rules.push(new Rule({
		name: 'require ' + clazz,
		when: [
			(facts) => (! document.querySelector('div.' + clazz))
		],
		then: (facts) => {
			appendSectionTemplate(sectionTemplates.get(clazz));
		}
	}));
})

You could have 8 required sections, but they will all hash to the same premise, and so only one of the 8 actions will fire, ever.

If I've not missed something and this is a valid concern, what about enhancing the API such that a premise could be a function or an array the first element of which would always be a function.
Something like:
[(facts) => (! document.querySelector('div.' + clazz)), clazz]

This would still allow for hashing of the premise, would not break any existing rules/code, and would only require changes to 2 lines of code.

RuleSet.register would need a 1 line change:

        premise = new Premise({
          ...rule,
          id: this.nextPremiseId(),
          name: `${rule.name} / ${index}`,
          when: Array.isArray(when) ? when[0] : when,
        });

And to keep bad things from happening, the assert on line 36 of Rule.js would need to be:
this.when.reduce((acc, premise) => acc && (isFunction(premise) || (Array.isArray(premise) && isFunction(premise[0]))), true),

This would provide premise merging by default, but allow an override on an as needed basis.

If this sounds interesting, I would be happy to provide a PR.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions