Upgrade Electron to 39.2.7 to fix macOS Tahoe GPU performance regression (#931)
This commit is contained in:
@@ -92,6 +92,6 @@
|
|||||||
"webpack-dev-server": "^5.0.4"
|
"webpack-dev-server": "^5.0.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"electron": "^29"
|
"electron": "^39"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ interface BrowserAuthWrapperProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isBrowserMode =
|
const isBrowserMode =
|
||||||
typeof window !== 'undefined' &&
|
typeof window !== 'undefined' && (typeof process === 'undefined' || process.env?.BROWSER_MODE === 'true')
|
||||||
(typeof process === 'undefined' || process.env?.BROWSER_MODE === 'true')
|
|
||||||
|
|
||||||
export function BrowserAuthWrapper(props: BrowserAuthWrapperProps) {
|
export function BrowserAuthWrapper(props: BrowserAuthWrapperProps) {
|
||||||
const [isAuthenticated, setIsAuthenticated] = React.useState(false)
|
const [isAuthenticated, setIsAuthenticated] = React.useState(false)
|
||||||
|
|||||||
@@ -10,9 +10,8 @@ import { ConnectionOptions } from '../../model/ConnectionOptions'
|
|||||||
import { Theme, withStyles } from '@material-ui/core/styles'
|
import { Theme, withStyles } from '@material-ui/core/styles'
|
||||||
|
|
||||||
// Check if we're in browser mode
|
// Check if we're in browser mode
|
||||||
const isBrowserMode =
|
const isBrowserMode =
|
||||||
typeof window !== 'undefined' &&
|
typeof window !== 'undefined' && (typeof process === 'undefined' || process.env?.BROWSER_MODE === 'true')
|
||||||
(typeof process === 'undefined' || process.env?.BROWSER_MODE === 'true')
|
|
||||||
const CertSelector = isBrowserMode ? BrowserCertificateFileSelection : CertificateFileSelection
|
const CertSelector = isBrowserMode ? BrowserCertificateFileSelection : CertificateFileSelection
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default class ConfigStorage {
|
|||||||
private file: string
|
private file: string
|
||||||
private database: any
|
private database: any
|
||||||
private rpc: Rpc
|
private rpc: Rpc
|
||||||
|
|
||||||
constructor(file: string, rpc: Rpc) {
|
constructor(file: string, rpc: Rpc) {
|
||||||
this.file = file
|
this.file = file
|
||||||
this.rpc = rpc
|
this.rpc = rpc
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export class Base64Message {
|
|||||||
|
|
||||||
let str: string = ''
|
let str: string = ''
|
||||||
buf.forEach(element => {
|
buf.forEach(element => {
|
||||||
let hex = element.toString(16).toUpperCase()
|
const hex = element.toString(16).toUpperCase()
|
||||||
str += `0x${hex.length < 2 ? '0' + hex : hex} `
|
str += `0x${hex.length < 2 ? '0' + hex : hex} `
|
||||||
})
|
})
|
||||||
return str.trimRight()
|
return str.trimRight()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export class IpcMainEventBus implements EventBusInterface {
|
|||||||
private clients: Map<number, WebContents> = new Map() // webContentsId -> WebContents
|
private clients: Map<number, WebContents> = new Map() // webContentsId -> WebContents
|
||||||
private connectionOwners: Map<string, number> = new Map() // connectionId -> webContentsId
|
private connectionOwners: Map<string, number> = new Map() // connectionId -> webContentsId
|
||||||
private currentClient: WebContents | undefined
|
private currentClient: WebContents | undefined
|
||||||
|
|
||||||
constructor(ipc: IpcMain) {
|
constructor(ipc: IpcMain) {
|
||||||
this.ipc = ipc
|
this.ipc = ipc
|
||||||
}
|
}
|
||||||
@@ -16,34 +16,34 @@ export class IpcMainEventBus implements EventBusInterface {
|
|||||||
this.ipc.on(subscribeEvent.topic, (event: any, arg: any) => {
|
this.ipc.on(subscribeEvent.topic, (event: any, arg: any) => {
|
||||||
const sender = event.sender as WebContents
|
const sender = event.sender as WebContents
|
||||||
this.currentClient = sender
|
this.currentClient = sender
|
||||||
|
|
||||||
// Track the client (O(1) operation)
|
// Track the client (O(1) operation)
|
||||||
if (!this.clients.has(sender.id)) {
|
if (!this.clients.has(sender.id)) {
|
||||||
this.clients.set(sender.id, sender)
|
this.clients.set(sender.id, sender)
|
||||||
|
|
||||||
// Clean up when window is closed
|
// Clean up when window is closed
|
||||||
sender.once('destroyed', () => {
|
sender.once('destroyed', () => {
|
||||||
this.clients.delete(sender.id)
|
this.clients.delete(sender.id)
|
||||||
|
|
||||||
// Clean up owned connections
|
// Clean up owned connections
|
||||||
for (const [connectionId, webContentsId] of this.connectionOwners.entries()) {
|
Array.from(this.connectionOwners.entries()).forEach(([connectionId, webContentsId]) => {
|
||||||
if (webContentsId === sender.id) {
|
if (webContentsId === sender.id) {
|
||||||
this.connectionOwners.delete(connectionId)
|
this.connectionOwners.delete(connectionId)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track connection ownership
|
// Track connection ownership
|
||||||
if (subscribeEvent.topic === 'connection/add/mqtt' && arg?.id) {
|
if (subscribeEvent.topic === 'connection/add/mqtt' && arg?.id) {
|
||||||
this.connectionOwners.set(arg.id, sender.id)
|
this.connectionOwners.set(arg.id, sender.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove connection ownership
|
// Remove connection ownership
|
||||||
if (subscribeEvent.topic === 'connection/remove' && typeof arg === 'string') {
|
if (subscribeEvent.topic === 'connection/remove' && typeof arg === 'string') {
|
||||||
this.connectionOwners.delete(arg)
|
this.connectionOwners.delete(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(arg)
|
callback(arg)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ export class IpcMainEventBus implements EventBusInterface {
|
|||||||
|
|
||||||
public emit<MessageType>(event: Event<MessageType>, msg: MessageType) {
|
public emit<MessageType>(event: Event<MessageType>, msg: MessageType) {
|
||||||
const topic = event.topic
|
const topic = event.topic
|
||||||
|
|
||||||
// RPC responses go only to the requesting client
|
// RPC responses go only to the requesting client
|
||||||
if (topic.includes('/response/')) {
|
if (topic.includes('/response/')) {
|
||||||
if (this.currentClient && !this.currentClient.isDestroyed()) {
|
if (this.currentClient && !this.currentClient.isDestroyed()) {
|
||||||
@@ -66,18 +66,18 @@ export class IpcMainEventBus implements EventBusInterface {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connection-specific events - optimized with early pattern match
|
// Connection-specific events - optimized with early pattern match
|
||||||
if (topic.startsWith('conn/')) {
|
if (topic.startsWith('conn/')) {
|
||||||
const parts = topic.split('/')
|
const parts = topic.split('/')
|
||||||
let connectionId: string | undefined
|
let connectionId: string | undefined
|
||||||
|
|
||||||
if (parts.length === 2) {
|
if (parts.length === 2) {
|
||||||
connectionId = parts[1]
|
connectionId = parts[1]
|
||||||
} else if (parts.length === 3 && (parts[1] === 'state' || parts[1] === 'publish')) {
|
} else if (parts.length === 3 && (parts[1] === 'state' || parts[1] === 'publish')) {
|
||||||
connectionId = parts[2]
|
connectionId = parts[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connectionId) {
|
if (connectionId) {
|
||||||
const ownerWebContentsId = this.connectionOwners.get(connectionId)
|
const ownerWebContentsId = this.connectionOwners.get(connectionId)
|
||||||
if (ownerWebContentsId !== undefined) {
|
if (ownerWebContentsId !== undefined) {
|
||||||
@@ -89,7 +89,7 @@ export class IpcMainEventBus implements EventBusInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All other events go to all clients
|
// All other events go to all clients
|
||||||
this.clients.forEach(client => {
|
this.clients.forEach(client => {
|
||||||
if (!client.isDestroyed()) {
|
if (!client.isDestroyed()) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class SocketIOServerEventBus implements EventBusInterface {
|
|||||||
private globalHandlers: Map<string, (socket: Socket, arg: any) => void> = new Map()
|
private globalHandlers: Map<string, (socket: Socket, arg: any) => void> = new Map()
|
||||||
|
|
||||||
// Per-socket subscriptions for cleanup
|
// Per-socket subscriptions for cleanup
|
||||||
private socketSubscriptions: Map<string, SocketSubscription[]> = new Map()
|
private socketSubscriptions: Map<string, Array<SocketSubscription>> = new Map()
|
||||||
|
|
||||||
// Track which socket is currently processing a request
|
// Track which socket is currently processing a request
|
||||||
private currentSocket: Socket | undefined
|
private currentSocket: Socket | undefined
|
||||||
@@ -73,7 +73,7 @@ export class SocketIOServerEventBus implements EventBusInterface {
|
|||||||
event,
|
event,
|
||||||
totalClients,
|
totalClients,
|
||||||
totalSubscriptions,
|
totalSubscriptions,
|
||||||
|
|
||||||
totalConnections,
|
totalConnections,
|
||||||
socketId.substring(0, 8),
|
socketId.substring(0, 8),
|
||||||
socketSubs,
|
socketSubs,
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
"builder-util-runtime": "^9",
|
"builder-util-runtime": "^9",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"cspell": "^8.6.1",
|
"cspell": "^8.6.1",
|
||||||
"electron": "29.2.0",
|
"electron": "39.2.7",
|
||||||
"electron-builder": "^24.13.3",
|
"electron-builder": "^24.13.3",
|
||||||
"mocha": "^10.4.0",
|
"mocha": "^10.4.0",
|
||||||
"mustache": "4",
|
"mustache": "4",
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ async function startServer() {
|
|||||||
|
|
||||||
backendRpc.on(makeSaveDialogRpc(), async request => {
|
backendRpc.on(makeSaveDialogRpc(), async request => {
|
||||||
// In browser mode, file saving is handled client-side via download
|
// In browser mode, file saving is handled client-side via download
|
||||||
return { canceled: true, filePath: undefined }
|
return { canceled: true, filePath: '' }
|
||||||
})
|
})
|
||||||
|
|
||||||
backendRpc.on(getAppVersion, async () => {
|
backendRpc.on(getAppVersion, async () => {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ export interface MockSparkplugClient {
|
|||||||
stop: () => void
|
stop: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
var sample = (function () {
|
let sample = (function () {
|
||||||
var config = {
|
let config = {
|
||||||
serverUrl: 'tcp://127.0.0.1:1883',
|
serverUrl: 'tcp://127.0.0.1:1883',
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
@@ -169,12 +169,12 @@ var sample = (function () {
|
|||||||
// Create node command handler
|
// Create node command handler
|
||||||
// spell-checker: disable-next-line
|
// spell-checker: disable-next-line
|
||||||
sparkplugClient.on('ncmd', function (payload: UPayload) {
|
sparkplugClient.on('ncmd', function (payload: UPayload) {
|
||||||
var timestamp = payload.timestamp,
|
let timestamp = payload.timestamp,
|
||||||
metrics = payload.metrics
|
metrics = payload.metrics
|
||||||
|
|
||||||
if (metrics !== undefined && metrics !== null) {
|
if (metrics !== undefined && metrics !== null) {
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (let i = 0; i < metrics.length; i++) {
|
||||||
var metric = metrics[i]
|
let metric = metrics[i]
|
||||||
if (metric.name == 'Node Control/Rebirth' && metric.value) {
|
if (metric.name == 'Node Control/Rebirth' && metric.value) {
|
||||||
console.log("Received 'Rebirth' command")
|
console.log("Received 'Rebirth' command")
|
||||||
// Publish Node BIRTH certificate
|
// Publish Node BIRTH certificate
|
||||||
@@ -189,7 +189,7 @@ var sample = (function () {
|
|||||||
// Create device command handler
|
// Create device command handler
|
||||||
// spell-checker: disable-next-line
|
// spell-checker: disable-next-line
|
||||||
sparkplugClient.on('dcmd', function (deviceId: string, payload: UPayload) {
|
sparkplugClient.on('dcmd', function (deviceId: string, payload: UPayload) {
|
||||||
var timestamp = payload.timestamp,
|
let timestamp = payload.timestamp,
|
||||||
metrics = payload.metrics,
|
metrics = payload.metrics,
|
||||||
inboundMetricMap: { [name: string]: any } = {},
|
inboundMetricMap: { [name: string]: any } = {},
|
||||||
outboundMetric: Array<UMetric> = [],
|
outboundMetric: Array<UMetric> = [],
|
||||||
@@ -199,8 +199,8 @@ var sample = (function () {
|
|||||||
|
|
||||||
// Loop over the metrics and store them in a map
|
// Loop over the metrics and store them in a map
|
||||||
if (metrics !== undefined && metrics !== null) {
|
if (metrics !== undefined && metrics !== null) {
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (let i = 0; i < metrics.length; i++) {
|
||||||
var metric = metrics[i]
|
let metric = metrics[i]
|
||||||
if (metric.name !== undefined && metric.name !== null) {
|
if (metric.name !== undefined && metric.name !== null) {
|
||||||
inboundMetricMap[metric.name] = metric.value
|
inboundMetricMap[metric.name] = metric.value
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ var sample = (function () {
|
|||||||
return connected
|
return connected
|
||||||
}
|
}
|
||||||
|
|
||||||
return { run: run }
|
return { run }
|
||||||
})()
|
})()
|
||||||
|
|
||||||
export default sample
|
export default sample
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ async function main() {
|
|||||||
console.log(`✓ Window ready, title: ${title}`)
|
console.log(`✓ Window ready, title: ${title}`)
|
||||||
|
|
||||||
// Check console logs for remote debugging message
|
// Check console logs for remote debugging message
|
||||||
const logs: string[] = []
|
const logs: Array<string> = []
|
||||||
page.on('console', msg => {
|
page.on('console', msg => {
|
||||||
const text = msg.text()
|
const text = msg.text()
|
||||||
logs.push(text)
|
logs.push(text)
|
||||||
|
|||||||
24
yarn.lock
24
yarn.lock
@@ -1500,13 +1500,20 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~7.16.0"
|
undici-types "~7.16.0"
|
||||||
|
|
||||||
"@types/node@>=13.7.0", "@types/node@^20.9.0":
|
"@types/node@>=13.7.0":
|
||||||
version "20.12.4"
|
version "20.12.4"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz"
|
resolved "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz"
|
||||||
integrity sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==
|
integrity sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types "~5.26.4"
|
undici-types "~5.26.4"
|
||||||
|
|
||||||
|
"@types/node@^22.7.7":
|
||||||
|
version "22.19.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.3.tgz#8dfde7630d7a8528dc9b34db23d34f764467c02c"
|
||||||
|
integrity sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==
|
||||||
|
dependencies:
|
||||||
|
undici-types "~6.21.0"
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.3":
|
"@types/normalize-package-data@^2.4.3":
|
||||||
version "2.4.4"
|
version "2.4.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901"
|
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901"
|
||||||
@@ -3112,13 +3119,13 @@ electron-updater@^4.6:
|
|||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
|
|
||||||
electron@29.2.0:
|
electron@39.2.7:
|
||||||
version "29.2.0"
|
version "39.2.7"
|
||||||
resolved "https://registry.npmjs.org/electron/-/electron-29.2.0.tgz"
|
resolved "https://registry.yarnpkg.com/electron/-/electron-39.2.7.tgz#1cf2371304994fe26c564764bd50878fe405fb4b"
|
||||||
integrity sha512-ALKrCN52RG4g9prx4DriXSPnY5WoiyRUCNp7zEVQuoiNOpHTNqMMpRidQAHzntV4hajF1LMWHVoBkwqIs1jHhg==
|
integrity sha512-KU0uFS6LSTh4aOIC3miolcbizOFP7N1M46VTYVfqIgFiuA2ilfNaOHLDS9tCMvwwHRowAsvqBrh9NgMXcTOHCQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@electron/get" "^2.0.0"
|
"@electron/get" "^2.0.0"
|
||||||
"@types/node" "^20.9.0"
|
"@types/node" "^22.7.7"
|
||||||
extract-zip "^2.0.1"
|
extract-zip "^2.0.1"
|
||||||
|
|
||||||
emoji-regex@^8.0.0:
|
emoji-regex@^8.0.0:
|
||||||
@@ -7995,6 +8002,11 @@ undici-types@~5.26.4:
|
|||||||
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
|
resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz"
|
||||||
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
|
||||||
|
|
||||||
|
undici-types@~6.21.0:
|
||||||
|
version "6.21.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb"
|
||||||
|
integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==
|
||||||
|
|
||||||
undici-types@~7.16.0:
|
undici-types@~7.16.0:
|
||||||
version "7.16.0"
|
version "7.16.0"
|
||||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
|
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
|
||||||
|
|||||||
Reference in New Issue
Block a user