Skip to content

Draft client interface#10

Closed
bergundy wants to merge 8 commits intonexus-rpc:mainfrom
bergundy:client-interface
Closed

Draft client interface#10
bergundy wants to merge 8 commits intonexus-rpc:mainfrom
bergundy:client-interface

Conversation

@bergundy
Copy link
Copy Markdown
Contributor

No description provided.

Comment thread src/client.ts Outdated
}

export interface ClientStartOperationResultSync<T> {
isSync(): this is ClientStartOperationResultSync<T>;
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.

isSync: Why a method rather than a readonly field? And how would you generally expect this to be implemented by the framework or library providing the client?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

E  77 ▎ isSync: this is ClientStartOperationResultSync<T>;     ■ A type predicate is only allowed in return type position for functions and methods.

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.

Yeah, but it could have been just a bool property, hardcoded to either true or false in the variants. That would make it a type determinant by itself, so no need for a type predicate.

I don't really mind, but the problem with current approach is that tsc can't assert that function creating a ClientStartOperationResult(Sync|Async) is self-coherent, whereas a boolean property would implicitly assert that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, good point, I can just change to isSync: false and isSync: true.

Comment thread src/client.ts Outdated
* Inbound links that contain arbitrary information, e.g. provided by the caller.
* Used as metadata for the call.
*/
readonly inboundLinks?: Link[];
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.

Here, it's called inboundLinks, but in Result, it is only links.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, we should be consistent. Thanks.

Comment thread src/client.ts

export interface ResultWithDetails<T> {
result: T;
links: Link[];
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.

outboundLinks?

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.

Given the current design, I think it would make more sense for this property to be optional.

I mean, if having Client only as abstraction, that means implementers will be responsible for producing objects of this interface. And therefore, adding new required properties to this interface at a later time would be breaking. So we'll instead make new properties be optional, and links will therefore adhere to a different semantic than other properties added later.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Making this optional would put the burden of null checks on the consumer and I'd rather avoid that.

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.

Making this optional would put the burden of null checks on the consumer and I'd rather avoid that.

I know, and so would I. Yet, this is what we'll have to do for all other properties added going forward if we don't want to break existing Client implementations in the future.

That is, unless we make the Nexus RPC library itself ensure normalization of the return value.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree, but at least for now it's part of the established contract. This concern will come into play if this contract is extended though.

I would consider introducing a transport abstraction and wrapping the transport's results in the client as you suggested.

@bergundy bergundy closed this Mar 31, 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