feat(hang): compressed catalog track (catalog.json.z)#1904
Conversation
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>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThe PR introduces a DEFLATE-compressed 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches✨ Simplify code
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (15)
CLAUDE.mddoc/concept/layer/hang.mddoc/lib/js/@moq/watch.mdjs/hang/src/catalog/consumer.tsjs/hang/src/catalog/format.tsjs/json/src/producer.test.tsjs/json/src/producer.tsjs/publish/src/broadcast.tsjs/watch/src/broadcast.tsrs/hang/src/catalog/root.rsrs/moq-cli/src/subscribe.rsrs/moq-mux/src/catalog/format.rsrs/moq-mux/src/catalog/hang/consumer.rsrs/moq-mux/src/catalog/producer.rsrs/moq-mux/src/container/source.rs
| /// 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>, |
There was a problem hiding this comment.
📐 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' || trueRepository: 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 || trueRepository: 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
doneRepository: 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 || trueRepository: moq-dev/moq
Length of output: 551
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,220p' doc/bin/cli.md | cat -nRepository: moq-dev/moq
Length of output: 8198
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,220p' doc/bin/cli.md | cat -nRepository: moq-dev/moq
Length of output: 8198
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,220p' doc/bin/cli.md | cat -nRepository: 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>
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.jsonby default and opt into the compressed one explicitly via a newHangZformat. No happy-eyeballs — we just start producing it and move consumers over later.The
.hangbroadcast suffix is unchanged:HangZis 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)Producerserves the compressed track from a secondmoq_json::Producer(compression on, deltas off for parity); addsconsume_compressed()hang::Consumer::compressed(track);CatalogSource::newHangZ armmoq-cli subscribe --catalog hangzJS
@moq/jsonProducer.serve(track, effect, { compression })— per-subscriber override so one fan-out producer serves both encodings@moq/hang/catalogTRACK/TRACK_COMPRESSEDconsts;Catalog.Consumernow takes a config object withcompression@moq/publishservescatalog.json.z;@moq/watchadds the"hangz"formatDocs (per Cross-Package Sync)
doc/concept/layer/hang.mdgains a Compression sectiondoc/lib/js/@moq/watch.mdlistshangzAlso: a CLAUDE.md note to prefer an options struct/object over positional params when more configuration may be added later.
Public API changes
Catalog::COMPRESSED_NAME,Catalog::compressed_track(),CatalogFormat::HangZ(enum is#[non_exhaustive]),hang::Consumer::compressed(),Producer::consume_compressed(),--catalog hangz.@moq/jsonProducer.serve()optional 3rd param;@moq/hang/catalogTRACK/TRACK_COMPRESSED;@moq/watch"hangz"format.@moq/hangCatalog.Consumer(track, schema?)→Catalog.Consumer(track, config?). Theschemafield 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 (positionalschemaunused).Test plan
cargoworkspace check; moq-mux + hang tests (incl. a new plain-vs-compressed catalog roundtrip)cargo fmt --checkandclippyclean@moq/json/@moq/hang/@moq/watch/@moq/publishtype-check + tests (incl. a newserve()compression override test)biome checkclean🤖 Generated with Claude Code
(Written by Claude)