diff --git a/js/net/api/index.api.md b/js/net/api/index.api.md index b56597dcd5b..4f93af96a7e 100644 --- a/js/net/api/index.api.md +++ b/js/net/api/index.api.md @@ -388,10 +388,13 @@ export namespace Origin { announced(scope?: Path.Pattern, options?: Announce.Options): Announce.Consumer; get closed(): Signals.GetPromise; get discovery(): Signals.Getter; - follow(path: Path.Valid, options?: Origin.RequestOptions): Origin.Following; + follow(path: Path.Valid, options?: Origin.FollowOptions): Origin.Following; request(path: Path.Valid, options?: Origin.RequestOptions): Origin.Requesting; } export type Cost = bigint; + export interface FollowOptions { + instance?: Instance.Valid; + } export class Following { readonly active: Signals.Getter; close(): void; @@ -414,7 +417,7 @@ export namespace Origin { consume(): Origin.Consumer; createBroadcast(path: Path.Valid): Origin.Publication; get discovery(): Signals.Getter; - follow(path: Path.Valid, options?: Origin.RequestOptions): Origin.Following; + follow(path: Path.Valid, options?: Origin.FollowOptions): Origin.Following; request(path: Path.Valid, options?: Origin.RequestOptions): Origin.Requesting; requests(prefix: Path.Valid): Origin.Requests; scope(root: Path.Valid, patterns: Path.Patterns): Origin.Producer; @@ -435,7 +438,7 @@ export namespace Origin { announced(scope?: Path.Pattern, options?: Announce.Options): Announce.Consumer; readonly closed: Signals.GetPromise; readonly discovery: Signals.Getter; - follow(path: Path.Valid, options?: Origin.RequestOptions): Origin.Following; + follow(path: Path.Valid, options?: Origin.FollowOptions): Origin.Following; request(path: Path.Valid, options?: Origin.RequestOptions): Origin.Requesting; } export class Request { diff --git a/js/net/src/origin.ts b/js/net/src/origin.ts index cbabea6b1bd..ce31ad0afba 100644 --- a/js/net/src/origin.ts +++ b/js/net/src/origin.ts @@ -1220,7 +1220,7 @@ export interface Reader { request(path: Path.Valid, options?: RequestOptions): Requesting; /** Follow `path` across publisher instances; see {@link Consumer.follow}. */ - follow(path: Path.Valid, options?: RequestOptions): Following; + follow(path: Path.Valid, options?: FollowOptions): Following; /** The available broadcasts under `scope`, as a live stream; see {@link Consumer.announced}. */ announced(scope?: Path.Pattern, options?: Announce.Options): Announce.Consumer; @@ -1258,12 +1258,18 @@ export interface Table extends Reader { ): Requests; } -/** Options for resolving a broadcast path, by {@link Consumer.request} or {@link Consumer.follow}. */ +/** Options for resolving one publisher instance with {@link Consumer.request}. */ export interface RequestOptions { /** Refuse a different publisher instance, including an asynchronous answer or a retry. */ instance?: Instance.Valid; } +/** Options for following a broadcast path with {@link Consumer.follow}. */ +export interface FollowOptions { + /** Follow only this publisher instance, waiting for it to return across gaps. */ + instance?: Instance.Valid; +} + /** * The write side of an origin: create broadcasts by path and advertise them. * @@ -1662,7 +1668,7 @@ export class Producer implements Table { } /** Follow `path` across publisher instances; see {@link Consumer.follow}. */ - follow(path: Path.Valid, options?: RequestOptions): Following { + follow(path: Path.Valid, options?: FollowOptions): Following { return this.#reader.follow(path, options); } @@ -1954,7 +1960,7 @@ export class Consumer implements Reader { * its path until closed. Requires discovery: a session without it never serves a follower. * A selected handler's refusal or the origin closing ends it. */ - follow(path: Path.Valid, options: RequestOptions = {}): Following { + follow(path: Path.Valid, options: FollowOptions = {}): Following { const instance = options.instance; const absolute = this.#scope.path(path); Path.Pattern.literal(path); diff --git a/quest/m1/api-audit/resolve/README.md b/quest/m1/api-audit/resolve/README.md index 2006acb5bed..14d21088e4b 100644 --- a/quest/m1/api-audit/resolve/README.md +++ b/quest/m1/api-audit/resolve/README.md @@ -1,4 +1,4 @@ -# Two broadcast resolutions +# [M] Two broadcast resolutions ## Goal @@ -54,10 +54,6 @@ Public API: breaking task shape in moq-net; behavior changes in `@moq/net` and the bindings. The method and epoch renames broke every wrapper. Wire: none. -## Required - -- [JS follow takes FollowOptions](/quest/m1/api-audit/resolve/follow-options.md) - `follow` and `request` get their own JS options types - ## Related - [Origin fronts park](/quest/m2/origin-front-parks.md) - touches the same retry diff --git a/quest/m1/api-audit/resolve/follow-options.md b/quest/m1/api-audit/resolve/follow-options.md deleted file mode 100644 index 783f4ab0aa3..00000000000 --- a/quest/m1/api-audit/resolve/follow-options.md +++ /dev/null @@ -1,22 +0,0 @@ -# [S] JS follow takes FollowOptions - -## Goal - -In `@moq/net`, `Origin.Consumer.follow` (and the `Producer` and `Table` -passthroughs) takes its own `FollowOptions`, and `request` keeps -`RequestOptions`. Each options type documents only what its method does. -Every caller in `js/` compiles against the split, and the API report is -regenerated. - -## Plan - -Planned 2026-10-31 (`/quest-plan`, maintainer), a follow-up from -[JS follow returns a Following](https://github.com/moq-dev/moq/pull/7476), -which split the return types but kept one `RequestOptions` for both -methods. Keep the shared fields' names. Drop a field from `FollowOptions` -only if `follow` ignores it today, and say which in the PR. If the two -types still end up identical, a shared base with two aliases is fine; the -point is that each method's docs describe one behavior. - -Public API: breaking for TypeScript type annotations that name -`RequestOptions` for a `follow` call. Wire: none.