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({
|
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