ssevents/limit

Parser and decoder safety limits.

These values bound memory growth for the incremental decoder. The new constructor rejects nonsensical values with a panic so callers do not silently run with ineffective limits. For dynamic input (config / env / framework), use new_checked and surface LimitConfigError.NonPositiveLimit through your normal result chain.

Types

Why a checked limit constructor refused its argument.

field names the offending parameter so a single handler can produce meaningful diagnostics across many checked constructors; given carries the rejected value.

pub type LimitConfigError {
  NonPositiveLimit(field: String, given: Int)
}

Constructors

  • NonPositiveLimit(field: String, given: Int)
pub opaque type Limits

Values

pub fn default() -> Limits
pub const default_max_data_lines: Int
pub const default_max_event_bytes: Int
pub const default_max_line_bytes: Int
pub const default_max_retry_value: Int
pub fn max_data_lines(limits: Limits) -> Int
pub fn max_event_bytes(limits: Limits) -> Int
pub fn max_event_size(limits: Limits) -> Int

Alias of max_event_bytes/1. Reads the per-event byte cap the decoder uses to reject oversize events with Error(EventTooLarge(_)). Provided so callers can stay in the with_max_event_size / max_event_size spelling pair when raising the limit explicitly. (#96)

pub fn max_line_bytes(limits: Limits) -> Int
pub fn max_retry_value(limits: Limits) -> Int
pub fn new(
  max_line_bytes max_line_bytes: Int,
  max_event_bytes max_event_bytes: Int,
  max_data_lines max_data_lines: Int,
  max_retry_value max_retry_value: Int,
) -> Limits
pub fn new_checked(
  max_line_bytes max_line_bytes: Int,
  max_event_bytes max_event_bytes: Int,
  max_data_lines max_data_lines: Int,
  max_retry_value max_retry_value: Int,
) -> Result(Limits, LimitConfigError)

Like new, but returns the argument-validation failure as a Result instead of panicking. Use this when limit values come from configuration, environment variables, or other dynamic sources where a malformed value is a recoverable runtime condition rather than a programmer error.

On success the returned Limits is identical to what new would return for the same arguments.

pub fn strict_retry_cap(limits: Limits) -> Bool

Read the strict_retry_cap flag from a Limits value.

When True, the decoder errors with InvalidRetry(_) on retry: values above max_retry_value; when False (the default), it silently drops the offending field to None and the surrounding event still dispatches. See with_strict_retry_cap/2. (#95)

pub fn with_max_event_size(limits: Limits, bytes: Int) -> Limits

Override the per-event byte cap on a Limits value.

ssevents.decode/1 runs with default_max_event_bytes (65_536) and fails the whole stream with Error(EventTooLarge(65_536)) for any event above that cap — symmetric with max_line_bytes / max_data_lines, but asymmetric with the encoder side which never rejects an event for sheer size. A caller that knowingly emits a 100 KB event and pipes it back through the decoder needs to raise the cap explicitly:

let limits =
  ssevents.default_limits()
  |> ssevents.with_max_event_size(200_000)
ssevents.decode_with_limits(wire, limits: limits)

The default decode/1 deliberately keeps the 65_536-byte ceiling as a memory-bound safety net for untrusted input; reach for decode_with_limits + with_max_event_size when the input is trusted and known to be larger. Panics on bytes < 1 to mirror new/4’s posture. (#96)

pub fn with_strict_retry_cap(
  limits: Limits,
  strict: Bool,
) -> Limits

Toggle the decoder’s retry: cap-overrun posture.

Defaults to False (lenient): a retry: value whose integer form exceeds max_retry_value is silently dropped to None so the surrounding event still dispatches, mirroring the encoder’s retry_clamp/2 and matching WHATWG SSE’s lenient parser thesis. Opt into True when downstream code needs to detect adversarial retry values explicitly. (#95)

Search Document