diff --git a/packages/core/realtime-js/src/RealtimeClient.ts b/packages/core/realtime-js/src/RealtimeClient.ts index 19db54fa6..94794d4b2 100755 --- a/packages/core/realtime-js/src/RealtimeClient.ts +++ b/packages/core/realtime-js/src/RealtimeClient.ts @@ -645,6 +645,7 @@ export default class RealtimeClient { this.conn = null } this._clearAllTimers() + this._terminateWorker() this.channels.forEach((channel) => channel.teardown()) } @@ -698,7 +699,7 @@ export default class RealtimeClient { this.workerRef = new Worker(objectUrl) this.workerRef.onerror = (error) => { this.log('worker', 'worker error', (error as ErrorEvent).message) - this.workerRef!.terminate() + this._terminateWorker() } this.workerRef.onmessage = (event) => { if (event.data.event === 'keepAlive') { @@ -710,6 +711,18 @@ export default class RealtimeClient { interval: this.heartbeatIntervalMs, }) } + + /** + * Terminate the Web Worker and clear the reference + * @internal + */ + private _terminateWorker(): void { + if (this.workerRef) { + this.log('worker', 'terminating worker') + this.workerRef.terminate() + this.workerRef = undefined + } + } /** @internal */ private _onConnClose(event: any) { this._setConnectionState('disconnected') diff --git a/packages/core/realtime-js/test/RealtimeClient.worker.test.ts b/packages/core/realtime-js/test/RealtimeClient.worker.test.ts index 0c0bd644c..b159326c5 100644 --- a/packages/core/realtime-js/test/RealtimeClient.worker.test.ts +++ b/packages/core/realtime-js/test/RealtimeClient.worker.test.ts @@ -98,3 +98,27 @@ test('creates worker with blob URL when no workerUrl provided', () => { global.URL.createObjectURL = originalCreateObjectURL } }) + +test('terminates worker on disconnect', () => { + // Establish connection first + client.connect() + + // Trigger worker creation + client._onConnOpen() + + // Verify worker was created + assert.ok(client.workerRef) + const worker = client.workerRef + + // Spy on worker terminate method + const terminateSpy = vi.spyOn(worker, 'terminate') + + // Disconnect the client + client.disconnect() + + // Verify worker was terminated + expect(terminateSpy).toHaveBeenCalled() + + // Verify workerRef was cleared + assert.equal(client.workerRef, undefined) +})