feat(hang): generic base catalog with app-layer extensions#1654
Closed
kixelated wants to merge 2 commits into
Closed
feat(hang): generic base catalog with app-layer extensions#1654kixelated wants to merge 2 commits into
kixelated wants to merge 2 commits into
Conversation
Make the base catalog carry only `video`/`audio` and let applications add
their own root sections (e.g. SCTE-35) without modifying hang. The mechanism
is plain composition on top of the already-generic `@moq/json`:
- JS: `z.extend(Catalog.RootSchema, { scte35: ... })`
- Rust: `#[serde(flatten)] base: hang::Catalog`
The base catalog ignores unknown sections, so an extended catalog stays
readable by a plain hang consumer.
App-specific sections (chat, user, preview, location, capabilities) and their
watch/publish implementations are removed; they belong in the application
layer (hang.live) and remain in git history for that move. `@moq/publish`'s
`Broadcast` gains a `sections` input (merged into the published catalog) and a
`tracks` map (serve app-defined tracks) so the app layer can reuse it; watch
needs no hook since the app subscribes to `catalog.json` with its own schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Freshly published advisory failing CI repo-wide, unrelated to the catalog change. proc-macro-error2 is pulled transitively via foundations (quiche) in moq-native; it's a build-time-only proc-macro with no safe upgrade. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Supersedes the very stale #1149. Instead of a bespoke
Section<T>registry, this leans on what already shipped: the base catalog becomes minimal and applications extend it with plain language features feeding the generic@moq/json/moq_jsonhelper. No new catalog machinery.Base catalog is now just
video+audio. App-specific sections are gone from@moq/hang.Extensions are composition, not a registry:
z.extend(Catalog.RootSchema, { scte35: z.optional(Scte35Schema) })→ hand the schema to@moq/json'sProducer/Consumer.#[serde(flatten)] base: hang::Catalogin the app's own struct → usemoq_json::Producer<AppCatalog>.deny_unknown_fields, so an extended catalog stays readable by a plain hang consumer (it just ignores the extra sections). This is what makes e.g. SCTE-35 addable entirely in the application layer (hang.live) without touching hang.Removed app sections (
chat,user,preview,location,capabilities) from@moq/hang, and their feature subtrees + library exports from@moq/watchand@moq/publish. These are application concerns and move tohang.live; the deleted code remains in git history for that migration. The built-in<moq-watch>/<moq-publish>elements anddemo/webnever used these, so the UI is unaffected.@moq/publishBroadcastextension hooks so the app layer can reuse it:sections: extra catalog sections merged into the publishedcatalog.json(only one producer may own that track, hence the hook).tracks: handlers for app-defined tracks (e.g. a section's own update track), consulted for otherwise-unknown subscriptions.catalog.jsonindependently with its own extended schema.Why not redo #1149 as written
Half of #1149 already shipped differently: the generic "typed JSON over a track with validation, publishing, subscribing" machinery it hand-rolled is now
@moq/json/moq_json(snapshot + delta, schema validation). And the Rusthang::Catalogwas already trimmed tovideo/audio. So the registry is redundant; the remaining gap was making the JS base schema open-by-extension and moving the app sections out.Breaking changes (hence
dev)@moq/hang: removedChatSchema,UserSchema,PreviewSchema,LocationSchema/PositionSchema/PeersSchema,CapabilitiesSchema;RootSchemano longer has those fields; removed unusedencode/decode/fetch;PRIORITYtrimmed tocatalog/audio/video.@moq/watch/@moq/publish: removed theChat,Location,User,Previewexports and their implementations.{ video, audio }); apps that relied on hang shipping chat/location/etc. must define those sections themselves.Cross-package sync
rs/hangcatalogjs/hang✅,doc/concept/layer/hang.md✅ (new "Extensions" section)js/hangcatalogjs/watch,js/publish✅No
rs/moq-ffi/ wrapper changes:hang::Catalog's shape is unchanged, so FFI consumers are unaffected.Test plan
just check— EXIT 0 (Rust clippy + JS tsc + biome + remark + cargo doc/shear/sort)js/hang/src/catalog/root.test.ts(extension contract)cargo test -p hang -p moq-mux -p moq-ffiall green, incl. newextension_roundtriptest + theCatalogdoctest🤖 Generated with Claude Code
(Written by Claude)