Skip to content

Handle relays without announcement subscription support#1352

Merged
kixelated merged 5 commits into
mainfrom
claude/verify-cloudflare-reload-flag-lDUbA
Apr 29, 2026
Merged

Handle relays without announcement subscription support#1352
kixelated merged 5 commits into
mainfrom
claude/verify-cloudflare-reload-flag-lDUbA

Conversation

@kixelated
Copy link
Copy Markdown
Collaborator

Summary

Updated broadcast and connection handling to properly support relays that don't implement announcement subscriptions (like Cloudflare's relay). Instead of waiting indefinitely for announcements that will never arrive, the system now signals this unsupported state with undefined and behaves gracefully.

Key Changes

  • Type updates: Changed announced getter type from Set<Path.Valid> to Set<Path.Valid> | undefined to distinguish between "supported but empty" and "not supported"
  • Cloudflare relay detection: When connecting to Cloudflare's relay (mediaoverquic.com), explicitly set announced to undefined instead of silently skipping announcement subscriptions
  • Broadcast reload logic: Added check to treat undefined announced state as reload=false, preventing indefinite waiting for announcements that will never arrive
  • Mutation safety: Added null check in announcement mutation handler to safely handle undefined state

Implementation Details

  • The undefined value is semantically distinct from an empty Set(), allowing consumers to differentiate between "relay doesn't support announcements" vs "relay supports announcements but none are currently active"
  • Updated comments throughout to clarify the new behavior and expectations
  • Maintains backward compatibility for relays that do support announcement subscriptions

https://claude.ai/code/session_01ErUfz2GBh8U4pbPhdvawr1

claude added 3 commits April 27, 2026 22:53
The Cloudflare relay skips SUBSCRIBE_NAMESPACE, leaving the connection's
announced set permanently empty. Combined with reload=true, Broadcast
would wait forever for an announcement that never arrives, so the
broadcast silently never subscribed.

Expose `announceSupported` on Reload and have Broadcast.#isAnnounced
short-circuit to true when announcements aren't supported, matching the
reload=false code path.
Replace the separate `announceSupported` signal with `undefined` on the
existing `announced` getter to express "relay doesn't support
SUBSCRIBE_NAMESPACE". Broadcast now has a single check that mirrors the
reload=false fast path, instead of two parallel branches.
Move the announcement-unsupported workaround back into Broadcast so the
moq-lite layer stays generic and free of relay-specific quirks.
Broadcast now checks the established connection's URL and treats a
Cloudflare host as reload=false, since SUBSCRIBE_NAMESPACE will never
fire there.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Walkthrough

Hostname-aware logic was added so Broadcast.#isAnnounced treats connections whose hostname ends with mediaoverquic.com as announced, returning true immediately (previously emitted a console warning in the watch code). The reload path no longer emits that warning. Separately, an internal TypeScript import in the audio encoder was converted to a type-only import.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main objective: handling relays (like Cloudflare) that lack announcement subscription support, which aligns with all three file changes and the PR's core purpose.
Description check ✅ Passed The description comprehensively explains the changes including type updates, Cloudflare relay detection, broadcast reload logic, and mutation safety handling, all of which relate directly to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/verify-cloudflare-reload-flag-lDUbA
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/verify-cloudflare-reload-flag-lDUbA

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@js/lite/src/connection/reload.ts`:
- Around line 161-164: The hostname check using
conn.url.hostname.endsWith("mediaoverquic.com") can false-positively match
lookalikes; update the condition in the block that logs "Cloudflare relay..."
(the code that sets this.#announced and returns from the subscribe_namespace
flow) to perform boundary-safe matching: normalize hostname to lowercase and use
hostname === "mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com") (or
equivalently check for a dot-prefix suffix) instead of the current endsWith call
so only the exact host or subdomains of mediaoverquic.com match.
🪄 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: b435fba6-1c07-4b9e-a77b-647fbede142f

📥 Commits

Reviewing files that changed from the base of the PR and between 0331db7 and c201ee6.

📒 Files selected for processing (2)
  • js/lite/src/connection/reload.ts
  • js/watch/src/broadcast.ts

Comment on lines 161 to 164
if (conn.url.hostname.endsWith("mediaoverquic.com")) {
console.warn("Cloudflare relay does not support broadcast discovery yet; skipping subscribe_namespace.");
this.#announced.set(undefined);
return;
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.

⚠️ Potential issue | 🟡 Minor

Make Cloudflare hostname matching boundary-safe.

.endsWith("mediaoverquic.com") also matches lookalike hostnames (for example, notmediaoverquic.com). Use exact-host or dot-suffix matching to avoid false positives.

Proposed fix
-		if (conn.url.hostname.endsWith("mediaoverquic.com")) {
+		const hostname = conn.url.hostname;
+		const isCloudflareRelay =
+			hostname === "mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com");
+		if (isCloudflareRelay) {
 			console.warn("Cloudflare relay does not support broadcast discovery yet; skipping subscribe_namespace.");
 			this.#announced.set(undefined);
 			return;
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (conn.url.hostname.endsWith("mediaoverquic.com")) {
console.warn("Cloudflare relay does not support broadcast discovery yet; skipping subscribe_namespace.");
this.#announced.set(undefined);
return;
const hostname = conn.url.hostname;
const isCloudflareRelay =
hostname === "mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com");
if (isCloudflareRelay) {
console.warn("Cloudflare relay does not support broadcast discovery yet; skipping subscribe_namespace.");
this.#announced.set(undefined);
return;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/lite/src/connection/reload.ts` around lines 161 - 164, The hostname check
using conn.url.hostname.endsWith("mediaoverquic.com") can false-positively match
lookalikes; update the condition in the block that logs "Cloudflare relay..."
(the code that sets this.#announced and returns from the subscribe_namespace
flow) to perform boundary-safe matching: normalize hostname to lowercase and use
hostname === "mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com") (or
equivalently check for a dot-prefix suffix) instead of the current endsWith call
so only the exact host or subdomains of mediaoverquic.com match.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@js/watch/src/broadcast.ts`:
- Around line 71-76: The hostname check using endsWith("mediaoverquic.com") is
too permissive and can match unrelated hosts; update the condition around
effect.get(this.connection) / conn?.url.hostname to perform exact host or
dot-boundary subdomain matching (for example, check hostname ===
"mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com") or use a regex
like /(^|\.)mediaoverquic\.com$/) instead of the plain
endsWith("mediaoverquic.com") so only the root host or its subdomains bypass the
announcement gating.
🪄 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: 906fbb48-8d32-4d41-b5de-0582f608a64c

📥 Commits

Reviewing files that changed from the base of the PR and between c201ee6 and 0048850.

📒 Files selected for processing (1)
  • js/watch/src/broadcast.ts

Comment thread js/watch/src/broadcast.ts
Comment on lines +71 to +76
// Cloudflare's relay does not yet support announcement subscriptions,
// so an announcement will never arrive. Fall back to subscribing
// immediately (reload=false behaviour) instead of waiting forever.
const conn = effect.get(this.connection);
if (conn?.url.hostname.endsWith("mediaoverquic.com")) return true;

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.

⚠️ Potential issue | 🟡 Minor

Harden hostname matching to avoid accidental bypasses.

endsWith("mediaoverquic.com") can also match unrelated hosts like notmediaoverquic.com, which would incorrectly skip announcement gating. Use exact-host or dot-boundary subdomain matching.

Suggested fix
+const ANNOUNCEMENT_UNSUPPORTED_HOST = "mediaoverquic.com";
+
 	`#isAnnounced`(effect: Effect): boolean {
 		const reload = effect.get(this.reload);
 		if (!reload) return true;
@@
-		const conn = effect.get(this.connection);
-		if (conn?.url.hostname.endsWith("mediaoverquic.com")) return true;
+		const conn = effect.get(this.connection);
+		const hostname = conn?.url.hostname;
+		if (
+			hostname === ANNOUNCEMENT_UNSUPPORTED_HOST ||
+			hostname?.endsWith(`.${ANNOUNCEMENT_UNSUPPORTED_HOST}`)
+		) {
+			return true;
+		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/watch/src/broadcast.ts` around lines 71 - 76, The hostname check using
endsWith("mediaoverquic.com") is too permissive and can match unrelated hosts;
update the condition around effect.get(this.connection) / conn?.url.hostname to
perform exact host or dot-boundary subdomain matching (for example, check
hostname === "mediaoverquic.com" || hostname.endsWith(".mediaoverquic.com") or
use a regex like /(^|\.)mediaoverquic\.com$/) instead of the plain
endsWith("mediaoverquic.com") so only the root host or its subdomains bypass the
announcement gating.

kixelated and others added 2 commits April 28, 2026 17:59
Move the existing Cloudflare console.warn from the moq-lite reload layer
into Broadcast where the reload-skip actually happens, so users see why
their reload=true request is being ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
js/watch/src/broadcast.ts (1)

75-76: ⚠️ Potential issue | 🟡 Minor

Tighten hostname matching to prevent unintended reload bypasses.

endsWith("mediaoverquic.com") also matches unrelated hosts (for example, notmediaoverquic.com), which can incorrectly skip announcement gating. Match exact host or dot-boundary subdomains only.

Proposed fix
+const ANNOUNCEMENT_UNSUPPORTED_HOST = "mediaoverquic.com";
+
 		const conn = effect.get(this.connection);
-		if (conn?.url.hostname.endsWith("mediaoverquic.com")) {
+		const hostname = conn?.url.hostname;
+		if (
+			hostname === ANNOUNCEMENT_UNSUPPORTED_HOST ||
+			hostname?.endsWith(`.${ANNOUNCEMENT_UNSUPPORTED_HOST}`)
+		) {
 			console.warn("Cloudflare relay does not support broadcast discovery yet; ignoring reload signal.");
 			return true;
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/watch/src/broadcast.ts` around lines 75 - 76, The hostname check using
conn?.url.hostname.endsWith("mediaoverquic.com") can match unintended hosts
(e.g., notmediaoverquic.com); update the gating in broadcast.ts to only allow an
exact match or real subdomains by changing the condition to require hostname ===
"mediaoverquic.com" OR hostname.endsWith(".mediaoverquic.com") (ensure you still
guard for conn?.url.hostname existence). Locate the check around
conn?.url.hostname in the broadcast/reload handling and replace the
endsWith-only test with the exact-or-dot-prefixed-subdomain logic to prevent
false positives.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@js/watch/src/broadcast.ts`:
- Around line 75-76: The hostname check using
conn?.url.hostname.endsWith("mediaoverquic.com") can match unintended hosts
(e.g., notmediaoverquic.com); update the gating in broadcast.ts to only allow an
exact match or real subdomains by changing the condition to require hostname ===
"mediaoverquic.com" OR hostname.endsWith(".mediaoverquic.com") (ensure you still
guard for conn?.url.hostname existence). Locate the check around
conn?.url.hostname in the broadcast/reload handling and replace the
endsWith-only test with the exact-or-dot-prefixed-subdomain logic to prevent
false positives.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 996e3cf3-ba49-4854-8824-8289cb35a9f6

📥 Commits

Reviewing files that changed from the base of the PR and between 0048850 and 2ecbb78.

📒 Files selected for processing (3)
  • js/lite/src/connection/reload.ts
  • js/publish/src/audio/encoder.ts
  • js/watch/src/broadcast.ts
💤 Files with no reviewable changes (1)
  • js/lite/src/connection/reload.ts
✅ Files skipped from review due to trivial changes (1)
  • js/publish/src/audio/encoder.ts

@kixelated kixelated merged commit 3197020 into main Apr 29, 2026
1 check passed
@kixelated kixelated deleted the claude/verify-cloudflare-reload-flag-lDUbA branch April 29, 2026 01:32
@coderabbitai coderabbitai Bot mentioned this pull request Apr 30, 2026
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.

2 participants