mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Implement requesting from renderer in main
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
2c38a65da8
commit
6c310034c2
@ -227,6 +227,75 @@ describe("channel", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("requesting from renderer in main, given listener for channel in a renderer and application has started", () => {
|
||||
let testRequestChannel: TestRequestChannel;
|
||||
let requestListenerInRendererMock: AsyncFnMock<(arg: string) => string>;
|
||||
let rendererDi: DiContainer;
|
||||
let mainDi: DiContainer;
|
||||
let requestFromChannel: RequestFromChannel;
|
||||
|
||||
beforeEach(async () => {
|
||||
const applicationBuilder = getApplicationBuilder();
|
||||
|
||||
mainDi = applicationBuilder.dis.mainDi;
|
||||
rendererDi = applicationBuilder.dis.rendererDi;
|
||||
|
||||
requestListenerInRendererMock = asyncFn();
|
||||
|
||||
const testChannelListenerInRendererInjectable = getInjectable({
|
||||
id: "test-channel-listener-in-renderer",
|
||||
|
||||
instantiate: (di) => ({
|
||||
channel: di.inject(testRequestChannelInjectable),
|
||||
|
||||
handler: requestListenerInRendererMock,
|
||||
}),
|
||||
|
||||
injectionToken: requestChannelListenerInjectionToken,
|
||||
});
|
||||
|
||||
rendererDi.register(testChannelListenerInRendererInjectable);
|
||||
|
||||
// Notice how test channel has presence in both DIs, being from common
|
||||
mainDi.register(testRequestChannelInjectable);
|
||||
rendererDi.register(testRequestChannelInjectable);
|
||||
|
||||
testRequestChannel = mainDi.inject(testRequestChannelInjectable);
|
||||
|
||||
requestFromChannel = mainDi.inject(
|
||||
requestFromChannelInjectionToken,
|
||||
);
|
||||
|
||||
await applicationBuilder.render();
|
||||
});
|
||||
|
||||
describe("when requesting from channel", () => {
|
||||
let actualPromise: Promise<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
actualPromise = requestFromChannel(testRequestChannel, "some-request");
|
||||
});
|
||||
|
||||
it("triggers listener in renderer", () => {
|
||||
expect(requestListenerInRendererMock).toHaveBeenCalledWith("some-request");
|
||||
});
|
||||
|
||||
it("does not resolve yet", async () => {
|
||||
const promiseStatus = await getPromiseStatus(actualPromise);
|
||||
|
||||
expect(promiseStatus.fulfilled).toBe(false);
|
||||
});
|
||||
|
||||
it("when renderer resolves with response, resolves with response", async () => {
|
||||
await requestListenerInRendererMock.resolve("some-response");
|
||||
|
||||
const actual = await actualPromise;
|
||||
|
||||
expect(actual).toBe("some-response");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const testMessageChannelInjectable = getInjectable({
|
||||
|
||||
@ -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 type { MessageChannel } from "../message-channel-injection-token";
|
||||
import { messageChannelInjectionToken } from "../message-channel-injection-token";
|
||||
|
||||
export type RequestFromChannelForMainRequestChannel = MessageChannel<{ channelId: string; request: any }>;
|
||||
|
||||
const requestFromChannelForMainRequestChannelInjectable = getInjectable({
|
||||
id: "request-from-channel-for-main-request-channel",
|
||||
|
||||
instantiate: (): RequestFromChannelForMainRequestChannel => ({
|
||||
id: "request-from-channel-for-main-request-channel",
|
||||
}),
|
||||
|
||||
injectionToken: messageChannelInjectionToken,
|
||||
});
|
||||
|
||||
export default requestFromChannelForMainRequestChannelInjectable;
|
||||
@ -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 type { MessageChannel } from "../message-channel-injection-token";
|
||||
import { messageChannelInjectionToken } from "../message-channel-injection-token";
|
||||
|
||||
export type RequestFromChannelForMainResponseChannel = MessageChannel<{ channelId: string; response: any }>;
|
||||
|
||||
const requestFromChannelForMainResponseChannelInjectable = getInjectable({
|
||||
id: "request-from-channel-for-main-response-channel",
|
||||
|
||||
instantiate: (): RequestFromChannelForMainResponseChannel => ({
|
||||
id: "request-from-channel-for-main-response-channel",
|
||||
}),
|
||||
|
||||
injectionToken: messageChannelInjectionToken,
|
||||
});
|
||||
|
||||
export default requestFromChannelForMainResponseChannelInjectable;
|
||||
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 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 { MessageChannelListener } from "../../../common/channel/message-channel-listener-injection-token";
|
||||
import { messageChannelListenerInjectionToken } from "../../../common/channel/message-channel-listener-injection-token";
|
||||
import type { RequestFromChannelForMainResponseChannel } from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-response-channel.injectable";
|
||||
import requestFromChannelForMainResponseChannelInjectable from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-response-channel.injectable";
|
||||
import requestFromChannelForMainResponsePromiseInjectable from "./request-from-channel-for-main-response-promise.injectable";
|
||||
|
||||
const requestFromChannelForMainResponseChannelListenerInjectable =
|
||||
getInjectable({
|
||||
id: "request-from-channel-for-main-response-channel-listener",
|
||||
|
||||
instantiate: (
|
||||
di,
|
||||
): MessageChannelListener<RequestFromChannelForMainResponseChannel> => {
|
||||
const channel = di.inject(requestFromChannelForMainResponseChannelInjectable);
|
||||
const getResponsePromise = (channelId: string) => di.inject(requestFromChannelForMainResponsePromiseInjectable, channelId);
|
||||
|
||||
return {
|
||||
channel,
|
||||
|
||||
handler: ({ channelId, response }) => {
|
||||
const responsePromise = getResponsePromise(channelId);
|
||||
|
||||
responsePromise.resolve(response);
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: messageChannelListenerInjectionToken,
|
||||
});
|
||||
|
||||
export default requestFromChannelForMainResponseChannelListenerInjectable;
|
||||
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
|
||||
|
||||
const requestFromChannelForMainResponsePromiseInjectable = getInjectable({
|
||||
id: "request-from-channel-for-main-response-promise",
|
||||
|
||||
instantiate: (di, channelId: string) => {
|
||||
void channelId;
|
||||
|
||||
let resolve: (response: boolean) => void;
|
||||
|
||||
const promise = new Promise<boolean>(_resolve => {
|
||||
resolve = _resolve;
|
||||
});
|
||||
|
||||
return ({
|
||||
promise,
|
||||
|
||||
resolve: (response: boolean) => {
|
||||
resolve(response);
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
lifecycle: lifecycleEnum.keyedSingleton({
|
||||
getInstanceKey: (di, channelId: string) => channelId,
|
||||
}),
|
||||
});
|
||||
|
||||
export default requestFromChannelForMainResponsePromiseInjectable;
|
||||
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* 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 { requestFromChannelInjectionToken } from "../../../common/channel/request-from-channel-injection-token";
|
||||
import { messageToChannelInjectionToken } from "../../../common/channel/message-to-channel-injection-token";
|
||||
import requestFromChannelForMainRequestChannelInjectable from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-request-channel.injectable";
|
||||
import requestFromChannelForMainResponsePromiseInjectable from "./request-from-channel-for-main-response-promise.injectable";
|
||||
|
||||
const requestFromChannelInjectable = getInjectable({
|
||||
id: "request-from-channel",
|
||||
|
||||
instantiate: (di) => {
|
||||
const messageToChannel = di.inject(messageToChannelInjectionToken);
|
||||
const requestFromChannelForMainMessageChannel = di.inject(requestFromChannelForMainRequestChannelInjectable);
|
||||
const getResponsePromise = (channelId: string) => di.inject(requestFromChannelForMainResponsePromiseInjectable, channelId);
|
||||
|
||||
return async (channel, ...[request]) => {
|
||||
const responsePromise = getResponsePromise(channel.id);
|
||||
|
||||
messageToChannel(requestFromChannelForMainMessageChannel, { channelId: channel.id, request });
|
||||
|
||||
return await responsePromise.promise;
|
||||
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: requestFromChannelInjectionToken,
|
||||
});
|
||||
|
||||
export default requestFromChannelInjectable;
|
||||
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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 { MessageChannelListener } from "../../../common/channel/message-channel-listener-injection-token";
|
||||
import { messageChannelListenerInjectionToken } from "../../../common/channel/message-channel-listener-injection-token";
|
||||
import type { RequestFromChannelForMainRequestChannel } from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-request-channel.injectable";
|
||||
import requestFromChannelForMainRequestChannelInjectable from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-request-channel.injectable";
|
||||
import { requestChannelListenerInjectionToken } from "../../../common/channel/request-channel-listener-injection-token";
|
||||
import requestFromChannelForMainResponseChannelInjectable from "../../../common/channel/request-from-channel-for-main/request-from-channel-for-main-response-channel.injectable";
|
||||
import { messageToChannelInjectionToken } from "../../../common/channel/message-to-channel-injection-token";
|
||||
|
||||
const requestFromChannelForMainMessageChannelListenerInjectable = getInjectable(
|
||||
{
|
||||
id: "request-from-channel-for-main-message-channel-listener",
|
||||
|
||||
instantiate: (di): MessageChannelListener<RequestFromChannelForMainRequestChannel> => {
|
||||
const requestChannel = di.inject(requestFromChannelForMainRequestChannelInjectable);
|
||||
const responseChannel = di.inject(requestFromChannelForMainResponseChannelInjectable);
|
||||
const messageToChannel = di.inject(messageToChannelInjectionToken);
|
||||
const listeners = di.injectMany(requestChannelListenerInjectionToken);
|
||||
|
||||
return {
|
||||
channel: requestChannel,
|
||||
|
||||
handler: async ({ channelId, request }) => {
|
||||
const targetListener = listeners.find(listener => listener.channel.id === channelId);
|
||||
|
||||
if (targetListener) {
|
||||
const response = await targetListener.handler(request);
|
||||
|
||||
messageToChannel(responseChannel, {
|
||||
channelId,
|
||||
response,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
injectionToken: messageChannelListenerInjectionToken,
|
||||
},
|
||||
);
|
||||
|
||||
export default requestFromChannelForMainMessageChannelListenerInjectable;
|
||||
Loading…
Reference in New Issue
Block a user