Skip to content

feat(hang): compressed catalog track (catalog.json.z)#1904

Merged
kixelated merged 2 commits into
mainfrom
claude/inspiring-wilson-528c76
Jun 24, 2026
Merged

feat(hang): compressed catalog track (catalog.json.z)#1904
kixelated merged 2 commits into
mainfrom
claude/inspiring-wilson-528c76

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Summary

Adds catalog support for the group-scoped DEFLATE compression from #1897. Publishers now serve the catalog on two tracks with identical content:

  • catalog.json — plain JSON (unchanged)
  • catalog.json.z — the same JSON, group-scoped raw DEFLATE (moq-json / @moq/json)

The compressed track is always produced. Consumers keep reading catalog.json by default and opt into the compressed one explicitly via a new HangZ format. No happy-eyeballs — we just start producing it and move consumers over later.

The .hang broadcast suffix is unchanged: HangZ is an extra track on the same broadcast and is never auto-detected from the name. The track name is .z (raw deflate), not .gz (which implies gzip framing).

Changes

Rust

  • hang::Catalog::COMPRESSED_NAME / compressed_track()
  • CatalogFormat::HangZ (extension().hang; detect() never returns it)
  • moq-mux catalog Producer serves the compressed track from a second moq_json::Producer (compression on, deltas off for parity); adds consume_compressed()
  • hang::Consumer::compressed(track); CatalogSource::new HangZ arm
  • moq-cli subscribe --catalog hangz

JS

  • @moq/json Producer.serve(track, effect, { compression }) — per-subscriber override so one fan-out producer serves both encodings
  • @moq/hang/catalog TRACK / TRACK_COMPRESSED consts; Catalog.Consumer now takes a config object with compression
  • @moq/publish serves catalog.json.z; @moq/watch adds the "hangz" format

Docs (per Cross-Package Sync)

  • doc/concept/layer/hang.md gains a Compression section
  • doc/lib/js/@moq/watch.md lists hangz

Also: a CLAUDE.md note to prefer an options struct/object over positional params when more configuration may be added later.

Public API changes

  • Rust (additive): Catalog::COMPRESSED_NAME, Catalog::compressed_track(), CatalogFormat::HangZ (enum is #[non_exhaustive]), hang::Consumer::compressed(), Producer::consume_compressed(), --catalog hangz.
  • JS additive: @moq/json Producer.serve() optional 3rd param; @moq/hang/catalog TRACK/TRACK_COMPRESSED; @moq/watch "hangz" format.
  • JS breaking: @moq/hang Catalog.Consumer(track, schema?)Catalog.Consumer(track, config?). The schema field lives on inside the config; only the positional convention is dropped. Since the positional schema arg is unused, this targets main rather than dev.

Branch targeting

Targets main. Everything is additive in practice; the lone breaking signature change has no real callers (positional schema unused).

Test plan

  • cargo workspace check; moq-mux + hang tests (incl. a new plain-vs-compressed catalog roundtrip)
  • nix cargo fmt --check and clippy clean
  • @moq/json/@moq/hang/@moq/watch/@moq/publish type-check + tests (incl. a new serve() compression override test)
  • biome check clean

🤖 Generated with Claude Code

(Written by Claude)

Publishers now serve the catalog on two tracks with identical content:
`catalog.json` (plain) and `catalog.json.z` (the same JSON, group-scoped
raw DEFLATE from moq-json / @moq/json). The compressed track is always
produced; consumers keep reading `catalog.json` by default and opt into
the compressed one explicitly via the new HangZ format. No happy-eyeballs.

The `.hang` broadcast suffix is unchanged: HangZ is an extra track on the
same broadcast, never auto-detected from the name, so migration is flipping
a consumer over rather than renaming a broadcast.

Rust:
- hang::Catalog::COMPRESSED_NAME / compressed_track()
- CatalogFormat::HangZ (extension() -> .hang; detect() never returns it)
- moq-mux catalog Producer serves the compressed track from a second
  moq_json::Producer (compression on, deltas off for parity); adds
  consume_compressed()
- hang::Consumer::compressed(track); CatalogSource HangZ arm
- moq-cli subscribe --catalog hangz

JS:
- @moq/json Producer.serve(track, effect, { compression }) per-subscriber
  override so one fan-out producer serves both encodings
- @moq/hang/catalog TRACK / TRACK_COMPRESSED consts; Catalog.Consumer takes
  a config object with compression
- @moq/publish serves catalog.json.z; @moq/watch adds the "hangz" format

Docs: doc/concept/layer/hang.md gains a Compression section;
doc/lib/js/@moq/watch.md lists hangz.

The Catalog.Consumer constructor reshape (positional schema -> config) is
technically breaking, but the positional schema arg is unused, so this
targets main rather than dev.

Also adds a CLAUDE.md note to prefer an options struct/object over
positional params when more configuration may be added later.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6276fac2-4621-44f9-8a54-d60a8d838d68

📥 Commits

Reviewing files that changed from the base of the PR and between 4fa5daf and 496460b.

📒 Files selected for processing (2)
  • doc/bin/cli.md
  • rs/hang/src/catalog/root.rs

Walkthrough

The PR introduces a DEFLATE-compressed hangz catalog track alongside the existing catalog track. It updates Rust and JS catalog format definitions, adds compression-aware consumer and producer APIs, and wires broadcast, watch, CLI, and container paths to select or serve the compressed track only when explicitly requested. Documentation and tests were updated to reflect the new opt-in behavior.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a compressed catalog track for hang.
Description check ✅ Passed The description directly matches the changeset and explains the compressed catalog track, API updates, and docs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/inspiring-wilson-528c76

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rs/moq-cli/src/subscribe.rs`:
- Around line 54-60: The Subscribe catalog format documentation is missing the
new hangz option, so update the CLI docs used by the subscribe command to
include hangz wherever the supported `--format` values are listed. In the
documentation block for the `catalog`/format argument and any example that
enumerates formats, add `hangz` alongside the existing entries such as `hang`,
`msf`, and `flv`, matching the behavior described by `CatalogFormatArg` in
subscribe.rs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91eaf792-b726-4bd5-a267-2553cf9996a8

📥 Commits

Reviewing files that changed from the base of the PR and between 23a4ead and 4fa5daf.

📒 Files selected for processing (15)
  • CLAUDE.md
  • doc/concept/layer/hang.md
  • doc/lib/js/@moq/watch.md
  • js/hang/src/catalog/consumer.ts
  • js/hang/src/catalog/format.ts
  • js/json/src/producer.test.ts
  • js/json/src/producer.ts
  • js/publish/src/broadcast.ts
  • js/watch/src/broadcast.ts
  • rs/hang/src/catalog/root.rs
  • rs/moq-cli/src/subscribe.rs
  • rs/moq-mux/src/catalog/format.rs
  • rs/moq-mux/src/catalog/hang/consumer.rs
  • rs/moq-mux/src/catalog/producer.rs
  • rs/moq-mux/src/container/source.rs

Comment on lines 54 to 60
/// Catalog format to subscribe to for track discovery.
///
/// When omitted, the format is auto-detected from the broadcast name suffix
/// (`.hang` -> hang, `.msf` -> msf), falling back to hang.
/// (`.hang` -> hang, `.msf` -> msf), falling back to hang. Pass `hangz` to read
/// the DEFLATE-compressed `catalog.json.z` track instead (same `.hang` broadcast).
#[arg(long)]
pub catalog: Option<CatalogFormatArg>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find docs referencing the catalog flag / format values to reconcile against the new `hangz` value.
rg -nP --glob 'doc/**' -e '--catalog' -e '\bhangz\b' -e 'catalog.json.z'

Repository: moq-dev/moq

Length of output: 149


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## repo files matching cli docs\n'
git ls-files 'doc/**' 'docs/**' | rg 'cli\.md|catalog|subscribe' || true

printf '\n## search for catalog/hangz references across docs\n'
rg -n --hidden --glob 'doc/**' --glob 'docs/**' --glob '*.md' --glob '*.mdx' --glob '*.txt' \
  --fixed-strings -- 'hangz' 'catalog.json.z' '--catalog' || true

Repository: moq-dev/moq

Length of output: 354


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## locate subscribe.rs and related type definitions\n'
fd -a 'subscribe.rs|CatalogFormatArg|catalog' rs/moq-cli/src rs -t f || true

printf '\n## search format enum/arg docs in source\n'
rg -n --hidden -S 'hangz|catalog\.json\.z|CatalogFormatArg|Catalog format' rs/moq-cli/src || true

Repository: moq-dev/moq

Length of output: 1424


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## list possible cli docs\n'
git ls-files 'doc/**' 'docs/**' | sed -n '1,200p'

printf '\n## check whether doc/bin/cli.md exists and mention catalog values\n'
for f in doc/bin/cli.md docs/bin/cli.md; do
  if [ -f "$f" ]; then
    printf '\nFILE: %s\n' "$f"
    rg -n --fixed-strings -- 'hangz' 'catalog.json.z' '--catalog' "$f" || true
  fi
done

Repository: moq-dev/moq

Length of output: 2667


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## inspect subscribe.rs and CatalogFormatArg definition\n'
rg -n --hidden -S 'enum CatalogFormatArg|struct CatalogFormatArg|hangz|catalog\.json\.z|#[[:space:]]*arg\(long\)' rs/moq-cli/src || true

Repository: moq-dev/moq

Length of output: 551


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' doc/bin/cli.md | cat -n

Repository: moq-dev/moq

Length of output: 8198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' doc/bin/cli.md | cat -n

Repository: moq-dev/moq

Length of output: 8198


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' doc/bin/cli.md | cat -n

Repository: moq-dev/moq

Length of output: 8198


Document hangz in doc/bin/cli.md:147-152. The Subscribe --format list still ends at flv; add hangz to the catalog format docs and any example invocation that enumerates supported values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rs/moq-cli/src/subscribe.rs` around lines 54 - 60, The Subscribe catalog
format documentation is missing the new hangz option, so update the CLI docs
used by the subscribe command to include hangz wherever the supported `--format`
values are listed. In the documentation block for the `catalog`/format argument
and any example that enumerates formats, add `hangz` alongside the existing
entries such as `hang`, `msf`, and `flv`, matching the behavior described by
`CatalogFormatArg` in subscribe.rs.

- COMPRESSED_NAME doc linked `DEFAULT_NAME` without a path, which broke
  `cargo doc` (warnings-as-errors) in CI. Qualify it as Self::DEFAULT_NAME.
- Document the `subscribe --catalog` flag (hang/hangz/msf) in doc/bin/cli.md,
  which previously documented only `--format` (CodeRabbit).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kixelated kixelated enabled auto-merge (squash) June 24, 2026 19:00
@kixelated kixelated merged commit a7c937e into main Jun 24, 2026
1 check passed
@kixelated kixelated deleted the claude/inspiring-wilson-528c76 branch June 24, 2026 19:04
@moq-bot moq-bot Bot mentioned this pull request Jun 24, 2026
kixelated added a commit that referenced this pull request Jun 26, 2026
@kixelated kixelated mentioned this pull request Jun 30, 2026
4 tasks
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