1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Separate concept of message and request channels

Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Iku-turso <mikko.aspiala@gmail.com>
This commit is contained in:
Iku-turso 2022-05-25 15:07:17 +03:00 committed by Janne Savolainen
parent c5809d3d0a
commit 7a54a89e80
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
64 changed files with 685 additions and 497 deletions

View File

@ -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<AppPaths, AppPaths>;
export type AppPathsChannel = RequestChannel<void, AppPaths>;
const appPathsChannelInjectable = getInjectable({
id: "app-paths-channel",
@ -16,7 +16,7 @@ const appPathsChannelInjectable = getInjectable({
id: "app-paths",
}),
injectionToken: channelInjectionToken,
injectionToken: messageChannelInjectionToken,
});
export default appPathsChannelInjectable;

View File

@ -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<ApplicationUpdateStatusChannelMessage>;
export type ApplicationUpdateStatusChannel = MessageChannel<ApplicationUpdateStatusChannelMessage>;
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;

View File

@ -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;

View File

@ -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<AskBooleanQuestionParameters>;
export type AskBooleanQuestionChannel = MessageChannel<AskBooleanQuestionParameters>;
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;

View File

@ -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<MessageTemplate = void, ReturnTemplate = void> {
id: string;
@ -11,6 +10,3 @@ export interface Channel<MessageTemplate = void, ReturnTemplate = void> {
_returnTemplate?: ReturnTemplate;
}
export const channelInjectionToken = getInjectionToken<Channel<any, any>>({
id: "channel",
});

View File

@ -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<TChannel extends Channel<any, any>> {
channel: TChannel;
handler: (value: TChannel["_messageTemplate"]) => TChannel["_returnTemplate"];
}
export const channelListenerInjectionToken = getInjectionToken<ChannelListener<Channel<any, any>>>(
{
id: "channel-listener",
},
);

View File

@ -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<string>;
type TestChannel = MessageChannel<string>;
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");
});

View File

@ -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 = <TChannel extends Channel<unknown, unknown>>(
channel: TChannel,
handler: (value: TChannel["_messageTemplate"]) => TChannel["_returnTemplate"]
) => () => void;
export const enlistChannelListenerInjectionToken =
getInjectionToken<EnlistChannelListener>({
id: "enlist-channel-listener",
});

View File

@ -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<unknown>,
>(listener: MessageChannelListener<TChannel>) => () => void;
export const enlistMessageChannelListenerInjectionToken =
getInjectionToken<EnlistMessageChannelListener>({
id: "enlist-message-channel-listener",
});

View File

@ -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<unknown, unknown>,
>(listener: RequestChannelListener<TChannel>) => () => void;
export const enlistRequestChannelListenerInjectionToken =
getInjectionToken<EnlistRequestChannelListener>({
id: "enlist-request-channel-listener",
});

View File

@ -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);
});
},
});

View File

@ -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<Message = void> {
id: string;
_messageSignature?: Message;
}
export const messageChannelInjectionToken = getInjectionToken<MessageChannel<any>>({
id: "message-channel",
});

View File

@ -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<TChannel extends MessageChannel<any>> {
channel: TChannel;
handler: (value: SetRequired<TChannel, "_messageSignature">["_messageSignature"]) => void;
}
export const messageChannelListenerInjectionToken = getInjectionToken<MessageChannelListener<MessageChannel<any>>>(
{
id: "message-channel-listener",
},
);

View File

@ -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 {
<TChannel extends MessageChannel<TMessage>, TMessage extends void>(
channel: TChannel,
): void;
<TChannel extends MessageChannel<TMessage>, TMessage>(
channel: TChannel,
message: TMessage
): void;
}
export const messageToChannelInjectionToken =
getInjectionToken<MessageToChannel>({
id: "message-to-message-channel",
});

View File

@ -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<Request = void, Response = void> {
id: string;
_requestSignature?: Request;
_responseSignature?: Response;
}
export const requestChannelInjectionToken = getInjectionToken<RequestChannel<any, any>>({
id: "request-channel",
});

View File

@ -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<TChannel extends RequestChannel<any, any>> {
channel: TChannel;
handler: (request: TChannel["_requestSignature"]) => TChannel["_responseSignature"];
}
export const requestChannelListenerInjectionToken = getInjectionToken<RequestChannelListener<RequestChannel<any, any>>>(
{
id: "request-channel-listener",
},
);

View File

@ -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<unknown, unknown>,
>(
channel: TChannel,
...request: TChannel["_requestSignature"] extends void
? []
: [TChannel["_requestSignature"]]
) => Promise<SetRequired<TChannel, "_responseSignature">["_responseSignature"]>;
export const requestFromChannelInjectionToken =
getInjectionToken<RequestFromChannel>({
id: "request-from-request-channel",
});

View File

@ -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 = <TChannel extends Channel<unknown, unknown>>(
channel: TChannel,
message?: TChannel["_messageTemplate"]
) => void;
export const sendToChannelInjectionToken =
getInjectionToken<SendToChannel>({
id: "send-to-channel",
});

View File

@ -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<string>;
export type AppNavigationChannel = MessageChannel<string>;
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;

View File

@ -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<string>;
export type ClusterFrameNavigationChannel = MessageChannel<string>;
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;

View File

@ -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;

View File

@ -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 <TData>(id: string, initialValue: TData): SyncBox<TData> => {
@ -30,7 +30,7 @@ const createSyncBoxInjectable = getInjectable({
set: (value) => {
state.set(value);
sendToChannel(syncBoxChannel, { id, value });
messageToChannel(syncBoxChannel, { id, value });
},
};
};

View File

@ -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<SyncBoxChannel> => {
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;

View File

@ -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;

View File

@ -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<never, { id: string; value: unknown }[]>;
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;

View File

@ -4,8 +4,9 @@
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import type { JsonValue } from "type-fest";
export interface SyncBox<TValue> {
export interface SyncBox<TValue extends JsonValue> {
id: string;
value: IComputedValue<TValue>;
set: (value: TValue) => void;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) =>
<TChannel extends Channel<unknown, unknown>>(
channel: TChannel,
getValue: () => TChannel["_messageTemplate"],
) =>
ipcMain.handle(channel.id, getValue);

View File

@ -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);
},
};
},

View File

@ -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);
};
},
});

View File

@ -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<AskBooleanAnswerChannel> => ({
channel: di.inject(askBooleanAnswerChannelInjectable),
handler: ({ id, value }) => {
@ -20,7 +23,7 @@ const askBooleanAnswerChannelListenerInjectable = getInjectable({
},
}),
injectionToken: channelListenerInjectionToken,
injectionToken: messageChannelListenerInjectionToken,
});
export default askBooleanAnswerChannelListenerInjectable;

View File

@ -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;
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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<unknown>, 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;

View File

@ -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) => {

View File

@ -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",

View File

@ -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;

View File

@ -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;

View File

@ -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);
},
};

View File

@ -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<ApplicationUpdateStatusChannel> => {
const channel = di.inject(applicationUpdateStatusChannelInjectable);
const showInfoNotification = di.inject(showInfoNotificationInjectable);
const eventHandlers: Record<ApplicationUpdateStatusEventId, { handle: (version: string) => void }> = {
const eventHandlers: Record<ApplicationUpdateStatusEventId, { handle: (version?: string) => 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;

View File

@ -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<AskBooleanQuestionChannel> => {
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;

View File

@ -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;

View File

@ -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;

View File

@ -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 <TChannel extends Channel<unknown, unknown>>(
channel: TChannel,
): Promise<TChannel["_returnTemplate"]> =>
ipcRenderer.invoke(channel.id);
},
});
export default getValueFromChannelInjectable;

View File

@ -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<unknown>, message?: unknown) => {
sendToMain(channel.id, message);
};
},
injectionToken: messageToChannelInjectionToken,
});
export default messageToChannelInjectable;

View File

@ -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;

View File

@ -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;

View File

@ -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] : []));
};
},
});

View File

@ -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<void>;
@ -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;
},
}));

View File

@ -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);
};
},
});

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
};
};

View File

@ -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<MessageChannelListener<MessageChannel<unknown>>>
>();
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<MessageChannel<unknown>>,
);
return () => {
// TODO: Figure out typing
listeners.delete(
listener as unknown as MessageChannelListener<
MessageChannel<unknown>
>,
);
};
},
);
};
};

View File

@ -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<MessageChannelListener<MessageChannel<unknown>>>
>();
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<MessageChannel<unknown>>,
);
return () => {
// TODO: Figure out typing
listeners.delete(
listener as unknown as MessageChannelListener<MessageChannel<unknown>>,
);
};
},
);
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));
});
};
};

View File

@ -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<RequestChannel<unknown, unknown>>
>();
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<unknown, unknown>
>,
);
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);
},
);
};
};

View File

@ -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,
};
};

View File

@ -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<any>; resolve: (arg0: any) => Promise<void> }
>();
const mainIpcRegistrations = {
set: <TChannel extends Channel<unknown, unknown>>(
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: <TChannel extends Channel<unknown, unknown>>(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 () => {
};
},
);
};