Skip to content

[0.6] refactor(ipc): extract registerCommand wrapper + migrate notes handlers - #212

Merged
h4yfans merged 3 commits into
mainfrom
debt/0.6-register-command-wrapper
Apr 15, 2026
Merged

[0.6] refactor(ipc): extract registerCommand wrapper + migrate notes handlers#212
h4yfans merged 3 commits into
mainfrom
debt/0.6-register-command-wrapper

Conversation

@h4yfans

@h4yfans h4yfans commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Unit 0.6 of the IPC tech-debt cleanup. Extracts the repeated triple-nested IPC handler registration pattern into a single registerCommand helper and migrates the qualifying notes handler sites to use it.

What changed

  • New: apps/desktop/src/main/ipc/lib/register-command.tsregisterCommand(channel, schema, command, fallback?) composes createValidatedHandler + withErrorHandler + ipcMain.handle in a single call. Handler callback retains full control over its return shape; no envelope is imposed.
  • New: apps/desktop/src/main/ipc/lib/register-command.test.ts — 5 tests covering registration, validated input forwarding, schema rejection, thrown-error envelope, fallback message.
  • Migrated 15 handler sites in apps/desktop/src/main/ipc/notes-handlers.ts:
    • create, update, rename, move
    • rename-folder
    • create-property-definition, update-property-definition
    • delete-attachment, set-folder-config
    • export-pdf, export-html
    • get-positions, reorder, import-files, set-local-only
  • Untouched (as specified): handlers using createHandler (no input) or createStringHandler (bare string input), and bare createValidatedHandler calls without nested withErrorHandler.

Line deltas

  • notes-handlers.ts: 951 → 942 (-9 net, diff shows +236 / -249 of migrated content)
  • Still over the 800-line guideline; splitting the file is out of scope for this refactor (would block on deciding handler grouping and would touch unrelated surface area).

IPC generator updates

The migration caused two regressions in generated-ipc-invoke-map.ts that had to be fixed in scripts/generate-ipc-invoke-map.js:

  1. Migrated channels were dropped because the scanner only looked for literal ipcMain.handle(...) calls. Added detection for registerCommand(...).
  2. Input type narrowed incorrectly. The old pipeline typed the IPC boundary via rawInput: z.input<TSchema> (defaulted fields optional). With registerCommand, the command callback is typed (input: z.infer<TSchema>) => TResult (defaulted fields required), which narrowed the boundary type and broke callers. Generator now reads z.input from the schema's own type via its _input property for registerCommand calls, matching previous semantics.
  3. Return type was losing the { success: false; error: string } branch that withErrorHandler adds at runtime. Generator now unions that branch into the awaited return for registerCommand calls, matching the previous union shape.

E2E smoke

pnpm test:e2e -- --grep "note" was launched but did not complete end-to-end within the available run window (Playwright was still iterating through body-crdt-*, note-sync-helpers, and notes.e2e.ts suites after ~10 minutes with no failures reported, then stopped producing new artifacts with no output written to stdout). The run was terminated without a full pass/fail summary. Cannot confirm e2e end-to-end.

Instead, the final npx electron-vite build succeeded cleanly — evidence below (last 20 lines):

../../out/renderer/assets/c-Bl5xafGJ.js                                               86.65 kB
../../out/renderer/assets/swift-Cohr-WZC.js                                           86.72 kB
../../out/renderer/assets/markdown-C7dg6S-0.js                                        88.93 kB
../../out/renderer/assets/latex-BmLmUh3i.js                                           97.40 kB
../../out/renderer/assets/less-zLwf3ygQ.js                                           116.23 kB
../../out/renderer/assets/objective-c-BTI_-NdD.js                                    118.78 kB
../../out/renderer/assets/php-RZFa1R9o.js                                            122.85 kB
../../out/renderer/assets/react-BQmmxN09.js                                          124.55 kB
../../out/renderer/assets/csharp-C-3Z-GKA.js                                         131.37 kB
../../out/renderer/assets/mdx-CAb1w3A_.js                                            181.53 kB
../../out/renderer/assets/javascript-S2Lhd_8f.js                                     205.60 kB
../../out/renderer/assets/tsx-_uqdJL1n.js                                            206.31 kB
../../out/renderer/assets/jsx-Bc8fwi-X.js                                            208.56 kB
../../out/renderer/assets/typescript-pLKQCwWX.js                                     212.27 kB
../../out/renderer/assets/index-CxAH9-ZR.js                                          778.83 kB
../../out/renderer/assets/cpp-D70-f36R.js                                            897.48 kB
../../out/renderer/assets/hls-BmqwCFVH.js                                          1,115.49 kB
../../out/renderer/assets/dash.all.min-Ms6H1cSG.js                                 1,306.00 kB
../../out/renderer/assets/index-I0IF_00U.js                                       16,085.02 kB
✓ built in 17.07s

Verification

  • pnpm ipc:check - pass
  • pnpm lint - 0 errors, 1420 pre-existing warnings (none introduced by this PR in notes-handlers.ts)
  • pnpm --filter @memry/desktop typecheck:node - pass
  • pnpm --filter @memry/desktop typecheck:web - pass
  • pnpm typecheck:packages - pass (FULL TURBO)
  • pnpm test - 5691/5692 pass; single failure is the known calendar-page.test.tsx:258 "Due draft" flake
  • npx electron-vite build - pass
  • New register-command.test.ts - 5/5 pass

Test plan

  • Create, update, rename, move a note through the app
  • Create and update property definitions (text, select, status)
  • Delete an attachment
  • Set/rename/delete a folder config
  • Export a note to PDF and HTML (including cancel dialogue path)
  • Reorder notes in a folder
  • Import files into the vault
  • Toggle local-only flag on a note

h4yfans added 3 commits April 15, 2026 20:31
…lers

Extract a `registerCommand(channel, schema, command, fallback?)` helper
that composes `createValidatedHandler` and `withErrorHandler` in a single
call, collapsing the repeated triple-nested pattern

  ipcMain.handle(channel, createValidatedHandler(schema, withErrorHandler(fn, fallback)))

to a single line. Migrate 15 matching handler sites in notes-handlers.ts
(create, update, rename, move, rename-folder, create/update property
definitions, delete-attachment, set-folder-config, export-pdf, export-html,
get-positions, reorder, import-files, set-local-only). Handlers that take
no input or a bare string (createHandler/createStringHandler) are left
unchanged per the wrapper's scope.

Teach the IPC invoke-map generator to recognise `registerCommand` calls
alongside `ipcMain.handle`, read the raw input type from the schema
(so defaulted fields remain optional at the boundary), and augment the
handler return type with the `{ success: false; error: string }` branch
that `withErrorHandler` injects at runtime. This keeps the generated
invoke map and RPC bindings stable after the refactor.

Add `register-command.test.ts` covering the five behavioural contracts:
registration, validated input forwarding, schema rejection, thrown-error
envelope, and fallback message handling.
@h4yfans
h4yfans merged commit 9a92f48 into main Apr 15, 2026
2 checks passed
@h4yfans
h4yfans deleted the debt/0.6-register-command-wrapper branch April 15, 2026 20:25
h4yfans added a commit that referenced this pull request May 6, 2026
[0.6] refactor(ipc): extract registerCommand wrapper + migrate notes handlers
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