Skip to content

Commit c43ae93

Browse files
authored
Fix replies only getting routed to main frame. (#146)
1 parent ed178f7 commit c43ae93

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

.changeset/issue-145.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'electron-trpc': patch
3+
---
4+
5+
Fix `handleIPCMessage` only sending replies to Electron's main frame.
6+
7+
pr: 146

packages/electron-trpc/src/main/__tests__/handleIPCMessage.test.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ import * as trpc from '@trpc/server';
44
import { observable } from '@trpc/server/observable';
55
import { EventEmitter } from 'events';
66
import { handleIPCMessage } from '../handleIPCMessage';
7-
import { IpcMainInvokeEvent } from 'electron';
7+
import { IpcMainEvent } from 'electron';
88

99
interface MockEvent {
10+
reply: MockedFunction<any>;
1011
sender: {
1112
isDestroyed: () => boolean;
1213
on: (event: string, cb: () => void) => void;
13-
send: MockedFunction<any>;
1414
};
1515
}
16-
const makeEvent = (event: MockEvent) =>
17-
event as unknown as IpcMainInvokeEvent & { sender: { send: MockedFunction<any> } };
16+
const makeEvent = (event: MockEvent) => event as unknown as IpcMainEvent & Pick<MockEvent, 'reply'>;
1817

1918
const ee = new EventEmitter();
2019

@@ -44,10 +43,10 @@ const testRouter = t.router({
4443
describe('api', () => {
4544
test('handles queries', async () => {
4645
const event = makeEvent({
46+
reply: vi.fn(),
4747
sender: {
4848
isDestroyed: () => false,
4949
on: () => {},
50-
send: vi.fn(),
5150
},
5251
});
5352

@@ -69,8 +68,8 @@ describe('api', () => {
6968
subscriptions: new Map(),
7069
});
7170

72-
expect(event.sender.send).toHaveBeenCalledOnce();
73-
expect(event.sender.send.mock.lastCall[1]).toMatchObject({
71+
expect(event.reply).toHaveBeenCalledOnce();
72+
expect(event.reply.mock.lastCall![1]).toMatchObject({
7473
id: 1,
7574
result: {
7675
data: {
@@ -83,10 +82,10 @@ describe('api', () => {
8382

8483
test('does not respond if sender is gone', async () => {
8584
const event = makeEvent({
85+
reply: vi.fn(),
8686
sender: {
8787
isDestroyed: () => true,
8888
on: () => {},
89-
send: vi.fn(),
9089
},
9190
});
9291

@@ -108,15 +107,15 @@ describe('api', () => {
108107
subscriptions: new Map(),
109108
});
110109

111-
expect(event.sender.send).not.toHaveBeenCalled();
110+
expect(event.reply).not.toHaveBeenCalled();
112111
});
113112

114113
test('handles subscriptions', async () => {
115114
const event = makeEvent({
115+
reply: vi.fn(),
116116
sender: {
117117
isDestroyed: () => false,
118118
on: () => {},
119-
send: vi.fn(),
120119
},
121120
});
122121

@@ -138,12 +137,12 @@ describe('api', () => {
138137
event,
139138
});
140139

141-
expect(event.sender.send).not.toHaveBeenCalled();
140+
expect(event.reply).not.toHaveBeenCalled();
142141

143142
ee.emit('test');
144143

145-
expect(event.sender.send).toHaveBeenCalledOnce();
146-
expect(event.sender.send.mock.lastCall[1]).toMatchObject({
144+
expect(event.reply).toHaveBeenCalledOnce();
145+
expect(event.reply.mock.lastCall![1]).toMatchObject({
147146
id: 1,
148147
result: {
149148
data: 'test response',
@@ -153,10 +152,10 @@ describe('api', () => {
153152

154153
test('subscription responds using custom serializer', async () => {
155154
const event = makeEvent({
155+
reply: vi.fn(),
156156
sender: {
157157
isDestroyed: () => false,
158158
on: () => {},
159-
send: vi.fn(),
160159
},
161160
});
162161

@@ -203,12 +202,12 @@ describe('api', () => {
203202
event,
204203
});
205204

206-
expect(event.sender.send).not.toHaveBeenCalled();
205+
expect(event.reply).not.toHaveBeenCalled();
207206

208207
ee.emit('test');
209208

210-
expect(event.sender.send).toHaveBeenCalledOnce();
211-
expect(event.sender.send.mock.lastCall[1]).toMatchObject({
209+
expect(event.reply).toHaveBeenCalledOnce();
210+
expect(event.reply.mock.lastCall![1]).toMatchObject({
212211
id: 1,
213212
result: {
214213
type: 'data',

packages/electron-trpc/src/main/createIPCHandler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { AnyRouter, inferRouterContext } from '@trpc/server';
22
import { ipcMain } from 'electron';
3-
import type { BrowserWindow, IpcMainInvokeEvent } from 'electron';
3+
import type { BrowserWindow, IpcMainEvent } from 'electron';
44
import { handleIPCMessage } from './handleIPCMessage';
55
import { CreateContextOptions } from './types';
66
import { ELECTRON_TRPC_CHANNEL } from '../constants';
@@ -9,7 +9,7 @@ import { Unsubscribable } from '@trpc/server/observable';
99

1010
type Awaitable<T> = T | Promise<T>;
1111

12-
const getInternalId = (event: IpcMainInvokeEvent, request: ETRPCRequest) => {
12+
const getInternalId = (event: IpcMainEvent, request: ETRPCRequest) => {
1313
const messageId = request.method === 'request' ? request.operation.id : request.id;
1414
return `${event.sender.id}-${event.senderFrame.routingId}:${messageId}`;
1515
};
@@ -29,7 +29,7 @@ class IPCHandler<TRouter extends AnyRouter> {
2929
}) {
3030
windows.forEach((win) => this.attachWindow(win));
3131

32-
ipcMain.on(ELECTRON_TRPC_CHANNEL, (event: IpcMainInvokeEvent, request: ETRPCRequest) => {
32+
ipcMain.on(ELECTRON_TRPC_CHANNEL, (event: IpcMainEvent, request: ETRPCRequest) => {
3333
handleIPCMessage({
3434
router,
3535
createContext,

packages/electron-trpc/src/main/handleIPCMessage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { callProcedure, TRPCError } from '@trpc/server';
22
import type { AnyRouter, inferRouterContext } from '@trpc/server';
33
import type { TRPCResponseMessage } from '@trpc/server/rpc';
4-
import type { IpcMainInvokeEvent } from 'electron';
4+
import type { IpcMainEvent } from 'electron';
55
import { isObservable, Unsubscribable } from '@trpc/server/observable';
66
import { CreateContextOptions } from './types';
77
import { getTRPCErrorFromUnknown, transformTRPCResponseItem } from './utils';
@@ -20,7 +20,7 @@ export async function handleIPCMessage<TRouter extends AnyRouter>({
2020
createContext?: (opts: CreateContextOptions) => Promise<inferRouterContext<TRouter>>;
2121
internalId: string;
2222
message: ETRPCRequest;
23-
event: IpcMainInvokeEvent;
23+
event: IpcMainEvent;
2424
subscriptions: Map<string, Unsubscribable>;
2525
}) {
2626
if (message.method === 'subscription.stop') {
@@ -43,7 +43,7 @@ export async function handleIPCMessage<TRouter extends AnyRouter>({
4343

4444
const respond = (response: TRPCResponseMessage) => {
4545
if (event.sender.isDestroyed()) return;
46-
event.sender.send(ELECTRON_TRPC_CHANNEL, transformTRPCResponseItem(router, response));
46+
event.reply(ELECTRON_TRPC_CHANNEL, transformTRPCResponseItem(router, response));
4747
};
4848

4949
try {

0 commit comments

Comments
 (0)