diff --git a/src/common/utils/channel/channel.test.ts b/src/common/utils/channel/channel.test.ts index e3b9ed1d82..5ce46019c3 100644 --- a/src/common/utils/channel/channel.test.ts +++ b/src/common/utils/channel/channel.test.ts @@ -13,12 +13,13 @@ import type { MessageChannel } from "./message-channel-listener-injection-token" import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token"; import type { RequestFromChannel } from "./request-from-channel-injection-token"; import { requestFromChannelInjectionToken } from "./request-from-channel-injection-token"; -import type { RequestChannel, RequestChannelHandler } from "./request-channel-listener-injection-token"; -import { getRequestChannelListenerInjectable } from "./request-channel-listener-injection-token"; +import type { RequestChannel } from "./request-channel-listener-injection-token"; import type { AsyncFnMock } from "@async-fn/jest"; import asyncFn from "@async-fn/jest"; import { getPromiseStatus } from "../../test-utils/get-promise-status"; import { runInAction } from "mobx"; +import type { RequestChannelHandler } from "../../../main/utils/channel/channel-listeners/listener-tokens"; +import { getRequestChannelListenerInjectable } from "../../../main/utils/channel/channel-listeners/listener-tokens"; type TestMessageChannel = MessageChannel; type TestRequestChannel = RequestChannel; @@ -148,19 +149,13 @@ describe("channel", () => { requestListenerInMainMock = asyncFn(); - const testChannelHandlerInjectable = getInjectable({ - id: "test-channel-handler", - instantiate: (): RequestChannelHandler => requestListenerInMainMock, - }); - const testChannelListenerInMainInjectable = getRequestChannelListenerInjectable({ channel: testRequestChannel, - handlerInjectable: testChannelHandlerInjectable, + handler: () => requestListenerInMainMock, }); applicationBuilder.beforeApplicationStart((mainDi) => { runInAction(() => { - mainDi.register(testChannelHandlerInjectable); mainDi.register(testChannelListenerInMainInjectable); }); }); diff --git a/src/common/utils/channel/enlist-request-channel-listener-injection-token.ts b/src/common/utils/channel/enlist-request-channel-listener-injection-token.ts deleted file mode 100644 index 27bd565785..0000000000 --- a/src/common/utils/channel/enlist-request-channel-listener-injection-token.ts +++ /dev/null @@ -1,13 +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 { Disposer } from "../disposer"; -import type { RequestChannel, RequestChannelListener } from "./request-channel-listener-injection-token"; - -export type EnlistRequestChannelListener = >(listener: RequestChannelListener) => Disposer; - -export const enlistRequestChannelListenerInjectionToken = getInjectionToken({ - id: "enlist-request-channel-listener", -}); diff --git a/src/common/utils/channel/listening-of-channels.injectable.ts b/src/common/utils/channel/listening-of-channels.injectable.ts index 30fee42fb9..6ee7d7aaf7 100644 --- a/src/common/utils/channel/listening-of-channels.injectable.ts +++ b/src/common/utils/channel/listening-of-channels.injectable.ts @@ -6,24 +6,19 @@ import { getInjectable } from "@ogre-tools/injectable"; import { getStartableStoppable } from "../get-startable-stoppable"; import { disposer } from "../index"; 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 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 messageChannelDisposers = messageChannelListeners.map(enlistMessageChannelListener); - const requestChannelDisposers = requestChannelListeners.map(enlistRequestChannelListener); - return disposer(...messageChannelDisposers, ...requestChannelDisposers); + return disposer(...messageChannelDisposers); }); }, }); diff --git a/src/common/utils/channel/request-channel-listener-injection-token.ts b/src/common/utils/channel/request-channel-listener-injection-token.ts index c523bf6665..2f0b84a3cc 100644 --- a/src/common/utils/channel/request-channel-listener-injection-token.ts +++ b/src/common/utils/channel/request-channel-listener-injection-token.ts @@ -2,48 +2,9 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { Injectable } from "@ogre-tools/injectable"; -import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; - -export type RequestChannelHandler = Channel extends RequestChannel - ? (req: Request) => Promise | Response - : never; - -export interface RequestChannelListener { - channel: Channel; - handler: RequestChannelHandler; -} export interface RequestChannel { id: string; _requestSignature?: Request; // used only to mark `Request` as "used" _responseSignature?: Response; // used only to mark `Response` as "used" } - -export const requestChannelListenerInjectionToken = getInjectionToken>>( { - id: "request-channel-listener", -}); - -export interface GetRequestChannelListenerInjectableInfo< - Channel extends RequestChannel, - Request, - Response, -> { - channel: Channel; - handlerInjectable: Injectable, unknown, void>; -} - -export function getRequestChannelListenerInjectable< - Channel extends RequestChannel, - Request, - Response, ->(info: GetRequestChannelListenerInjectableInfo) { - return getInjectable({ - id: `${info.channel.id}-listener-for-${info.handlerInjectable.id}`, - instantiate: (di) => ({ - channel: info.channel, - handler: di.inject(info.handlerInjectable), - }), - injectionToken: requestChannelListenerInjectionToken, - }); -} diff --git a/src/common/utils/iter.ts b/src/common/utils/iter.ts index 9752e56dc5..a2fc7fbd21 100644 --- a/src/common/utils/iter.ts +++ b/src/common/utils/iter.ts @@ -11,6 +11,7 @@ interface Iterator { find(fn: (val: T) => unknown): T | undefined; collect(fn: (values: Iterable) => U): U; map(fn: (val: T) => U): Iterator; + tap(fn: (val: T) => void): Iterator; flatMap(fn: (val: T) => U[]): Iterator; join(sep?: string): string; } @@ -21,6 +22,7 @@ export function pipeline(src: IterableIterator): Iterator { filterMap: (fn) => pipeline(filterMap(src, fn)), map: (fn) => pipeline(map(src, fn)), flatMap: (fn) => pipeline(flatMap(src, fn)), + tap: (fn) => pipeline(tap(src, fn)), find: (fn) => find(src, fn), join: (sep) => join(src, sep), collect: (fn) => fn(src), @@ -33,6 +35,13 @@ export function pipeline(src: IterableIterator): Iterator { */ export function* newEmpty(): IterableIterator {} +export function* tap(src: Iterable, fn: (val: T) => void): IterableIterator { + for (const val of src) { + fn(val); + yield val; + } +} + /** * Creates a new `Iterable` that yields at most n items from src. * Does not modify `src` which can be used later. diff --git a/src/features/cluster/delete-dialog/main/clear-as-deleting-channel-listener.injectable.ts b/src/features/cluster/delete-dialog/main/clear-as-deleting-channel-listener.injectable.ts index a62f8b41d2..a8dd2a80b0 100644 --- a/src/features/cluster/delete-dialog/main/clear-as-deleting-channel-listener.injectable.ts +++ b/src/features/cluster/delete-dialog/main/clear-as-deleting-channel-listener.injectable.ts @@ -2,13 +2,19 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; +import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable"; +import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens"; import { clearClusterAsDeletingChannel } from "../common/clear-as-deleting-channel"; -import clearClusterAsDeletingHandlerInjectable from "./clear-as-deleting-handler.injectable"; const clearClusterAsDeletingChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: clearClusterAsDeletingChannel, - handlerInjectable: clearClusterAsDeletingHandlerInjectable, + handler: (di) => { + const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable); + + return (clusterId) => { + clustersThatAreBeingDeleted.delete(clusterId); + }; + }, }); export default clearClusterAsDeletingChannelListenerInjectable; diff --git a/src/features/cluster/delete-dialog/main/clear-as-deleting-handler.injectable.ts b/src/features/cluster/delete-dialog/main/clear-as-deleting-handler.injectable.ts deleted file mode 100644 index d9342dde25..0000000000 --- a/src/features/cluster/delete-dialog/main/clear-as-deleting-handler.injectable.ts +++ /dev/null @@ -1,21 +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 { RequestChannelHandler } from "../../../../common/utils/channel/request-channel-listener-injection-token"; -import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable"; -import type { ClearClusterAsDeletingChannel } from "../common/clear-as-deleting-channel"; - -const clearClusterAsDeletingHandlerInjectable = getInjectable({ - id: "clear-cluster-as-deleting-handler", - instantiate: (di): RequestChannelHandler => { - const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable); - - return (clusterId) => { - clustersThatAreBeingDeleted.delete(clusterId); - }; - }, -}); - -export default clearClusterAsDeletingHandlerInjectable; diff --git a/src/features/cluster/delete-dialog/main/delete-channel-listener.injectable.ts b/src/features/cluster/delete-dialog/main/delete-channel-listener.injectable.ts index 733e3f8c4c..9b7617293a 100644 --- a/src/features/cluster/delete-dialog/main/delete-channel-listener.injectable.ts +++ b/src/features/cluster/delete-dialog/main/delete-channel-listener.injectable.ts @@ -2,13 +2,50 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; +import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable"; +import clusterFramesInjectable from "../../../../common/cluster-frames.injectable"; +import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable"; +import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; +import deleteFileInjectable from "../../../../common/fs/delete-file.injectable"; +import joinPathsInjectable from "../../../../common/path/join-paths.injectable"; +import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens"; import { deleteClusterChannel } from "../common/delete-channel"; -import deleteClusterHandlerInjectable from "./delete-cluster-handler.injectable"; const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: deleteClusterChannel, - handlerInjectable: deleteClusterHandlerInjectable, + handler: (di) => { + const appEventBus = di.inject(appEventBusInjectable); + const clusterStore = di.inject(clusterStoreInjectable); + const clusterFrames = di.inject(clusterFramesInjectable); + const joinPaths = di.inject(joinPathsInjectable); + const directoryForLensLocalStorage = di.inject(directoryForLensLocalStorageInjectable); + const deleteFile = di.inject(deleteFileInjectable); + + return async (clusterId) => { + appEventBus.emit({ name: "cluster", action: "remove" }); + + const cluster = clusterStore.getById(clusterId); + + if (!cluster) { + return; + } + + cluster.disconnect(); + clusterFrames.delete(cluster.id); + + // Remove from the cluster store as well, this should clear any old settings + clusterStore.clusters.delete(cluster.id); + + try { + // remove the local storage file + const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`); + + await deleteFile(localStorageFilePath); + } catch { + // ignore error + } + }; + }, }); export default deleteClusterChannelListenerInjectable; diff --git a/src/features/cluster/delete-dialog/main/delete-cluster-handler.injectable.ts b/src/features/cluster/delete-dialog/main/delete-cluster-handler.injectable.ts deleted file mode 100644 index dd92f03170..0000000000 --- a/src/features/cluster/delete-dialog/main/delete-cluster-handler.injectable.ts +++ /dev/null @@ -1,52 +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 { RequestChannelHandler } from "../../../../common/utils/channel/request-channel-listener-injection-token"; -import type { DeleteClusterChannel } from "../common/delete-channel"; -import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable"; -import clusterFramesInjectable from "../../../../common/cluster-frames.injectable"; -import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable"; -import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable"; -import deleteFileInjectable from "../../../../common/fs/delete-file.injectable"; -import joinPathsInjectable from "../../../../common/path/join-paths.injectable"; - -const deleteClusterHandlerInjectable = getInjectable({ - id: "delete-cluster-handler", - instantiate: (di): RequestChannelHandler => { - const appEventBus = di.inject(appEventBusInjectable); - const clusterStore = di.inject(clusterStoreInjectable); - const clusterFrames = di.inject(clusterFramesInjectable); - const joinPaths = di.inject(joinPathsInjectable); - const directoryForLensLocalStorage = di.inject(directoryForLensLocalStorageInjectable); - const deleteFile = di.inject(deleteFileInjectable); - - return async (clusterId) => { - appEventBus.emit({ name: "cluster", action: "remove" }); - - const cluster = clusterStore.getById(clusterId); - - if (!cluster) { - return; - } - - cluster.disconnect(); - clusterFrames.delete(cluster.id); - - // Remove from the cluster store as well, this should clear any old settings - clusterStore.clusters.delete(cluster.id); - - try { - // remove the local storage file - const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`); - - await deleteFile(localStorageFilePath); - } catch { - // ignore error - } - }; - }, -}); - -export default deleteClusterHandlerInjectable; diff --git a/src/features/cluster/delete-dialog/main/set-as-deleteing-channel-listener.injectable.ts b/src/features/cluster/delete-dialog/main/set-as-deleteing-channel-listener.injectable.ts index 7856a888e2..f532b4a81f 100644 --- a/src/features/cluster/delete-dialog/main/set-as-deleteing-channel-listener.injectable.ts +++ b/src/features/cluster/delete-dialog/main/set-as-deleteing-channel-listener.injectable.ts @@ -2,13 +2,19 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; +import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable"; +import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens"; import { setClusterAsDeletingChannel } from "../common/set-as-deleting-channel"; -import setClusterAsDeletingHandlerInjectable from "./set-as-deleting-handler.injectable"; const setClusterAsDeletingChannelHandlerInjectable = getRequestChannelListenerInjectable({ channel: setClusterAsDeletingChannel, - handlerInjectable: setClusterAsDeletingHandlerInjectable, + handler: (di) => { + const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable); + + return (clusterId) => { + clustersThatAreBeingDeleted.add(clusterId); + }; + }, }); export default setClusterAsDeletingChannelHandlerInjectable; diff --git a/src/features/cluster/delete-dialog/main/set-as-deleting-handler.injectable.ts b/src/features/cluster/delete-dialog/main/set-as-deleting-handler.injectable.ts deleted file mode 100644 index 1334f56557..0000000000 --- a/src/features/cluster/delete-dialog/main/set-as-deleting-handler.injectable.ts +++ /dev/null @@ -1,21 +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 { RequestChannelHandler } from "../../../../common/utils/channel/request-channel-listener-injection-token"; -import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable"; -import type { SetClusterAsDeletingChannel } from "../common/set-as-deleting-channel"; - -const setClusterAsDeletingHandlerInjectable = getInjectable({ - id: "set-cluster-as-deleting-handler", - instantiate: (di): RequestChannelHandler => { - const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable); - - return (clusterId) => { - clustersThatAreBeingDeleted.add(clusterId); - }; - }, -}); - -export default setClusterAsDeletingHandlerInjectable; diff --git a/src/main/app-paths/app-paths-channel-handler.injectable.ts b/src/main/app-paths/app-paths-channel-handler.injectable.ts deleted file mode 100644 index d66f8d6d4e..0000000000 --- a/src/main/app-paths/app-paths-channel-handler.injectable.ts +++ /dev/null @@ -1,19 +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 { AppPathsChannel } from "../../common/app-paths/app-paths-channel"; -import appPathsInjectable from "../../common/app-paths/app-paths.injectable"; -import type { RequestChannelHandler } from "../../common/utils/channel/request-channel-listener-injection-token"; - -const appPathsChannelHandlerInjectable = getInjectable({ - id: "app-paths-channel-handler", - instantiate: (di): RequestChannelHandler => { - const appPaths = di.inject(appPathsInjectable); - - return () => appPaths; - }, -}); - -export default appPathsChannelHandlerInjectable; diff --git a/src/main/app-paths/app-paths-request-channel-listener.injectable.ts b/src/main/app-paths/app-paths-request-channel-listener.injectable.ts index 7b23540e4f..568d63f1ea 100644 --- a/src/main/app-paths/app-paths-request-channel-listener.injectable.ts +++ b/src/main/app-paths/app-paths-request-channel-listener.injectable.ts @@ -2,13 +2,17 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../common/utils/channel/request-channel-listener-injection-token"; import { appPathsChannel } from "../../common/app-paths/app-paths-channel"; -import appPathsChannelHandlerInjectable from "./app-paths-channel-handler.injectable"; +import appPathsInjectable from "../../common/app-paths/app-paths.injectable"; +import { getRequestChannelListenerInjectable } from "../utils/channel/channel-listeners/listener-tokens"; const appPathsRequestChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: appPathsChannel, - handlerInjectable: appPathsChannelHandlerInjectable, + handler: (di) => { + const appPaths = di.inject(appPathsInjectable); + + return () => appPaths; + }, }); export default appPathsRequestChannelListenerInjectable; diff --git a/src/main/helm/repositories/add-helm-repository/add-helm-repository-channel-listener.injectable.ts b/src/main/helm/repositories/add-helm-repository/add-helm-repository-channel-listener.injectable.ts index 9a7411cb63..1c68bf6fd7 100644 --- a/src/main/helm/repositories/add-helm-repository/add-helm-repository-channel-listener.injectable.ts +++ b/src/main/helm/repositories/add-helm-repository/add-helm-repository-channel-listener.injectable.ts @@ -3,12 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { addHelmRepositoryChannel } from "../../../../common/helm/add-helm-repository-channel"; +import { getRequestChannelListenerInjectable } from "../../../utils/channel/channel-listeners/listener-tokens"; import addHelmRepositoryInjectable from "./add-helm-repository.injectable"; -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; const addHelmRepositoryChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: addHelmRepositoryChannel, - handlerInjectable: addHelmRepositoryInjectable, + handler: (di) => di.inject(addHelmRepositoryInjectable), }); export default addHelmRepositoryChannelListenerInjectable; diff --git a/src/main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories-channel-listener.injectable.ts b/src/main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories-channel-listener.injectable.ts index 30bee4ef87..5ef0f2b5a4 100644 --- a/src/main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories-channel-listener.injectable.ts +++ b/src/main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories-channel-listener.injectable.ts @@ -2,13 +2,13 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; import { getActiveHelmRepositoriesChannel } from "../../../../common/helm/get-active-helm-repositories-channel"; +import { getRequestChannelListenerInjectable } from "../../../utils/channel/channel-listeners/listener-tokens"; import getActiveHelmRepositoriesInjectable from "./get-active-helm-repositories.injectable"; const getActiveHelmRepositoriesChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: getActiveHelmRepositoriesChannel, - handlerInjectable: getActiveHelmRepositoriesInjectable, + handler: (di) => di.inject(getActiveHelmRepositoriesInjectable), }); export default getActiveHelmRepositoriesChannelListenerInjectable; diff --git a/src/main/helm/repositories/remove-helm-repository/remove-helm-repository-channel-listener.injectable.ts b/src/main/helm/repositories/remove-helm-repository/remove-helm-repository-channel-listener.injectable.ts index cd843be5eb..8a4e04b87c 100644 --- a/src/main/helm/repositories/remove-helm-repository/remove-helm-repository-channel-listener.injectable.ts +++ b/src/main/helm/repositories/remove-helm-repository/remove-helm-repository-channel-listener.injectable.ts @@ -2,13 +2,13 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { getRequestChannelListenerInjectable } from "../../../../common/utils/channel/request-channel-listener-injection-token"; import removeHelmRepositoryInjectable from "./remove-helm-repository.injectable"; import { removeHelmRepositoryChannel } from "../../../../common/helm/remove-helm-repository-channel"; +import { getRequestChannelListenerInjectable } from "../../../utils/channel/channel-listeners/listener-tokens"; const removeHelmRepositoryChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: removeHelmRepositoryChannel, - handlerInjectable: removeHelmRepositoryInjectable, + handler: (di) => di.inject(removeHelmRepositoryInjectable), }); export default removeHelmRepositoryChannelListenerInjectable; diff --git a/src/main/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts b/src/main/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts index d29a1863ce..d72e4afcaf 100644 --- a/src/main/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts +++ b/src/main/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts @@ -5,12 +5,16 @@ import { getInjectable } from "@ogre-tools/injectable"; import type { IpcMainInvokeEvent } from "electron"; import ipcMainInjectable from "../ipc-main/ipc-main.injectable"; -import { enlistRequestChannelListenerInjectionToken } from "../../../../common/utils/channel/enlist-request-channel-listener-injection-token"; +import type { Disposer } from "../../../../common/utils"; +import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token"; +import type { RequestChannelListener } from "./listener-tokens"; + +export type EnlistRequestChannelListener = >(listener: RequestChannelListener) => Disposer; const enlistRequestChannelListenerInjectable = getInjectable({ id: "enlist-request-channel-listener-for-main", - instantiate: (di) => { + instantiate: (di): EnlistRequestChannelListener => { const ipcMain = di.inject(ipcMainInjectable); return ({ channel, handler }) => { @@ -23,8 +27,6 @@ const enlistRequestChannelListenerInjectable = getInjectable({ }; }; }, - - injectionToken: enlistRequestChannelListenerInjectionToken, }); export default enlistRequestChannelListenerInjectable; diff --git a/src/main/utils/channel/channel-listeners/handling-of-channels.injectable.ts b/src/main/utils/channel/channel-listeners/handling-of-channels.injectable.ts new file mode 100644 index 0000000000..40ac50882c --- /dev/null +++ b/src/main/utils/channel/channel-listeners/handling-of-channels.injectable.ts @@ -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 { disposer, iter } from "../../../../common/utils"; +import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token"; +import { getStartableStoppable } from "../../../../common/utils/get-startable-stoppable"; +import enlistRequestChannelListenerInjectable from "./enlist-request-channel-listener.injectable"; +import { requestChannelListenerInjectionToken } from "./listener-tokens"; + +const listenerOfRequestChannelsInjectable = getInjectable({ + id: "listener-of-request-channels", + instantiate: (di) => { + const enlistRequestChannelListener = di.inject(enlistRequestChannelListenerInjectable); + const requestChannelListeners = di.injectMany(requestChannelListenerInjectionToken); + + return getStartableStoppable("listening-of-request-channels", () => { + const seenChannels = new Set>(); + const requestChannelDisposers = iter.pipeline(requestChannelListeners.values()) + .tap(listener => { + if (seenChannels.has(listener.channel)) { + throw new Error(`Trying to register a multiple channel handlers for "${listener.channel.id}", which is an error`); + } + + seenChannels.add(listener.channel); + }) + .map(enlistRequestChannelListener) + .collect(v => Array.from(v)); + + return disposer(...requestChannelDisposers); + }); + }, +}); + +export default listenerOfRequestChannelsInjectable; diff --git a/src/main/utils/channel/channel-listeners/listener-tokens.ts b/src/main/utils/channel/channel-listeners/listener-tokens.ts new file mode 100644 index 0000000000..a3cd5af4f4 --- /dev/null +++ b/src/main/utils/channel/channel-listeners/listener-tokens.ts @@ -0,0 +1,46 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type { DiContainerForInjection } from "@ogre-tools/injectable"; +import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; +import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token"; + +export type RequestChannelHandler = Channel extends RequestChannel + ? (req: Request) => Promise | Response + : never; + +export interface RequestChannelListener { + channel: Channel; + handler: RequestChannelHandler; +} + + +export const requestChannelListenerInjectionToken = getInjectionToken>>( { + id: "request-channel-listener", +}); + +export interface GetRequestChannelListenerInjectableInfo< + Channel extends RequestChannel, + Request, + Response, +> { + channel: Channel; + handler: (di: DiContainerForInjection) => RequestChannelHandler; +} + +export function getRequestChannelListenerInjectable< + Channel extends RequestChannel, + Request, + Response, +>(info: GetRequestChannelListenerInjectableInfo) { + return getInjectable({ + id: `${info.channel.id}-listener`, + instantiate: (di) => ({ + channel: info.channel, + handler: info.handler(di), + }), + injectionToken: requestChannelListenerInjectionToken, + }); +} diff --git a/src/main/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts b/src/main/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts index 78d73044e9..ebb8afe385 100644 --- a/src/main/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts +++ b/src/main/utils/channel/channel-listeners/start-listening-of-channels.injectable.ts @@ -5,17 +5,20 @@ import { getInjectable } from "@ogre-tools/injectable"; import { onLoadOfApplicationInjectionToken } from "../../../start-main-application/runnable-tokens/on-load-of-application-injection-token"; import listeningOfChannelsInjectable from "../../../../common/utils/channel/listening-of-channels.injectable"; +import listenerOfRequestChannelsInjectable from "./handling-of-channels.injectable"; const startListeningOfChannelsInjectable = getInjectable({ id: "start-listening-of-channels-main", instantiate: (di) => { const listeningOfChannels = di.inject(listeningOfChannelsInjectable); + const listenerOfRequestChannels = di.inject(listenerOfRequestChannelsInjectable); return { id: "start-listening-of-channels-main", run: async () => { await listeningOfChannels.start(); + await listenerOfRequestChannels.start(); }, }; }, diff --git a/src/main/utils/resolve-system-proxy/resolve-system-proxy-channel-responder.injectable.ts b/src/main/utils/resolve-system-proxy/resolve-system-proxy-channel-responder.injectable.ts index b69d4d390e..a2cd605633 100644 --- a/src/main/utils/resolve-system-proxy/resolve-system-proxy-channel-responder.injectable.ts +++ b/src/main/utils/resolve-system-proxy/resolve-system-proxy-channel-responder.injectable.ts @@ -3,12 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { resolveSystemProxyChannel } from "../../../common/utils/resolve-system-proxy/resolve-system-proxy-channel"; +import { getRequestChannelListenerInjectable } from "../channel/channel-listeners/listener-tokens"; import resolveSystemProxyInjectable from "./resolve-system-proxy.injectable"; -import { getRequestChannelListenerInjectable } from "../../../common/utils/channel/request-channel-listener-injection-token"; const resolveSystemProxyChannelResponderInjectable = getRequestChannelListenerInjectable({ channel: resolveSystemProxyChannel, - handlerInjectable: resolveSystemProxyInjectable, + handler: (di) => di.inject(resolveSystemProxyInjectable), }); export default resolveSystemProxyChannelResponderInjectable; diff --git a/src/main/utils/sync-box/sync-box-initial-value-channel-listener.injectable.ts b/src/main/utils/sync-box/sync-box-initial-value-channel-listener.injectable.ts index 30e282587a..da78d76c36 100644 --- a/src/main/utils/sync-box/sync-box-initial-value-channel-listener.injectable.ts +++ b/src/main/utils/sync-box/sync-box-initial-value-channel-listener.injectable.ts @@ -3,12 +3,19 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { syncBoxInitialValueChannel } from "../../../common/utils/sync-box/channels"; -import { getRequestChannelListenerInjectable } from "../../../common/utils/channel/request-channel-listener-injection-token"; -import syncBoxInitialValueChannelHandlerInjectable from "./sync-box-initial-value-handler.injectable"; +import { syncBoxInjectionToken } from "../../../common/utils/sync-box/sync-box-injection-token"; +import { getRequestChannelListenerInjectable } from "../channel/channel-listeners/listener-tokens"; const syncBoxInitialValueChannelListenerInjectable = getRequestChannelListenerInjectable({ channel: syncBoxInitialValueChannel, - handlerInjectable: syncBoxInitialValueChannelHandlerInjectable, + handler: (di) => { + const syncBoxes = di.injectMany(syncBoxInjectionToken); + + return () => syncBoxes.map((box) => ({ + id: box.id, + value: box.value.get(), + })); + }, }); export default syncBoxInitialValueChannelListenerInjectable; diff --git a/src/renderer/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts b/src/renderer/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts deleted file mode 100644 index 03253a06f2..0000000000 --- a/src/renderer/utils/channel/channel-listeners/enlist-request-channel-listener.injectable.ts +++ /dev/null @@ -1,19 +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 { enlistRequestChannelListenerInjectionToken } from "../../../../common/utils/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;