Skip to content

feat(ffi)!: bindings yield a flat announce event with Live - #4266

Open
kixelated wants to merge 7 commits into
devfrom
quest/m1/announce-live-bindings
Open

kixelated wants to merge 7 commits into
devfrom
quest/m1/announce-live-bindings

Conversation

@kixelated

@kixelated kixelated commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

moq-net's announce consumer yields announce::Event::Live once every route live at subscribe time has landed, but moq-ffi and libmoq dropped it. A binding app could not list what is live and stop without a timer.

Approach

Mirror announce::Event one to one:

  • moq-ffi: MoqAnnounceConsumer::next returns MoqAnnounceEvent (Announced, Updated, Retracted carrying a MoqAnnounce record, or Live). MoqAnnounce is a record (prefix, captures, route), mirroring announce::Announce, so the getter-only MoqAnnounceUpdate object is gone.
  • libmoq: moq_announce_update.kind (moq_announce_kind: ANNOUNCED, UPDATED, RETRACTED, LIVE) replaces active. A LIVE event arrives through the same on_announce callback with no prefix or captures, and is freed like any other record.
  • Wrappers re-export Announce and AnnounceEvent, and name the variants with one convention, now recorded in /quest/m1/ffi-shape/net.md: AnnounceEventAnnounced, AnnounceEventUpdated, AnnounceEventRetracted, AnnounceEventLive in Go, Kotlin, Dart, and Python, whatever the generated name. Swift keeps its generated cases (.announced(announce:), ..., .live), since it cannot alias a case.
  • Every binding with a test suite gets a test that an empty origin yields Live at once, and that an existing route comes before Live. Existing tests skip Live wherever it lands.

Impact

  • moq-ffi (breaking): MoqAnnounceConsumer::next returns Option<MoqAnnounceEvent>. MoqAnnounceUpdate (object with prefix(), captures(), route(), active()) is replaced by the MoqAnnounce record plus the MoqAnnounceEvent enum.
  • libmoq C ABI (breaking): moq_announce_update.active is moq_announce_update.kind, a new moq_announce_kind enum. on_announce also fires once for LIVE.
  • Python (breaking): moq.AnnounceUpdate is removed; AnnounceConsumer yields moq.AnnounceEvent. New moq.Announce and the four variant aliases.
  • Go (breaking): AnnounceUpdate is removed; AnnounceConsumer.Next/All yield AnnounceEvent. New Announce and the four variant aliases.
  • Swift (breaking): AnnounceUpdate is removed; AnnounceConsumer.Element is AnnounceEvent. New Announce.
  • Kotlin (breaking): AnnounceUpdate is removed; announcements() is a Flow<AnnounceEvent>. New Announce, AnnounceEvent, and the four variant aliases.
  • Dart (breaking): AnnounceUpdate is removed; announcements() is a Stream<AnnounceEvent>. New Announce, AnnounceEvent, and the four variant aliases.
  • Wire: none.

Alternatives

  • Keep MoqAnnounceUpdate as an object and add a kind() getter. Rejected: it keeps a getter-only handle (which /quest/m1/ffi-shape/net.md wants gone) and would not mirror Rust's Event enum.
  • A separate libmoq callback or status code for LIVE. Rejected: the existing record plus kind keeps one callback and matches the quest plan.

Follow-ups

  • Swift was not compiled locally (no Swift toolchain on Linux); CI covers it.
  • doc/setup/upgrade.md covers the 2026-09-23 train only; the next train's page should list this break.

🤖 Generated with Claude Code

(Written by Opus 5.5)

kixelated and others added 7 commits September 26, 2026 10:03
moq-ffi's MoqAnnounceConsumer::next returns MoqAnnounceEvent (Announced,
Updated, Retracted carrying a MoqAnnounce record, or Live), mirroring
moq-net's announce::Event and replacing MoqAnnounceUpdate::active().
libmoq's moq_announce_update gains a moq_announce_kind in place of the
active flag, and delivers a LIVE record once caught up. The Python, Go,
Swift, Kotlin, and Dart wrappers follow, each with a test that an empty
origin yields Live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-bindings

# Conflicts:
#	doc/lib/c/index.md
#	rs/libmoq/src/test.rs
#	rs/moq-ffi/src/test.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review September 26, 2026 20:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-26T20:27:14.506016Z 42c9074 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42c9074647

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

///
/// A [AnnounceEventLive] follows the routes live at subscribe time, so a
/// listener can collect what is live and stop there.
Stream<AnnounceEvent> announcements({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the Dart README for the new event type

Update dart/moq/README.md with this breaking return-type change. Its quickstart still calls announcement.prefix() and announcement.captures(), but each value is now an AnnounceEvent, which exposes neither method, so the documented example no longer compiles. It should pattern-match AnnounceEventAnnounced, read event.announce.prefix and captures, and account for AnnounceEventLive.

AGENTS.md reference: AGENTS.md:L27-L27

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant