Skip to content

Commit a15c6c4

Browse files
authored
Clean up subscriptions when frames perform navigation. (#165)
1 parent 650b277 commit a15c6c4

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

.changeset/stale-dogs-collect.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'electron-trpc': minor
3+
---
4+
5+
Subscriptions will now be cleaned up when the frame owning that subscription performs a navigation.

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

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { CreateContextOptions } from './types';
66
import { ELECTRON_TRPC_CHANNEL } from '../constants';
77
import { ETRPCRequest } from '../types';
88
import { Unsubscribable } from '@trpc/server/observable';
9+
import debugFactory from 'debug';
10+
11+
const debug = debugFactory('electron-trpc:main:IPCHandler');
912

1013
type Awaitable<T> = T | Promise<T>;
1114

@@ -46,23 +49,49 @@ class IPCHandler<TRouter extends AnyRouter> {
4649
return;
4750
}
4851

52+
debug('Attaching window', win.id);
53+
4954
this.#windows.push(win);
50-
this.#attachSubscriptionCleanupHandler(win);
55+
this.#attachSubscriptionCleanupHandlers(win);
5156
}
5257

5358
detachWindow(win: BrowserWindow) {
59+
debug('Detaching window', win.id);
60+
5461
this.#windows = this.#windows.filter((w) => w !== win);
62+
this.#cleanUpSubscriptions({ webContentsId: win.webContents.id });
63+
}
5564

65+
#cleanUpSubscriptions({
66+
webContentsId,
67+
frameRoutingId,
68+
}: {
69+
webContentsId: number;
70+
frameRoutingId?: number;
71+
}) {
5672
for (const [key, sub] of this.#subscriptions.entries()) {
57-
if (key.startsWith(`${win.webContents.id}-`)) {
73+
if (key.startsWith(`${webContentsId}-${frameRoutingId ?? ''}`)) {
74+
debug('Closing subscription', key);
5875
sub.unsubscribe();
5976
this.#subscriptions.delete(key);
6077
}
6178
}
6279
}
6380

64-
#attachSubscriptionCleanupHandler(win: BrowserWindow) {
81+
#attachSubscriptionCleanupHandlers(win: BrowserWindow) {
82+
win.webContents.on('did-start-navigation', ({ frame }) => {
83+
debug(
84+
'Handling webContents `did-start-navigation` event',
85+
`webContentsId: ${win.webContents.id}`,
86+
`frameRoutingId: ${frame.routingId}`
87+
);
88+
this.#cleanUpSubscriptions({
89+
webContentsId: win.webContents.id,
90+
frameRoutingId: frame.routingId,
91+
});
92+
});
6593
win.webContents.on('destroyed', () => {
94+
debug('Handling webContents `destroyed` event');
6695
this.detachWindow(win);
6796
});
6897
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { getTRPCErrorFromUnknown } from './utils';
88
import { CreateContextOptions } from './types';
99
import { ELECTRON_TRPC_CHANNEL } from '../constants';
1010
import { ETRPCRequest } from '../types';
11+
import debugFactory from 'debug';
12+
13+
const debug = debugFactory('electron-trpc:main:handleIPCMessage');
1114

1215
export async function handleIPCMessage<TRouter extends AnyRouter>({
1316
router,
@@ -107,6 +110,7 @@ export async function handleIPCMessage<TRouter extends AnyRouter>({
107110
},
108111
});
109112

113+
debug('Creating subscription', internalId);
110114
subscriptions.set(internalId, subscription);
111115
} catch (cause) {
112116
const error: TRPCError = getTRPCErrorFromUnknown(cause);

packages/electron-trpc/src/renderer/ipcLink.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import type { TRPCResponseMessage } from '@trpc/server/rpc';
44
import type { RendererGlobalElectronTRPC } from '../types';
55
import { observable, Observer } from '@trpc/server/observable';
66
import { transformResult } from './utils';
7-
import debug from 'debug';
7+
import debugFactory from 'debug';
88

9-
const log = debug('electron-trpc:renderer:ipcLink');
9+
const debug = debugFactory('electron-trpc:renderer:ipcLink');
1010

1111
type IPCCallbackResult<TRouter extends AnyRouter = AnyRouter> = TRPCResponseMessage<
1212
unknown,
@@ -47,7 +47,7 @@ class IPCClient {
4747
}
4848

4949
#handleResponse(response: TRPCResponseMessage) {
50-
log('handling response', response);
50+
debug('handling response', response);
5151
const request = response.id && this.#pendingRequests.get(response.id);
5252
if (!request) {
5353
return;

0 commit comments

Comments
 (0)