Elixir Media over QUIC library.
Protocol code is built on top of a small transport adapter boundary so that native QUIC and deterministic support transports can share the same contract.
Summary
Types
Object delivery selected for a published track.
Protocol-neutral reason for publisher-initiated subscription completion.
Option accepted by add_track/4.
Option accepted by subscribe/3.
Relative object boundary requested when a subscription begins.
Option accepted by update_subscription/3.
Error returned by withdraw_track/3.
Functions
Accepts one pending inbound publisher subscription.
Registers a retained catalog track under a ready publication.
Registers a track under an active publication.
Cancels one discovery, withdrawing its reported broadcasts before DiscoveryDone.
Gracefully closes the selected protocol connection.
Connects to an endpoint using one explicitly selected protocol implementation.
Discovers matching Lite05 broadcasts using a literal path prefix.
Finishes every active delivery and withdraws a namespace publication.
Finishes one accepted publisher subscription without withdrawing its track or namespace publication.
Advertises a namespace through the selected protocol implementation.
Publishes a complete catalog snapshot on a handle returned by add_catalog/3.
Publishes one object on a registered track.
Rejects one pending inbound publisher subscription.
Subscribes to a protocol-neutral track address.
Returns the default native QUIC transport implementation.
Ends an active subscription and sends the selected protocol's unsubscribe message.
Updates an active subscription's draft-neutral filter and delivery parameters.
Withdraws one registered track while keeping its publication and siblings active.
Types
@type publication_delivery() :: :subgroup | :datagram
Object delivery selected for a published track.
@type published_subscription_status() ::
:internal_error
| :unauthorized
| :track_ended
| :subscription_ended
| :going_away
| :expired
| :too_far_behind
| :malformed_track
| :update_failed
Protocol-neutral reason for publisher-initiated subscription completion.
@type published_track_option() :: {:retention, :live | :latest | :all} | {:delivery, publication_delivery()} | {:timescale, pos_integer()} | {:publisher_priority, 0..255} | {:publisher_max_latency, non_neg_integer()}
Option accepted by add_track/4.
@type subscription_option() :: {:profile, MOQX.Profile.t()} | {:max_catalog_bytes, pos_integer()} | {:max_catalog_encoded_bytes, pos_integer()} | {:start, subscription_start()} | {:filter, MOQX.SubscriptionFilter.t()} | {:priority, 0..255} | {:group_order, :ascending | :descending} | {:delivery_timeout, pos_integer()} | {:parameters, [MOQX.SubscriptionParameter.t()]}
Option accepted by subscribe/3.
@type subscription_start() :: :next_object | :next_group
Relative object boundary requested when a subscription begins.
:next_object starts after the publisher's current largest object and is the
compatibility default. :next_group waits for the first object in a later
group. A selected protocol returns an error when it cannot represent the
requested policy.
@type subscription_update_option() :: {:start, subscription_start()} | {:filter, MOQX.SubscriptionFilter.t()} | {:priority, 0..255} | {:delivery_timeout, pos_integer()} | {:forward, boolean()} | {:new_group, non_neg_integer()} | {:parameters, [MOQX.SubscriptionParameter.t()]}
Option accepted by update_subscription/3.
@type withdraw_track_error() :: :unknown_published_track | :wrong_client_published_track | :unsupported_completion_status | :invalid_track_completion | :timeout | {:connection_closed, term()} | {:transport_action_failed, term()}
Error returned by withdraw_track/3.
Functions
@spec accept_subscription( MOQX.Client.t(), MOQX.PublicationSubscriptionRequest.t(), MOQX.PublishedTrack.t(), keyword() ) :: {:ok, MOQX.PublishedSubscription.t()} | {:error, term()}
Accepts one pending inbound publisher subscription.
Pass an existing PublishedTrack to attach another subscriber to a
registered track; the result contains its PublishedSubscription handle.
Pass track options instead to register the requested track reactively and
accept its first subscription without sending a separate publisher-initiated
PUBLISH; that result contains both the new track and subscription handles.
@spec add_catalog(MOQX.Client.t(), MOQX.Publication.t(), keyword()) :: {:ok, MOQX.PublishedTrack.t()} | {:error, term()}
Registers a retained catalog track under a ready publication.
Requires an explicit :profile. HANG supports compression: :none (default,
catalog.json) and :deflate (catalog.json.z). Register both to serve both
forms. Each handle has independent update numbering and retains its latest
snapshot for late subscribers. CMSF uses its profile's conventional name.
@spec add_track(MOQX.Client.t(), MOQX.Publication.t(), binary(), [ published_track_option() ]) :: {:ok, MOQX.PublishedTrack.t()} | {:error, term()}
Registers a track under an active publication.
:delivery defaults to :subgroup. The selected protocol rejects a delivery
mode it cannot represent. MoQ Lite draft-05 additionally requires a positive
:timescale and accepts :publisher_priority and
:publisher_max_latency for its immutable TRACK_INFO.
@spec cancel_discovery(MOQX.Client.t(), MOQX.Discovery.t()) :: :ok | {:error, term()}
Cancels one discovery, withdrawing its reported broadcasts before DiscoveryDone.
@spec close(MOQX.Client.t(), keyword()) :: :ok | {:error, term()}
Gracefully closes the selected protocol connection.
@spec connect(binary() | URI.t(), keyword()) :: {:ok, MOQX.Client.t()} | {:error, term()}
Connects to an endpoint using one explicitly selected protocol implementation.
@spec discover(MOQX.Client.t(), binary(), keyword()) :: {:ok, MOQX.Discovery.t()} | {:error, term()}
Discovers matching Lite05 broadcasts using a literal path prefix.
BroadcastAvailable events enumerate initial matches, followed by
DiscoveryReady; additions and withdrawals then continue live. This does not
subscribe to track catalogs. max_broadcasts defaults to 1024; exceeding it
ends only that discovery. Replacement advertisements emit withdrawal with
reason :replaced followed by availability. An unknown withdrawal terminates
the discovery with :invalid_announcement, clearing all its broadcasts.
Other protocols return :unsupported_operation.
@spec finish_publication(MOQX.Client.t(), MOQX.Publication.t(), keyword()) :: :ok | {:error, term()}
Finishes every active delivery and withdraws a namespace publication.
Pending controlled subscription requests are cancelled before established subscriptions and published tracks complete. The selected protocol withdraws the namespace only after those per-request completion boundaries.
@spec finish_subscription( MOQX.Client.t(), MOQX.PublishedSubscription.t(), status: published_subscription_status(), reason: binary() ) :: :ok | {:error, term()}
Finishes one accepted publisher subscription without withdrawing its track or namespace publication.
The selected implementation maps the protocol-neutral :status atom to its
native PUBLISH_DONE code. The default is :subscription_ended.
@spec publish(MOQX.Client.t(), [binary()], keyword()) :: {:ok, MOQX.Publication.t()} | {:error, term()}
Advertises a namespace through the selected protocol implementation.
@spec publish_catalog(MOQX.Client.t(), MOQX.PublishedTrack.t(), MOQX.Catalog.t()) :: :ok | {:error, term()}
Publishes a complete catalog snapshot on a handle returned by add_catalog/3.
Groups increase from zero independently per handle. Every update is one
object, immediately finished, and retained for late subscribers. A failed
validation does not consume a group number. This is transport admission;
CatalogReceived at a receiver proves delivery.
@spec publish_object(MOQX.Client.t(), MOQX.PublishedTrack.t(), MOQX.Object.t()) :: :ok | {:error, term()}
Publishes one object on a registered track.
@spec reject_subscription( MOQX.Client.t(), MOQX.PublicationSubscriptionRequest.t(), MOQX.SubscriptionRejection.t() ) :: :ok | {:error, term()}
Rejects one pending inbound publisher subscription.
@spec subscribe(MOQX.Client.t(), MOQX.TrackRef.t(), [subscription_option()]) :: {:ok, MOQX.Subscription.t()} | {:error, term()}
Subscribes to a protocol-neutral track address.
:profile defaults to :none: even catalog-named tracks emit opaque
ObjectReceived events. Select :cloudflare_cmsf, :moqtail_cmsf, or :hang
explicitly for CatalogReceived snapshots. The byte-limit options default to
1 MiB each. HANG catalog.json.z selects raw DEFLATE; other HANG track names
select plain JSON. Malformed updates emit CatalogFailed on this handle and
preserve the last valid snapshot; a newer valid group can recover. HANG
snapshots replace the whole catalog, report added/removed/changed track refs,
and ignore older groups. Duplicate groups and nonzero object IDs are errors.
Profile selection is immutable for the subscription lifetime.
The :start option accepts :next_object or :next_group and defaults to
:next_object. Protocol implementations map that application policy to
their native subscription filter and reject unsupported policies explicitly.
@spec transport() :: module()
Returns the default native QUIC transport implementation.
@spec unsubscribe(MOQX.Client.t(), MOQX.Subscription.t()) :: :ok | {:error, term()}
Ends an active subscription and sends the selected protocol's unsubscribe message.
@spec update_subscription( MOQX.Client.t(), MOQX.Subscription.t(), [subscription_update_option()] ) :: :ok | {:error, term()}
Updates an active subscription's draft-neutral filter and delivery parameters.
@spec withdraw_track( MOQX.Client.t(), MOQX.PublishedTrack.t(), status: published_subscription_status(), reason: binary() ) :: :ok | {:error, withdraw_track_error()}
Withdraws one registered track while keeping its publication and siblings active.
The track is unavailable to new subscribers before this call returns. The
selected protocol maps :status to its native terminal code. The default
status is :track_ended.