chore(electron): upgrade from 24.2.0 to 41.3.0
Update Electron to 41.3.0 and adapt all affected layers:
Nix packaging:
- Rebuild electron headers derivation for 41.3.0
- Update patchelf/rpath/interpreter handling for new binary layout
- Expand runtime-nodejs-deps.json to include transitive closure (~445 packages)
- Add ELECTRON_SKIP_BINARY_DOWNLOAD=1 to prevent install script fetching
- Migrate nixpkgsJs compat shim to nixpkgs-25.11 nodejs_22; drop glibc-electron-loader.patch
JS dependencies (yarn.lock / package.json):
- @ledgerhq/hw-transport-node-hid 6.33.0, @trezor/connect 9.7.2
- @cardano-foundation/ledgerjs-hw-app-cardano 7.1.4
- @electron/rebuild 4.0.4, @swc/core 1.10.18, webpack 5.106.2
- node-hid 3.3.0, node-forge 1.4.0, moment 2.30.1, ws 8.18.2, axios 1.7.7
Renderer / MobX compatibility (SWC 1.10):
- Set legacyDecorator: true and useDefineForClassFields: false in swc-loader
options so MobX 5 prototype setters intercept observable class field
initialisation (SWC 1.3+ changed decorator defaults)
- Relax MobX enforceActions to 'observed' (was 'always'); 'always' blocked
constructor initialisation routed through setters outside any action
Main process / Electron 41 API fixes:
- safeExitWithCode: app.exit() → process.exit() — app.exit() triggers
Chromium teardown that causes SIGABRT when renderer is still alive
- CardanoNode._handleCardanoNodeExit: return early when state is STOPPING
or STOPPED so stop() exclusively owns the shutdown sequence; prevents a
double broadcastStateChange(STOPPED) IPC call that crashes Chromium
- mainErrorHandler: 'gpu-process-crashed' → 'child-process-gone' (Electron 23+)
- windows/main: 'crashed' → 'render-process-gone' (Electron 23+); remove
event parameter from 'closed' handler (listener takes no arguments)
- webpack.config (dev): exit webpack watcher when Electron closes cleanly
- package.json dev script: --kill-others --success first so concurrently
stops all processes when Electron exits
TypeScript fixes (updated @trezor/connect 9.x API):
- Define BridgeInfo/UdevInfo locally (removed from public exports)
- Add required appName field to Trezor manifest
- type: 'warning' as const for dialog MessageBoxOptions
- Cast devicePath to DeviceUniquePath branded type
- Make node-hid-incompatible Device fields optional in local types
- Remove non-existent onLearnMoreClick prop from StakingRewards story