The central place subjects, primitives, and rules come together.

This package only describes the contract; the actual behavior is supplied by an implementation, reached through the platform service ruleRegistry.

What the API does, by area:

Saved rules are loaded by the host client from its own config layer at boot and live in the same id namespace as primitives. They are not registered through this interface. The registry resolves references during compile and validate but exposes no public API for managing them.

Example

Compiling and evaluating a rule from a web component

const registry = platform.get(PlatformServiceName.RuleRegistry);
const compiled = registry.compile(this.descriptor.rules.visibility);
const visible = compiled(registry.scope({ host: this.host }));

Example

Test-fixture scope

const scope = registry.scope({
with: { user: testUser, limeobject: testObject },
});
const passes = registry.compile(rule)(scope);

Hierarchy

  • RuleRegistry

Methods

  • Turn a Rule into a callable predicate.

    Every ref is resolved against the registered primitives and saved rules. Saved rules are expanded in place and cycles are detected. Args at each leaf are not validated by the contract; primitives are responsible for handling their own args (see RulePrimitive). An implementation may surface args-mismatch issues if it has a way to introspect a primitive's args, but the contract does not require it.

    The returned predicate is a snapshot: it reflects whatever was registered when compile ran, so anything compiled against an older set of saved rules is stale once those rules change. If results are cached, recompile when saved rules change. Re-running compile on a structurally-equal rule may or may not return the same CompiledRule instance, so don't rely on identity equality.

    Thrown errors inside a predicate are caught and treated as false for that node, the same outcome as a missing slot. Callers do not need to wrap evaluations in try/catch. This fail-closed behavior applies only to errors raised at evaluation time. Errors raised by build while compiling propagate out of compile, so a primitive that cannot handle its args should return a constant-false predicate from build rather than throwing.

    Returns

    A predicate over RuleScope.

    Throws

    If the rule has an unknown-ref or cycle issue, or if a build call throws. Implementations that validate args may also throw args-mismatch. args-on-saved-rule does not throw, the args are dropped and validate reports it as a diagnostic. Use validate for the non-throwing variant.

    Parameters

    • rule: Rule

      The rule to compile.

    Returns CompiledRule

  • List the display metadata supplied at registration.

    Optional, an implementation that doesn't track metadata can leave this method off. When present, returns one entry per registered primitive.

    Returns

    Metadata for each registered primitive.

    Returns PrimitiveMetadata[]

  • Attach a value for a subject slot to a host element. Typically called during a component's lifetime.

    When something later builds a scope rooted in a descendant of this host and asks for slot, the closest ancestor that registered a provider for that slot wins.

    Two copies of the same component in different parts of the page each get their own scope, they don't interfere.

    Returns

    Teardown function. Call from disconnectedCallback (or equivalent) to detach the provider.

    Type Parameters

    • K extends keyof SubjectRegistry

      The slot id. Pinning it to a known slot makes getter's return type match the slot's value type.

    Parameters

    • host: HTMLElement

      Element to attach the provider to.

    • slot: K

      The slot this provider answers.

    • getter: (() => SubjectRegistry[K])

      Returns the current value. Called every time a scope walk hits this provider, so keep it cheap. May return undefined when no value is currently available; the scope walk then continues to the next provider.

    Returns (() => void)

      • (): void
      • Attach a value for a subject slot to a host element. Typically called during a component's lifetime.

        When something later builds a scope rooted in a descendant of this host and asks for slot, the closest ancestor that registered a provider for that slot wins.

        Two copies of the same component in different parts of the page each get their own scope, they don't interfere.

        Returns

        Teardown function. Call from disconnectedCallback (or equivalent) to detach the provider.

        Returns void

  • Register a RulePrimitive.

    The id must be namespaced (contain a .) and must not be in use already, neither by another primitive nor by a saved rule.

    metadata is optional and carries the display side of things: title, description, icon, tags, and a ConfigMetadata.configComponent | configComponent for editing the primitive's args. None of it is used at evaluation time; it shows up later via listMetadata.

    Throws

    If the id is unnamespaced, already taken by another primitive, or already in use by a saved rule.

    Parameters

    Returns void

  • Declare that a subject slot exists. Called once per slot at bootstrap.

    The optional provider is a session-wide fallback, used when no DOM ancestor and no per-call override has supplied a value. Good for slots that are the same for the whole session, like the current user or device.

    Compare with provideSubject, which supplies a value scoped to a specific host element.

    Type Parameters

    • K extends keyof SubjectRegistry

      The slot id. Tying it to a known slot makes the provider's return type match the slot's value type.

    Parameters

    • metadata: SubjectMetadata<K>

      Metadata for the slot (id, label, description).

    • Optional provider: (() => SubjectRegistry[K])

      Optional session-wide fallback. May return undefined when no value is currently available; treated the same as no provider being registered.

    Returns void

  • Build a RuleScope. The only supported way to make one.

    • Pass host to walk the DOM from there. Typical for components.
    • Pass with to hand in fixed values. Typical for tests and headless code.
    • Pass both to walk the DOM with overrides for specific slots.
    • Pass nothing for an empty scope where every get returns undefined.

    Returns

    A new scope.

    Parameters

    Returns RuleScope

  • Same checks as compile, but returns structured diagnostics instead of throwing, and no predicate is produced.

    available is a hint from the caller, not something the registry can verify: the registry doesn't know which slots will be supplied at evaluation time, only the caller building the scope does. Pass it when known; otherwise the runtime fallback (missing slots produce false) catches the gap.

    Returns

    ok: true when the rule passes every check; otherwise ok: false with a list of issues.

    Parameters

    • rule: Rule

      The rule to validate.

    • Optional available: (keyof SubjectRegistry)[]

      Optional list of slots the caller knows will be available where the rule runs. Used to surface missing-slot issues at save time.

    Returns RuleValidationResult