feat(frontend/hooks): replace 3rd-party BroadcastChannel with native Web API equivalence (#29584)

Signed-off-by: hainenber <dotronghai96@gmail.com>
This commit is contained in:
Đỗ Trọng Hải 2024-07-18 02:15:20 +07:00 committed by GitHub
parent 3ade01f828
commit ae6e58f918
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 92 additions and 105 deletions

View File

@ -62,7 +62,6 @@
"babel-plugin-typescript-to-proptypes": "^2.0.0",
"bootstrap": "^3.4.1",
"brace": "^0.11.1",
"broadcast-channel": "^4.10.0",
"chrono-node": "^2.7.5",
"classnames": "^2.2.5",
"core-js": "^3.37.1",
@ -20724,6 +20723,7 @@
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
"dev": true,
"engines": {
"node": ">=0.6"
}
@ -21026,21 +21026,6 @@
"brfs": "bin/cmd.js"
}
},
"node_modules/broadcast-channel": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-4.10.0.tgz",
"integrity": "sha512-hOUh312XyHk6JTVyX9cyXaH1UYs+2gHVtnW16oQAu9FL7ALcXGXc/YoJWqlkV8vUn14URQPMmRi4A9q4UrwVEQ==",
"dependencies": {
"@babel/runtime": "^7.16.0",
"detect-node": "^2.1.0",
"microseconds": "0.2.0",
"nano-time": "1.0.0",
"oblivious-set": "1.0.0",
"p-queue": "6.6.2",
"rimraf": "3.0.2",
"unload": "2.3.1"
}
},
"node_modules/browser-assert": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz",
@ -25352,7 +25337,8 @@
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
"node_modules/detect-node-es": {
"version": "1.1.0",
@ -27799,7 +27785,8 @@
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true
},
"node_modules/events": {
"version": "3.3.0",
@ -47730,11 +47717,6 @@
"node": ">=0.10.0"
}
},
"node_modules/microseconds": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
"integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@ -48254,14 +48236,6 @@
"dev": true,
"optional": true
},
"node_modules/nano-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
"integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=",
"dependencies": {
"big-integer": "^1.6.16"
}
},
"node_modules/nanoid": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz",
@ -50084,11 +50058,6 @@
"integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==",
"dev": true
},
"node_modules/oblivious-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
},
"node_modules/obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@ -50286,6 +50255,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
"dev": true,
"engines": {
"node": ">=4"
}
@ -50366,6 +50336,7 @@
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
"integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
"dev": true,
"dependencies": {
"eventemitter3": "^4.0.4",
"p-timeout": "^3.2.0"
@ -50404,6 +50375,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
"dev": true,
"dependencies": {
"p-finally": "^1.0.0"
},
@ -60326,15 +60298,6 @@
"node": ">= 10.0.0"
}
},
"node_modules/unload": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/unload/-/unload-2.3.1.tgz",
"integrity": "sha512-MUZEiDqvAN9AIDRbbBnVYVvfcR6DrjCqeU2YQMmliFZl9uaBUjTkhuDQkBiyAy8ad5bx1TXVbqZ3gg7namsWjA==",
"dependencies": {
"@babel/runtime": "^7.6.2",
"detect-node": "2.1.0"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@ -84800,7 +84763,8 @@
"big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg=="
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
"dev": true
},
"big.js": {
"version": "5.2.2",
@ -85045,21 +85009,6 @@
"through2": "^2.0.0"
}
},
"broadcast-channel": {
"version": "4.10.0",
"resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-4.10.0.tgz",
"integrity": "sha512-hOUh312XyHk6JTVyX9cyXaH1UYs+2gHVtnW16oQAu9FL7ALcXGXc/YoJWqlkV8vUn14URQPMmRi4A9q4UrwVEQ==",
"requires": {
"@babel/runtime": "^7.16.0",
"detect-node": "^2.1.0",
"microseconds": "0.2.0",
"nano-time": "1.0.0",
"oblivious-set": "1.0.0",
"p-queue": "6.6.2",
"rimraf": "3.0.2",
"unload": "2.3.1"
}
},
"browser-assert": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz",
@ -88336,7 +88285,8 @@
"detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
"detect-node-es": {
"version": "1.1.0",
@ -90206,7 +90156,8 @@
"eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"dev": true
},
"events": {
"version": "3.3.0",
@ -104156,11 +104107,6 @@
}
}
},
"microseconds": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz",
"integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA=="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@ -104562,14 +104508,6 @@
"dev": true,
"optional": true
},
"nano-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz",
"integrity": "sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=",
"requires": {
"big-integer": "^1.6.16"
}
},
"nanoid": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz",
@ -105891,11 +105829,6 @@
"integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==",
"dev": true
},
"oblivious-set": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz",
"integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw=="
},
"obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
@ -106051,7 +105984,8 @@
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
"dev": true
},
"p-iteration": {
"version": "1.1.8",
@ -106102,6 +106036,7 @@
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz",
"integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
"dev": true,
"requires": {
"eventemitter3": "^4.0.4",
"p-timeout": "^3.2.0"
@ -106127,6 +106062,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz",
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
"dev": true,
"requires": {
"p-finally": "^1.0.0"
}
@ -113384,15 +113320,6 @@
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
},
"unload": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/unload/-/unload-2.3.1.tgz",
"integrity": "sha512-MUZEiDqvAN9AIDRbbBnVYVvfcR6DrjCqeU2YQMmliFZl9uaBUjTkhuDQkBiyAy8ad5bx1TXVbqZ3gg7namsWjA==",
"requires": {
"@babel/runtime": "^7.6.2",
"detect-node": "2.1.0"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",

View File

@ -127,7 +127,6 @@
"babel-plugin-typescript-to-proptypes": "^2.0.0",
"bootstrap": "^3.4.1",
"brace": "^0.11.1",
"broadcast-channel": "^4.10.0",
"chrono-node": "^2.7.5",
"classnames": "^2.2.5",
"core-js": "^3.37.1",

View File

@ -0,0 +1,63 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Credit to Eric Wong at https://stackoverflow.com/a/78491331
interface StrictBroadcastChannelEventMap<T> {
message: MessageEvent<T>;
messageerror: MessageEvent<T>;
}
export interface StrictBroadcastChannel<T> extends EventTarget {
readonly name: string;
onmessage: ((this: BroadcastChannel, ev: MessageEvent<T>) => any) | null;
onmessageerror: ((this: BroadcastChannel, ev: MessageEvent<T>) => any) | null;
close(): void;
postMessage(message: T): void;
addEventListener<K extends keyof StrictBroadcastChannelEventMap<T>>(
type: K,
listener: (
this: BroadcastChannel,
ev: StrictBroadcastChannelEventMap<T>[K],
) => any,
options?: boolean | AddEventListenerOptions,
): void;
addEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
): void;
removeEventListener<K extends keyof StrictBroadcastChannelEventMap<T>>(
type: K,
listener: (
this: BroadcastChannel,
ev: StrictBroadcastChannelEventMap<T>[K],
) => any,
options?: boolean | EventListenerOptions,
): void;
removeEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): void;
}
export interface TabIdChannelMessage {
type: 'REQUESTING_TAB_ID' | 'TAB_ID_DENIED';
tabId: string;
}

View File

@ -18,17 +18,15 @@
*/
import { useEffect, useState } from 'react';
import { nanoid } from 'nanoid';
import { BroadcastChannel } from 'broadcast-channel';
import {
StrictBroadcastChannel,
TabIdChannelMessage,
} from './strictBroadcastChannel';
interface TabIdChannelMessage {
type: 'REQUESTING_TAB_ID' | 'TAB_ID_DENIED';
tabId: string;
}
const TAB_ID_CHANNEL_NAME = 'tab_id_channel';
// TODO: We are using broadcast-channel to support Safari.
// The native BroadcastChannel API will be supported in Safari version 15.4.
// After that, we should remove this dependency and use the native API.
const channel = new BroadcastChannel<TabIdChannelMessage>('tab_id_channel');
const channel: StrictBroadcastChannel<TabIdChannelMessage> =
new BroadcastChannel(TAB_ID_CHANNEL_NAME);
export function useTabId() {
const [tabId, setTabId] = useState<string>();
@ -83,14 +81,14 @@ export function useTabId() {
}
channel.onmessage = messageEvent => {
if (messageEvent.tabId === tabId) {
if (messageEvent.type === 'REQUESTING_TAB_ID') {
if (messageEvent.data.tabId === tabId) {
if (messageEvent.data.type === 'REQUESTING_TAB_ID') {
const message: TabIdChannelMessage = {
type: 'TAB_ID_DENIED',
tabId: messageEvent.tabId,
tabId: messageEvent.data.tabId,
};
channel.postMessage(message);
} else if (messageEvent.type === 'TAB_ID_DENIED') {
} else if (messageEvent.data.type === 'TAB_ID_DENIED') {
updateTabId();
}
}