Improvements to communication between clients and relays

Some cleaning up, and removing over-explanation of AND and OR logic as it becomes overwhelming to read such unnecessary details. 

It is mentioned once when filter attributes are introduced (AND for attributes, OR for lists), and again for grouping filters (OR), left as is. 

Some other minor changes to improve readability.
This commit is contained in:
Arman The Parman 2024-06-18 15:03:02 +10:00 committed by GitHub
parent 1728f93d17
commit 6975e15e0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

22
01.md
View File

@ -115,35 +115,27 @@ Clients can send 3 types of messages, which must be JSON arrays, according to th
* `["REQ", <subscription_id>, <filters1>, <filters2>, ...]`, used to request events and subscribe to new updates. * `["REQ", <subscription_id>, <filters1>, <filters2>, ...]`, used to request events and subscribe to new updates.
* `["CLOSE", <subscription_id>]`, used to stop previous subscriptions. * `["CLOSE", <subscription_id>]`, used to stop previous subscriptions.
`<subscription_id>` is an arbitrary, non-empty string of max length 64 chars. It represents a subscription per connection. Relays MUST manage `<subscription_id>`s independently for each WebSocket connection. `<subscription_id>`s are not guaranteed to be globally unique. The `<subscription_id>` is an arbitrary, non-empty string of max length 64 chars generated by the client. It represents a subscription per connection. Relays MUST manage `<subscription_id>`s independently for each WebSocket connection. `<subscription_id>`s are not guaranteed to be globally unique.
`<filtersX>` is a JSON object that determines what events will be sent in that subscription, it can have the following attributes: `<filtersX>` is a JSON object containing filter attributes to determine which events will be sent in that subscription. The possible attributes are listed below, and they are filtered with logical AND. If an attribute contains a list (JSON array), the list is filtered with logical OR.
```json ```json
{ {
"ids": <a list of event ids>, "ids": <a list of event ids>,
"authors": <a list of lowercase pubkeys, the pubkey of an event must be one of these>, "authors": <a list of lowercase pubkeys>,
"kinds": <a list of a kind numbers>, "kinds": <a list of a kind numbers>,
"#<single-letter (a-zA-Z)>": <a list of tag values, for #e a list of event ids, for #p a list of pubkeys, etc.>, "#<single-letter (a-zA-Z)>": <a list of tag values, for #e a list of event ids, for #p a list of pubkeys, etc.>,
"since": <an integer unix timestamp in seconds, events must be newer than this to pass>, "since": <an integer Unix timestamp in seconds, events must be newer than this to pass>,
"until": <an integer unix timestamp in seconds, events must be older than this to pass>, "until": <an integer Unix timestamp in seconds, events must be older than this to pass>,
"limit": <maximum number of events relays SHOULD return in the initial query> "limit": <maximum number of events relays SHOULD return in the INITIAL query>
} }
``` ```
Upon receiving a `REQ` message, the relay SHOULD query its internal database and return events that match the filter, then store that filter and send again all future events it receives to that same websocket until the websocket is closed. The `CLOSE` event is received with the same `<subscription_id>` or a new `REQ` is sent using the same `<subscription_id>`, in which case relay MUST overwrite the previous subscription. Upon receiving a `REQ` message, the relay SHOULD query its internal database and return events that match the filter, then store that filter and send again all future events it receives to that same websocket until the websocket is closed. The `CLOSE` event is received with the same `<subscription_id>` or a new `REQ` is sent using the same `<subscription_id>`, in which case relay MUST overwrite the previous subscription.
Filter attributes containing lists (`ids`, `authors`, `kinds` and tag filters like `#e`) are JSON arrays with one or more values. At least one of the arrays' values must match the relevant field in an event for the condition to be considered a match. For scalar event attributes such as `authors` and `kind`, the attribute from the event must be contained in the filter list. In the case of tag attributes such as `#e`, for which an event may have multiple values, the event and filter condition values must have at least one item in common.
The `ids`, `authors`, `#e` and `#p` filter lists MUST contain exact 64-character lowercase hex values.
The `since` and `until` properties can be used to specify the time range of events returned in the subscription. If a filter includes the `since` property, events with `created_at` greater than or equal to `since` are considered to match the filter. The `until` property is similar except that `created_at` must be less than or equal to `until`. In short, an event matches a filter if `since <= created_at <= until` holds.
All conditions of a filter that are specified must match for an event for it to pass the filter, i.e., multiple conditions are interpreted as `&&` conditions.
A `REQ` message may contain multiple filters. In this case, events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as `||` conditions. A `REQ` message may contain multiple filters. In this case, events that match any of the filters are to be returned, i.e., multiple filters are to be interpreted as `||` conditions.
The `limit` property of a filter is only valid for the initial query and MUST be ignored afterwards. When `limit: n` is present it is assumed that the events returned in the initial query will be the last `n` events ordered by the `created_at`. It is safe to return less events than `limit` specifies, but it is expected that relays do not return (much) more events than requested so clients don't get unnecessarily overwhelmed by data. The `limit` property of a filter is only valid for the initial query and MUST be ignored afterwards. When `limit: n` is present it is assumed that the events returned in the initial query will be the last `n` events ordered by the `created_at`. It is acceptable to return fewer events than `limit` specifies, but it is expected that relays do not return (much) more events than requested, to avoid clients getting overwhelmed by data.
### From relay to client: sending events and notices ### From relay to client: sending events and notices