Gathering detailed insights and metrics for broadcast-channel
Gathering detailed insights and metrics for broadcast-channel
Gathering detailed insights and metrics for broadcast-channel
Gathering detailed insights and metrics for broadcast-channel
📡 BroadcastChannel to send data between different browser-tabs or nodejs-processes 📡 + LeaderElection over the channels https://pubkey.github.io/broadcast-channel/
npm install broadcast-channel
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1,861 Stars
1,626 Commits
124 Forks
20 Watching
17 Branches
25 Contributors
Updated on 27 Nov 2024
JavaScript (99.74%)
Shell (0.14%)
HTML (0.13%)
Cumulative downloads
Total Downloads
Last day
-6.7%
367,864
Compared to previous day
Last week
3.6%
2,076,377
Compared to previous week
Last month
7.3%
8,686,296
Compared to previous month
Last year
8.6%
95,411,284
Compared to previous year
4
51
A BroadcastChannel to send data across multiple browser-tabs or nodejs-processes or Deno-Deploy-Instances
+ LeaderElection over the channels
A BroadcastChannel that allows you to send data between different browser-tabs or nodejs-processes or Deno-Deploy-Instances.
This behaves similar to the BroadcastChannel-API which is currently only featured in some browsers.
1npm install --save broadcast-channel
1import { BroadcastChannel } from 'broadcast-channel'; 2const channel = new BroadcastChannel('foobar'); 3channel.postMessage('I am not alone');
1import { BroadcastChannel } from 'broadcast-channel'; 2const channel = new BroadcastChannel('foobar'); 3channel.onmessage = msg => console.dir(msg); 4// > 'I am not alone'
1import { BroadcastChannel } from 'broadcast-channel'; 2const channel = new BroadcastChannel('foobar'); 3 4const handler = msg => console.log(msg); 5channel.addEventListener('message', handler); 6 7// remove it 8channel.removeEventListener('message', handler);
Returns a Promise
which is resolved when everything is processed.
1await channel.close();
1const options = { 2 type: 'localstorage', // (optional) enforce a type, oneOf['native', 'idb', 'localstorage', 'node'] 3 webWorkerSupport: true; // (optional) set this to false if you know that your channel will never be used in a WebWorker (increases performance) 4}; 5const channel = new BroadcastChannel('foobar', options);
1import { BroadcastChannel } from 'broadcast-channel'; 2declare type Message = { 3 foo: string; 4}; 5const channel: BroadcastChannel<Message> = new BroadcastChannel('foobar'); 6channel.postMessage({ 7 foo: 'bar' 8});
When you use this module in a test-suite, it is recommended to enforce the fast simulate
method on all channels so your tests run faster. You can do this with enforceOptions()
. If you set this, all channels have the enforced options, no mather what options are given in the constructor.
1import { enforceOptions } from 'broadcast-channel'; 2 3// enforce this config for all channels 4enforceOptions({ 5 type: 'simulate' 6}); 7 8// reset the enforcement 9enforceOptions(null);
When used in NodeJs, the BroadcastChannel will communicate with other processes over filesystem sockets.
When you create a huge amount of channels, like you would do when running unit tests, you might get problems because there are too many folders in the tmp-directory. Calling BroadcastChannel.clearNodeFolder()
will clear the tmp-folder. It is recommended to run this at the beginning of your test-suite.
1import { clearNodeFolder } from 'broadcast-channel'; 2// jest 3beforeAll(async () => { 4 const hasRun = await clearNodeFolder(); 5 console.log(hasRun); // > true on NodeJs, false on Browsers 6})
1import { clearNodeFolder } from 'broadcast-channel'; 2// mocha 3before(async () => { 4 const hasRun = await clearNodeFolder(); 5 console.log(hasRun); // > true on NodeJs, false on Browsers 6})
IndexedDB databases can close unexpectedly for various reasons. This could happen, for example, if the underlying storage is removed or if a user clears the database in the browser's history preferences. Most often we have seen this happen in Mobile Safari. By default, we let the connection close and stop polling for changes. If you would like to continue listening you should close BroadcastChannel and create a new one.
Example of how you might do this:
1import { BroadcastChannel } from 'broadcast-channel'; 2 3let channel; 4 5const createChannel = () => { 6 channel = new BroadcastChannel(CHANNEL_NAME, { 7 idb: { 8 onclose: () => { 9 // the onclose event is just the IndexedDB closing. 10 // you should also close the channel before creating 11 // a new one. 12 channel.close(); 13 createChannel(); 14 }, 15 }, 16 }); 17 18 channel.onmessage = message => { 19 // handle message 20 }; 21};
Depending in which environment this is used, a proper method is automatically selected to ensure it always works.
Method | Used in | Description |
---|---|---|
Native | Modern Browsers | If the browser supports the BroadcastChannel-API, this method will be used because it is the fastest. This is also used in Deno runtimes. |
IndexedDB | Browsers with WebWorkers | If there is no native BroadcastChannel support, the IndexedDB method is used because it supports messaging between browser-tabs, iframes and WebWorkers |
LocalStorage | Older Browsers | In older browsers that do not support IndexedDb, a localstorage-method is used |
Sockets | NodeJs | In NodeJs the communication is handled by sockets that send each other messages |
Simulate | none per default | This method simulates the behavior of the other methods but only runs in the current process without sharing data between processes. Use this method in your test-suite because it is much faster. |
This module also comes with a leader-election which can be used to elect a leader between different BroadcastChannels. For example if you have a stable connection from the frontend to your server, you can use the LeaderElection to save server-side performance by only connecting once, even if the user has opened your website in multiple tabs.
In the background it will use the Web Locks API if possible and fall back to a message-based election algorithm if WebLocks is not available.
In this example the leader is marked with the crown â™›:
Create a channel and an elector:
1import { 2 BroadcastChannel, 3 createLeaderElection 4} from 'broadcast-channel'; 5const channel = new BroadcastChannel('foobar'); 6const elector = createLeaderElection(channel);
Wait until the elector becomes leader:
1import { createLeaderElection } from 'broadcast-channel'; 2const elector = createLeaderElection(channel); 3elector.awaitLeadership().then(()=> { 4 console.log('this tab is now leader'); 5});
Check if there is a leader at this point in time. hasLeader()
returns true when there is a leader. It returns false, if the leader is dead. Then it returns true again when a new leader is elected.
1const elector = createLeaderElection(channel); 2const hasLeader = await elector.hasLeader(); 3console.log('leader exists: ' + hasLeader);
If more than one tab is becoming leader adjust LeaderElectionOptions
configuration.
1import { createLeaderElection } from 'broadcast-channel';
2const elector = createLeaderElection(channel, {
3 fallbackInterval: 2000, // optional configuration for how often will renegotiation for leader occur
4 responseTime: 1000, // optional configuration for how long will instances have to respond
5});
6elector.awaitLeadership().then(()=> {
7 console.log('this tab is now leader');
8})
Let the leader die. (automatically happens if a tab is closed or the process exits).
1const elector = createLeaderElection(channel); 2await elector.die();
Duplicate leadership can happen on rare occurences like when the CPU is on 100% for longer time, or the browser has throttled the javascript timers.
1const elector = createLeaderElection(channel); 2elector.onduplicate = () => { 3 alert('have duplicate leaders!'); 4}
This module is optimised for:
postMessage
to a channel, it will be delivered to other channels as soon as possible,window.BroadcastChannel
. This implementation behaves similiar to the BroadcastChannel-Standard with these limitations:
JSON.stringify
-ed,I have tested this in all browsers that I could find. For ie8 and ie9 you must transpile the code before you can use this. If you want to know if this works with your browser, open the demo page.
Thanks to Hemanth.HM for the module name.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Reason
Found 0/29 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
security policy file not detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More