Skip to content

refactor(ipc): apply registerCommand wrapper to sync handlers (Phase 2.5) - #242

Merged
h4yfans merged 1 commit into
mainfrom
debt/phase-2.5-register-command
Apr 16, 2026
Merged

refactor(ipc): apply registerCommand wrapper to sync handlers (Phase 2.5)#242
h4yfans merged 1 commit into
mainfrom
debt/phase-2.5-register-command

Conversation

@h4yfans

@h4yfans h4yfans commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to PR #241 (Phase 2.1–2.4). Migrates 19 schema-input handlers across the
4 split sync handler files from raw
ipcMain.handle(CH, createValidatedHandler(S, fn)) to the unified
registerCommand(CH, S, fn, fallback) wrapper introduced in Phase 0.6 (PR #212).

registerCommand composes createValidatedHandler + withErrorHandler in one call,
so thrown errors now resolve to { success: false, error } envelopes instead of
propagating as rejected promises. This is the same contract notes-handlers.ts has
been on since Phase 0.6, so renderer-side handling already lives alongside both
patterns. The change standardizes on the envelope pattern across the sync IPC
surface.

Scope

File Handlers migrated
sync-attachment-handlers.ts UPLOAD_ATTACHMENT, GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS
auth-oauth-handlers.ts AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE
auth-device-handlers.ts AUTH_REQUEST_OTP, AUTH_VERIFY_OTP, AUTH_RESEND_OTP, LINK_VIA_QR, COMPLETE_LINKING_QR, LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, REMOVE_DEVICE, RENAME_DEVICE
sync-core-handlers.ts GET_HISTORY, UPDATE_SYNCED_SETTING

Untouched (no schema, stay on raw ipcMain.handle): SETUP_NEW_ACCOUNT,
GET_RECOVERY_PHRASE, AUTH_REFRESH_TOKEN, AUTH_LOGOUT, GET_DEVICES,
GENERATE_LINKING_QR, GET_STATUS, TRIGGER_SYNC, GET_QUEUE_SIZE, PAUSE,
RESUME, GET_SYNCED_SETTINGS, GET_STORAGE_BREAKDOWN, GET_QUARANTINED_ITEMS,
CHECK_DEVICE_STATUS, EMERGENCY_WIPE.

Incidental improvement

UPDATE_SYNCED_SETTING previously used a manual schema.parse(input) inside a raw
ipcMain.handle with input: unknown. Migrating to registerCommand gives the
generated IPC invoke map a properly typed argument signature
({ fieldPath: string; value: unknown } instead of unknown).

Test plan

  • pnpm lint — 0 errors (1435 pre-existing warnings, none new)
  • pnpm --filter @memry/desktop exec tsc --noEmit -p tsconfig.node.json — clean
  • pnpm --filter @memry/desktop test --run src/main/ipc — 24 files, 300 tests pass
  • pnpm check:architecture — pass
  • pnpm ipc:check — pass (RPC bindings + invoke map up to date)
  • Manual OTP sign-in flow
  • Manual OAuth sign-in flow
  • Manual device rename/remove
  • Manual attachment upload/download round-trip

…2.5)

Migrate 19 schema-input handlers across 4 sync handler files from raw
ipcMain.handle(CH, createValidatedHandler(S, fn)) to the unified
registerCommand(CH, S, fn, fallback) wrapper that composes
createValidatedHandler + withErrorHandler in one call.

Files:
- sync-attachment-handlers.ts: 4 handlers (UPLOAD_ATTACHMENT,
  GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS)
- auth-oauth-handlers.ts: 3 handlers (AUTH_INIT_OAUTH,
  SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE)
- auth-device-handlers.ts: 10 handlers (AUTH_REQUEST_OTP,
  AUTH_VERIFY_OTP, AUTH_RESEND_OTP, LINK_VIA_QR, COMPLETE_LINKING_QR,
  LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, REMOVE_DEVICE,
  RENAME_DEVICE)
- sync-core-handlers.ts: 2 handlers (GET_HISTORY,
  UPDATE_SYNCED_SETTING)

Behavior change: handlers that previously propagated thrown errors to
the renderer as rejected promises (AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE,
LINK_VIA_QR, APPROVE_LINKING, GET_LINKING_SAS, and the OTP trio via
postToServer) now resolve with { success: false, error } envelopes.
Renderer call sites already handle error envelopes via extractErrorMessage
and existing try/catch, so no UI changes needed.

UPDATE_SYNCED_SETTING also gets a typed input
({ fieldPath: string; value: unknown }) in the generated invoke map
instead of `unknown`, a strict improvement over the prior manual
schema.parse call.

Raw ipcMain.handle calls for no-schema channels (SETUP_NEW_ACCOUNT,
GET_RECOVERY_PHRASE, AUTH_REFRESH_TOKEN, AUTH_LOGOUT, GET_DEVICES,
GENERATE_LINKING_QR, GET_STATUS, TRIGGER_SYNC, GET_QUEUE_SIZE, PAUSE,
RESUME, GET_SYNCED_SETTINGS, GET_STORAGE_BREAKDOWN,
GET_QUARANTINED_ITEMS, CHECK_DEVICE_STATUS, EMERGENCY_WIPE) are left
untouched — they have no Zod schema to wrap.

Regenerated generated-ipc-invoke-map.ts via pnpm ipc:generate.

Verification: lint 0 errors, tsc --noEmit -p tsconfig.node.json clean,
24 IPC test files with 300 tests pass, check:architecture pass,
ipc:check pass. No tests required updating.
@h4yfans
h4yfans merged commit 4fe15f8 into main Apr 16, 2026
2 checks passed
h4yfans added a commit that referenced this pull request May 6, 2026
…2.5) (#242)

Migrate 19 schema-input handlers across 4 sync handler files from raw
ipcMain.handle(CH, createValidatedHandler(S, fn)) to the unified
registerCommand(CH, S, fn, fallback) wrapper that composes
createValidatedHandler + withErrorHandler in one call.

Files:
- sync-attachment-handlers.ts: 4 handlers (UPLOAD_ATTACHMENT,
  GET_UPLOAD_PROGRESS, DOWNLOAD_ATTACHMENT, GET_DOWNLOAD_PROGRESS)
- auth-oauth-handlers.ts: 3 handlers (AUTH_INIT_OAUTH,
  SETUP_FIRST_DEVICE, CONFIRM_RECOVERY_PHRASE)
- auth-device-handlers.ts: 10 handlers (AUTH_REQUEST_OTP,
  AUTH_VERIFY_OTP, AUTH_RESEND_OTP, LINK_VIA_QR, COMPLETE_LINKING_QR,
  LINK_VIA_RECOVERY, APPROVE_LINKING, GET_LINKING_SAS, REMOVE_DEVICE,
  RENAME_DEVICE)
- sync-core-handlers.ts: 2 handlers (GET_HISTORY,
  UPDATE_SYNCED_SETTING)

Behavior change: handlers that previously propagated thrown errors to
the renderer as rejected promises (AUTH_INIT_OAUTH, SETUP_FIRST_DEVICE,
LINK_VIA_QR, APPROVE_LINKING, GET_LINKING_SAS, and the OTP trio via
postToServer) now resolve with { success: false, error } envelopes.
Renderer call sites already handle error envelopes via extractErrorMessage
and existing try/catch, so no UI changes needed.

UPDATE_SYNCED_SETTING also gets a typed input
({ fieldPath: string; value: unknown }) in the generated invoke map
instead of `unknown`, a strict improvement over the prior manual
schema.parse call.

Raw ipcMain.handle calls for no-schema channels (SETUP_NEW_ACCOUNT,
GET_RECOVERY_PHRASE, AUTH_REFRESH_TOKEN, AUTH_LOGOUT, GET_DEVICES,
GENERATE_LINKING_QR, GET_STATUS, TRIGGER_SYNC, GET_QUEUE_SIZE, PAUSE,
RESUME, GET_SYNCED_SETTINGS, GET_STORAGE_BREAKDOWN,
GET_QUARANTINED_ITEMS, CHECK_DEVICE_STATUS, EMERGENCY_WIPE) are left
untouched — they have no Zod schema to wrap.

Regenerated generated-ipc-invoke-map.ts via pnpm ipc:generate.

Verification: lint 0 errors, tsc --noEmit -p tsconfig.node.json clean,
24 IPC test files with 300 tests pass, check:architecture pass,
ipc:check pass. No tests required updating.
@h4yfans
h4yfans deleted the debt/phase-2.5-register-command branch May 6, 2026 16:36
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