reckon_db_filters (reckon_db v3.0.0)
View SourceKhepri event filters for reckon-db
Provides filter builders for Khepri event subscriptions. These filters are used to watch for new events matching specific criteria.
Summary
Functions
Create a filter matching events with a specific pattern in their metadata
Create a filter matching events with a specific pattern in their payload
Create a filter for events of a specific type
Build a Khepri tree-event filter for subscriptions of type stream (a.k.a. by_stream).
Create a filter matching events with specific tags
In-memory predicate matching an #event{} record against a subscription's (Type, Selector) pair.
Types
-type event() :: #event{event_id :: binary(), event_type :: binary(), stream_id :: binary(), version :: non_neg_integer(), data :: map() | binary(), metadata :: map(), tags :: [binary()] | undefined, timestamp :: integer(), epoch_us :: integer(), data_content_type :: binary(), metadata_content_type :: binary(), prev_event_hash :: binary() | undefined, mac :: {KeyId :: non_neg_integer(), MacBytes :: binary()} | undefined, signature :: binary() | undefined}.
-type subscription_type() ::
stream | event_type | event_pattern | event_payload | tags | by_stream | by_event_type |
by_event_pattern | by_event_payload | by_tags.
Functions
-spec by_event_pattern(map()) -> khepri_evf:tree_event_filter().
Create a filter matching events with a specific pattern in their metadata
The pattern is a map that must be a subset of the event record.
-spec by_event_payload(map()) -> khepri_evf:tree_event_filter().
Create a filter matching events with a specific pattern in their payload
The pattern is checked against the data field of the event.
-spec by_event_type(binary()) -> khepri_evf:tree_event_filter().
Create a filter for events of a specific type
Uses #event{} record pattern matching since events are stored as records.
-spec by_stream(binary()) -> khepri_evf:tree_event_filter() | {error, empty_selector}.
Build a Khepri tree-event filter for subscriptions of type stream (a.k.a. by_stream).
Selector grammar
<<"$all">>— the only recognised wildcard sentinel. Matches every event in every stream in the store.- Any other non-empty binary — a literal stream id; the filter matches events on that exact stream only.
Stream id conventions
The filter doesn't enforce stream-id shape (it just treats the selector as a path component), but reckon-db has two formats:
- **User streams** —
<prefix>-<hex>, where prefix is[A-Za-z]+and hex is[A-Fa-f0-9]+(typically a UUIDv7 with dashes stripped). Example:account-018f6a7b8c9d4abc8901234567890abc. - **System streams** —
$<namespace>:<name>, where the$prefix marks "reckon-db-managed, not user data" and<name>is intentionally human-readable. Example:$link:high-value-ordersfromreckon_db_links. Same role as EventStoreDB's$ce-/$et-/$by_*prefixes.
Both formats subscribe identically — the filter doesn't care. The $ namespace is only special at the sentinel level ($all).
Returns {error, empty_selector} for an empty binary; every other input builds a filter. Append-time validation of the user-stream-id shape lives in reckon_db_streams (and is currently advisory; a strict-rejection mode is a follow-up).
-spec by_tags([binary()]) -> khepri_evf:tree_event_filter().
Create a filter matching events with specific tags
Note: Khepri's pattern matching doesn't natively support list membership, so this creates a broad filter that matches all events with tags. The actual tag filtering must be done by the subscription consumer. For efficient tag-based queries, use reckon_db_streams:read_by_tags/4.
In-memory predicate matching an #event{} record against a subscription's (Type, Selector) pair.
The Khepri event filters above are evaluated by Khepri itself on live triggers, but the catch-up replay path bypasses Khepri's trigger engine — it reads the global stream and delivers events directly to the subscriber. Without this predicate, every subscription with start_from = 0 would receive the entire log regardless of its declared selector. Use this to filter the catch-up batch before sending.
Tag membership uses set inclusion: the event must carry ALL of the requested tags (consistent with read_by_tags default match semantics).