diff --git a/mobile/src/session/github-pr-mutations.ts b/mobile/src/session/github-pr-mutations.ts index 48329bfe619..e7327fc76b5 100644 --- a/mobile/src/session/github-pr-mutations.ts +++ b/mobile/src/session/github-pr-mutations.ts @@ -1,5 +1,5 @@ import type { GitHubPRMergeMethod } from '../../../src/shared/github/pull-request-types' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' import { buildGithubPrParams, githubPrRepoSlugParam, type GitHubPrRepoSlug } from './github-pr-rpc' // Mutation wrappers for the github.* PR surface, split out so github-pr-rpc.ts @@ -17,7 +17,7 @@ export type GitHubPrMutationOutcome = { ok: true; comment?: unknown } | { ok: fa type RawResult = { ok: true; result: unknown } | { ok: false; error: string } async function sendRaw( - client: Pick, + client: RpcRequestSender, method: string, params: Record ): Promise { @@ -52,7 +52,7 @@ function extractMutationError(error: unknown, method: string): string { // `response.ok === false` (timeout/connection) is also a failure. Both collapse // into one outcome the action hook classifies via classifyPrSidebarFailure. async function sendGithubPrMutation( - client: Pick, + client: RpcRequestSender, method: string, params: Record, options?: { timeoutMs?: number } @@ -83,7 +83,7 @@ async function sendGithubPrMutation( } export async function fetchMergePR( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number; method?: GitHubPRMergeMethod; prRepo?: GitHubPrRepoSlug | null }, options?: { timeoutMs?: number } @@ -104,7 +104,7 @@ export async function fetchMergePR( // which sendGithubPrMutation reads via its "no structured status" success branch // only when not boolean — so handle the boolean explicitly like resolveReviewThread. export async function fetchUpdatePRTitle( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number; title: string; prRepo?: GitHubPrRepoSlug | null } ): Promise { @@ -126,7 +126,7 @@ export async function fetchUpdatePRTitle( } export async function fetchSetPRAutoMerge( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number @@ -147,7 +147,7 @@ export async function fetchSetPRAutoMerge( } export async function fetchUpdatePRState( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number; state: 'open' | 'closed'; prRepo?: GitHubPrRepoSlug | null } ): Promise { @@ -164,7 +164,7 @@ export async function fetchUpdatePRState( } export async function fetchRequestPRReviewers( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number; reviewers: string[]; prRepo?: GitHubPrRepoSlug | null } ): Promise { @@ -181,7 +181,7 @@ export async function fetchRequestPRReviewers( } export async function fetchRemovePRReviewers( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number; reviewers: string[]; prRepo?: GitHubPrRepoSlug | null } ): Promise { @@ -201,7 +201,7 @@ export async function fetchRemovePRReviewers( // (`{ ok, comment } | { ok:false, error }`), which sendGithubPrMutation reads via // its `ok in result` branch. We refetch afterward, so the returned comment is unused. export async function fetchAddPRReviewCommentReply( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number @@ -238,7 +238,7 @@ export async function fetchAddPRReviewCommentReply( // Add a root conversation comment to a PR or an issue. Host returns GitHubCommentResult. export async function fetchAddIssueComment( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number @@ -265,7 +265,7 @@ export async function fetchAddIssueComment( // the matching GraphQL mutation). Unlike the comment mutations, the host returns a // bare boolean, so a falsy result is a failure rather than the "no status" success. export async function fetchResolveReviewThread( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { threadId: string; resolve: boolean; prRepo?: GitHubPrRepoSlug | null } ): Promise { @@ -298,7 +298,7 @@ export async function fetchResolveReviewThread( // directly rather than via buildGithubPrParams. Host returns the // GitHubProjectMutationResult `{ ok }` envelope sendGithubPrMutation reads. export async function fetchUpdateIssueComment( - client: Pick, + client: RpcRequestSender, args: { owner: string; repo: string; host?: string; commentId: number; body: string } ): Promise { return sendGithubPrMutation(client, 'github.project.updateIssueCommentBySlug', { @@ -310,7 +310,7 @@ export async function fetchUpdateIssueComment( // Delete a root conversation (issue) comment. Slug-addressed like the edit wrapper. export async function fetchDeleteIssueComment( - client: Pick, + client: RpcRequestSender, args: { owner: string; repo: string; host?: string; commentId: number } ): Promise { return sendGithubPrMutation(client, 'github.project.deleteIssueCommentBySlug', { @@ -320,7 +320,7 @@ export async function fetchDeleteIssueComment( } export async function fetchRerunPRChecks( - client: Pick, + client: RpcRequestSender, worktreeId: string, args: { prNumber: number diff --git a/mobile/src/tasks/native-host-task-detail-operations.ts b/mobile/src/tasks/native-host-task-detail-operations.ts index 32e09747d47..969020c8701 100644 --- a/mobile/src/tasks/native-host-task-detail-operations.ts +++ b/mobile/src/tasks/native-host-task-detail-operations.ts @@ -5,8 +5,7 @@ import type { import type { MobileWebTaskLinearIssue } from '../../../src/shared/mobile-web/task-list-contract' import type { HostTaskDetailOperations } from './host-task-detail-operations' import { projectGitHubTaskDetail } from './github-task-detail-projection' -import type { RpcClient } from '../transport/rpc-client' -import type { RpcSuccess } from '../transport/types' +import type { RpcRequestSender } from '../transport/rpc-client' type GitLabRawDetails = Partial & { item?: { @@ -15,7 +14,7 @@ type GitLabRawDetails = Partial & { } } -export function nativeHostTaskDetailOperations(client: RpcClient): HostTaskDetailOperations { +export function nativeHostTaskDetailOperations(client: RpcRequestSender): HostTaskDetailOperations { return { async listGitHubLabels(repoId) { return successfulResult( @@ -114,5 +113,5 @@ async function successfulResult(request: Promise): Promise { if (!response.ok) { throw new Error(response.error?.message ?? 'Task provider request failed') } - return (response as RpcSuccess).result as T + return response.result as T } diff --git a/mobile/src/tasks/native-host-task-item-file-operations.ts b/mobile/src/tasks/native-host-task-item-file-operations.ts index 0a69cff9e7a..17a37175c5d 100644 --- a/mobile/src/tasks/native-host-task-item-file-operations.ts +++ b/mobile/src/tasks/native-host-task-item-file-operations.ts @@ -1,7 +1,9 @@ import type { HostTaskItemFileOperations } from './host-task-item-file-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' -export function nativeHostTaskItemFileOperations(client: RpcClient): HostTaskItemFileOperations { +export function nativeHostTaskItemFileOperations( + client: RpcRequestSender +): HostTaskItemFileOperations { return { async refreshChecks(target, headSha) { const checks = await request(client, 'github.prChecks', { @@ -70,14 +72,14 @@ function repoPayload(target: { repoId: string }) { } async function request( - client: RpcClient, + client: RpcRequestSender, method: string, payload: object, timeoutMs = 30_000 ): Promise { const response = await client.sendRequest(method, payload, { timeoutMs }) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } return response.result as T } diff --git a/mobile/src/tasks/native-host-task-item-mutation-operations.ts b/mobile/src/tasks/native-host-task-item-mutation-operations.ts index 1e69db11c7f..6c8498a4ffd 100644 --- a/mobile/src/tasks/native-host-task-item-mutation-operations.ts +++ b/mobile/src/tasks/native-host-task-item-mutation-operations.ts @@ -3,10 +3,10 @@ import type { HostTaskItemMutationOperations, HostTaskItemMutationTarget } from './host-task-item-mutation-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskItemMutationOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskItemMutationOperations { return { async setClosed(target, closed) { @@ -27,7 +27,7 @@ export function nativeHostTaskItemMutationOperations( } function setGitHubClosed( - client: RpcClient, + client: RpcRequestSender, target: Extract, closed: boolean ) { @@ -46,7 +46,7 @@ function setGitHubClosed( } function setGitLabClosed( - client: RpcClient, + client: RpcRequestSender, target: Extract, closed: boolean ) { @@ -67,7 +67,7 @@ function setGitLabClosed( } function updateGitHubMetadata( - client: RpcClient, + client: RpcRequestSender, target: Extract, updates: MobileWebTaskItemMetadataUpdates ) { @@ -89,7 +89,7 @@ function updateGitHubMetadata( } function updateGitLabMetadata( - client: RpcClient, + client: RpcRequestSender, target: Extract, updates: MobileWebTaskItemMetadataUpdates ) { @@ -122,11 +122,11 @@ function updateGitLabMetadata( } function assertMutation( - response: Awaited>, + response: Awaited>, fallback: string ): void { if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } const result = response.result as { ok?: boolean; error?: string } if (result.ok === false) { diff --git a/mobile/src/tasks/native-host-task-item-review-operations.ts b/mobile/src/tasks/native-host-task-item-review-operations.ts index 78f8927d893..99eefe2ddc1 100644 --- a/mobile/src/tasks/native-host-task-item-review-operations.ts +++ b/mobile/src/tasks/native-host-task-item-review-operations.ts @@ -1,10 +1,10 @@ import type { MobileWebTaskDetailComment } from '../../../src/shared/mobile-web/task-detail-contract' import type { HostTaskItemMutationTarget } from './host-task-item-mutation-operations' import type { HostTaskItemReviewOperations } from './host-task-item-review-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskItemReviewOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskItemReviewOperations { return { async addComment(target, body) { @@ -89,7 +89,7 @@ export function nativeHostTaskItemReviewOperations( } function addGitLabComment( - client: RpcClient, + client: RpcRequestSender, target: Extract, body: string ) { @@ -117,11 +117,11 @@ function addGitLabComment( } function mutationComment( - response: Awaited>, + response: Awaited>, fallback: string ): MobileWebTaskDetailComment | undefined { if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } const result = response.result as { ok?: boolean @@ -135,11 +135,11 @@ function mutationComment( } function assertMutation( - response: Awaited>, + response: Awaited>, fallback: string ): void { if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } const result = response.result as { ok?: boolean; error?: string } if (result.ok === false) { diff --git a/mobile/src/tasks/native-host-task-linear-operations.ts b/mobile/src/tasks/native-host-task-linear-operations.ts index 5bc61e40010..4f2fd3c2679 100644 --- a/mobile/src/tasks/native-host-task-linear-operations.ts +++ b/mobile/src/tasks/native-host-task-linear-operations.ts @@ -1,7 +1,7 @@ import type { HostTaskLinearOperations } from './host-task-linear-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' -export function nativeHostTaskLinearOperations(client: RpcClient): HostTaskLinearOperations { +export function nativeHostTaskLinearOperations(client: RpcRequestSender): HostTaskLinearOperations { return { async connect(apiKey) { assertMutation( @@ -74,13 +74,13 @@ export function nativeHostTaskLinearOperations(client: RpcClient): HostTaskLinea } async function request( - client: RpcClient, + client: RpcRequestSender, method: string, payload?: object ): Promise { const response = await client.sendRequest(method, payload, { timeoutMs: 30_000 }) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } return response.result as T } diff --git a/mobile/src/tasks/native-host-task-list-operations.ts b/mobile/src/tasks/native-host-task-list-operations.ts index ad3dbc51c22..532f4efdb84 100644 --- a/mobile/src/tasks/native-host-task-list-operations.ts +++ b/mobile/src/tasks/native-host-task-list-operations.ts @@ -1,9 +1,8 @@ import { extractLinearIssueReadItems } from './linear-mobile-issue-read' import type { HostTaskListOperations } from './host-task-list-operations' -import type { RpcClient } from '../transport/rpc-client' -import type { RpcSuccess } from '../transport/types' +import type { RpcRequestSender } from '../transport/rpc-client' -export function nativeHostTaskListOperations(client: RpcClient): HostTaskListOperations { +export function nativeHostTaskListOperations(client: RpcRequestSender): HostTaskListOperations { return { async listGitHub(payload) { return successfulResult( @@ -73,5 +72,5 @@ async function successfulResult(request: Promise): Promise { if (!response.ok) { throw new Error(response.error?.message ?? 'Task provider request failed') } - return (response as RpcSuccess).result as T + return response.result as T } diff --git a/mobile/src/tasks/native-host-task-preference-operations.ts b/mobile/src/tasks/native-host-task-preference-operations.ts index 64e7f3ce014..06986c2f475 100644 --- a/mobile/src/tasks/native-host-task-preference-operations.ts +++ b/mobile/src/tasks/native-host-task-preference-operations.ts @@ -1,9 +1,9 @@ import { persistSetupHookTrustApproval } from './setup-hook-trust' import type { HostTaskPreferenceOperations } from './host-task-preference-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskPreferenceOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskPreferenceOperations { return { async updateResume(taskResumeState) { diff --git a/mobile/src/tasks/native-host-task-project-file-operations.ts b/mobile/src/tasks/native-host-task-project-file-operations.ts index 0f76b6aae8d..126bbf0eae3 100644 --- a/mobile/src/tasks/native-host-task-project-file-operations.ts +++ b/mobile/src/tasks/native-host-task-project-file-operations.ts @@ -1,9 +1,9 @@ import type { HostTaskProjectFileOperations } from './host-task-project-file-operations' import type { HostTaskProjectItemTarget } from './host-task-project-mutation-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskProjectFileOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskProjectFileOperations { return { async refreshChecks(target, repoId, headSha) { @@ -60,13 +60,13 @@ function repoPayload(target: HostTaskProjectItemTarget, repoId: string) { } async function request( - client: RpcClient, + client: RpcRequestSender, method: string, payload: object ): Promise { const response = await client.sendRequest(method, payload, { timeoutMs: 30_000 }) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } return response.result as T } diff --git a/mobile/src/tasks/native-host-task-project-mutation-operations.ts b/mobile/src/tasks/native-host-task-project-mutation-operations.ts index 539b7c31622..18aef9c0981 100644 --- a/mobile/src/tasks/native-host-task-project-mutation-operations.ts +++ b/mobile/src/tasks/native-host-task-project-mutation-operations.ts @@ -3,7 +3,7 @@ import type { HostTaskProjectItemTarget, HostTaskProjectMutationOperations } from './host-task-project-mutation-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' import { fetchAddIssueComment, fetchAddPRReviewCommentReply, @@ -17,7 +17,7 @@ import { const PROJECT_PR_MUTATION_TIMEOUT_MS = 60_000 export function nativeHostTaskProjectMutationOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskProjectMutationOperations { return { async updateItem(target, updates) { @@ -154,7 +154,7 @@ function slugPayload(target: HostTaskProjectItemTarget) { } async function projectMutation( - client: RpcClient, + client: RpcRequestSender, method: string, payload: object ): Promise { diff --git a/mobile/src/tasks/native-host-task-project-read-operations.ts b/mobile/src/tasks/native-host-task-project-read-operations.ts index 5a834212004..0609bbf5d00 100644 --- a/mobile/src/tasks/native-host-task-project-read-operations.ts +++ b/mobile/src/tasks/native-host-task-project-read-operations.ts @@ -6,10 +6,10 @@ import type { import type { MobileWebTaskProjectTable } from '../../../src/shared/mobile-web/task-project-table-contract' import type { HostTaskProjectReadOperations } from './host-task-project-read-operations' import { projectGitHubTaskDetail } from './github-task-detail-projection' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskProjectReadOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskProjectReadOperations { return { async listAccessible(host) { diff --git a/mobile/src/tasks/native-host-task-provider-write-operations.ts b/mobile/src/tasks/native-host-task-provider-write-operations.ts index 84bba8048ff..be5741b80c6 100644 --- a/mobile/src/tasks/native-host-task-provider-write-operations.ts +++ b/mobile/src/tasks/native-host-task-provider-write-operations.ts @@ -1,8 +1,8 @@ import type { HostTaskProviderWriteOperations } from './host-task-provider-write-operations' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export function nativeHostTaskProviderWriteOperations( - client: RpcClient + client: RpcRequestSender ): HostTaskProviderWriteOperations { return { async createIssue(payload) { @@ -15,7 +15,7 @@ export function nativeHostTaskProviderWriteOperations( } ) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } const result = response.result as { ok?: boolean @@ -41,7 +41,7 @@ export function nativeHostTaskProviderWriteOperations( { timeoutMs: 15_000 } ) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Task request failed') } } } diff --git a/mobile/src/tasks/native-host-task-read-operations.ts b/mobile/src/tasks/native-host-task-read-operations.ts index 03dcdb8a3b5..973e6032867 100644 --- a/mobile/src/tasks/native-host-task-read-operations.ts +++ b/mobile/src/tasks/native-host-task-read-operations.ts @@ -6,10 +6,9 @@ import type { HostTaskReadOperations, HostTaskRepository } from './host-task-read-operations' -import type { RpcClient } from '../transport/rpc-client' -import type { RpcSuccess } from '../transport/types' +import type { RpcRequestReply, RpcRequestSender } from '../transport/rpc-client' -export function nativeHostTaskReadOperations(client: RpcClient): HostTaskReadOperations { +export function nativeHostTaskReadOperations(client: RpcRequestSender): HostTaskReadOperations { return { bootstrap: () => bootstrap(client), listRepositories: () => listRepositories(client), @@ -18,10 +17,10 @@ export function nativeHostTaskReadOperations(client: RpcClient): HostTaskReadOpe } } -async function bootstrap(client: RpcClient): Promise { +async function bootstrap(client: RpcRequestSender): Promise { const statusResponse = await client.sendRequest('status.get') requireSuccess(statusResponse) - const status = (statusResponse as RpcSuccess).result as { capabilities?: string[] } + const status = statusResponse.result as { capabilities?: string[] } if (!status.capabilities?.includes(MOBILE_TASKS_CAPABILITY)) { return emptyBootstrap(false) } @@ -53,17 +52,17 @@ async function bootstrap(client: RpcClient): Promise { } } -async function listRepositories(client: RpcClient): Promise { +async function listRepositories(client: RpcRequestSender): Promise { const response = await client.sendRequest('repo.list') requireSuccess(response) - const result = (response as RpcSuccess).result as { repos?: HostTaskRepository[] } + const result = response.result as { repos?: HostTaskRepository[] } return result.repos ?? [] } -async function loadLinearContext(client: RpcClient): Promise { +async function loadLinearContext(client: RpcRequestSender): Promise { const statusResponse = await client.sendRequest('linear.status') requireSuccess(statusResponse) - const status = normalizeLinearStatus((statusResponse as RpcSuccess).result) + const status = normalizeLinearStatus(statusResponse.result) if (!status.connected) { return { status, teams: [] } } @@ -75,12 +74,12 @@ async function loadLinearContext(client: RpcClient): Promise { const response = await client.sendRequest( @@ -89,7 +88,7 @@ async function resolveGitHubRepoSlug( { timeoutMs: 30_000 } ) requireSuccess(response) - return (response as RpcSuccess).result as GitHubOwnerRepo | null + return response.result as GitHubOwnerRepo | null } function emptyBootstrap(supported: boolean): HostTaskBootstrap { @@ -113,11 +112,13 @@ function normalizeLinearStatus(value: unknown): HostTaskBootstrap['linearStatus' } } -function successResult(response: { ok: boolean; result?: unknown }): T | null { +function successResult(response: RpcRequestReply): T | null { return response.ok ? (response.result as T) : null } -function requireSuccess(response: { ok: boolean; error?: { message?: string } }): void { +function requireSuccess( + response: RpcRequestReply +): asserts response is { ok: true; result: unknown } { if (!response.ok) { throw new Error(response.error?.message ?? 'Task operation failed') } diff --git a/mobile/src/tasks/setup-hook-trust.ts b/mobile/src/tasks/setup-hook-trust.ts index 72381393989..493f4ba9d2c 100644 --- a/mobile/src/tasks/setup-hook-trust.ts +++ b/mobile/src/tasks/setup-hook-trust.ts @@ -1,5 +1,5 @@ import type { PersistedTrustedOrcaHooks } from '../../../src/shared/orca-yaml-hook-types' -import type { RpcClient } from '../transport/rpc-client' +import type { RpcRequestSender } from '../transport/rpc-client' export type SetupHookTrust = { contentHash: string @@ -38,7 +38,7 @@ export function trustedOrcaHooksWithSetupApproval(args: { } export async function persistSetupHookTrustApproval(args: { - client: RpcClient + client: RpcRequestSender trust: PersistedTrustedOrcaHooks repoId: string contentHash: string @@ -47,7 +47,7 @@ export async function persistSetupHookTrustApproval(args: { const next = trustedOrcaHooksWithSetupApproval(args) const response = await args.client.sendRequest('ui.set', { trustedOrcaHooks: next }) if (!response.ok) { - throw new Error(response.error.message) + throw new Error(response.error?.message ?? 'Hook trust update failed') } return next } diff --git a/mobile/src/tasks/web-host-task-rpc-sender.ts b/mobile/src/tasks/web-host-task-rpc-sender.ts new file mode 100644 index 00000000000..98de846bd8e --- /dev/null +++ b/mobile/src/tasks/web-host-task-rpc-sender.ts @@ -0,0 +1,19 @@ +import type { MobileWebHostRequestClient } from '../../../src/mobile-web/src/mobile-web-host-request-client' +import type { RpcRequestSender } from '../transport/rpc-client' + +/** The hosted page reaches the same desktop methods the native app calls, so the task operation + * modules are shared verbatim. A desktop error arrives as a rejected bridge request, never as an + * `ok: false` reply, which is why this sender only ever resolves successes. */ +export function webHostTaskRpcSender(host: MobileWebHostRequestClient): RpcRequestSender { + return { + async sendRequest(method, params) { + return { ok: true, result: await host.request({ method, params: hostParams(params) }) } + } + } +} + +function hostParams(params: unknown): Record { + return typeof params === 'object' && params !== null && !Array.isArray(params) + ? (params as Record) + : {} +} diff --git a/mobile/src/transport/rpc-client.ts b/mobile/src/transport/rpc-client.ts index 01bdd2e8fce..f2b006b6508 100644 --- a/mobile/src/transport/rpc-client.ts +++ b/mobile/src/transport/rpc-client.ts @@ -18,6 +18,22 @@ export type SendRequestOptions = { beforeSend?: () => void } +/** A unary reply as its caller reads it. The hosted page answers over the capability bridge, which + * carries no request id or runtime metadata, so those stay on the transport's own `RpcResponse`. */ +export type RpcRequestReply = + | { ok: true; result: unknown } + | { ok: false; error?: { code?: string; message?: string } } + +/** The only surface a unary caller needs, so the same operation modules serve the native app over a + * socket and the hosted page over the bridge. */ +export type RpcRequestSender = { + sendRequest: ( + method: string, + params?: unknown, + options?: SendRequestOptions + ) => Promise +} + type StreamingListener = (result: unknown) => void export type RpcClient = {