Skip to content

feat(net): name the origin read side as Origin.Reader - #7557

Merged
kixelated merged 12 commits into
mainfrom
quest/m1/api-audit/origin-reader
Nov 2, 2026
Merged

kixelated merged 12 commits into
mainfrom
quest/m1/api-audit/origin-reader

Conversation

@kixelated

@kixelated kixelated commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

@moq/watch's origin inputs repeat a Pick<Origin.Consumer, "closed" | "discovery" | "request" | "follow" | "announced"> list (from moq-dev/moq#7251), and @moq/net has no name for "an origin you can only read".

Approach

  • @moq/net exports Origin.Reader: closed, discovery, request, follow, announced. Origin.Table now extends it (adding createBroadcast, requests), and Origin.Consumer declares implements Reader, so both stay checked against the one definition.
  • @moq/watch's BroadcastInput.origin and PlayerInput.origin take Getter<Origin.Reader | undefined>; the local Origin alias in broadcast.ts is gone.
  • The stats demo's subscribeNode only reads, so it takes Origin.Reader too. @moq/publish and Connection.Pool.origin keep Origin.Table, since they publish or lend publishing.
  • Finishes the quest: deletes quest/m1/api-audit/origin-reader.md and its Required entry in the api-audit epic.

moq-dev/moq#7251 has merged, and main is merged in here, so the diff now holds only this PR's changes. The merge conflicted in js/net/src/origin.ts, js/watch/src/{broadcast,player}.ts, and js/watch/api/index.api.md. Each conflict was #7251's Pick list or alias against this branch's Origin.Reader, and was resolved to Origin.Reader.

js/watch/api/element.api.md is regenerated. TypeScript prints the element's observed-attribute union in the order it creates the literal types, and that order shifts with the origin types it checks first. #7251 reordered the union, and this change restores the earlier order. The element itself is unchanged.

Impact

  • Public API: @moq/net adds Origin.Reader; Origin.Table now extends it with the same members as before. @moq/watch's origin inputs read as Origin.Reader instead of the Pick list (same shape). Additive; nothing migrates.
  • Wire: none.

Validation

  • quest gate nix develop --command just check on 556d6752b3: passed.
  • quest check --base origin/main: passed.

Choices made without asking

  • Moved the demo's read-only helper to Origin.Reader; left writers on Origin.Table.
  • Reader.closed's doc points at Consumer.closed instead of Producer.closed; both describe the same promise.
  • PlayerInput.origin names Origin.Reader directly instead of fix(watch): accept structural read-side origins #7251's BroadcastInput["origin"] indirection, so player.ts no longer imports BroadcastInput.

Review

Codex quest review (gpt-6.1-sol, medium effort), round 1 on 556d6752b36917a4a9185548e314569404381e48 against origin/main (a546cac082): no findings.

Online reviews posted on the earlier head 7bec1e1e7f (OpenAI review, Pullfrog) reported no issues. CodeRabbit was rate-limited.

Follow-ups

  • API reports print string-literal unions in TypeScript's type-creation order, so an unrelated type change can reorder a report (as element.api.md shows here). Sorting union members when the reports are normalized would remove that churn.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

kixelated and others added 10 commits October 29, 2026 09:30
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
# Conflicts:
#	js/watch/src/broadcast.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…solve/watch-origin

# Conflicts:
#	quest/m1/api-audit/resolve/README.md
…-origin' into quest/m1/api-audit/origin-reader

# Conflicts:
#	quest/m1/api-audit/route/handle.md
Origin.Table extends Origin.Reader and Origin.Consumer implements it, so
@moq/watch's Player and Broadcast take Origin.Reader instead of a Pick
list, and the stats demo reads through it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title @moq/net names the origin read side feat(net): name the origin read side as Origin.Reader Nov 1, 2026
@kixelated
kixelated marked this pull request as ready for review November 1, 2026 12:49
@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9e0eebdd-64f2-443f-9c3a-025e6ed124ce
Commits

Reviewing files that changed from the base of the PR and between 76a659c and 556d675.

Files selected for processing: 9
  • demo/web/src/stats.ts
  • js/net/api/index.api.md
  • js/net/src/origin.ts
  • js/watch/api/element.api.md
  • js/watch/api/index.api.md
  • js/watch/src/broadcast.ts
  • js/watch/src/player.ts
  • quest/m1/api-audit/README.md
  • quest/m1/api-audit/origin-reader.md
Files with no reviewable changes: 2
  • quest/m1/api-audit/README.md
  • quest/m1/api-audit/origin-reader.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.

Walkthrough

The change adds the public Origin.Reader interface for shared read operations. Origin.Table extends it, and Origin.Consumer implements it. Watch broadcast and player origin types, internal broadcast entries, and the demo subscribeNode parameter now use the reader interface. The API references are updated, and the origin-reader planning document and audit-list entry are removed.

Merge Risk: Minimal · up to 556d6

No actionable merge-blocking risk is established by the reviewed changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main change: adding the named Origin.Reader read-side API.
Description check Passed The description directly explains the Origin.Reader interface, its use in @moq/watch and the stats demo, retained publishing APIs, and validation results.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 4 files. (3 skipped: 3 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

Biome (2.5.15)
demo/web/src/stats.ts

Biome could not lint this file: configuration resulted in errors. Check the repository's Biome configuration and plugins.

js/net/src/origin.ts

Biome could not lint this file: configuration resulted in errors. Check the repository's Biome configuration and plugins.

js/watch/src/broadcast.ts

Biome could not lint this file: configuration resulted in errors. Check the repository's Biome configuration and plugins.

  • 1 others

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

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 7bec1e1.

No actionable bugs found. Naming the existing read-side shape as Origin.Reader is a proportionate simplification: Table extends it, Consumer implements it, and watch borrows only the capabilities it uses without gaining lifecycle ownership. The table/consumer/structural-origin tests cover the intended widening; publishing inputs remain on Table. The additive API has no wire change.

Verification: static inspection of the diff and relevant origin, player, broadcast, and export code only. I did not run tests, builds, or independently verify the reported gate results.

(Written by OpenAI)

@pullfrog pullfrog 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.

✅ No new issues found.

Reviewed changes

  • Origin.Reader introduced — js/net/src/origin.ts gains an exported Reader interface with the five read members (closed, discovery, request, follow, announced); Table is re-declared as interface Table extends Reader, keeping only createBroadcast/requests, and Consumer is marked implements Reader.
  • @moq/watch widens to the read side — PlayerInput.origin and BroadcastInput.origin now take Getter<Origin.Reader | undefined>, and the local helper/map signatures in broadcast.ts follow; the local Pick<...> alias is removed.
  • Read-only demo helper — demo/web/src/stats.ts's subscribeNode takes Net.Origin.Reader. Writers (Connection.Pool.origin, @moq/publish) stay on Origin.Table, which is correct.
  • Tests + API reports — broadcast.test.ts uses owner.consume(); player.test.ts adds a test.each over table / consumer / structural origins asserting the borrowed handle does not close the owner. Both api/*.api.md files regenerated.
  • Quest bookkeeping — origin-reader.md and resolve/watch-origin.md deleted with their list entries, plus the route/handle.md Related link.

I verified bunx tsc --noEmit is clean in js/net and js/watch, the new player.test.ts cases pass (5/5), there are no dangling links to the deleted quest files, and the only remaining Origin.Table sites are publishing/lending paths. The docs reference chain (Reader.closed → Consumer.closed → Producer.closed) is chained but accurate.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

kixelated and others added 2 commits November 1, 2026 20:42
TypeScript prints the observed-attribute union in literal-creation order,
which shifts with the origin types checked before it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 64ffd7e Nov 2, 2026
8 checks passed
@kixelated
kixelated deleted the quest/m1/api-audit/origin-reader branch November 2, 2026 17:20
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