From 7a54a89e809afb2db1aebbe44a4a6349ca248308 Mon Sep 17 00:00:00 2001 From: Iku-turso Date: Wed, 25 May 2022 15:07:17 +0300 Subject: [PATCH] Separate concept of message and request channels Co-authored-by: Janne Savolainen Signed-off-by: Iku-turso --- .../app-paths/app-paths-channel.injectable.ts | 8 +- ...cation-update-status-channel.injectable.ts | 8 +- .../ask-boolean-answer-channel.injectable.ts | 8 +- ...ask-boolean-question-channel.injectable.ts | 8 +- src/common/channel/channel-injection-token.ts | 4 - .../channel-listener-injection-token.ts | 17 -- src/common/channel/channel.test.ts | 34 ++-- ...enlist-channel-listener-injection-token.ts | 16 -- ...essage-channel-listener-injection-token.ts | 16 ++ ...equest-channel-listener-injection-token.ts | 16 ++ .../listening-of-channels.injectable.ts | 19 ++- .../message-channel-injection-token.ts | 15 ++ ...essage-channel-listener-injection-token.ts | 18 +++ .../message-to-channel-injection-token.ts | 22 +++ .../request-channel-injection-token.ts | 16 ++ ...equest-channel-listener-injection-token.ts | 17 ++ .../request-from-channel-injection-token.ts | 21 +++ .../send-to-channel-injection-token.ts | 16 -- .../app-navigation-channel.injectable.ts | 8 +- ...ter-frame-navigation-channel.injectable.ts | 8 +- .../root-frame-rendered-channel.injectable.ts | 8 +- .../sync-box/create-sync-box.injectable.ts | 6 +- .../sync-box-channel-listener.injectable.ts | 8 +- .../sync-box/sync-box-channel.injectable.ts | 8 +- ...nc-box-initial-value-channel.injectable.ts | 11 +- .../sync-box/sync-box-injection-token.ts | 3 +- ...ths-request-channel-listener.injectable.ts | 25 +++ .../get-electron-app-path.test.ts | 2 - .../register-channel.injectable.ts | 20 --- .../register-channel/register-channel.ts | 18 --- .../app-paths/setup-app-paths.injectable.ts | 6 - ...st-change-in-updating-status.injectable.ts | 6 +- ...lean-answer-channel-listener.injectable.ts | 9 +- .../ask-boolean/ask-boolean.injectable.ts | 6 +- .../enlist-channel-listener.injectable.ts | 37 ----- ...ist-message-channel-listener.injectable.ts | 31 ++++ ...ist-request-channel-listener.injectable.ts | 30 ++++ .../ipc-main/ipc-main.injectable.ts | 0 ...le.ts => message-to-channel.injectable.ts} | 17 +- src/main/getDiForUnitTesting.ts | 10 +- .../application-window.injectable.ts | 2 +- ...me-rendered-channel-listener.injectable.ts | 4 +- ...itial-value-channel-listener.injectable.ts | 4 +- .../app-paths/setup-app-paths.injectable.ts | 15 +- ...ation-update-status-listener.injectable.ts | 13 +- ...n-question-channel-listener.injectable.tsx | 17 +- ...st-message-channel-listener.injectable.ts} | 12 +- ...ist-request-channel-listener.injectable.ts | 19 +++ .../get-value-from-channel.injectable.ts | 22 --- .../channel/message-to-channel.injectable.ts | 26 ++++ .../request-from-channel.injectable.ts | 21 +++ .../channel/send-to-channel.injectable.ts | 23 --- .../channel/send-to-main.injectable.ts | 3 +- .../test-utils/get-application-builder.tsx | 16 +- ...-that-root-frame-is-rendered.injectable.ts | 6 +- src/renderer/getDiForUnitTesting.tsx | 7 +- .../navigation-channel-listener.injectable.ts | 6 +- ...nitial-values-for-sync-boxes.injectable.ts | 9 +- .../channel-fakes/override-channels.ts | 20 +++ .../override-messaging-from-main-to-window.ts | 90 +++++++++++ .../override-messaging-from-window-to-main.ts | 64 ++++++++ ...override-requesting-from-window-to-main.ts | 59 +++++++ src/test-utils/get-dis-for-unit-testing.ts | 23 --- src/test-utils/override-ipc-bridge.ts | 145 ------------------ 64 files changed, 685 insertions(+), 497 deletions(-) delete mode 100644 src/common/channel/channel-listener-injection-token.ts delete mode 100644 src/common/channel/enlist-channel-listener-injection-token.ts create mode 100644 src/common/channel/enlist-message-channel-listener-injection-token.ts create mode 100644 src/common/channel/enlist-request-channel-listener-injection-token.ts create mode 100644 src/common/channel/message-channel-injection-token.ts create mode 100644 src/common/channel/message-channel-listener-injection-token.ts create mode 100644 src/common/channel/message-to-channel-injection-token.ts create mode 100644 src/common/channel/request-channel-injection-token.ts create mode 100644 src/common/channel/request-channel-listener-injection-token.ts create mode 100644 src/common/channel/request-from-channel-injection-token.ts delete mode 100644 src/common/channel/send-to-channel-injection-token.ts create mode 100644 src/main/app-paths/app-paths-request-channel-listener.injectable.ts delete mode 100644 src/main/app-paths/register-channel/register-channel.injectable.ts delete mode 100644 src/main/app-paths/register-channel/register-channel.ts delete mode 100644 src/main/channel/channel-listeners/enlist-channel-listener.injectable.ts create mode 100644 src/main/channel/channel-listeners/enlist-message-channel-listener.injectable.ts create mode 100644 src/main/channel/channel-listeners/enlist-request-channel-listener.injectable.ts rename src/main/{app-paths/register-channel => channel}/ipc-main/ipc-main.injectable.ts (100%) rename src/main/channel/{send-to-channel.injectable.ts => message-to-channel.injectable.ts} (51%) rename src/renderer/channel/channel-listeners/{enlist-channel-listener.injectable.ts => enlist-message-channel-listener.injectable.ts} (61%) create mode 100644 src/renderer/channel/channel-listeners/enlist-request-channel-listener.injectable.ts delete mode 100644 src/renderer/channel/get-value-from-channel.injectable.ts create mode 100644 src/renderer/channel/message-to-channel.injectable.ts create mode 100644 src/renderer/channel/request-from-channel.injectable.ts delete mode 100644 src/renderer/channel/send-to-channel.injectable.ts create mode 100644 src/test-utils/channel-fakes/override-channels.ts create mode 100644 src/test-utils/channel-fakes/override-messaging-from-main-to-window.ts create mode 100644 src/test-utils/channel-fakes/override-messaging-from-window-to-main.ts create mode 100644 src/test-utils/channel-fakes/override-requesting-from-window-to-main.ts delete mode 100644 src/test-utils/get-dis-for-unit-testing.ts delete mode 100644 src/test-utils/override-ipc-bridge.ts diff --git a/src/common/app-paths/app-paths-channel.injectable.ts b/src/common/app-paths/app-paths-channel.injectable.ts index 4f1836d2bb..fd93ed14d8 100644 --- a/src/common/app-paths/app-paths-channel.injectable.ts +++ b/src/common/app-paths/app-paths-channel.injectable.ts @@ -3,11 +3,11 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; import type { AppPaths } from "./app-path-injection-token"; +import type { RequestChannel } from "../channel/request-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -export type AppPathsChannel = Channel; +export type AppPathsChannel = RequestChannel; const appPathsChannelInjectable = getInjectable({ id: "app-paths-channel", @@ -16,7 +16,7 @@ const appPathsChannelInjectable = getInjectable({ id: "app-paths", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default appPathsChannelInjectable; diff --git a/src/common/application-update/application-update-status-channel.injectable.ts b/src/common/application-update/application-update-status-channel.injectable.ts index 1f68ab12ae..127f0cec2f 100644 --- a/src/common/application-update/application-update-status-channel.injectable.ts +++ b/src/common/application-update/application-update-status-channel.injectable.ts @@ -3,8 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; export type ApplicationUpdateStatusEventId = | "checking-for-updates" @@ -13,7 +13,7 @@ export type ApplicationUpdateStatusEventId = | "download-for-update-failed"; export interface ApplicationUpdateStatusChannelMessage { eventId: ApplicationUpdateStatusEventId; version?: string } -export type ApplicationUpdateStatusChannel = Channel; +export type ApplicationUpdateStatusChannel = MessageChannel; const applicationUpdateStatusChannelInjectable = getInjectable({ id: "application-update-status-channel", @@ -22,7 +22,7 @@ const applicationUpdateStatusChannelInjectable = getInjectable({ id: "application-update-status-channel", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default applicationUpdateStatusChannelInjectable; diff --git a/src/common/ask-boolean/ask-boolean-answer-channel.injectable.ts b/src/common/ask-boolean/ask-boolean-answer-channel.injectable.ts index abdaa31a53..94f2277b5c 100644 --- a/src/common/ask-boolean/ask-boolean-answer-channel.injectable.ts +++ b/src/common/ask-boolean/ask-boolean-answer-channel.injectable.ts @@ -3,10 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -type AskBooleanAnswerChannel = Channel<{ id: string; value: boolean }>; +export type AskBooleanAnswerChannel = MessageChannel<{ id: string; value: boolean }>; const askBooleanAnswerChannelInjectable = getInjectable({ id: "ask-boolean-answer-channel", @@ -15,7 +15,7 @@ const askBooleanAnswerChannelInjectable = getInjectable({ id: "ask-boolean-answer", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default askBooleanAnswerChannelInjectable; diff --git a/src/common/ask-boolean/ask-boolean-question-channel.injectable.ts b/src/common/ask-boolean/ask-boolean-question-channel.injectable.ts index 10cdf4511e..8ac603b2d2 100644 --- a/src/common/ask-boolean/ask-boolean-question-channel.injectable.ts +++ b/src/common/ask-boolean/ask-boolean-question-channel.injectable.ts @@ -3,11 +3,11 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; export interface AskBooleanQuestionParameters { id: string; title: string; question: string } -export type AskBooleanQuestionChannel = Channel; +export type AskBooleanQuestionChannel = MessageChannel; const askBooleanQuestionChannelInjectable = getInjectable({ id: "ask-boolean-question-channel", @@ -16,7 +16,7 @@ const askBooleanQuestionChannelInjectable = getInjectable({ id: "ask-boolean-question", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default askBooleanQuestionChannelInjectable; diff --git a/src/common/channel/channel-injection-token.ts b/src/common/channel/channel-injection-token.ts index be62efef4f..6006290f89 100644 --- a/src/common/channel/channel-injection-token.ts +++ b/src/common/channel/channel-injection-token.ts @@ -3,7 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getInjectionToken } from "@ogre-tools/injectable"; export interface Channel { id: string; @@ -11,6 +10,3 @@ export interface Channel { _returnTemplate?: ReturnTemplate; } -export const channelInjectionToken = getInjectionToken>({ - id: "channel", -}); diff --git a/src/common/channel/channel-listener-injection-token.ts b/src/common/channel/channel-listener-injection-token.ts deleted file mode 100644 index b148ab0317..0000000000 --- a/src/common/channel/channel-listener-injection-token.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectionToken } from "@ogre-tools/injectable"; -import type { Channel } from "./channel-injection-token"; - -export interface ChannelListener> { - channel: TChannel; - handler: (value: TChannel["_messageTemplate"]) => TChannel["_returnTemplate"]; -} - -export const channelListenerInjectionToken = getInjectionToken>>( - { - id: "channel-listener", - }, -); diff --git a/src/common/channel/channel.test.ts b/src/common/channel/channel.test.ts index b64eb4349a..d0dbce2b6b 100644 --- a/src/common/channel/channel.test.ts +++ b/src/common/channel/channel.test.ts @@ -6,22 +6,22 @@ import type { DiContainer } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable"; import type { LensWindow } from "../../main/start-main-application/lens-window/application-window/lens-window-injection-token"; import { lensWindowInjectionToken } from "../../main/start-main-application/lens-window/application-window/lens-window-injection-token"; -import type { SendToChannel } from "./send-to-channel-injection-token"; -import { sendToChannelInjectionToken } from "./send-to-channel-injection-token"; +import type { MessageToChannel } from "./message-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "./message-to-channel-injection-token"; import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder"; -import { channelListenerInjectionToken } from "./channel-listener-injection-token"; import createLensWindowInjectable from "../../main/start-main-application/lens-window/application-window/create-lens-window.injectable"; -import type { Channel } from "./channel-injection-token"; import closeAllWindowsInjectable from "../../main/start-main-application/lens-window/hide-all-windows/close-all-windows.injectable"; +import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token"; +import type { MessageChannel } from "./message-channel-injection-token"; -type TestChannel = Channel; +type TestChannel = MessageChannel; describe("channel", () => { describe("messaging from main to renderer, given listener for channel in a window and application has started", () => { let testChannel: TestChannel; let testListenerInWindowMock: jest.Mock; let mainDi: DiContainer; - let sendToChannel: SendToChannel; + let messageToChannel: MessageToChannel; beforeEach(async () => { const applicationBuilder = getApplicationBuilder(); @@ -40,7 +40,7 @@ describe("channel", () => { handler: testListenerInWindowMock, }), - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); rendererDi.register(testChannelListenerInTestWindowInjectable); @@ -51,8 +51,8 @@ describe("channel", () => { testChannel = mainDi.inject(testChannelInjectable); - sendToChannel = mainDi.inject( - sendToChannelInjectionToken, + messageToChannel = mainDi.inject( + messageToChannelInjectionToken, ); await applicationBuilder.render(); @@ -72,7 +72,7 @@ describe("channel", () => { }); it("when sending message, triggers listener in window", () => { - sendToChannel(testChannel, "some-message"); + messageToChannel(testChannel, "some-message"); expect(testListenerInWindowMock).toHaveBeenCalledWith("some-message"); }); @@ -80,7 +80,7 @@ describe("channel", () => { it("given window is hidden, when sending message, does not trigger listener in window", () => { someWindowFake.close(); - sendToChannel(testChannel, "some-message"); + messageToChannel(testChannel, "some-message"); expect(testListenerInWindowMock).not.toHaveBeenCalled(); }); @@ -93,7 +93,7 @@ describe("channel", () => { await someWindowFake.show(); await someOtherWindowFake.show(); - sendToChannel(testChannel, "some-message"); + messageToChannel(testChannel, "some-message"); expect(testListenerInWindowMock.mock.calls).toEqual([ ["some-message"], @@ -107,7 +107,7 @@ describe("channel", () => { let testListenerInMainMock: jest.Mock; let rendererDi: DiContainer; let mainDi: DiContainer; - let sendToChannel: SendToChannel; + let messageToChannel: MessageToChannel; beforeEach(async () => { const applicationBuilder = getApplicationBuilder(); @@ -126,7 +126,7 @@ describe("channel", () => { handler: testListenerInMainMock, }), - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); mainDi.register(testChannelListenerInMainInjectable); @@ -137,15 +137,15 @@ describe("channel", () => { testChannel = rendererDi.inject(testChannelInjectable); - sendToChannel = rendererDi.inject( - sendToChannelInjectionToken, + messageToChannel = rendererDi.inject( + messageToChannelInjectionToken, ); await applicationBuilder.render(); }); it("when sending message, triggers listener in main", () => { - sendToChannel(testChannel, "some-message"); + messageToChannel(testChannel, "some-message"); expect(testListenerInMainMock).toHaveBeenCalledWith("some-message"); }); diff --git a/src/common/channel/enlist-channel-listener-injection-token.ts b/src/common/channel/enlist-channel-listener-injection-token.ts deleted file mode 100644 index b4728fb20d..0000000000 --- a/src/common/channel/enlist-channel-listener-injection-token.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectionToken } from "@ogre-tools/injectable"; -import type { Channel } from "./channel-injection-token"; - -export type EnlistChannelListener = >( - channel: TChannel, - handler: (value: TChannel["_messageTemplate"]) => TChannel["_returnTemplate"] -) => () => void; - -export const enlistChannelListenerInjectionToken = - getInjectionToken({ - id: "enlist-channel-listener", - }); diff --git a/src/common/channel/enlist-message-channel-listener-injection-token.ts b/src/common/channel/enlist-message-channel-listener-injection-token.ts new file mode 100644 index 0000000000..e75a50468d --- /dev/null +++ b/src/common/channel/enlist-message-channel-listener-injection-token.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { MessageChannel } from "./message-channel-injection-token"; +import type { MessageChannelListener } from "./message-channel-listener-injection-token"; + +export type EnlistMessageChannelListener = < + TChannel extends MessageChannel, +>(listener: MessageChannelListener) => () => void; + +export const enlistMessageChannelListenerInjectionToken = + getInjectionToken({ + id: "enlist-message-channel-listener", + }); diff --git a/src/common/channel/enlist-request-channel-listener-injection-token.ts b/src/common/channel/enlist-request-channel-listener-injection-token.ts new file mode 100644 index 0000000000..ccab218bd2 --- /dev/null +++ b/src/common/channel/enlist-request-channel-listener-injection-token.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { RequestChannel } from "./request-channel-injection-token"; +import type { RequestChannelListener } from "./request-channel-listener-injection-token"; + +export type EnlistRequestChannelListener = < + TChannel extends RequestChannel, +>(listener: RequestChannelListener) => () => void; + +export const enlistRequestChannelListenerInjectionToken = + getInjectionToken({ + id: "enlist-request-channel-listener", + }); diff --git a/src/common/channel/listening-of-channels.injectable.ts b/src/common/channel/listening-of-channels.injectable.ts index de4af36171..0a48772945 100644 --- a/src/common/channel/listening-of-channels.injectable.ts +++ b/src/common/channel/listening-of-channels.injectable.ts @@ -4,23 +4,26 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { getStartableStoppable } from "../utils/get-startable-stoppable"; -import { channelListenerInjectionToken } from "./channel-listener-injection-token"; -import { enlistChannelListenerInjectionToken } from "./enlist-channel-listener-injection-token"; import { disposer } from "../utils"; +import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token"; +import { requestChannelListenerInjectionToken } from "./request-channel-listener-injection-token"; +import { enlistMessageChannelListenerInjectionToken } from "./enlist-message-channel-listener-injection-token"; +import { enlistRequestChannelListenerInjectionToken } from "./enlist-request-channel-listener-injection-token"; const listeningOfChannelsInjectable = getInjectable({ id: "listening-of-channels", instantiate: (di) => { - const enlistChannelListener = di.inject(enlistChannelListenerInjectionToken); - const channelListeners = di.injectMany(channelListenerInjectionToken); + const enlistMessageChannelListener = di.inject(enlistMessageChannelListenerInjectionToken); + const enlistRequestChannelListener = di.inject(enlistRequestChannelListenerInjectionToken); + const messageChannelListeners = di.injectMany(messageChannelListenerInjectionToken); + const requestChannelListeners = di.injectMany(requestChannelListenerInjectionToken); return getStartableStoppable("listening-of-channels", () => { - const disposers = channelListeners.map(({ channel, handler }) => - enlistChannelListener(channel, handler), - ); + const messageChannelDisposers = messageChannelListeners.map(enlistMessageChannelListener); + const requestChannelDisposers = requestChannelListeners.map(enlistRequestChannelListener); - return disposer(...disposers); + return disposer(...messageChannelDisposers, ...requestChannelDisposers); }); }, }); diff --git a/src/common/channel/message-channel-injection-token.ts b/src/common/channel/message-channel-injection-token.ts new file mode 100644 index 0000000000..e7502c6e34 --- /dev/null +++ b/src/common/channel/message-channel-injection-token.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; + +export interface MessageChannel { + id: string; + _messageSignature?: Message; +} + +export const messageChannelInjectionToken = getInjectionToken>({ + id: "message-channel", +}); diff --git a/src/common/channel/message-channel-listener-injection-token.ts b/src/common/channel/message-channel-listener-injection-token.ts new file mode 100644 index 0000000000..8879e19013 --- /dev/null +++ b/src/common/channel/message-channel-listener-injection-token.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { SetRequired } from "type-fest"; +import type { MessageChannel } from "./message-channel-injection-token"; + +export interface MessageChannelListener> { + channel: TChannel; + handler: (value: SetRequired["_messageSignature"]) => void; +} + +export const messageChannelListenerInjectionToken = getInjectionToken>>( + { + id: "message-channel-listener", + }, +); diff --git a/src/common/channel/message-to-channel-injection-token.ts b/src/common/channel/message-to-channel-injection-token.ts new file mode 100644 index 0000000000..d70be48e5e --- /dev/null +++ b/src/common/channel/message-to-channel-injection-token.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { MessageChannel } from "./message-channel-injection-token"; + +export interface MessageToChannel { + , TMessage extends void>( + channel: TChannel, + ): void; + + , TMessage>( + channel: TChannel, + message: TMessage + ): void; +} + +export const messageToChannelInjectionToken = + getInjectionToken({ + id: "message-to-message-channel", + }); diff --git a/src/common/channel/request-channel-injection-token.ts b/src/common/channel/request-channel-injection-token.ts new file mode 100644 index 0000000000..4cb290cc63 --- /dev/null +++ b/src/common/channel/request-channel-injection-token.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import { getInjectionToken } from "@ogre-tools/injectable"; + +export interface RequestChannel { + id: string; + _requestSignature?: Request; + _responseSignature?: Response; +} + +export const requestChannelInjectionToken = getInjectionToken>({ + id: "request-channel", +}); diff --git a/src/common/channel/request-channel-listener-injection-token.ts b/src/common/channel/request-channel-listener-injection-token.ts new file mode 100644 index 0000000000..0455bc2ec2 --- /dev/null +++ b/src/common/channel/request-channel-listener-injection-token.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { RequestChannel } from "./request-channel-injection-token"; + +export interface RequestChannelListener> { + channel: TChannel; + handler: (request: TChannel["_requestSignature"]) => TChannel["_responseSignature"]; +} + +export const requestChannelListenerInjectionToken = getInjectionToken>>( + { + id: "request-channel-listener", + }, +); diff --git a/src/common/channel/request-from-channel-injection-token.ts b/src/common/channel/request-from-channel-injection-token.ts new file mode 100644 index 0000000000..c56ee236c6 --- /dev/null +++ b/src/common/channel/request-from-channel-injection-token.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { SetRequired } from "type-fest"; +import type { RequestChannel } from "./request-channel-injection-token"; + +export type RequestFromChannel = < + TChannel extends RequestChannel, +>( + channel: TChannel, + ...request: TChannel["_requestSignature"] extends void + ? [] + : [TChannel["_requestSignature"]] +) => Promise["_responseSignature"]>; + +export const requestFromChannelInjectionToken = + getInjectionToken({ + id: "request-from-request-channel", + }); diff --git a/src/common/channel/send-to-channel-injection-token.ts b/src/common/channel/send-to-channel-injection-token.ts deleted file mode 100644 index 33c9c38d73..0000000000 --- a/src/common/channel/send-to-channel-injection-token.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectionToken } from "@ogre-tools/injectable"; -import type { Channel } from "./channel-injection-token"; - -export type SendToChannel = >( - channel: TChannel, - message?: TChannel["_messageTemplate"] -) => void; - -export const sendToChannelInjectionToken = - getInjectionToken({ - id: "send-to-channel", - }); diff --git a/src/common/front-end-routing/app-navigation-channel.injectable.ts b/src/common/front-end-routing/app-navigation-channel.injectable.ts index 7a0d9436cd..8dce3c6c0a 100644 --- a/src/common/front-end-routing/app-navigation-channel.injectable.ts +++ b/src/common/front-end-routing/app-navigation-channel.injectable.ts @@ -3,11 +3,11 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; import { IpcRendererNavigationEvents } from "../../renderer/navigation/events"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -export type AppNavigationChannel = Channel; +export type AppNavigationChannel = MessageChannel; const appNavigationChannelInjectable = getInjectable({ id: "app-navigation-channel", @@ -16,7 +16,7 @@ const appNavigationChannelInjectable = getInjectable({ id: IpcRendererNavigationEvents.NAVIGATE_IN_APP, }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default appNavigationChannelInjectable; diff --git a/src/common/front-end-routing/cluster-frame-navigation-channel.injectable.ts b/src/common/front-end-routing/cluster-frame-navigation-channel.injectable.ts index fa72cf2372..8e40d778c3 100644 --- a/src/common/front-end-routing/cluster-frame-navigation-channel.injectable.ts +++ b/src/common/front-end-routing/cluster-frame-navigation-channel.injectable.ts @@ -3,11 +3,11 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; import { IpcRendererNavigationEvents } from "../../renderer/navigation/events"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -export type ClusterFrameNavigationChannel = Channel; +export type ClusterFrameNavigationChannel = MessageChannel; const clusterFrameNavigationChannelInjectable = getInjectable({ id: "cluster-frame-navigation-channel", @@ -16,7 +16,7 @@ const clusterFrameNavigationChannelInjectable = getInjectable({ id: IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER, }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default clusterFrameNavigationChannelInjectable; diff --git a/src/common/root-frame-rendered-channel/root-frame-rendered-channel.injectable.ts b/src/common/root-frame-rendered-channel/root-frame-rendered-channel.injectable.ts index dc7471ed23..95ddf8fc60 100644 --- a/src/common/root-frame-rendered-channel/root-frame-rendered-channel.injectable.ts +++ b/src/common/root-frame-rendered-channel/root-frame-rendered-channel.injectable.ts @@ -3,10 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -export type RootFrameRenderedChannel = Channel; +export type RootFrameRenderedChannel = MessageChannel; const rootFrameRenderedChannelInjectable = getInjectable({ id: "root-frame-rendered-channel", @@ -15,7 +15,7 @@ const rootFrameRenderedChannelInjectable = getInjectable({ id: "root-frame-rendered", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default rootFrameRenderedChannelInjectable; diff --git a/src/common/sync-box/create-sync-box.injectable.ts b/src/common/sync-box/create-sync-box.injectable.ts index 5ac9c8dd04..2cf3de6a69 100644 --- a/src/common/sync-box/create-sync-box.injectable.ts +++ b/src/common/sync-box/create-sync-box.injectable.ts @@ -5,7 +5,7 @@ import { getInjectable } from "@ogre-tools/injectable"; import { computed } from "mobx"; import syncBoxChannelInjectable from "./sync-box-channel.injectable"; -import { sendToChannelInjectionToken } from "../channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../channel/message-to-channel-injection-token"; import syncBoxStateInjectable from "./sync-box-state.injectable"; import type { SyncBox } from "./sync-box-injection-token"; @@ -14,7 +14,7 @@ const createSyncBoxInjectable = getInjectable({ instantiate: (di) => { const syncBoxChannel = di.inject(syncBoxChannelInjectable); - const sendToChannel = di.inject(sendToChannelInjectionToken); + const messageToChannel = di.inject(messageToChannelInjectionToken); const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id); return (id: string, initialValue: TData): SyncBox => { @@ -30,7 +30,7 @@ const createSyncBoxInjectable = getInjectable({ set: (value) => { state.set(value); - sendToChannel(syncBoxChannel, { id, value }); + messageToChannel(syncBoxChannel, { id, value }); }, }; }; diff --git a/src/common/sync-box/sync-box-channel-listener.injectable.ts b/src/common/sync-box/sync-box-channel-listener.injectable.ts index 9310718185..b603c85997 100644 --- a/src/common/sync-box/sync-box-channel-listener.injectable.ts +++ b/src/common/sync-box/sync-box-channel-listener.injectable.ts @@ -3,14 +3,16 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; +import type { SyncBoxChannel } from "./sync-box-channel.injectable"; import syncBoxChannelInjectable from "./sync-box-channel.injectable"; -import { channelListenerInjectionToken } from "../channel/channel-listener-injection-token"; import syncBoxStateInjectable from "./sync-box-state.injectable"; +import type { MessageChannelListener } from "../channel/message-channel-listener-injection-token"; +import { messageChannelListenerInjectionToken } from "../channel/message-channel-listener-injection-token"; const syncBoxChannelListenerInjectable = getInjectable({ id: "sync-box-channel-listener", - instantiate: (di) => { + instantiate: (di): MessageChannelListener => { const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id); const channel = di.inject(syncBoxChannelInjectable); @@ -27,7 +29,7 @@ const syncBoxChannelListenerInjectable = getInjectable({ }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default syncBoxChannelListenerInjectable; diff --git a/src/common/sync-box/sync-box-channel.injectable.ts b/src/common/sync-box/sync-box-channel.injectable.ts index 7b9262f607..9389a99867 100644 --- a/src/common/sync-box/sync-box-channel.injectable.ts +++ b/src/common/sync-box/sync-box-channel.injectable.ts @@ -3,10 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { MessageChannel } from "../channel/message-channel-injection-token"; +import { messageChannelInjectionToken } from "../channel/message-channel-injection-token"; -export type SyncBoxChannel = Channel<{ id: string; value: unknown }>; +export type SyncBoxChannel = MessageChannel<{ id: string; value: any }>; const syncBoxChannelInjectable = getInjectable({ id: "sync-box-channel", @@ -15,7 +15,7 @@ const syncBoxChannelInjectable = getInjectable({ id: "sync-box-channel", }), - injectionToken: channelInjectionToken, + injectionToken: messageChannelInjectionToken, }); export default syncBoxChannelInjectable; diff --git a/src/common/sync-box/sync-box-initial-value-channel.injectable.ts b/src/common/sync-box/sync-box-initial-value-channel.injectable.ts index f3b1b4f1f2..6fe0534323 100644 --- a/src/common/sync-box/sync-box-initial-value-channel.injectable.ts +++ b/src/common/sync-box/sync-box-initial-value-channel.injectable.ts @@ -3,10 +3,13 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { Channel } from "../channel/channel-injection-token"; -import { channelInjectionToken } from "../channel/channel-injection-token"; +import type { RequestChannel } from "../channel/request-channel-injection-token"; +import { requestChannelInjectionToken } from "../channel/request-channel-injection-token"; -export type SyncBoxInitialValueChannel = Channel; +export type SyncBoxInitialValueChannel = RequestChannel< + void, + { id: string; value: unknown }[] +>; const syncBoxInitialValueChannelInjectable = getInjectable({ id: "sync-box-initial-value-channel", @@ -15,7 +18,7 @@ const syncBoxInitialValueChannelInjectable = getInjectable({ id: "sync-box-initial-value-channel", }), - injectionToken: channelInjectionToken, + injectionToken: requestChannelInjectionToken, }); export default syncBoxInitialValueChannelInjectable; diff --git a/src/common/sync-box/sync-box-injection-token.ts b/src/common/sync-box/sync-box-injection-token.ts index 980b917d3d..d35c7d5367 100644 --- a/src/common/sync-box/sync-box-injection-token.ts +++ b/src/common/sync-box/sync-box-injection-token.ts @@ -4,8 +4,9 @@ */ import { getInjectionToken } from "@ogre-tools/injectable"; import type { IComputedValue } from "mobx"; +import type { JsonValue } from "type-fest"; -export interface SyncBox { +export interface SyncBox { id: string; value: IComputedValue; set: (value: TValue) => void; diff --git a/src/main/app-paths/app-paths-request-channel-listener.injectable.ts b/src/main/app-paths/app-paths-request-channel-listener.injectable.ts new file mode 100644 index 0000000000..9cf12f5e65 --- /dev/null +++ b/src/main/app-paths/app-paths-request-channel-listener.injectable.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { requestChannelListenerInjectionToken } from "../../common/channel/request-channel-listener-injection-token"; +import appPathsChannelInjectable from "../../common/app-paths/app-paths-channel.injectable"; +import appPathsInjectable from "../../common/app-paths/app-paths.injectable"; + +const appPathsRequestChannelListenerInjectable = getInjectable({ + id: "app-paths-request-channel-listener", + + instantiate: (di) => { + const channel = di.inject(appPathsChannelInjectable); + const appPaths = di.inject(appPathsInjectable); + + return ({ + channel, + handler: () => appPaths, + }); + }, + injectionToken: requestChannelListenerInjectionToken, +}); + +export default appPathsRequestChannelListenerInjectable; diff --git a/src/main/app-paths/get-electron-app-path/get-electron-app-path.test.ts b/src/main/app-paths/get-electron-app-path/get-electron-app-path.test.ts index 6cb937f45d..8e28c806d7 100644 --- a/src/main/app-paths/get-electron-app-path/get-electron-app-path.test.ts +++ b/src/main/app-paths/get-electron-app-path/get-electron-app-path.test.ts @@ -6,7 +6,6 @@ import electronAppInjectable from "../../electron-app/electron-app.injectable"; import getElectronAppPathInjectable from "./get-electron-app-path.injectable"; import { getDiForUnitTesting } from "../../getDiForUnitTesting"; import type { App } from "electron"; -import registerChannelInjectable from "../register-channel/register-channel.injectable"; import joinPathsInjectable from "../../../common/path/join-paths.injectable"; import { joinPathsFake } from "../../../common/test-utils/join-paths-fake"; @@ -32,7 +31,6 @@ describe("get-electron-app-path", () => { } as App; di.override(electronAppInjectable, () => appStub); - di.override(registerChannelInjectable, () => () => undefined); di.override(joinPathsInjectable, () => joinPathsFake); getElectronAppPath = di.inject(getElectronAppPathInjectable) as (name: string) => string; diff --git a/src/main/app-paths/register-channel/register-channel.injectable.ts b/src/main/app-paths/register-channel/register-channel.injectable.ts deleted file mode 100644 index 379fb15975..0000000000 --- a/src/main/app-paths/register-channel/register-channel.injectable.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import ipcMainInjectable from "./ipc-main/ipc-main.injectable"; -import { registerChannel } from "./register-channel"; - -/** - * @deprecated Switch to using channelListenerInjectionToken - */ -const registerChannelInjectable = getInjectable({ - id: "register-channel", - - instantiate: (di) => registerChannel({ - ipcMain: di.inject(ipcMainInjectable), - }), -}); - -export default registerChannelInjectable; diff --git a/src/main/app-paths/register-channel/register-channel.ts b/src/main/app-paths/register-channel/register-channel.ts deleted file mode 100644 index ac3dfcb509..0000000000 --- a/src/main/app-paths/register-channel/register-channel.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import type { IpcMain } from "electron"; -import type { Channel } from "../../../common/channel/channel-injection-token"; - -interface Dependencies { - ipcMain: IpcMain; -} - -export const registerChannel = - ({ ipcMain }: Dependencies) => - >( - channel: TChannel, - getValue: () => TChannel["_messageTemplate"], - ) => - ipcMain.handle(channel.id, getValue); diff --git a/src/main/app-paths/setup-app-paths.injectable.ts b/src/main/app-paths/setup-app-paths.injectable.ts index 910aa29477..816c58db8b 100644 --- a/src/main/app-paths/setup-app-paths.injectable.ts +++ b/src/main/app-paths/setup-app-paths.injectable.ts @@ -12,10 +12,8 @@ import appPathsStateInjectable from "../../common/app-paths/app-paths-state.inje import { pathNames } from "../../common/app-paths/app-path-names"; import { fromPairs, map } from "lodash/fp"; import { pipeline } from "@ogre-tools/fp"; -import registerChannelInjectable from "./register-channel/register-channel.injectable"; import joinPathsInjectable from "../../common/path/join-paths.injectable"; import { beforeElectronIsReadyInjectionToken } from "../start-main-application/runnable-tokens/before-electron-is-ready-injection-token"; -import appPathsChannelInjectable from "../../common/app-paths/app-paths-channel.injectable"; const setupAppPathsInjectable = getInjectable({ id: "setup-app-paths", @@ -25,8 +23,6 @@ const setupAppPathsInjectable = getInjectable({ const appName = di.inject(appNameInjectable); const getAppPath = di.inject(getElectronAppPathInjectable); const appPathsState = di.inject(appPathsStateInjectable); - const registerChannel = di.inject(registerChannelInjectable); - const appPathsChannel = di.inject(appPathsChannelInjectable); const directoryForIntegrationTesting = di.inject(directoryForIntegrationTestingInjectable); const joinPaths = di.inject(joinPathsInjectable); @@ -47,8 +43,6 @@ const setupAppPathsInjectable = getInjectable({ ) as AppPaths; appPathsState.set(appPaths); - - registerChannel(appPathsChannel, () => appPaths); }, }; }, diff --git a/src/main/application-update/check-for-updates/broadcast-change-in-updating-status.injectable.ts b/src/main/application-update/check-for-updates/broadcast-change-in-updating-status.injectable.ts index 9d5566b83d..d74fde169e 100644 --- a/src/main/application-update/check-for-updates/broadcast-change-in-updating-status.injectable.ts +++ b/src/main/application-update/check-for-updates/broadcast-change-in-updating-status.injectable.ts @@ -4,18 +4,18 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import type { ApplicationUpdateStatusChannelMessage } from "../../../common/application-update/application-update-status-channel.injectable"; -import { sendToChannelInjectionToken } from "../../../common/channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../../../common/channel/message-to-channel-injection-token"; import applicationUpdateStatusChannelInjectable from "../../../common/application-update/application-update-status-channel.injectable"; const broadcastChangeInUpdatingStatusInjectable = getInjectable({ id: "broadcast-change-in-updating-status", instantiate: (di) => { - const sendToChannel = di.inject(sendToChannelInjectionToken); + const messageToChannel = di.inject(messageToChannelInjectionToken); const applicationUpdateStatusChannel = di.inject(applicationUpdateStatusChannelInjectable); return (data: ApplicationUpdateStatusChannelMessage) => { - sendToChannel(applicationUpdateStatusChannel, data); + messageToChannel(applicationUpdateStatusChannel, data); }; }, }); diff --git a/src/main/ask-boolean/ask-boolean-answer-channel-listener.injectable.ts b/src/main/ask-boolean/ask-boolean-answer-channel-listener.injectable.ts index c8f9f32871..99f04f2f08 100644 --- a/src/main/ask-boolean/ask-boolean-answer-channel-listener.injectable.ts +++ b/src/main/ask-boolean/ask-boolean-answer-channel-listener.injectable.ts @@ -3,14 +3,17 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token"; +import type { AskBooleanAnswerChannel } from "../../common/ask-boolean/ask-boolean-answer-channel.injectable"; import askBooleanAnswerChannelInjectable from "../../common/ask-boolean/ask-boolean-answer-channel.injectable"; import askBooleanPromiseInjectable from "./ask-boolean-promise.injectable"; +import type { MessageChannelListener } from "../../common/channel/message-channel-listener-injection-token"; +import { messageChannelListenerInjectionToken } from "../../common/channel/message-channel-listener-injection-token"; + const askBooleanAnswerChannelListenerInjectable = getInjectable({ id: "ask-boolean-answer-channel-listener", - instantiate: (di) => ({ + instantiate: (di): MessageChannelListener => ({ channel: di.inject(askBooleanAnswerChannelInjectable), handler: ({ id, value }) => { @@ -20,7 +23,7 @@ const askBooleanAnswerChannelListenerInjectable = getInjectable({ }, }), - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default askBooleanAnswerChannelListenerInjectable; diff --git a/src/main/ask-boolean/ask-boolean.injectable.ts b/src/main/ask-boolean/ask-boolean.injectable.ts index 5d39b63a10..8bdef37342 100644 --- a/src/main/ask-boolean/ask-boolean.injectable.ts +++ b/src/main/ask-boolean/ask-boolean.injectable.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { sendToChannelInjectionToken } from "../../common/channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../../common/channel/message-to-channel-injection-token"; import askBooleanQuestionChannelInjectable from "../../common/ask-boolean/ask-boolean-question-channel.injectable"; import askBooleanPromiseInjectable from "./ask-boolean-promise.injectable"; import getRandomIdInjectable from "../../common/utils/get-random-id.injectable"; @@ -20,7 +20,7 @@ const askBooleanInjectable = getInjectable({ id: "ask-boolean", instantiate: (di): AskBoolean => { - const sendToChannel = di.inject(sendToChannelInjectionToken); + const messageToChannel = di.inject(messageToChannelInjectionToken); const askBooleanChannel = di.inject(askBooleanQuestionChannelInjectable); const getRandomId = di.inject(getRandomIdInjectable); @@ -29,7 +29,7 @@ const askBooleanInjectable = getInjectable({ const returnValuePromise = di.inject(askBooleanPromiseInjectable, id); - await sendToChannel(askBooleanChannel, { id, title, question }); + await messageToChannel(askBooleanChannel, { id, title, question }); return await returnValuePromise.promise; }; diff --git a/src/main/channel/channel-listeners/enlist-channel-listener.injectable.ts b/src/main/channel/channel-listeners/enlist-channel-listener.injectable.ts deleted file mode 100644 index 5f2c8d79ff..0000000000 --- a/src/main/channel/channel-listeners/enlist-channel-listener.injectable.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import type { IpcMainEvent, IpcMainInvokeEvent } from "electron"; -import ipcMainInjectable from "../../app-paths/register-channel/ipc-main/ipc-main.injectable"; -import { enlistChannelListenerInjectionToken } from "../../../common/channel/enlist-channel-listener-injection-token"; - -const enlistChannelListenerInjectable = getInjectable({ - id: "enlist-channel-listener-for-main", - - instantiate: (di) => { - const ipcMain = di.inject(ipcMainInjectable); - - return (channel, handler) => { - const nativeOnCallback = (_: IpcMainEvent, message: unknown) => - handler(message); - - ipcMain.on(channel.id, nativeOnCallback); - - const nativeHandleCallback = (_: IpcMainInvokeEvent, message: unknown) => - handler(message); - - ipcMain.handle(channel.id, nativeHandleCallback); - - return () => { - ipcMain.off(channel.id, nativeOnCallback); - ipcMain.off(channel.id, nativeHandleCallback); - }; - }; - }, - - injectionToken: enlistChannelListenerInjectionToken, -}); - -export default enlistChannelListenerInjectable; diff --git a/src/main/channel/channel-listeners/enlist-message-channel-listener.injectable.ts b/src/main/channel/channel-listeners/enlist-message-channel-listener.injectable.ts new file mode 100644 index 0000000000..37db20de3f --- /dev/null +++ b/src/main/channel/channel-listeners/enlist-message-channel-listener.injectable.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import type { IpcMainEvent } from "electron"; +import ipcMainInjectable from "../ipc-main/ipc-main.injectable"; +import { enlistMessageChannelListenerInjectionToken } from "../../../common/channel/enlist-message-channel-listener-injection-token"; + +const enlistMessageChannelListenerInjectable = getInjectable({ + id: "enlist-message-channel-listener-for-main", + + instantiate: (di) => { + const ipcMain = di.inject(ipcMainInjectable); + + return ({ channel, handler }) => { + const nativeOnCallback = (_: IpcMainEvent, message: unknown) => + handler(message); + + ipcMain.on(channel.id, nativeOnCallback); + + return () => { + ipcMain.off(channel.id, nativeOnCallback); + }; + }; + }, + + injectionToken: enlistMessageChannelListenerInjectionToken, +}); + +export default enlistMessageChannelListenerInjectable; diff --git a/src/main/channel/channel-listeners/enlist-request-channel-listener.injectable.ts b/src/main/channel/channel-listeners/enlist-request-channel-listener.injectable.ts new file mode 100644 index 0000000000..bd4d49757f --- /dev/null +++ b/src/main/channel/channel-listeners/enlist-request-channel-listener.injectable.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import type { IpcMainInvokeEvent } from "electron"; +import ipcMainInjectable from "../ipc-main/ipc-main.injectable"; +import { enlistRequestChannelListenerInjectionToken } from "../../../common/channel/enlist-request-channel-listener-injection-token"; + +const enlistRequestChannelListenerInjectable = getInjectable({ + id: "enlist-request-channel-listener-for-main", + + instantiate: (di) => { + const ipcMain = di.inject(ipcMainInjectable); + + return ({ channel, handler }) => { + const nativeHandleCallback = (_: IpcMainInvokeEvent, message: unknown) => handler(message); + + ipcMain.handle(channel.id, nativeHandleCallback); + + return () => { + ipcMain.off(channel.id, nativeHandleCallback); + }; + }; + }, + + injectionToken: enlistRequestChannelListenerInjectionToken, +}); + +export default enlistRequestChannelListenerInjectable; diff --git a/src/main/app-paths/register-channel/ipc-main/ipc-main.injectable.ts b/src/main/channel/ipc-main/ipc-main.injectable.ts similarity index 100% rename from src/main/app-paths/register-channel/ipc-main/ipc-main.injectable.ts rename to src/main/channel/ipc-main/ipc-main.injectable.ts diff --git a/src/main/channel/send-to-channel.injectable.ts b/src/main/channel/message-to-channel.injectable.ts similarity index 51% rename from src/main/channel/send-to-channel.injectable.ts rename to src/main/channel/message-to-channel.injectable.ts index 0e5f6d87c5..7ffd82b96e 100644 --- a/src/main/channel/send-to-channel.injectable.ts +++ b/src/main/channel/message-to-channel.injectable.ts @@ -6,27 +6,30 @@ import { lensWindowInjectionToken } from "../start-main-application/lens-window/ import { pipeline } from "@ogre-tools/fp"; import { getInjectable } from "@ogre-tools/injectable"; import { filter } from "lodash/fp"; -import { sendToChannelInjectionToken } from "../../common/channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../../common/channel/message-to-channel-injection-token"; +import type { MessageChannel } from "../../common/channel/message-channel-injection-token"; -const sendToChannelInjectable = getInjectable({ - id: "send-to-channel", +const messageToChannelInjectable = getInjectable({ + id: "message-to-channel", instantiate: (di) => { const getAllLensWindows = () => di.injectMany(lensWindowInjectionToken); - return (channel, message) => { + // TODO: Figure out way to improve typing in internals + // Notice that this should be injected using "messageToChannelInjectionToken" which is typed correctly. + return (channel: MessageChannel, message?: unknown) => { const visibleWindows = pipeline( getAllLensWindows(), filter((lensWindow) => !!lensWindow.visible), ); visibleWindows.forEach((lensWindow) => - lensWindow.send({ channel: channel.id, data: [message] }), + lensWindow.send({ channel: channel.id, data: message ? [message] : [] }), ); }; }, - injectionToken: sendToChannelInjectionToken, + injectionToken: messageToChannelInjectionToken, }); -export default sendToChannelInjectable; +export default messageToChannelInjectable; diff --git a/src/main/getDiForUnitTesting.ts b/src/main/getDiForUnitTesting.ts index 9d401d31bb..3a19d91555 100644 --- a/src/main/getDiForUnitTesting.ts +++ b/src/main/getDiForUnitTesting.ts @@ -9,7 +9,6 @@ import type { DiContainer } from "@ogre-tools/injectable"; import { createContainer } from "@ogre-tools/injectable"; import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import appNameInjectable from "./app-paths/app-name/app-name.injectable"; -import registerChannelInjectable from "./app-paths/register-channel/register-channel.injectable"; import writeJsonFileInjectable from "../common/fs/write-json-file.injectable"; import readJsonFileInjectable from "../common/fs/read-json-file.injectable"; import readFileInjectable from "../common/fs/read-file.injectable"; @@ -30,7 +29,6 @@ import { getAbsolutePathFake } from "../common/test-utils/get-absolute-path-fake import joinPathsInjectable from "../common/path/join-paths.injectable"; import { joinPathsFake } from "../common/test-utils/join-paths-fake"; import hotbarStoreInjectable from "../common/hotbars/store.injectable"; -import type { GetDiForUnitTestingOptions } from "../test-utils/get-dis-for-unit-testing"; import appEventBusInjectable from "../common/app-event-bus/app-event-bus.injectable"; import { EventEmitter } from "../common/event-emitter"; import type { AppEvent } from "../common/app-event-bus/event-bus"; @@ -67,7 +65,7 @@ import type { ClusterFrameInfo } from "../common/cluster-frames"; import { observable } from "mobx"; import waitForElectronToBeReadyInjectable from "./electron-app/features/wait-for-electron-to-be-ready.injectable"; import setupListenerForCurrentClusterFrameInjectable from "./start-main-application/lens-window/current-cluster-frame/setup-listener-for-current-cluster-frame.injectable"; -import ipcMainInjectable from "./app-paths/register-channel/ipc-main/ipc-main.injectable"; +import ipcMainInjectable from "./channel/ipc-main/ipc-main.injectable"; import createElectronWindowForInjectable from "./start-main-application/lens-window/application-window/create-electron-window-for.injectable"; import setupRunnablesAfterWindowIsOpenedInjectable from "./electron-app/runnables/setup-runnables-after-window-is-opened.injectable"; import sendToChannelInElectronBrowserWindowInjectable from "./start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable"; @@ -86,10 +84,9 @@ import startCatalogSyncInjectable from "./catalog-sync-to-renderer/start-catalog import startKubeConfigSyncInjectable from "./start-main-application/runnables/kube-config-sync/start-kube-config-sync.injectable"; import appVersionInjectable from "../common/get-configuration-file-model/app-version/app-version.injectable"; import getRandomIdInjectable from "../common/utils/get-random-id.injectable"; -import periodicalCheckForUpdatesInjectable - from "./application-update/periodical-check-for-updates/periodical-check-for-updates.injectable"; +import periodicalCheckForUpdatesInjectable from "./application-update/periodical-check-for-updates/periodical-check-for-updates.injectable"; -export function getDiForUnitTesting(opts: GetDiForUnitTestingOptions = {}) { +export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) { const { doGeneralOverrides = false, } = opts; @@ -142,7 +139,6 @@ export function getDiForUnitTesting(opts: GetDiForUnitTestingOptions = {}) { di.override(appEventBusInjectable, () => new EventEmitter<[AppEvent]>()); di.override(appNameInjectable, () => "some-app-name"); - di.override(registerChannelInjectable, () => () => undefined); di.override(directoryForBundledBinariesInjectable, () => "some-bin-directory"); di.override(broadcastMessageInjectable, () => (channel) => { diff --git a/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts b/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts index 029bfa7d82..2ed08ab270 100644 --- a/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts +++ b/src/main/start-main-application/lens-window/application-window/application-window.injectable.ts @@ -11,7 +11,7 @@ import appNameInjectable from "../../../app-paths/app-name/app-name.injectable"; import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable"; import { delay } from "../../../../common/utils"; import { bundledExtensionsLoaded } from "../../../../common/ipc/extension-handling"; -import ipcMainInjectable from "../../../app-paths/register-channel/ipc-main/ipc-main.injectable"; +import ipcMainInjectable from "../../../channel/ipc-main/ipc-main.injectable"; const applicationWindowInjectable = getInjectable({ id: "application-window", diff --git a/src/main/start-main-application/runnables/root-frame-rendered-channel-listener/root-frame-rendered-channel-listener.injectable.ts b/src/main/start-main-application/runnables/root-frame-rendered-channel-listener/root-frame-rendered-channel-listener.injectable.ts index ef9da6f6d7..fb84799341 100644 --- a/src/main/start-main-application/runnables/root-frame-rendered-channel-listener/root-frame-rendered-channel-listener.injectable.ts +++ b/src/main/start-main-application/runnables/root-frame-rendered-channel-listener/root-frame-rendered-channel-listener.injectable.ts @@ -3,10 +3,10 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../../../common/channel/channel-listener-injection-token"; import rootFrameRenderedChannelInjectable from "../../../../common/root-frame-rendered-channel/root-frame-rendered-channel.injectable"; import { runManyFor } from "../../../../common/runnable/run-many-for"; import { afterRootFrameIsReadyInjectionToken } from "../../runnable-tokens/after-root-frame-is-ready-injection-token"; +import { messageChannelListenerInjectionToken } from "../../../../common/channel/message-channel-listener-injection-token"; const rootFrameRenderedChannelListenerInjectable = getInjectable({ id: "root-frame-rendered-channel-listener", @@ -29,7 +29,7 @@ const rootFrameRenderedChannelListenerInjectable = getInjectable({ }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default rootFrameRenderedChannelListenerInjectable; diff --git a/src/main/sync-box/sync-box-initial-value-channel-listener.injectable.ts b/src/main/sync-box/sync-box-initial-value-channel-listener.injectable.ts index 15b3f81d21..aa3406f22d 100644 --- a/src/main/sync-box/sync-box-initial-value-channel-listener.injectable.ts +++ b/src/main/sync-box/sync-box-initial-value-channel-listener.injectable.ts @@ -3,9 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token"; import syncBoxInitialValueChannelInjectable from "../../common/sync-box/sync-box-initial-value-channel.injectable"; import { syncBoxInjectionToken } from "../../common/sync-box/sync-box-injection-token"; +import { requestChannelListenerInjectionToken } from "../../common/channel/request-channel-listener-injection-token"; const syncBoxInitialValueChannelListenerInjectable = getInjectable({ id: "sync-box-initial-value-channel-listener", @@ -25,7 +25,7 @@ const syncBoxInitialValueChannelListenerInjectable = getInjectable({ }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: requestChannelListenerInjectionToken, }); export default syncBoxInitialValueChannelListenerInjectable; diff --git a/src/renderer/app-paths/setup-app-paths.injectable.ts b/src/renderer/app-paths/setup-app-paths.injectable.ts index 2babf95019..efdfaede70 100644 --- a/src/renderer/app-paths/setup-app-paths.injectable.ts +++ b/src/renderer/app-paths/setup-app-paths.injectable.ts @@ -3,32 +3,25 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import getValueFromChannelInjectable from "../channel/get-value-from-channel.injectable"; import appPathsStateInjectable from "../../common/app-paths/app-paths-state.injectable"; import { beforeFrameStartsInjectionToken } from "../before-frame-starts/before-frame-starts-injection-token"; import appPathsChannelInjectable from "../../common/app-paths/app-paths-channel.injectable"; -import assert from "assert"; +import { requestFromChannelInjectionToken } from "../../common/channel/request-from-channel-injection-token"; const setupAppPathsInjectable = getInjectable({ id: "setup-app-paths", instantiate: (di) => { - const getValueFromChannel = di.inject( - getValueFromChannelInjectable, - ); - + const requestFromChannel = di.inject(requestFromChannelInjectionToken); const appPathsChannel = di.inject(appPathsChannelInjectable); + const appPathsState = di.inject(appPathsStateInjectable); return { run: async () => { - const appPaths = await getValueFromChannel( + const appPaths = await requestFromChannel( appPathsChannel, ); - assert(appPaths); - - const appPathsState = di.inject(appPathsStateInjectable); - appPathsState.set(appPaths); }, }; diff --git a/src/renderer/application-update/application-update-status-listener.injectable.ts b/src/renderer/application-update/application-update-status-listener.injectable.ts index 9bbaca6391..11fe329e4f 100644 --- a/src/renderer/application-update/application-update-status-listener.injectable.ts +++ b/src/renderer/application-update/application-update-status-listener.injectable.ts @@ -3,19 +3,20 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token"; -import type { ApplicationUpdateStatusEventId } from "../../common/application-update/application-update-status-channel.injectable"; +import type { ApplicationUpdateStatusChannel, ApplicationUpdateStatusEventId } from "../../common/application-update/application-update-status-channel.injectable"; import applicationUpdateStatusChannelInjectable from "../../common/application-update/application-update-status-channel.injectable"; import showInfoNotificationInjectable from "../components/notifications/show-info-notification.injectable"; +import type { MessageChannelListener } from "../../common/channel/message-channel-listener-injection-token"; +import { messageChannelListenerInjectionToken } from "../../common/channel/message-channel-listener-injection-token"; const applicationUpdateStatusListenerInjectable = getInjectable({ id: "application-update-status-listener", - instantiate: (di) => { + instantiate: (di): MessageChannelListener => { const channel = di.inject(applicationUpdateStatusChannelInjectable); const showInfoNotification = di.inject(showInfoNotificationInjectable); - const eventHandlers: Record void }> = { + const eventHandlers: Record void }> = { "checking-for-updates": { handle: () => { showInfoNotification("Checking for updates..."); @@ -44,13 +45,13 @@ const applicationUpdateStatusListenerInjectable = getInjectable({ return { channel, - handler: ({ eventId, version }: { eventId: ApplicationUpdateStatusEventId; version: string }) => { + handler: ({ eventId, version }) => { eventHandlers[eventId].handle(version); }, }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default applicationUpdateStatusListenerInjectable; diff --git a/src/renderer/ask-boolean/ask-boolean-question-channel-listener.injectable.tsx b/src/renderer/ask-boolean/ask-boolean-question-channel-listener.injectable.tsx index 0b84a87e6b..6e9460fac8 100644 --- a/src/renderer/ask-boolean/ask-boolean-question-channel-listener.injectable.tsx +++ b/src/renderer/ask-boolean/ask-boolean-question-channel-listener.injectable.tsx @@ -3,28 +3,29 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token"; -import type { AskBooleanQuestionParameters } from "../../common/ask-boolean/ask-boolean-question-channel.injectable"; +import type { AskBooleanQuestionChannel } from "../../common/ask-boolean/ask-boolean-question-channel.injectable"; import askBooleanQuestionChannelInjectable from "../../common/ask-boolean/ask-boolean-question-channel.injectable"; import showInfoNotificationInjectable from "../components/notifications/show-info-notification.injectable"; import { Button } from "../components/button"; import React from "react"; -import { sendToChannelInjectionToken } from "../../common/channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../../common/channel/message-to-channel-injection-token"; import askBooleanAnswerChannelInjectable from "../../common/ask-boolean/ask-boolean-answer-channel.injectable"; import notificationsStoreInjectable from "../components/notifications/notifications-store.injectable"; +import type { MessageChannelListener } from "../../common/channel/message-channel-listener-injection-token"; +import { messageChannelListenerInjectionToken } from "../../common/channel/message-channel-listener-injection-token"; const askBooleanQuestionChannelListenerInjectable = getInjectable({ id: "ask-boolean-question-channel-listener", - instantiate: (di) => { + instantiate: (di): MessageChannelListener => { const questionChannel = di.inject(askBooleanQuestionChannelInjectable); const showInfoNotification = di.inject(showInfoNotificationInjectable); - const sendToChannel = di.inject(sendToChannelInjectionToken); + const messageToChannel = di.inject(messageToChannelInjectionToken); const answerChannel = di.inject(askBooleanAnswerChannelInjectable); const notificationsStore = di.inject(notificationsStoreInjectable); const sendAnswerFor = (id: string) => (value: boolean) => { - sendToChannel(answerChannel, { id, value }); + messageToChannel(answerChannel, { id, value }); }; const closeNotification = (notificationId: string) => { @@ -39,7 +40,7 @@ const askBooleanQuestionChannelListenerInjectable = getInjectable({ return { channel: questionChannel, - handler: ({ id: questionId, title, question }: AskBooleanQuestionParameters) => { + handler: ({ id: questionId, title, question }) => { const notificationId = `ask-boolean-for-${questionId}`; const sendAnswer = sendAnswerFor(questionId); @@ -64,7 +65,7 @@ const askBooleanQuestionChannelListenerInjectable = getInjectable({ }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default askBooleanQuestionChannelListenerInjectable; diff --git a/src/renderer/channel/channel-listeners/enlist-channel-listener.injectable.ts b/src/renderer/channel/channel-listeners/enlist-message-channel-listener.injectable.ts similarity index 61% rename from src/renderer/channel/channel-listeners/enlist-channel-listener.injectable.ts rename to src/renderer/channel/channel-listeners/enlist-message-channel-listener.injectable.ts index 415980e1b9..ed9736c454 100644 --- a/src/renderer/channel/channel-listeners/enlist-channel-listener.injectable.ts +++ b/src/renderer/channel/channel-listeners/enlist-message-channel-listener.injectable.ts @@ -5,15 +5,15 @@ import ipcRendererInjectable from "../ipc-renderer.injectable"; import { getInjectable } from "@ogre-tools/injectable"; import type { IpcRendererEvent } from "electron"; -import { enlistChannelListenerInjectionToken } from "../../../common/channel/enlist-channel-listener-injection-token"; +import { enlistMessageChannelListenerInjectionToken } from "../../../common/channel/enlist-message-channel-listener-injection-token"; -const enlistChannelListenerInjectable = getInjectable({ - id: "enlist-channel-listener-for-renderer", +const enlistMessageChannelListenerInjectable = getInjectable({ + id: "enlist-message-channel-listener-for-renderer", instantiate: (di) => { const ipcRenderer = di.inject(ipcRendererInjectable); - return (channel, handler) => { + return ({ channel, handler }) => { const nativeCallback = (_: IpcRendererEvent, message: unknown) => handler(message); @@ -25,7 +25,7 @@ const enlistChannelListenerInjectable = getInjectable({ }; }, - injectionToken: enlistChannelListenerInjectionToken, + injectionToken: enlistMessageChannelListenerInjectionToken, }); -export default enlistChannelListenerInjectable; +export default enlistMessageChannelListenerInjectable; diff --git a/src/renderer/channel/channel-listeners/enlist-request-channel-listener.injectable.ts b/src/renderer/channel/channel-listeners/enlist-request-channel-listener.injectable.ts new file mode 100644 index 0000000000..aa931a09ec --- /dev/null +++ b/src/renderer/channel/channel-listeners/enlist-request-channel-listener.injectable.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { enlistRequestChannelListenerInjectionToken } from "../../../common/channel/enlist-request-channel-listener-injection-token"; + +const enlistRequestChannelListenerInjectable = getInjectable({ + id: "enlist-request-channel-listener-for-renderer", + + instantiate: () => { + // Requests from main to renderer are not implemented yet. + return () => () => {}; + }, + + injectionToken: enlistRequestChannelListenerInjectionToken, +}); + +export default enlistRequestChannelListenerInjectable; diff --git a/src/renderer/channel/get-value-from-channel.injectable.ts b/src/renderer/channel/get-value-from-channel.injectable.ts deleted file mode 100644 index 060800eba0..0000000000 --- a/src/renderer/channel/get-value-from-channel.injectable.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import ipcRendererInjectable from "./ipc-renderer.injectable"; -import type { Channel } from "../../common/channel/channel-injection-token"; - -const getValueFromChannelInjectable = getInjectable({ - id: "get-value-from-channel", - - instantiate: (di) => { - const ipcRenderer = di.inject(ipcRendererInjectable); - - return >( - channel: TChannel, - ): Promise => - ipcRenderer.invoke(channel.id); - }, -}); - -export default getValueFromChannelInjectable; diff --git a/src/renderer/channel/message-to-channel.injectable.ts b/src/renderer/channel/message-to-channel.injectable.ts new file mode 100644 index 0000000000..921351dc60 --- /dev/null +++ b/src/renderer/channel/message-to-channel.injectable.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { messageToChannelInjectionToken } from "../../common/channel/message-to-channel-injection-token"; +import sendToMainInjectable from "./send-to-main.injectable"; +import type { MessageChannel } from "../../common/channel/message-channel-injection-token"; + +const messageToChannelInjectable = getInjectable({ + id: "message-to-channel", + + instantiate: (di) => { + const sendToMain = di.inject(sendToMainInjectable); + + // TODO: Figure out way to improve typing in internals + // Notice that this should be injected using "messageToChannelInjectionToken" which is typed correctly. + return (channel: MessageChannel, message?: unknown) => { + sendToMain(channel.id, message); + }; + }, + + injectionToken: messageToChannelInjectionToken, +}); + +export default messageToChannelInjectable; diff --git a/src/renderer/channel/request-from-channel.injectable.ts b/src/renderer/channel/request-from-channel.injectable.ts new file mode 100644 index 0000000000..ec1be037b7 --- /dev/null +++ b/src/renderer/channel/request-from-channel.injectable.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import ipcRendererInjectable from "./ipc-renderer.injectable"; +import { requestFromChannelInjectionToken } from "../../common/channel/request-from-channel-injection-token"; + +const requestFromChannelInjectable = getInjectable({ + id: "request-from-channel", + + instantiate: (di) => { + const ipcRenderer = di.inject(ipcRendererInjectable); + + return (channel, ...[request]) => ipcRenderer.invoke(channel.id, request); + }, + + injectionToken: requestFromChannelInjectionToken, +}); + +export default requestFromChannelInjectable; diff --git a/src/renderer/channel/send-to-channel.injectable.ts b/src/renderer/channel/send-to-channel.injectable.ts deleted file mode 100644 index 54da7d4512..0000000000 --- a/src/renderer/channel/send-to-channel.injectable.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getInjectable } from "@ogre-tools/injectable"; -import { sendToChannelInjectionToken } from "../../common/channel/send-to-channel-injection-token"; -import sendToMainInjectable from "./send-to-main.injectable"; - -const sendToChannelInjectable = getInjectable({ - id: "send-to-channel", - - instantiate: (di) => { - const sendToMain = di.inject(sendToMainInjectable); - - return (channel, message) => { - sendToMain(channel.id, message); - }; - }, - - injectionToken: sendToChannelInjectionToken, -}); - -export default sendToChannelInjectable; diff --git a/src/renderer/channel/send-to-main.injectable.ts b/src/renderer/channel/send-to-main.injectable.ts index 6eb4540062..a2b135ebd3 100644 --- a/src/renderer/channel/send-to-main.injectable.ts +++ b/src/renderer/channel/send-to-main.injectable.ts @@ -11,8 +11,9 @@ const sendToMainInjectable = getInjectable({ instantiate: (di) => { const ipcRenderer = di.inject(ipcRendererInjectable); + // TODO: Figure out way to improve typing in internals return (channelId: string, message: any) => { - ipcRenderer.send(channelId, message); + ipcRenderer.send(channelId, ...(message ? [message] : [])); }; }, }); diff --git a/src/renderer/components/test-utils/get-application-builder.tsx b/src/renderer/components/test-utils/get-application-builder.tsx index 33afbf8a88..5c8162cd2d 100644 --- a/src/renderer/components/test-utils/get-application-builder.tsx +++ b/src/renderer/components/test-utils/get-application-builder.tsx @@ -18,7 +18,6 @@ import type { RenderResult } from "@testing-library/react"; import { fireEvent } from "@testing-library/react"; import type { KubeResource } from "../../../common/rbac"; import { Sidebar } from "../layout/sidebar"; -import { getDisForUnitTesting } from "../../../test-utils/get-dis-for-unit-testing"; import type { DiContainer } from "@ogre-tools/injectable"; import clusterStoreInjectable from "../../../common/cluster-store/cluster-store.injectable"; import type { ClusterStore } from "../../../common/cluster-store/cluster-store"; @@ -49,6 +48,9 @@ import electronTrayInjectable from "../../../main/tray/electron-tray/electron-tr import applicationWindowInjectable from "../../../main/start-main-application/lens-window/application-window/application-window.injectable"; import { Notifications } from "../notifications/notifications"; import broadcastThatRootFrameIsRenderedInjectable from "../../frames/root-frame/broadcast-that-root-frame-is-rendered.injectable"; +import { getDiForUnitTesting as getRendererDi } from "../../getDiForUnitTesting"; +import { getDiForUnitTesting as getMainDi } from "../../../main/getDiForUnitTesting"; +import { overrideChannels } from "../../../test-utils/channel-fakes/override-channels"; type Callback = (dis: DiContainers) => void | Promise; @@ -95,10 +97,18 @@ interface Environment { } export const getApplicationBuilder = () => { - const { rendererDi, mainDi } = getDisForUnitTesting({ + const mainDi = getMainDi({ doGeneralOverrides: true, }); + const overrideChannelsForWindow = overrideChannels(mainDi); + + const rendererDi = getRendererDi({ + doGeneralOverrides: true, + }); + + overrideChannelsForWindow(rendererDi); + const dis = { rendererDi, mainDi }; const clusterStoreStub = { @@ -162,7 +172,7 @@ export const getApplicationBuilder = () => { start: () => {}, stop: () => {}, - setMenuItems: (items) => { + setMenuItems: (items) => { trayMenuItemsStateFake = items; }, })); diff --git a/src/renderer/frames/root-frame/broadcast-that-root-frame-is-rendered.injectable.ts b/src/renderer/frames/root-frame/broadcast-that-root-frame-is-rendered.injectable.ts index aafabb31d3..b94cbb8f1c 100644 --- a/src/renderer/frames/root-frame/broadcast-that-root-frame-is-rendered.injectable.ts +++ b/src/renderer/frames/root-frame/broadcast-that-root-frame-is-rendered.injectable.ts @@ -3,18 +3,18 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { sendToChannelInjectionToken } from "../../../common/channel/send-to-channel-injection-token"; +import { messageToChannelInjectionToken } from "../../../common/channel/message-to-channel-injection-token"; import rootFrameIsRenderedChannelInjectable from "../../../common/root-frame-rendered-channel/root-frame-rendered-channel.injectable"; const broadcastThatRootFrameIsRenderedInjectable = getInjectable({ id: "broadcast-that-root-frame-is-rendered", instantiate: (di) => { - const sendToChannel = di.inject(sendToChannelInjectionToken); + const messageToChannel = di.inject(messageToChannelInjectionToken); const rootFrameIsRenderedChannel = di.inject(rootFrameIsRenderedChannelInjectable); return () => { - sendToChannel(rootFrameIsRenderedChannel); + messageToChannel(rootFrameIsRenderedChannel); }; }, }); diff --git a/src/renderer/getDiForUnitTesting.tsx b/src/renderer/getDiForUnitTesting.tsx index 094afafe6a..e3f96725a2 100644 --- a/src/renderer/getDiForUnitTesting.tsx +++ b/src/renderer/getDiForUnitTesting.tsx @@ -7,7 +7,7 @@ import glob from "glob"; import { memoize, noop } from "lodash/fp"; import { createContainer } from "@ogre-tools/injectable"; import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; -import getValueFromChannelInjectable from "./channel/get-value-from-channel.injectable"; +import requestFromChannelInjectable from "./channel/request-from-channel.injectable"; import loggerInjectable from "../common/logger.injectable"; import { overrideFsWithFakes } from "../test-utils/override-fs-with-fakes"; import { createMemoryHistory } from "history"; @@ -31,7 +31,6 @@ import { joinPathsFake } from "../common/test-utils/join-paths-fake"; import hotbarStoreInjectable from "../common/hotbars/store.injectable"; import terminalSpawningPoolInjectable from "./components/dock/terminal/terminal-spawning-pool.injectable"; import hostedClusterIdInjectable from "../common/cluster-store/hosted-cluster-id.injectable"; -import type { GetDiForUnitTestingOptions } from "../test-utils/get-dis-for-unit-testing"; import historyInjectable from "./navigation/history.injectable"; import { ApiManager } from "../common/k8s-api/api-manager"; import lensResourcesDirInjectable from "../common/vars/lens-resources-dir.injectable"; @@ -47,7 +46,7 @@ import provideInitialValuesForSyncBoxesInjectable from "./sync-box/provide-initi import requestAnimationFrameInjectable from "./components/animate/request-animation-frame.injectable"; import getRandomIdInjectable from "../common/utils/get-random-id.injectable"; -export const getDiForUnitTesting = (opts: GetDiForUnitTestingOptions = {}) => { +export const getDiForUnitTesting = (opts: { doGeneralOverrides?: boolean } = {}) => { const { doGeneralOverrides = false, } = opts; @@ -125,7 +124,7 @@ export const getDiForUnitTesting = (opts: GetDiForUnitTestingOptions = {}) => { di.override(apiManagerInjectable, () => new ApiManager()); - di.override(getValueFromChannelInjectable, () => () => Promise.resolve(undefined as never)); + di.override(requestFromChannelInjectable, () => () => Promise.resolve(undefined as never)); overrideFsWithFakes(di); diff --git a/src/renderer/navigation/navigation-channel-listener.injectable.ts b/src/renderer/navigation/navigation-channel-listener.injectable.ts index b29dff1e55..94817078dd 100644 --- a/src/renderer/navigation/navigation-channel-listener.injectable.ts +++ b/src/renderer/navigation/navigation-channel-listener.injectable.ts @@ -3,14 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import { channelListenerInjectionToken } from "../../common/channel/channel-listener-injection-token"; - - import currentlyInClusterFrameInjectable from "../routes/currently-in-cluster-frame.injectable"; import appNavigationChannelInjectable from "../../common/front-end-routing/app-navigation-channel.injectable"; import clusterFrameNavigationChannelInjectable from "../../common/front-end-routing/cluster-frame-navigation-channel.injectable"; import focusWindowInjectable from "./focus-window.injectable"; import { navigateToUrlInjectionToken } from "../../common/front-end-routing/navigate-to-url-injection-token"; +import { messageChannelListenerInjectionToken } from "../../common/channel/message-channel-listener-injection-token"; const navigationChannelListenerInjectable = getInjectable({ id: "navigation-channel-listener", @@ -36,7 +34,7 @@ const navigationChannelListenerInjectable = getInjectable({ }, }; }, - injectionToken: channelListenerInjectionToken, + injectionToken: messageChannelListenerInjectionToken, }); export default navigationChannelListenerInjectable; diff --git a/src/renderer/sync-box/provide-initial-values-for-sync-boxes.injectable.ts b/src/renderer/sync-box/provide-initial-values-for-sync-boxes.injectable.ts index 9c8239572a..273be9a145 100644 --- a/src/renderer/sync-box/provide-initial-values-for-sync-boxes.injectable.ts +++ b/src/renderer/sync-box/provide-initial-values-for-sync-boxes.injectable.ts @@ -4,24 +4,21 @@ */ import { getInjectable } from "@ogre-tools/injectable"; import { beforeFrameStartsInjectionToken } from "../before-frame-starts/before-frame-starts-injection-token"; -import getValueFromChannelInjectable from "../channel/get-value-from-channel.injectable"; import syncBoxInitialValueChannelInjectable from "../../common/sync-box/sync-box-initial-value-channel.injectable"; -import assert from "assert"; import syncBoxStateInjectable from "../../common/sync-box/sync-box-state.injectable"; +import { requestFromChannelInjectionToken } from "../../common/channel/request-from-channel-injection-token"; const provideInitialValuesForSyncBoxesInjectable = getInjectable({ id: "provide-initial-values-for-sync-boxes", instantiate: (di) => { - const getValueFromChannel = di.inject(getValueFromChannelInjectable); + const requestFromChannel = di.inject(requestFromChannelInjectionToken); const syncBoxInitialValueChannel = di.inject(syncBoxInitialValueChannelInjectable); const setSyncBoxState = (id: string, state: any) => di.inject(syncBoxStateInjectable, id).set(state); return { run: async () => { - const initialValues = await getValueFromChannel(syncBoxInitialValueChannel); - - assert(initialValues); + const initialValues = await requestFromChannel(syncBoxInitialValueChannel); initialValues.forEach(({ id, value }) => { setSyncBoxState(id, value); diff --git a/src/test-utils/channel-fakes/override-channels.ts b/src/test-utils/channel-fakes/override-channels.ts new file mode 100644 index 0000000000..4d7a337e04 --- /dev/null +++ b/src/test-utils/channel-fakes/override-channels.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { DiContainer } from "@ogre-tools/injectable"; +import { overrideMessagingFromMainToWindow } from "./override-messaging-from-main-to-window"; +import { overrideMessagingFromWindowToMain } from "./override-messaging-from-window-to-main"; +import { overrideRequestingFromWindowToMain } from "./override-requesting-from-window-to-main"; + +export const overrideChannels = (mainDi: DiContainer) => { + const overrideMessagingFromMainToWindowForWindow = overrideMessagingFromMainToWindow(mainDi); + const overrideMessagingFromWindowToForWindow = overrideMessagingFromWindowToMain(mainDi); + const overrideRequestingFromWindowToMainForWindow = overrideRequestingFromWindowToMain(mainDi); + + return (windowDi: DiContainer) => { + overrideMessagingFromMainToWindowForWindow(windowDi); + overrideMessagingFromWindowToForWindow(windowDi); + overrideRequestingFromWindowToMainForWindow(windowDi); + }; +}; diff --git a/src/test-utils/channel-fakes/override-messaging-from-main-to-window.ts b/src/test-utils/channel-fakes/override-messaging-from-main-to-window.ts new file mode 100644 index 0000000000..5c2b839ad9 --- /dev/null +++ b/src/test-utils/channel-fakes/override-messaging-from-main-to-window.ts @@ -0,0 +1,90 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { MessageChannelListener } from "../../common/channel/message-channel-listener-injection-token"; +import type { MessageChannel } from "../../common/channel/message-channel-injection-token"; +import sendToChannelInElectronBrowserWindowInjectable from "../../main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable"; +import type { SendToViewArgs } from "../../main/start-main-application/lens-window/application-window/lens-window-injection-token"; +import enlistMessageChannelListenerInjectableInRenderer from "../../renderer/channel/channel-listeners/enlist-message-channel-listener.injectable"; +import type { DiContainer } from "@ogre-tools/injectable"; +import assert from "assert"; + +export const overrideMessagingFromMainToWindow = (mainDi: DiContainer) => { + const messageChannelListenerFakesForRenderer = new Map< + string, + Set>> + >(); + + mainDi.override( + sendToChannelInElectronBrowserWindowInjectable, + + () => + ( + browserWindow, + { channel: channelId, frameInfo, data = [] }: SendToViewArgs, + ) => { + const listeners = + messageChannelListenerFakesForRenderer.get(channelId) || new Set(); + + if (frameInfo) { + throw new Error( + `Tried to send message to frame "${frameInfo.frameId}" in process "${frameInfo.processId}" using channel "${channelId}" which isn't supported yet.`, + ); + } + + if (data.length > 1) { + throw new Error( + `Tried to send message to channel "${channelId}" with more than one argument which is not supported in MessageChannelListener yet.`, + ); + } + + if (listeners.size === 0) { + throw new Error( + `Tried to send message to channel "${channelId}" but there where no listeners. Current channels with listeners: "${[ + ...messageChannelListenerFakesForRenderer.keys(), + ].join('", "')}"`, + ); + } + + const message = data[0]; + + listeners.forEach((listener) => listener.handler(message)); + }, + ); + + return (windowDi: DiContainer) => { + windowDi.override( + enlistMessageChannelListenerInjectableInRenderer, + + () => (listener) => { + if (!messageChannelListenerFakesForRenderer.has(listener.channel.id)) { + messageChannelListenerFakesForRenderer.set( + listener.channel.id, + new Set(), + ); + } + + const listeners = messageChannelListenerFakesForRenderer.get( + listener.channel.id, + ); + + assert(listeners); + + // TODO: Figure out typing + listeners.add( + listener as unknown as MessageChannelListener>, + ); + + return () => { + // TODO: Figure out typing + listeners.delete( + listener as unknown as MessageChannelListener< + MessageChannel + >, + ); + }; + }, + ); + }; +}; diff --git a/src/test-utils/channel-fakes/override-messaging-from-window-to-main.ts b/src/test-utils/channel-fakes/override-messaging-from-window-to-main.ts new file mode 100644 index 0000000000..01538dc920 --- /dev/null +++ b/src/test-utils/channel-fakes/override-messaging-from-window-to-main.ts @@ -0,0 +1,64 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { DiContainer } from "@ogre-tools/injectable"; +import assert from "assert"; +import type { MessageChannel } from "../../common/channel/message-channel-injection-token"; +import type { MessageChannelListener } from "../../common/channel/message-channel-listener-injection-token"; +import enlistMessageChannelListenerInjectableInMain from "../../main/channel/channel-listeners/enlist-message-channel-listener.injectable"; +import sendToMainInjectable from "../../renderer/channel/send-to-main.injectable"; + +export const overrideMessagingFromWindowToMain = (mainDi: DiContainer) => { + const messageChannelListenerFakesForMain = new Map< + string, + Set>> + >(); + + mainDi.override( + enlistMessageChannelListenerInjectableInMain, + + () => (listener) => { + const channelId = listener.channel.id; + + if (!messageChannelListenerFakesForMain.has(channelId)) { + messageChannelListenerFakesForMain.set(channelId, new Set()); + } + + const listeners = messageChannelListenerFakesForMain.get( + channelId, + ); + + assert(listeners); + + // TODO: Figure out typing + listeners.add( + listener as unknown as MessageChannelListener>, + ); + + return () => { + // TODO: Figure out typing + listeners.delete( + listener as unknown as MessageChannelListener>, + ); + }; + }, + ); + + return (windowDi: DiContainer) => { + windowDi.override(sendToMainInjectable, () => (channelId, message) => { + const listeners = + messageChannelListenerFakesForMain.get(channelId) || new Set(); + + if (listeners.size === 0) { + throw new Error( + `Tried to send message to channel "${channelId}" but there where no listeners. Current channels with listeners: "${[ + ...messageChannelListenerFakesForMain.keys(), + ].join('", "')}"`, + ); + } + + listeners.forEach((listener) => listener.handler(message)); + }); + }; +}; diff --git a/src/test-utils/channel-fakes/override-requesting-from-window-to-main.ts b/src/test-utils/channel-fakes/override-requesting-from-window-to-main.ts new file mode 100644 index 0000000000..5897d93f9b --- /dev/null +++ b/src/test-utils/channel-fakes/override-requesting-from-window-to-main.ts @@ -0,0 +1,59 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import type { DiContainer } from "@ogre-tools/injectable"; +import type { RequestChannel } from "../../common/channel/request-channel-injection-token"; +import type { RequestChannelListener } from "../../common/channel/request-channel-listener-injection-token"; +import enlistRequestChannelListenerInjectableInMain from "../../main/channel/channel-listeners/enlist-request-channel-listener.injectable"; +import requestFromChannelInjectable from "../../renderer/channel/request-from-channel.injectable"; + +export const overrideRequestingFromWindowToMain = (mainDi: DiContainer) => { + const requestChannelListenerFakesForMain = new Map< + string, + RequestChannelListener> + >(); + + mainDi.override( + enlistRequestChannelListenerInjectableInMain, + + () => (listener) => { + if (requestChannelListenerFakesForMain.get(listener.channel.id)) { + throw new Error( + `Tried to enlist listener for channel "${listener.channel.id}", but it was already enlisted`, + ); + } + + requestChannelListenerFakesForMain.set( + listener.channel.id, + + // TODO: Figure out typingo + listener as unknown as RequestChannelListener< + RequestChannel + >, + ); + + return () => { + requestChannelListenerFakesForMain.delete(listener.channel.id); + }; + }, + ); + + return (windowDi: DiContainer) => { + windowDi.override( + requestFromChannelInjectable, + + () => async (channel, ...[request]) => { + const requestListener = requestChannelListenerFakesForMain.get(channel.id); + + if (!requestListener) { + throw new Error( + `Tried to get value from channel "${channel.id}", but no listeners were registered`, + ); + } + + return requestListener.handler(request); + }, + ); + }; +}; diff --git a/src/test-utils/get-dis-for-unit-testing.ts b/src/test-utils/get-dis-for-unit-testing.ts deleted file mode 100644 index 2f7d59d036..0000000000 --- a/src/test-utils/get-dis-for-unit-testing.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import { getDiForUnitTesting as getRendererDi } from "../renderer/getDiForUnitTesting"; -import { getDiForUnitTesting as getMainDi } from "../main/getDiForUnitTesting"; -import { overrideIpcBridge } from "./override-ipc-bridge"; - -export interface GetDiForUnitTestingOptions { - doGeneralOverrides?: boolean; -} - -export const getDisForUnitTesting = (opts?: GetDiForUnitTestingOptions) => { - const rendererDi = getRendererDi(opts); - const mainDi = getMainDi(opts); - - overrideIpcBridge({ rendererDi, mainDi }); - - return { - rendererDi, - mainDi, - }; -}; diff --git a/src/test-utils/override-ipc-bridge.ts b/src/test-utils/override-ipc-bridge.ts deleted file mode 100644 index e5c16810c8..0000000000 --- a/src/test-utils/override-ipc-bridge.ts +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import type { DiContainer } from "@ogre-tools/injectable"; -import getValueFromChannelInjectable from "../renderer/channel/get-value-from-channel.injectable"; -import registerChannelInjectable from "../main/app-paths/register-channel/register-channel.injectable"; -import asyncFn from "@async-fn/jest"; -import type { SendToViewArgs } from "../main/start-main-application/lens-window/application-window/lens-window-injection-token"; -import sendToChannelInElectronBrowserWindowInjectable from "../main/start-main-application/lens-window/application-window/send-to-channel-in-electron-browser-window.injectable"; -import { isEmpty } from "lodash/fp"; -import enlistChannelListenerInjectableInRenderer from "../renderer/channel/channel-listeners/enlist-channel-listener.injectable"; -import enlistChannelListenerInjectableInMain from "../main/channel/channel-listeners/enlist-channel-listener.injectable"; -import sendToMainInjectable from "../renderer/channel/send-to-main.injectable"; -import type { Channel } from "../common/channel/channel-injection-token"; - -export const overrideIpcBridge = ({ - rendererDi, - mainDi, -}: { - rendererDi: DiContainer; - mainDi: DiContainer; -}) => { - const fakeChannelMap = new Map< - string, - { promise: Promise; resolve: (arg0: any) => Promise } - >(); - - const mainIpcRegistrations = { - set: >( - channel: TChannel, - callback: () => TChannel["_messageTemplate"], - ) => { - const id = channel.id; - - if (!fakeChannelMap.has(id)) { - const mockInstance = asyncFn(); - - fakeChannelMap.set(id, { - promise: mockInstance(), - resolve: mockInstance.resolve, - }); - } - - return fakeChannelMap.get(id)?.resolve(callback); - }, - - get: >(channel: TChannel) => { - const id = channel.id; - - if (!fakeChannelMap.has(id)) { - const mockInstance = asyncFn(); - - fakeChannelMap.set(id, { - promise: mockInstance(), - resolve: mockInstance.resolve, - }); - } - - return fakeChannelMap.get(id)?.promise; - }, - }; - - // TODO: Consolidate to using mainIpcFakeHandles - rendererDi.override( - getValueFromChannelInjectable, - () => async (channel) => { - const callback = await mainIpcRegistrations.get(channel); - - return callback(); - }, - ); - - mainDi.override(registerChannelInjectable, () => (channel, callback) => { - mainIpcRegistrations.set(channel, callback); - }); - - const rendererIpcFakeHandles = new Map< - string, - ((...args: any[]) => void)[] - >(); - - mainDi.override( - sendToChannelInElectronBrowserWindowInjectable, - () => - (browserWindow, { channel: channelName, data = [] }: SendToViewArgs) => { - const handles = rendererIpcFakeHandles.get(channelName) || []; - - if (isEmpty(handles)) { - throw new Error( - `Tried to send message to channel "${channelName}" but there where no listeners. Current channels with listeners: "${[ - ...rendererIpcFakeHandles.keys(), - ].join('", "')}"`, - ); - } - - handles.forEach((handle) => handle(...data)); - }, - ); - - const mainIpcFakeHandles = new Map< - string, - ((...args: any[]) => void)[] - >(); - - rendererDi.override( - enlistChannelListenerInjectableInRenderer, - () => (channel, handler) => { - const existingHandles = rendererIpcFakeHandles.get(channel.id) || []; - - rendererIpcFakeHandles.set(channel.id, [...existingHandles, handler]); - - return () => { - - }; - }, - ); - - rendererDi.override(sendToMainInjectable, () => (channelId, message) => { - const handles = mainIpcFakeHandles.get(channelId) || []; - - if (isEmpty(handles)) { - throw new Error( - `Tried to send message to channel "${channelId}" but there where no listeners. Current channels with listeners: "${[ - ...mainIpcFakeHandles.keys(), - ].join('", "')}"`, - ); - } - - handles.forEach((handle) => handle(message)); - }); - - mainDi.override( - enlistChannelListenerInjectableInMain, - () => (channel, handler) => { - const existingHandles = mainIpcFakeHandles.get(channel.id) || []; - - mainIpcFakeHandles.set(channel.id, [...existingHandles, handler]); - - return () => { - - }; - }, - ); -};