refactor(mobile): give the one-key unchecked reader a name

Four readers were the same three lines: read one property off the reply, wrap
it unchecked. `rpcUncheckedMemberReader` is the one-key sibling of the existing
`rpcUncheckedPayloadReader`, so the annotation and the closure go away at each
site. The pilot's `commitCompareEntriesReader` is converted too, so the helper
has no longhand twin left to copy from.

No behaviour change: the helper composes the same `rpcReadUnchecked` over
`rpcPayloadMember`, including the property-read exception on a null result.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
This commit is contained in:
Jinwoo-H
2026-09-14 02:17:16 -04:00
parent a25ae31b8b
commit fe3868508c
4 changed files with 24 additions and 38 deletions
@@ -1,6 +1,9 @@
import { bindDeferredRpcOperation, defineRpcOperation } from '../transport/rpc-operation'
import type { RpcCompatibleReader } from '../transport/rpc-operation-contract'
import { rpcPayloadMember, rpcUncheckedPayloadReader } from '../transport/rpc-reader-payload'
import {
rpcUncheckedMemberReader,
rpcUncheckedPayloadReader
} from '../transport/rpc-reader-payload'
import { readMobileGitStatusResult } from '../session/mobile-diff-review-rpc'
import type { MobileGitStatusResult } from './mobile-git-status'
@@ -58,27 +61,18 @@ export const gitHistoryRead = bindDeferredRpcOperation(
})
)
const commitCompareEntriesReader: RpcCompatibleReader<
unknown,
'commit-compare-entries',
unknown
> = (raw) => ({
compatible: true,
variant: 'commit-compare-entries',
// Keeps the property-read exception the expanded-commit list already relies on: a null result
// throws inside the load, which is what leaves an already-loaded file list alone.
value: rpcPayloadMember(raw, 'entries'),
salvage: { droppedPaths: [], droppedCount: 0 }
})
/** A refused compare leaves the row's file list untouched, so refusal is a skip, not a throw. */
/**
* A refused compare leaves the row's file list untouched, so refusal is a skip, not a throw. The
* member read keeps the property-read exception a null result throws, which is what leaves an
* already-loaded file list alone.
*/
export const gitCommitCompareRead = bindDeferredRpcOperation(
defineRpcOperation({
name: 'git.commit-compare-entries-or-skip',
method: 'git.commitCompare',
acceptance: 'success-result-or-skip',
barrier: 'after-caller-barrier',
read: commitCompareEntriesReader
read: rpcUncheckedMemberReader('commit-compare-entries', 'entries')
})
)
@@ -1,8 +1,6 @@
import { bindDeferredRpcOperation, defineRpcOperation } from '../transport/rpc-operation'
import type { RpcCompatibleReader } from '../transport/rpc-operation-contract'
import {
rpcPayloadMember,
rpcReadUnchecked,
rpcUncheckedMemberReader,
rpcUncheckedPayloadReader
} from '../transport/rpc-reader-payload'
@@ -23,9 +21,6 @@ export const taskRuntimeStatusRead = bindDeferredRpcOperation(
})
)
const persistedUiStateReader: RpcCompatibleReader<unknown, 'ui-state-member', unknown> = (raw) =>
rpcReadUnchecked('ui-state-member', rpcPayloadMember(raw, 'ui'))
/**
* Persisted UI state, read at the hydration barrier alongside preflight and Linear status. A
* refused read leaves the screen on its defaults rather than failing hydration, so it is a skip.
@@ -36,7 +31,7 @@ export const taskUiStateRead = bindDeferredRpcOperation(
method: 'ui.get',
acceptance: 'success-result-or-skip',
barrier: 'after-caller-barrier',
read: persistedUiStateReader
read: rpcUncheckedMemberReader('ui-state-member', 'ui')
})
)
@@ -1,17 +1,13 @@
import { bindDeferredRpcOperation, defineRpcOperation } from '../transport/rpc-operation'
import type { RpcCompatibleReader } from '../transport/rpc-operation-contract'
import {
rpcPayloadMember,
rpcReadUnchecked,
rpcUncheckedMemberReader,
rpcUncheckedPayloadReader
} from '../transport/rpc-reader-payload'
// The repo and SSH reads the workspace-create drawer runs: connection state, agent detection,
// repo-owned setup hooks, sparse presets and base-branch search.
const sshConnectionStateReader: RpcCompatibleReader<unknown, 'ssh-connection-state', unknown> = (
raw
) => rpcReadUnchecked('ssh-connection-state', rpcPayloadMember(raw, 'state'))
const sshConnectionStateReader = rpcUncheckedMemberReader('ssh-connection-state', 'state')
/** Connecting an SSH repo before create. The reply's only read field is `state`. */
export const sshRepoConnectRun = bindDeferredRpcOperation(
@@ -69,30 +65,23 @@ export const repoSetupHooksRead = bindDeferredRpcOperation(
})
)
const sparsePresetListReader: RpcCompatibleReader<unknown, 'sparse-presets', unknown> = (raw) =>
rpcReadUnchecked('sparse-presets', rpcPayloadMember(raw, 'presets'))
export const repoSparsePresetListRead = bindDeferredRpcOperation(
defineRpcOperation({
name: 'repo.sparse-preset-list',
method: 'repo.sparsePresets',
acceptance: 'require-result-or-throw-message',
barrier: 'after-caller-barrier',
read: sparsePresetListReader
read: rpcUncheckedMemberReader('sparse-presets', 'presets')
})
)
const savedSparsePresetReader: RpcCompatibleReader<unknown, 'saved-sparse-preset', unknown> = (
raw
) => rpcReadUnchecked('saved-sparse-preset', rpcPayloadMember(raw, 'preset'))
export const repoSparsePresetSaveRun = bindDeferredRpcOperation(
defineRpcOperation({
name: 'repo.save-sparse-preset',
method: 'repo.saveSparsePreset',
acceptance: 'require-result-or-throw-message',
barrier: 'after-caller-barrier',
read: savedSparsePresetReader
read: rpcUncheckedMemberReader('saved-sparse-preset', 'preset')
})
)
@@ -25,3 +25,11 @@ export function rpcUncheckedPayloadReader<Variant extends string>(
): RpcCompatibleReader<unknown, Variant, unknown> {
return (raw) => rpcReadUnchecked(variant, raw)
}
/** One property off the payload, unchecked. The shape for a call site that cast `result.field`. */
export function rpcUncheckedMemberReader<Variant extends string>(
variant: Variant,
key: string
): RpcCompatibleReader<unknown, Variant, unknown> {
return (raw) => rpcReadUnchecked(variant, rpcPayloadMember(raw, key))
}