Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dart/moq/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final connection = await Moq.connect('https://relay.example.com');
await for (final event in connection.announcements(
options: const AnnounceOptions(prefix: 'live/', filter: '*/camera'),
)) {
if (event is AnnounceEventAnnounced) {
if (event is AnnounceEventStart) {
// Prefix stays origin-relative; captures reports wildcard matches.
print(event.announce.prefix);
print(event.announce.captures);
Expand Down
10 changes: 5 additions & 5 deletions dart/moq/lib/src/aliases.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ typedef AnnouncedBroadcast = MoqAnnouncedBroadcast;
/// A route over a prefix: its origin-relative path, wildcard captures, and route metadata.
typedef Announce = MoqAnnounce;

/// What an [AnnounceConsumer] yields: [AnnounceEventAnnounced],
/// [AnnounceEventUpdated], [AnnounceEventRetracted], or [AnnounceEventLive].
/// What an [AnnounceConsumer] yields: [AnnounceEventStart],
/// [AnnounceEventUpdate], [AnnounceEventEnd], or [AnnounceEventLive].
typedef AnnounceEvent = MoqAnnounceEvent;

/// A route now covers the prefix; the stream had none there.
typedef AnnounceEventAnnounced = AnnouncedMoqAnnounceEvent;
typedef AnnounceEventStart = StartMoqAnnounceEvent;

/// The route covering the prefix changed hops or cost.
typedef AnnounceEventUpdated = UpdatedMoqAnnounceEvent;
typedef AnnounceEventUpdate = UpdateMoqAnnounceEvent;

/// No route covers the prefix any more; carries its last route.
typedef AnnounceEventRetracted = RetractedMoqAnnounceEvent;
typedef AnnounceEventEnd = EndMoqAnnounceEvent;

/// Every route live at subscribe time has been delivered; what follows is live changes.
typedef AnnounceEventLive = LiveMoqAnnounceEvent;
Expand Down
24 changes: 11 additions & 13 deletions dart/moq/test/moq_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,13 @@ void main() {
expect(client.bandwidth(), isA<MoqBandwidth>());

final announcement = client.announcements().firstWhere(
(event) => event is AnnounceEventAnnounced,
(event) => event is AnnounceEventStart,
);
final broadcast = relay.createBroadcast(path: 'live');
final track = broadcast.publishTrack(name: 'events', info: null);
broadcast.announce(route: MoqRoute());
final announced =
(await announcement.timeout(timeout) as AnnounceEventAnnounced)
.announce;
(await announcement.timeout(timeout) as AnnounceEventStart).announce;
expect(announced.prefix, 'live');

final requested = await client
Expand Down Expand Up @@ -106,14 +105,13 @@ void main() {
final serverSession = await accepted;

final announcement = client.announcements().firstWhere(
(event) => event is AnnounceEventAnnounced,
(event) => event is AnnounceEventStart,
);
final broadcast = server.createBroadcast('live');
final track = broadcast.publishTrack(name: 'events', info: null);
broadcast.announce(route: MoqRoute());
final announced =
(await announcement.timeout(timeout) as AnnounceEventAnnounced)
.announce;
(await announcement.timeout(timeout) as AnnounceEventStart).announce;
expect(announced.prefix, 'live');

client.close();
Expand Down Expand Up @@ -184,20 +182,20 @@ void main() {
broadcast.announce(route: MoqRoute());
final announced = consumer.announced(config: MoqAnnounceConfig());
final first = await nextRoute(announced);
expect(first, isA<AnnounceEventAnnounced>());
expect((first as AnnounceEventAnnounced).announce.prefix, 'live');
expect(first, isA<AnnounceEventStart>());
expect((first as AnnounceEventStart).announce.prefix, 'live');

broadcast.unannounce();
final retracted = await nextRoute(announced);
expect(retracted, isA<AnnounceEventRetracted>());
expect((retracted as AnnounceEventRetracted).announce.prefix, 'live');
expect(retracted, isA<AnnounceEventEnd>());
expect((retracted as AnnounceEventEnd).announce.prefix, 'live');
await expectLater(
consumer.requestBroadcast(path: 'live').timeout(timeout),
throwsA(anything),
);

broadcast.announce(route: MoqRoute());
expect(await nextRoute(announced), isA<AnnounceEventAnnounced>());
expect(await nextRoute(announced), isA<AnnounceEventStart>());
await consumer.requestBroadcast(path: 'live').timeout(timeout);
announced.cancel();
announced.dispose();
Expand All @@ -211,7 +209,7 @@ void main() {
final broadcast = origin.createBroadcast(path: 'room/alice/chat');
broadcast.announce(route: MoqRoute());

final update = await nextRoute(announced) as AnnounceEventAnnounced;
final update = await nextRoute(announced) as AnnounceEventStart;
expect(update.announce.prefix, 'room/alice/chat');
expect(update.announce.captures, ['alice']);
});
Expand All @@ -231,7 +229,7 @@ void main() {

final announced = consumer.announced(config: MoqAnnounceConfig());
final first = await announced.next().timeout(timeout);
expect((first as AnnounceEventAnnounced).announce.prefix, 'cam');
expect((first as AnnounceEventStart).announce.prefix, 'cam');
expect(await announced.next().timeout(timeout), isA<AnnounceEventLive>());
announced.cancel();
announced.dispose();
Expand Down
38 changes: 19 additions & 19 deletions dart/moq_ffi/lib/src/moq.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3917,19 +3917,19 @@ class FfiConverterMoqAnnounceEvent {
final subview = Uint8List.view(buf.buffer, buf.offsetInBytes + 4);
switch (index) {
case 1:
final lifted = AnnouncedMoqAnnounceEvent.read(subview);
final lifted = StartMoqAnnounceEvent.read(subview);
return LiftRetVal<MoqAnnounceEvent>(
lifted.value,
lifted.bytesRead - subview.offsetInBytes + 4,
);
case 2:
final lifted = UpdatedMoqAnnounceEvent.read(subview);
final lifted = UpdateMoqAnnounceEvent.read(subview);
return LiftRetVal<MoqAnnounceEvent>(
lifted.value,
lifted.bytesRead - subview.offsetInBytes + 4,
);
case 3:
final lifted = RetractedMoqAnnounceEvent.read(subview);
final lifted = EndMoqAnnounceEvent.read(subview);
return LiftRetVal<MoqAnnounceEvent>(
lifted.value,
lifted.bytesRead - subview.offsetInBytes + 4,
Expand Down Expand Up @@ -3961,18 +3961,18 @@ class FfiConverterMoqAnnounceEvent {
}
}

class AnnouncedMoqAnnounceEvent extends MoqAnnounceEvent {
class StartMoqAnnounceEvent extends MoqAnnounceEvent {
final MoqAnnounce announce;
AnnouncedMoqAnnounceEvent(MoqAnnounce this.announce);
AnnouncedMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<AnnouncedMoqAnnounceEvent> read(Uint8List buf) {
StartMoqAnnounceEvent(MoqAnnounce this.announce);
StartMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<StartMoqAnnounceEvent> read(Uint8List buf) {
int new_offset = buf.offsetInBytes;
final announce_lifted = FfiConverterMoqAnnounce.read(
Uint8List.view(buf.buffer, new_offset),
);
final announce = announce_lifted.value;
new_offset += announce_lifted.bytesRead;
return LiftRetVal(AnnouncedMoqAnnounceEvent._(announce), new_offset);
return LiftRetVal(StartMoqAnnounceEvent._(announce), new_offset);
}

@override
Expand All @@ -3999,18 +3999,18 @@ class AnnouncedMoqAnnounceEvent extends MoqAnnounceEvent {
}
}

class UpdatedMoqAnnounceEvent extends MoqAnnounceEvent {
class UpdateMoqAnnounceEvent extends MoqAnnounceEvent {
final MoqAnnounce announce;
UpdatedMoqAnnounceEvent(MoqAnnounce this.announce);
UpdatedMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<UpdatedMoqAnnounceEvent> read(Uint8List buf) {
UpdateMoqAnnounceEvent(MoqAnnounce this.announce);
UpdateMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<UpdateMoqAnnounceEvent> read(Uint8List buf) {
int new_offset = buf.offsetInBytes;
final announce_lifted = FfiConverterMoqAnnounce.read(
Uint8List.view(buf.buffer, new_offset),
);
final announce = announce_lifted.value;
new_offset += announce_lifted.bytesRead;
return LiftRetVal(UpdatedMoqAnnounceEvent._(announce), new_offset);
return LiftRetVal(UpdateMoqAnnounceEvent._(announce), new_offset);
}

@override
Expand All @@ -4037,18 +4037,18 @@ class UpdatedMoqAnnounceEvent extends MoqAnnounceEvent {
}
}

class RetractedMoqAnnounceEvent extends MoqAnnounceEvent {
class EndMoqAnnounceEvent extends MoqAnnounceEvent {
final MoqAnnounce announce;
RetractedMoqAnnounceEvent(MoqAnnounce this.announce);
RetractedMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<RetractedMoqAnnounceEvent> read(Uint8List buf) {
EndMoqAnnounceEvent(MoqAnnounce this.announce);
EndMoqAnnounceEvent._(MoqAnnounce this.announce);
static LiftRetVal<EndMoqAnnounceEvent> read(Uint8List buf) {
int new_offset = buf.offsetInBytes;
final announce_lifted = FfiConverterMoqAnnounce.read(
Uint8List.view(buf.buffer, new_offset),
);
final announce = announce_lifted.value;
new_offset += announce_lifted.bytesRead;
return LiftRetVal(RetractedMoqAnnounceEvent._(announce), new_offset);
return LiftRetVal(EndMoqAnnounceEvent._(announce), new_offset);
}

@override
Expand Down Expand Up @@ -12844,7 +12844,7 @@ void _checkApiChecksums() {
throw UniffiInternalError.panicked("UniFFI API checksum mismatch");
}
if (uniffi_moq_ffi_checksum_method_moqannouncedbroadcast_available() !=
64570) {
17719) {
throw UniffiInternalError.panicked("UniFFI API checksum mismatch");
}
if (uniffi_moq_ffi_checksum_method_moqannouncedbroadcast_cancel() != 63175) {
Expand Down
2 changes: 1 addition & 1 deletion demo/web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ discovery.run((effect) => {
// Only catalog-backed broadcasts are watchable streams; this skips the relay's
// `.stats` broadcast (see the stats dashboard demo for that one).
if (!path.endsWith(".hang") && !path.endsWith(".msf")) continue;
if (entry.kind === "retracted") live.delete(path);
if (entry.kind === "end") live.delete(path);
else live.add(path);
broadcasts.set([...live].sort());
}
Expand Down
2 changes: 1 addition & 1 deletion demo/web/src/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ discovery.run((effect) => {
const node = Net.Path.stripPrefix(prefix, path);
if (!node) continue;

if (entry.kind !== "retracted") {
if (entry.kind !== "end") {
if (subs.has(node)) continue;
const ne = new Signals.Effect();
subs.set(node, ne);
Expand Down
6 changes: 3 additions & 3 deletions doc/concept/moq-lite.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ prefixes it is told about.
A subscriber watching under a root sees advertisements named relative to that
root. The pattern scope filters which prefixes are visible without changing a
route's prefix. Announce events carry the covered path, captures, and what
happened to it: Rust `announce::Event::{Announced, Updated, Retracted}`, each
happened to it: Rust `announce::Event::{Start, Update, End}`, each
holding an `announce::Announce { prefix, captures: Option<Vec<Pattern>>, route }`,
and TypeScript `Announce.Event`, whose `kind` is `"announced"`, `"updated"`, or
`"retracted"` alongside the same `Announce.Announce` fields. An update is a
and TypeScript `Announce.Event`, whose `kind` is `"start"`, `"update"`, or
`"end"` alongside the same `Announce.Announce` fields. An update is a
reprice in place. Captures are present when the announced prefix pins every
wildcard in the most-specific matching scope member. The Rust consumer is a
`Stream` and the TypeScript one an async iterable. Both, and every binding over
Expand Down
2 changes: 1 addition & 1 deletion doc/lib/c/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ beside `pkgconfig/`.
- **Server.** `moq_server_listen` binds before it returns (a bad address or certificate fails there) and hands each incoming session to `on_request` as a request handle. Read `moq_session_request_path` and `_query` to route and authenticate, then `moq_session_request_accept` (a session handle, with origins like `moq_session_connect`) or `moq_session_request_reject` with an HTTP-style code (401 and 403 become the protocol's unauthorized close). An accepted session reports `1` once SETUP completes and never reconnects. `moq_server_addr` reports an ephemeral port and `moq_server_fingerprints` the hashes a client pins for a `tls_generate` certificate. `moq_server_close` stops listening; its terminal callback fires once the sockets are released.
- **Demand.** A watcher on a published track (`moq_publish_track_demand`, `moq_publish_media_demand`, `moq_encode_video_demand`, `moq_encode_audio_demand`) calls `on_demand` with `MOQ_DEMAND_USED` or `MOQ_DEMAND_UNUSED` right away and again on every change, so an encoder on a battery-powered device runs only while someone is watching. The first call is the current state, so a track that went unused before the watcher existed still reports it. `moq_publish_demand_cancel` stops it; the terminal callback still fires. A container has no single demand and is refused. Demand follows the last real subscriber: an origin that served the track drops its source copy on the unused edge, so a cache linger never delays it. Only a relay keeps what it already delivered warm for 30 seconds, and a returning subscriber is served that cache only once the publisher confirms it is still current.
- **Requests.** `moq_publish_dynamic` serves subscriptions to tracks the broadcast never declared: each arrives as a request handle, read its name with `moq_track_request_name`, then `moq_track_request_accept` (a raw track handle), `moq_track_request_video` / `_audio` (the media handle `moq_publish_video` / `_audio` return), or `moq_track_request_abort` with an application code the subscriber sees. Without a live handler an unknown name is refused. `moq_publish_track_dynamic` does the same for fetches of groups a track no longer has cached, delivered as `moq_group_request_*` (`sequence`, `priority`, `frame_start`); `moq_group_request_accept` starts the producer at `frame_start` so written frames keep their group indices. Register it with `moq_track_request_dynamic` before accepting a track that was itself requested by a fetch, so that pending group survives the transition. Both handlers stop with `moq_publish_dynamic_cancel`.
- **Everything the bindings can do** ([list](/lib/#what-every-binding-can-do)): media publish and consume with the catalog managed for you, raw pixels and PCM with the codec inside (`moq_encode_video`, `moq_encode_audio`, and the `moq_decode_*` mirrors), raw tracks with timestamps and datagrams, JSON and binary data tracks (snapshot or stream, each advertised in the catalog for as long as it lives), group fetch, catalog sections, shared video properties, and stalled hints. The three advertising operations are `moq_origin_create_broadcast` (unannounced producer, invisible to everyone), `moq_publish_announce` / `moq_publish_unannounce` (exact-path advertisement), `moq_publish_close` (ends the broadcast for good and releases its handle), and `moq_origin_dynamic` (a claim over a path prefix and everything beneath it; `""` for everything). A route is a capability, not an inventory. `moq_origin_announced` takes a `moq_announce_config` (NULL or zeroed for everything): a literal prefix and an optional relative pattern filter; each `moq_announce_update` has a `kind` (`MOQ_ANNOUNCE_KIND_ANNOUNCED`, `_UPDATED`, `_RETRACTED`, or `_LIVE` once every route live when the listener started has been delivered, with no prefix or captures); `prefix` stays relative to the origin, while `captures` reports what each wildcard matched when `has_captures` is true. Paths with a `.`-prefixed segment below the prefix are [hidden](/concept/moq-lite#hidden-broadcasts); set `hidden` or name the dot segment in `prefix` to list them.
- **Everything the bindings can do** ([list](/lib/#what-every-binding-can-do)): media publish and consume with the catalog managed for you, raw pixels and PCM with the codec inside (`moq_encode_video`, `moq_encode_audio`, and the `moq_decode_*` mirrors), raw tracks with timestamps and datagrams, JSON and binary data tracks (snapshot or stream, each advertised in the catalog for as long as it lives), group fetch, catalog sections, shared video properties, and stalled hints. The three advertising operations are `moq_origin_create_broadcast` (unannounced producer, invisible to everyone), `moq_publish_announce` / `moq_publish_unannounce` (exact-path advertisement), `moq_publish_close` (ends the broadcast for good and releases its handle), and `moq_origin_dynamic` (a claim over a path prefix and everything beneath it; `""` for everything). A route is a capability, not an inventory. `moq_origin_announced` takes a `moq_announce_config` (NULL or zeroed for everything): a literal prefix and an optional relative pattern filter; each `moq_announce_event` has a `kind` (`MOQ_ANNOUNCE_KIND_START`, `_UPDATE`, `_END`, or `_LIVE` once every route live when the listener started has been delivered, with no prefix or captures); `prefix` stays relative to the origin, while `captures` reports what each wildcard matched when `has_captures` is true. Paths with a `.`-prefixed segment below the prefix are [hidden](/concept/moq-lite#hidden-broadcasts); set `hidden` or name the dot segment in `prefix` to list them.

```c
moq_client_config config;
Expand Down
4 changes: 2 additions & 2 deletions doc/lib/dart/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final moq = await Moq.connect('https://relay.example.com');
moq.announcements(
options: const AnnounceOptions(prefix: 'live/', filter: '*/camera'),
).listen((event) {
if (event is AnnounceEventAnnounced) {
if (event is AnnounceEventStart) {
print(event.announce.prefix);
print(event.announce.captures);
} else if (event is AnnounceEventLive) {
Expand Down Expand Up @@ -76,7 +76,7 @@ every path beneath it (`''` for everything; Dart spells the origin method
claim should stay advertised, and reject the requests you will not serve. A
route is a capability, not an inventory. `announcements(options:)` takes a
literal prefix plus an optional relative pattern and yields `AnnounceEvent`s:
`AnnounceEventAnnounced`, `AnnounceEventUpdated`, or `AnnounceEventRetracted`
`AnnounceEventStart`, `AnnounceEventUpdate`, or `AnnounceEventEnd`
carrying an `Announce`, whose `prefix` stays origin-relative and whose
`captures` reports the wildcard matches, or `AnnounceEventLive` once every route
live at subscribe time has been delivered. Paths with
Expand Down
6 changes: 3 additions & 3 deletions doc/lib/go/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ for event, err := range announced.All(ctx) {
if moq.IsShutdown(err) { break }
log.Fatal(err)
}
ann, ok := event.(moq.AnnounceEventAnnounced)
ann, ok := event.(moq.AnnounceEventStart)
if !ok {
continue // AnnounceEventUpdated, AnnounceEventRetracted, or AnnounceEventLive
continue // AnnounceEventUpdate, AnnounceEventEnd, or AnnounceEventLive
}
// Prefix stays origin-relative; Captures reports what each wildcard matched.
fmt.Printf("captures: %v\n", ann.Announce.Captures)
Expand Down Expand Up @@ -86,7 +86,7 @@ path beneath it (`""` for everything). Hold the returned `OriginDynamic`
while the claim should stay advertised, and reject the requests you will not
serve. A route is a capability, not an inventory. `Announced(options)` combines
a literal prefix with an optional relative pattern and yields an `AnnounceEvent`:
`AnnounceEventAnnounced`, `AnnounceEventUpdated`, or `AnnounceEventRetracted`
`AnnounceEventStart`, `AnnounceEventUpdate`, or `AnnounceEventEnd`
carrying an `Announce`, whose `Prefix` stays relative to the origin and whose
`Captures` reports the wildcard matches, or `AnnounceEventLive` once every route
live at subscribe time has been delivered. Break on `AnnounceEventLive` to list
Expand Down
Loading
Loading