Skip to content

Commit

Permalink
fix unload event detection + test
Browse files Browse the repository at this point in the history
  • Loading branch information
Sysix committed Jun 16, 2024
1 parent 9d71798 commit a0a10d3
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 33 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ worker.addListener('stop-worker', () => {

// connect to worker to the channel, other browser tab will be notified
// this will trigger start-worker event for the current tab
// this will tigger stop-worker event for the other tab with has the main worker
// this will trigger stop-worker event for the other tab with has the main worker
worker.connect();

// when you no longer want to listen for other tabs
Expand All @@ -40,12 +40,16 @@ When multiple tabs are connected to the server, then every tab starts a request
This library makes it possible to reduce server requests with this following example:

```typescript
import BreadcastSingleWorker from 'broeadcast-single-worker';
import BroadcastSingleWorker from '@sysix/broadcast-single-worker';

const worker = new BreadcastSingleWorker('channel_name');
const UIChannel = new BreadcastChannel('channel_name_ui');
const worker = new BroadcastSingleWorker('channel_name');
const UIChannel = new BroadcastChannel('channel_name_ui');
let intervalId: number | undefined;

const updateUi = (json: unknown) => {
document.body.innerText = JSON.stringify(json);
}

worker.addListener('start-worker', () => {
intervalId = window.setInterval(async () => {
const response = await window.fetch('https://host/poll-ui-changes');
Expand All @@ -62,8 +66,8 @@ worker.addListener('stop-worker', () => {
}
});

UIChannel.onmessage = (json: unkown) => {
updateUi(json);
UIChannel.onmessage = (message: MessageEvent<unknown>) => {
updateUi(message.data);
}

worker.connect();
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "@sysix/broadcast-single-worker",
"version": "1.0.0",
"version": "0.1.0",
"description": "Create a single worker for multiple browser tabs",
"main": "dist/index.js",
"module": "dist/index.js",
"browser": "dist/index.js",
"types": "types/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"default": "./dist/index.js"
"import": "./dist/index.js"
}
},
"sideEffects": false,
Expand All @@ -21,7 +21,6 @@
"build": "tsc --project ./tsconfig.json",
"test": "jest ./src --config=jest.config.js"
},
"author": "",
"license": "MIT",
"dependencies": {
"eventemitter3": "^5.0.1"
Expand Down
22 changes: 8 additions & 14 deletions src/BroadcastSingleWorker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,31 +90,25 @@ describe('breadocast single worker', () => {
worker1.disconnect();
});

// ToDo: somehow the event listener is not triggered
test.skip('disconnect channel when window is closing', async () => {
test('disconnect channel when window is closing', async () => {
const spy = jest.spyOn(BroadcastSingleWorker.prototype, 'disconnect');
const worker = new BroadcastSingleWorker('worker');

const disconnectMock = jest.fn();
const originalDisconnect = worker.disconnect;

worker.disconnect = () => {
originalDisconnect();
disconnectMock();
};

worker.connect();

window.dispatchEvent(new Event('beforeunload'));
window.dispatchEvent(new Event('unload'));

// ToDo: Maybe Mock BroadcastChannel, so we dont need to wait
await sleep(100);
await sleep(10);

expect(disconnectMock).toBeCalledTimes(1);
expect(spy).toBeCalledTimes(1);
expect(worker.isActiveWorker()).toBe(false);

worker.removeAllListeners();
});

spy.mockRestore();
});

test('don\'t fire start-worker event when non main worker disconnect', async () => {
const worker1 = new BroadcastSingleWorker('worker');
const worker2 = new BroadcastSingleWorker('worker');
Expand Down
10 changes: 5 additions & 5 deletions src/BroadcastSingleWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default class BroadcastSingleWorker extends EventEmitter<'start-worker' |

#otherWorkerIds: string[] = [];

#beforeUnloadCallback = this.disconnect.bind(this);
#unloadCallback = this.disconnect.bind(this);

constructor(channelName: string) {
super();
Expand Down Expand Up @@ -40,8 +40,8 @@ export default class BroadcastSingleWorker extends EventEmitter<'start-worker' |
// tell the current tab to start their job
this.emit('start-worker');

// listen for onbeforeunload event
window.addEventListener('onbeforeunload', this.#beforeUnloadCallback);
// listen for unload event
window.addEventListener('unload', this.#unloadCallback);
}
/**
* disconnect to the broadcast channel and tell other tabs
Expand All @@ -67,8 +67,8 @@ export default class BroadcastSingleWorker extends EventEmitter<'start-worker' |
this.#channel.close();
this.#channel = undefined;

// don't listen to the onbeforeunload event
window.removeEventListener('onbeforeunload', this.#beforeUnloadCallback);
// don't listen to the unload event
window.removeEventListener('unload', this.#unloadCallback);
}

/**
Expand Down

0 comments on commit a0a10d3

Please sign in to comment.