mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove global version of appEventBus (#6096)
* Remove global version of appEventBus Signed-off-by: Sebastian Malton <sebastian@malton.name> * Introduce a temporary but better shape of ExecFileInjectable error Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
1 parent
ba349e8b8d
commit
900f02fd8c
53 files changed
+330
-283
No files matched your search
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { AppEvent } from "../app-event-bus/event-bus";
|
||||
import { appEventBus } from "../app-event-bus/event-bus";
|
||||
import { assert, Console } from "console";
|
||||
import { stdout, stderr } from "process";
|
||||
|
||||
console = new Console(stdout, stderr);
|
||||
|
||||
describe("event bus tests", () => {
|
||||
describe("emit", () => {
|
||||
it("emits an event", () => {
|
||||
let event: AppEvent | undefined;
|
||||
|
||||
appEventBus.addListener((data) => {
|
||||
event = data;
|
||||
});
|
||||
|
||||
appEventBus.emit({ name: "foo", action: "bar" });
|
||||
assert(event);
|
||||
expect(event?.name).toBe("foo");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getGlobalOverride } from "../test-utils/get-global-override";
|
||||
import emitEventInjectable from "./emit-event.injectable";
|
||||
|
||||
export default getGlobalOverride(emitEventInjectable, () => () => {});
|
||||
@@ -3,12 +3,12 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { appEventBus } from "./event-bus";
|
||||
import { EventEmitter } from "../event-emitter";
|
||||
import type { AppEvent } from "./event-bus";
|
||||
|
||||
const appEventBusInjectable = getInjectable({
|
||||
id: "app-event-bus",
|
||||
instantiate: () => appEventBus,
|
||||
causesSideEffects: true,
|
||||
instantiate: () => new EventEmitter<[AppEvent]>,
|
||||
decorable: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -4,11 +4,18 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import appEventBusInjectable from "./app-event-bus.injectable";
|
||||
import type { AppEvent } from "./event-bus";
|
||||
|
||||
const emitEventInjectable = getInjectable({
|
||||
id: "emit-event",
|
||||
instantiate: (di) => di.inject(appEventBusInjectable).emit,
|
||||
export type EmitAppEvent = (event: AppEvent) => void;
|
||||
|
||||
const emitAppEventInjectable = getInjectable({
|
||||
id: "emit-app-event",
|
||||
instantiate: (di): EmitAppEvent => {
|
||||
const bus = di.inject(appEventBusInjectable);
|
||||
|
||||
return (event) => bus.emit(event);
|
||||
},
|
||||
decorable: false,
|
||||
});
|
||||
|
||||
export default emitEventInjectable;
|
||||
export default emitAppEventInjectable;
|
||||
@@ -3,13 +3,12 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { EventEmitter } from "../event-emitter";
|
||||
|
||||
/**
|
||||
* Data for telemetry
|
||||
*/
|
||||
export interface AppEvent {
|
||||
name: string;
|
||||
action: string;
|
||||
destination?: string;
|
||||
params?: Record<string, any>;
|
||||
}
|
||||
|
||||
export const appEventBus = new EventEmitter<[AppEvent]>();
|
||||
@@ -6,6 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { ClusterStore } from "./cluster-store";
|
||||
import { createClusterInjectionToken } from "../cluster/create-cluster-injection-token";
|
||||
import readClusterConfigSyncInjectable from "./read-cluster-config.injectable";
|
||||
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||
|
||||
const clusterStoreInjectable = getInjectable({
|
||||
id: "cluster-store",
|
||||
@@ -16,6 +17,7 @@ const clusterStoreInjectable = getInjectable({
|
||||
return ClusterStore.createInstance({
|
||||
createCluster: di.inject(createClusterInjectionToken),
|
||||
readClusterConfigSync: di.inject(readClusterConfigSyncInjectable),
|
||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import { BaseStore } from "../base-store";
|
||||
import { Cluster } from "../cluster/cluster";
|
||||
import migrations from "../../migrations/cluster-store";
|
||||
import logger from "../../main/logger";
|
||||
import { appEventBus } from "../app-event-bus/event-bus";
|
||||
import { ipcMainHandle } from "../ipc";
|
||||
import { disposer, toJS } from "../utils";
|
||||
import type { ClusterModel, ClusterId, ClusterState } from "../cluster-types";
|
||||
@@ -18,6 +17,7 @@ import { requestInitialClusterStates } from "../../renderer/ipc";
|
||||
import { clusterStates } from "../ipc/cluster";
|
||||
import type { CreateCluster } from "../cluster/create-cluster-injection-token";
|
||||
import type { ReadClusterConfigSync } from "./read-cluster-config.injectable";
|
||||
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||
|
||||
export interface ClusterStoreModel {
|
||||
clusters?: ClusterModel[];
|
||||
@@ -26,6 +26,7 @@ export interface ClusterStoreModel {
|
||||
interface Dependencies {
|
||||
createCluster: CreateCluster;
|
||||
readClusterConfigSync: ReadClusterConfigSync;
|
||||
emitAppEvent: EmitAppEvent;
|
||||
}
|
||||
|
||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
@@ -34,7 +35,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
|
||||
protected disposer = disposer();
|
||||
|
||||
constructor(private dependencies: Dependencies) {
|
||||
constructor(private readonly dependencies: Dependencies) {
|
||||
super({
|
||||
configName: "lens-cluster-store",
|
||||
accessPropertiesByDotNotation: false, // To make dots safe in cluster context names
|
||||
@@ -115,7 +116,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
}
|
||||
|
||||
addCluster(clusterOrModel: ClusterModel | Cluster): Cluster {
|
||||
appEventBus.emit({ name: "cluster", action: "add" });
|
||||
this.dependencies.emitAppEvent({ name: "cluster", action: "add" });
|
||||
|
||||
const cluster = clusterOrModel instanceof Cluster
|
||||
? clusterOrModel
|
||||
|
||||
@@ -29,7 +29,7 @@ export class EventEmitter<D extends [...any[]]> {
|
||||
this.listeners.length = 0;
|
||||
}
|
||||
|
||||
emit = (...data: D) => {
|
||||
emit(...data: D) {
|
||||
for (const [callback, { once }] of this.listeners) {
|
||||
if (once) {
|
||||
this.removeListener(callback);
|
||||
@@ -39,5 +39,5 @@ export class EventEmitter<D extends [...any[]]> {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,26 +3,23 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { ExecFileOptions } from "child_process";
|
||||
import type { ExecFileException, ExecFileOptions } from "child_process";
|
||||
import { execFile } from "child_process";
|
||||
import type { AsyncResult } from "../utils/async-result";
|
||||
|
||||
export interface ExecFile {
|
||||
(filePath: string, args: string[], options: ExecFileOptions): Promise<AsyncResult<string, { stderr: string; error: Error }>>;
|
||||
(filePath: string, args: string[], options?: ExecFileOptions): Promise<AsyncResult<string, ExecFileException & { stderr: string }>>;
|
||||
}
|
||||
|
||||
const execFileInjectable = getInjectable({
|
||||
id: "exec-file",
|
||||
|
||||
instantiate: (): ExecFile => (filePath, args, options) => new Promise((resolve) => {
|
||||
execFile(filePath, args, options, (error, stdout, stderr) => {
|
||||
execFile(filePath, args, options ?? {}, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
resolve({
|
||||
callWasSuccessful: false,
|
||||
error: {
|
||||
error,
|
||||
stderr,
|
||||
},
|
||||
error: Object.assign(error, { stderr }),
|
||||
});
|
||||
} else {
|
||||
resolve({
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { HelmRepo } from "./helm-repo";
|
||||
import type { AsyncResult } from "../utils/async-result";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
|
||||
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string>>;
|
||||
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||
|
||||
export const addHelmRepositoryChannel: AddHelmRepositoryChannel = {
|
||||
id: "add-helm-repository-channel",
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { AsyncResult } from "../utils/async-result";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
import type { HelmRepo } from "./helm-repo";
|
||||
|
||||
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string, string>>;
|
||||
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||
|
||||
export const removeHelmRepositoryChannel: RemoveHelmRepositoryChannel = {
|
||||
id: "remove-helm-repository-channel",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import fse from "fs-extra";
|
||||
import path from "path";
|
||||
import hb from "handlebars";
|
||||
import { ResourceApplier } from "../../main/resource-applier";
|
||||
import type { KubernetesCluster } from "../catalog-entities";
|
||||
import logger from "../../main/logger";
|
||||
import { app } from "electron";
|
||||
@@ -14,6 +13,8 @@ import yaml from "js-yaml";
|
||||
import { requestKubectlApplyAll, requestKubectlDeleteAll } from "../../renderer/ipc";
|
||||
import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import productNameInjectable from "../vars/product-name.injectable";
|
||||
import { asLegacyGlobalFunctionForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
|
||||
import createResourceApplierInjectable from "../../main/resource-applier/create-resource-applier.injectable";
|
||||
|
||||
export class ResourceStack {
|
||||
constructor(protected cluster: KubernetesCluster, protected name: string) {}
|
||||
@@ -52,7 +53,9 @@ export class ResourceStack {
|
||||
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
||||
|
||||
if (app) {
|
||||
return await new ResourceApplier(clusterModel).kubectlApplyAll(resources, kubectlArgs);
|
||||
const createResourceApplier = asLegacyGlobalFunctionForExtensionApi(createResourceApplierInjectable);
|
||||
|
||||
return await createResourceApplier(clusterModel).kubectlApplyAll(resources, kubectlArgs);
|
||||
} else {
|
||||
const response = await requestKubectlApplyAll(this.cluster.getId(), resources, kubectlArgs);
|
||||
|
||||
@@ -76,7 +79,9 @@ export class ResourceStack {
|
||||
kubectlArgs = this.appendKubectlArgs(kubectlArgs);
|
||||
|
||||
if (app) {
|
||||
return await new ResourceApplier(clusterModel).kubectlDeleteAll(resources, kubectlArgs);
|
||||
const createResourceApplier = asLegacyGlobalFunctionForExtensionApi(createResourceApplierInjectable);
|
||||
|
||||
return await createResourceApplier(clusterModel).kubectlDeleteAll(resources, kubectlArgs);
|
||||
} else {
|
||||
const response = await requestKubectlDeleteAll(this.cluster.getId(), resources, kubectlArgs);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { UserStore } from "./user-store";
|
||||
import selectedUpdateChannelInjectable from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||
import emitAppEventInjectable from "../app-event-bus/emit-event.injectable";
|
||||
|
||||
const userStoreInjectable = getInjectable({
|
||||
id: "user-store",
|
||||
@@ -14,6 +15,7 @@ const userStoreInjectable = getInjectable({
|
||||
|
||||
return UserStore.createInstance({
|
||||
selectedUpdateChannel: di.inject(selectedUpdateChannelInjectable),
|
||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { getOrInsertSet, toggle, toJS, object } from "../../renderer/utils";
|
||||
import { DESCRIPTORS } from "./preferences-helpers";
|
||||
import type { UserPreferencesModel, StoreType } from "./preferences-helpers";
|
||||
import logger from "../../main/logger";
|
||||
import type { EmitAppEvent } from "../app-event-bus/emit-event.injectable";
|
||||
|
||||
// TODO: Remove coupling with Feature
|
||||
import type { SelectedUpdateChannel } from "../../features/application-update/common/selected-update-channel/selected-update-channel.injectable";
|
||||
@@ -23,6 +24,7 @@ export interface UserStoreModel {
|
||||
|
||||
interface Dependencies {
|
||||
readonly selectedUpdateChannel: SelectedUpdateChannel;
|
||||
emitAppEvent: EmitAppEvent;
|
||||
}
|
||||
|
||||
export class UserStore extends BaseStore<UserStoreModel> /* implements UserStoreFlatModel (when strict null is enabled) */ {
|
||||
|
||||
@@ -3,5 +3,9 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
export type AsyncResult<Response, Error = string> =
|
||||
| { callWasSuccessful: true; response: Response }
|
||||
| (
|
||||
Response extends void
|
||||
? { callWasSuccessful: true; response?: undefined }
|
||||
: { callWasSuccessful: true; response: Response }
|
||||
)
|
||||
| { callWasSuccessful: false; error: Error };
|
||||
Reference in new issue
Block a user