-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: sync version download statuses between windows #1391
feat: sync version download statuses between windows #1391
Conversation
f9ddc9a
to
b7ef4c5
Compare
Looks like the Node.js version of BroadcastChannel and Jest don't get along on CircleCI (though it works fine on my machine), the tests seem to run but Jest hangs after they're finished (maybe it actually creates a worker thread that keeps running?) Anyway, I mocked it out and now it works. |
Mocking is the correct thing to do here, rather than trying to use |
I think the typings are cleaner if you use a discriminated union on the possible message types - removes the need to do a type cast. Also shouldn't be adding anything to diff --git a/src/ambient.d.ts b/src/ambient.d.ts
index 18c01d1f..a9315109 100644
--- a/src/ambient.d.ts
+++ b/src/ambient.d.ts
@@ -2,7 +2,6 @@ import { ReleaseInfo } from '@electron/fiddle-core';
import * as MonacoType from 'monaco-editor';
import {
- AppStateBroadcastMessage,
BisectRequest,
BlockableAccelerator,
EditorValues,
@@ -126,8 +125,4 @@ declare global {
themePath: string;
};
}
-
- interface AppStateBroadcastChannel extends BroadcastChannel {
- postMessage<T = unknown>(params: AppStateBroadcastMessage<T>): void;
- }
}
diff --git a/src/interfaces.ts b/src/interfaces.ts
index 6252c926..87933298 100644
--- a/src/interfaces.ts
+++ b/src/interfaces.ts
@@ -221,11 +221,17 @@ export enum WindowSpecificSetting {
export type WindowSpecificSettingKey = keyof typeof WindowSpecificSetting;
-export interface AppStateBroadcastMessage<T = unknown> {
- type: AppStateBroadcastMessageType;
- payload: T;
+export interface AppStateBroadcastChannel extends BroadcastChannel {
+ postMessage(params: AppStateBroadcastMessage): void;
}
+// Use a discriminated union of types (there's only one here at the moment) so
+// that the payload can easily be typed correctly for each message type
+export type AppStateBroadcastMessage = {
+ type: AppStateBroadcastMessageType.syncVersion;
+ payload: RunnableVersion;
+};
+
export enum AppStateBroadcastMessageType {
syncVersion = 'syncVersion',
}
diff --git a/src/renderer/state.ts b/src/renderer/state.ts
index a02bd1e5..0d1f95ca 100644
--- a/src/renderer/state.ts
+++ b/src/renderer/state.ts
@@ -16,6 +16,7 @@ import {
} from 'mobx';
import {
+ AppStateBroadcastChannel,
AppStateBroadcastMessage,
AppStateBroadcastMessageType,
BlockableAccelerator,
@@ -215,7 +216,7 @@ export class AppState {
// Notifies other windows that this version has changed so they can update their state to reflect that.
private updateVersionDownloadStatus(version: RunnableVersion) {
- this.broadcastChannel.postMessage<RunnableVersion>({
+ this.broadcastChannel.postMessage({
type: AppStateBroadcastMessageType.syncVersion,
payload: { ...version },
});
@@ -445,7 +446,7 @@ export class AppState {
switch (type) {
case AppStateBroadcastMessageType.syncVersion: {
- this.addNewVersions([payload as RunnableVersion]);
+ this.addNewVersions([payload]);
break;
} |
Done. To be extra thorough, we'd still need to type cast if we want the general case of multiple types to work with the current Typescript version — but since we only have one type right now, it's probably simpler to leave it as is and just add the type casts if we happen to add any other types before #1389 lands. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get some test coverage on this before we merge.
There's also a couple of corner cases we should think about more carefully:
- We should probably handle the case where one window updates the Electron versions (can happen manually under settings, or by loading a gist with a new version specified)
- Maybe we make the broadcast message more generic, make it
syncVersions
(plural) - takes an array - Make a private
AppState.addNewVersionsImpl
and move the existing code there - Then broadcast the message in
AppState.addNewVersions
with the full list of versions - the broadcast message listener would use the privateAppState.addNewVersionsImpl
to avoid triggering a new broadcast
- Maybe we make the broadcast message more generic, make it
- What happens to the UI if one window removes a version another window is using? Might need to make a separate issue for this, we should likely prevent removing a version which any window is using - although figuring out the best way to share that state might be tricky (may need to use the main process to coordinate that)
- I've opened Prevent Removing Other Window Current Versions #1394 with some more thoughts on this
74e216d
to
eaca76a
Compare
… `postMessage` method and move `AppStateBroadcastChannel` out of `ambient.d.ts`
…ate Electron Release List" button
eaca76a
to
5e5fa1a
Compare
Co-authored-by: David Sanders <[email protected]>
I extended test coverage to test the broadcasting side as well (not just the receiving) and also made |
Thanks for the test case, looks solid! |
@erikian, since #1404 landed, I've pushed c79fdf9 to also broadcast If c79fdf9 looks good to you we can go ahead and merge this. 👍 |
LGTM! |
This allows the download status and progress to be shared between windows:
2023-07-06_23-50-57.mp4
I also tried to make the BroadcastChannel logic extensible so we can use it to sync other data in the future.