diff --git a/src/common/runnable/run-many-for.test.ts b/src/common/runnable/run-many-for.test.ts index c73f448dd2..c2cc152681 100644 --- a/src/common/runnable/run-many-for.test.ts +++ b/src/common/runnable/run-many-for.test.ts @@ -223,7 +223,7 @@ describe("runManyFor", () => { ); return expect(() => runMany()).rejects.toThrow( - 'Tried to run runnable "some-runnable-1" after the runnable "some-runnable-2" which does not share the "some-injection-token" injection token.', + /Tried to get a composite but encountered missing parent ids: "some-runnable-2".\n\nAvailable parent ids are:\n"[0-9a-z-]+",\n"some-runnable-1"/, ); }); diff --git a/src/common/runnable/run-many-for.ts b/src/common/runnable/run-many-for.ts index 478d7f84a4..ce3123c0b0 100644 --- a/src/common/runnable/run-many-for.ts +++ b/src/common/runnable/run-many-for.ts @@ -2,13 +2,10 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { pipeline } from "@ogre-tools/fp"; -import type { - DiContainerForInjection, - InjectionToken, -} from "@ogre-tools/injectable"; -import { filter, forEach, map, tap } from "lodash/fp"; -import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for"; +import type { DiContainerForInjection, InjectionToken } from "@ogre-tools/injectable"; +import type { Composite } from "../utils/composite/get-composite/get-composite"; +import { getCompositeFor } from "../utils/composite/get-composite/get-composite"; +import * as uuid from "uuid"; export interface Runnable { id: string; @@ -18,35 +15,34 @@ export interface Runnable { type Run = (parameter: Param) => Promise | void; -export type RunMany = ( - injectionToken: InjectionToken, void> -) => Run; +export type RunMany = (injectionToken: InjectionToken, void>) => Run; + +async function runCompositeRunnables(param: Param, composite: Composite>) { + await composite.value.run(param); + await Promise.all(composite.children.map(composite => runCompositeRunnables(param, composite))); +} export function runManyFor(di: DiContainerForInjection): RunMany { - return (injectionToken) => async (parameter) => { + return (injectionToken: InjectionToken, void>) => async (param: Param) => { const allRunnables = di.injectMany(injectionToken); + const rootId = uuid.v4(); + const getCompositeRunnables = getCompositeFor>({ + getId: (runnable) => runnable.id, + getParentId: (runnable) => ( + runnable.id === rootId + ? undefined + : runnable.runAfter?.id ?? rootId + ), + }); + const composite = getCompositeRunnables([ + // This is a dummy runnable to conform to the requirements of `getCompositeFor` to only have one root + { + id: rootId, + run: () => {}, + }, + ...allRunnables, + ]); - const throwWithIncorrectHierarchy = throwWithIncorrectHierarchyFor((injectionToken as any).id, allRunnables); - - const recursedRun = async ( - runAfterRunnable: Runnable | undefined = undefined, - ) => - await pipeline( - allRunnables, - - tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)), - - filter((runnable) => runnable.runAfter === runAfterRunnable), - - map(async (runnable) => { - await runnable.run(parameter); - - await recursedRun(runnable); - }), - - (promises) => Promise.all(promises), - ); - - await recursedRun(); + await runCompositeRunnables(param, composite); }; } diff --git a/src/common/runnable/run-many-sync-for.test.ts b/src/common/runnable/run-many-sync-for.test.ts index 43d2832663..3aadcad0bf 100644 --- a/src/common/runnable/run-many-sync-for.test.ts +++ b/src/common/runnable/run-many-sync-for.test.ts @@ -69,7 +69,7 @@ describe("runManySyncFor", () => { instantiate: (di) => ({ id: "some-injectable-1", - run: () => runMock("third-level-run"), + run: () => void runMock("third-level-run"), runAfter: di.inject(someInjectable2), }), @@ -81,7 +81,7 @@ describe("runManySyncFor", () => { instantiate: (di) => ({ id: "some-injectable-2", - run: () => runMock("second-level-run"), + run: () => void runMock("second-level-run"), runAfter: di.inject(someInjectable3), }), @@ -92,7 +92,7 @@ describe("runManySyncFor", () => { id: "some-injectable-3", instantiate: () => ({ id: "some-injectable-3", - run: () => runMock("first-level-run"), + run: () => void runMock("first-level-run"), }), injectionToken: someInjectionTokenForRunnables, }); @@ -151,13 +151,13 @@ describe("runManySyncFor", () => { someInjectionToken, ); - return expect(() => runMany()).rejects.toThrow( - 'Tried to run runnable "some-runnable-1" after the runnable "some-runnable-2" which does not share the "some-injection-token" injection token.', + return expect(() => runMany()).toThrow( + /Tried to get a composite but encountered missing parent ids: "some-runnable-2".\n\nAvailable parent ids are:\n"[0-9a-z-]+",\n"some-runnable-1"/, ); }); describe("when running many with parameter", () => { - let runMock: jest.Mock<(arg: string, arg2: string) => void>; + let runMock: jest.Mock<(arg: string, arg2: string) => undefined>; beforeEach(() => { const rootDi = createContainer("irrelevant"); @@ -175,7 +175,7 @@ describe("runManySyncFor", () => { instantiate: () => ({ id: "some-runnable-1", - run: (parameter) => runMock("run-of-some-runnable-1", parameter), + run: (parameter) => void runMock("run-of-some-runnable-1", parameter), }), injectionToken: someInjectionTokenForRunnablesWithParameter, @@ -186,7 +186,7 @@ describe("runManySyncFor", () => { instantiate: () => ({ id: "some-runnable-2", - run: (parameter) => runMock("run-of-some-runnable-2", parameter), + run: (parameter) => void runMock("run-of-some-runnable-2", parameter), }), injectionToken: someInjectionTokenForRunnablesWithParameter, diff --git a/src/common/runnable/run-many-sync-for.ts b/src/common/runnable/run-many-sync-for.ts index 1d3dcec2c5..08dba2f72d 100644 --- a/src/common/runnable/run-many-sync-for.ts +++ b/src/common/runnable/run-many-sync-for.ts @@ -2,11 +2,10 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import { pipeline } from "@ogre-tools/fp"; import type { DiContainerForInjection, InjectionToken } from "@ogre-tools/injectable"; -import { filter, forEach, map, tap } from "lodash/fp"; -import type { Runnable } from "./run-many-for"; -import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for"; +import type { Composite } from "../utils/composite/get-composite/get-composite"; +import { getCompositeFor } from "../utils/composite/get-composite/get-composite"; +import * as uuid from "uuid"; export interface RunnableSync { id: string; @@ -14,35 +13,43 @@ export interface RunnableSync { runAfter?: RunnableSync; } -type RunSync = (parameter: Param) => void; +/** + * NOTE: this is the worse of two evils. This makes sure that `RunnableSync` always is sync. + * If the return type is `void` instead then async functions (those return `Promise`) can + * coerce to it. + */ +type RunSync = (parameter: Param) => undefined; -export type RunManySync = ( - injectionToken: InjectionToken, void> -) => RunSync; +export type RunManySync = (injectionToken: InjectionToken, void>) => RunSync; + +function runCompositeRunnableSyncs(param: Param, composite: Composite>): undefined { + composite.value.run(param); + composite.children.map(composite => runCompositeRunnableSyncs(param, composite)); + + return undefined; +} export function runManySyncFor(di: DiContainerForInjection): RunManySync { - return (injectionToken) => async (parameter) => { + return (injectionToken: InjectionToken, void>) => (param: Param): undefined => { const allRunnables = di.injectMany(injectionToken); + const rootId = uuid.v4(); + const getCompositeRunnables = getCompositeFor>({ + getId: (runnable) => runnable.id, + getParentId: (runnable) => ( + runnable.id === rootId + ? undefined + : runnable.runAfter?.id ?? rootId + ), + }); + const composite = getCompositeRunnables([ + // This is a dummy runnable to conform to the requirements of `getCompositeFor` to only have one root + { + id: rootId, + run: () => undefined, + }, + ...allRunnables, + ]); - const throwWithIncorrectHierarchy = throwWithIncorrectHierarchyFor((injectionToken as any).id, allRunnables); - - const recursedRun = ( - runAfterRunnable: RunnableSync | undefined = undefined, - ) => - pipeline( - allRunnables, - - tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)), - - filter((runnable) => runnable.runAfter === runAfterRunnable), - - map((runnable) => { - runnable.run(parameter); - - recursedRun(runnable); - }), - ); - - recursedRun(); + return runCompositeRunnableSyncs(param, composite); }; } diff --git a/src/common/runnable/throw-with-incorrect-hierarchy-for.ts b/src/common/runnable/throw-with-incorrect-hierarchy-for.ts deleted file mode 100644 index bddf8037c2..0000000000 --- a/src/common/runnable/throw-with-incorrect-hierarchy-for.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ -import type { Runnable } from "./run-many-for"; -import type { RunnableSync } from "./run-many-sync-for"; - -export const throwWithIncorrectHierarchyFor = (injectionTokenId: string, allRunnables: Runnable[] | RunnableSync[]) => ( - (runnable: Runnable | RunnableSync) => { - if (runnable.runAfter && !allRunnables.includes(runnable.runAfter)) { - throw new Error(`Tried to run runnable "${runnable.id}" after the runnable "${runnable.runAfter.id}" which does not share the "${injectionTokenId}" injection token.`); - } - } -); diff --git a/src/common/utils/get-startable-stoppable.test.ts b/src/common/utils/get-startable-stoppable.test.ts index 24b9e1862d..dc8b24dd43 100644 --- a/src/common/utils/get-startable-stoppable.test.ts +++ b/src/common/utils/get-startable-stoppable.test.ts @@ -2,21 +2,17 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { AsyncFnMock } from "@async-fn/jest"; -import asyncFn from "@async-fn/jest"; +import type { StartableStoppable } from "./get-startable-stoppable"; import { getStartableStoppable } from "./get-startable-stoppable"; -import { getPromiseStatus } from "../test-utils/get-promise-status"; -import { flushPromises } from "../test-utils/flush-promises"; describe("getStartableStoppable", () => { - let stopMock: AsyncFnMock<() => Promise>; - let startMock: AsyncFnMock<() => Promise<() => Promise>>; - let actual: { stop: () => Promise; start: () => Promise; started: boolean }; + let stopMock: jest.MockedFunction<() => void>; + let startMock: jest.MockedFunction<() => () => void>; + let actual: StartableStoppable; beforeEach(() => { - stopMock = asyncFn(); - startMock = asyncFn(); - + stopMock = jest.fn(); + startMock = jest.fn().mockImplementation(() => stopMock); actual = getStartableStoppable("some-id", startMock); }); @@ -29,7 +25,7 @@ describe("getStartableStoppable", () => { }); it("when stopping before ever starting, throws", () => { - expect(actual.stop).rejects.toThrow("Tried to stop \"some-id\", but it has not started yet."); + expect(() => actual.stop()).toThrow("Tried to stop \"some-id\", but it is already stopped."); }); it("is not started", () => { @@ -37,199 +33,30 @@ describe("getStartableStoppable", () => { }); describe("when started", () => { - let startPromise: Promise; - beforeEach(() => { - startPromise = actual.start(); + actual.start(); }); - it("starts starting", () => { + it("calls start function", () => { expect(startMock).toHaveBeenCalled(); }); - it("starting does not resolve yet", async () => { - const promiseStatus = await getPromiseStatus(startPromise); - - expect(promiseStatus.fulfilled).toBe(false); + it("is started", () => { + expect(actual.started).toBe(true); }); - it("is not started yet", () => { - expect(actual.started).toBe(false); - }); - - describe("when started again before the start has finished", () => { - let error: Error; - + describe("when stopped", () => { beforeEach(() => { - startMock.mockClear(); - - actual.start().catch((e) => { error = e; }); + actual.stop(); }); - it("does not start starting again", () => { - expect(startMock).not.toHaveBeenCalled(); + it("calls stop function", () => { + expect(stopMock).toBeCalled(); }); - it("throws", () => { - expect(error.message).toBe("Tried to start \"some-id\", but it is already being started."); - }); - }); - - describe("when starting finishes", () => { - beforeEach(async () => { - await startMock.resolve(stopMock); - }); - - it("is started", () => { - expect(actual.started).toBe(true); - }); - - it("starting resolves", async () => { - const promiseStatus = await getPromiseStatus(startPromise); - - expect(promiseStatus.fulfilled).toBe(true); - }); - - it("when started again, throws", () => { - expect(actual.start).rejects.toThrow("Tried to start \"some-id\", but it has already started."); - }); - - it("does not stop yet", () => { - expect(stopMock).not.toHaveBeenCalled(); - }); - - describe("when stopped", () => { - let stopPromise: Promise; - - beforeEach(() => { - stopPromise = actual.stop(); - }); - - it("starts stopping", () => { - expect(stopMock).toHaveBeenCalled(); - }); - - it("stopping does not resolve yet", async () => { - const promiseStatus = await getPromiseStatus(stopPromise); - - expect(promiseStatus.fulfilled).toBe(false); - }); - - it("is not stopped yet", () => { - expect(actual.started).toBe(true); - }); - - describe("when stopping finishes", () => { - beforeEach(async () => { - await stopMock.resolve(); - }); - - it("is not started", () => { - expect(actual.started).toBe(false); - }); - - it("stopping resolves", async () => { - const promiseStatus = await getPromiseStatus(stopPromise); - - expect(promiseStatus.fulfilled).toBe(true); - }); - - it("when stopped again, throws", () => { - expect(actual.stop).rejects.toThrow("Tried to stop \"some-id\", but it has already stopped."); - }); - - describe("when started again", () => { - beforeEach( - () => { - startMock.mockClear(); - - actual.start(); - }); - - it("starts", () => { - expect(startMock).toHaveBeenCalled(); - }); - - it("is not started yet", () => { - expect(actual.started).toBe(false); - }); - - describe("when starting finishes", () => { - beforeEach(async () => { - await startMock.resolve(stopMock); - }); - - it("is started", () => { - expect(actual.started).toBe(true); - }); - - it("when stopped again, starts stopping again", async () => { - stopMock.mockClear(); - - actual.stop(); - - await flushPromises(); - - expect(stopMock).toHaveBeenCalled(); - }); - }); - }); - }); - }); - }); - - describe("when stopped before starting finishes", () => { - let stopPromise: Promise; - - beforeEach(() => { - stopPromise = actual.stop(); - }); - - it("does not resolve yet", async () => { - const promiseStatus = await getPromiseStatus(stopPromise); - - expect(promiseStatus.fulfilled).toBe(false); - }); - - it("is not started yet", () => { + it("is stopped", () => { expect(actual.started).toBe(false); }); - - describe("when starting finishes", () => { - beforeEach(async () => { - await startMock.resolve(stopMock); - }); - - it("starts stopping", () => { - expect(stopMock).toHaveBeenCalled(); - }); - - it("is not stopped yet", () => { - expect(actual.started).toBe(true); - }); - - it("does not resolve yet", async () => { - const promiseStatus = await getPromiseStatus(stopPromise); - - expect(promiseStatus.fulfilled).toBe(false); - }); - - describe("when stopping finishes", () => { - beforeEach(async () => { - await stopMock.resolve(); - }); - - it("is stopped", () => { - expect(actual.started).toBe(false); - }); - - it("resolves", async () => { - const promiseStatus = await getPromiseStatus(stopPromise); - - expect(promiseStatus.fulfilled).toBe(true); - }); - }); - }); }); }); }); diff --git a/src/common/utils/get-startable-stoppable.ts b/src/common/utils/get-startable-stoppable.ts index 5590157ab8..05d8b4d9af 100644 --- a/src/common/utils/get-startable-stoppable.ts +++ b/src/common/utils/get-startable-stoppable.ts @@ -3,58 +3,43 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -type Stopper = () => Promise | void; -type Starter = () => Promise | Stopper; +export type Stopper = () => void; +export type Starter = () => Stopper; -export const getStartableStoppable = ( - id: string, - startAndGetStopCallback: Starter, -) => { +export interface StartableStoppable { + readonly started: boolean; + start: () => void; + stop: () => void; +} + +type StartableStoppableState = "stopped" | "started" | "starting"; + +export function getStartableStoppable(id: string, startAndGetStopper: Starter): StartableStoppable { let stop: Stopper; - let stopped = false; - let started = false; - let starting = false; - let startingPromise: Promise | Stopper; + let state: StartableStoppableState = "stopped"; return { get started() { - return started; + return state === "started"; }, - start: async () => { - if (starting) { - throw new Error(`Tried to start "${id}", but it is already being started.`); + start: () => { + if (state !== "stopped") { + throw new Error(`Tried to start "${id}", but it is already ${state}.`); } - starting = true; - - if (started) { - throw new Error(`Tried to start "${id}", but it has already started.`); - } - - startingPromise = startAndGetStopCallback(); - stop = await startingPromise; - - stopped = false; - started = true; - starting = false; + state = "starting"; + stop = startAndGetStopper(); + state = "started"; }, - stop: async () => { - await startingPromise; - - if (stopped) { - throw new Error(`Tried to stop "${id}", but it has already stopped.`); + stop: () => { + if (state !== "started") { + throw new Error(`Tried to stop "${id}", but it is already ${state}.`); } - if (!started) { - throw new Error(`Tried to stop "${id}", but it has not started yet.`); - } - - await stop(); - - started = false; - stopped = true; + stop(); + state = "stopped"; }, }; -}; +} diff --git a/src/features/application-menu/main/application-menu-reactivity.injectable.ts b/src/features/application-menu/main/application-menu-reactivity.injectable.ts index 67631322aa..80bfd108fd 100644 --- a/src/features/application-menu/main/application-menu-reactivity.injectable.ts +++ b/src/features/application-menu/main/application-menu-reactivity.injectable.ts @@ -15,8 +15,9 @@ const applicationMenuReactivityInjectable = getInjectable({ const applicationMenuItemComposite = di.inject(applicationMenuItemCompositeInjectable); const populateApplicationMenu = di.inject(populateApplicationMenuInjectable); - return getStartableStoppable("application-menu-reactivity", () => - autorun(() => populateApplicationMenu(applicationMenuItemComposite.get()), { + return getStartableStoppable( + "application-menu-reactivity", + () => autorun(() => populateApplicationMenu(applicationMenuItemComposite.get()), { delay: 100, }), ); diff --git a/src/features/application-menu/main/stop-application-menu.injectable.ts b/src/features/application-menu/main/stop-application-menu.injectable.ts index 63abccadf9..62abd439df 100644 --- a/src/features/application-menu/main/stop-application-menu.injectable.ts +++ b/src/features/application-menu/main/stop-application-menu.injectable.ts @@ -10,15 +10,11 @@ const stopApplicationMenuInjectable = getInjectable({ id: "stop-application-menu", instantiate: (di) => { - const applicationMenu = di.inject( - applicationMenuReactivityInjectable, - ); + const applicationMenu = di.inject(applicationMenuReactivityInjectable); return { id: "stop-application-menu", - run: async () => { - await applicationMenu.stop(); - }, + run: () => void applicationMenu.stop(), }; }, diff --git a/src/features/application-update/child-features/periodical-checking-of-updates/main/periodical-check-for-updates.injectable.ts b/src/features/application-update/child-features/periodical-checking-of-updates/main/periodical-check-for-updates.injectable.ts index 472cf31a06..85c687e478 100644 --- a/src/features/application-update/child-features/periodical-checking-of-updates/main/periodical-check-for-updates.injectable.ts +++ b/src/features/application-update/child-features/periodical-checking-of-updates/main/periodical-check-for-updates.injectable.ts @@ -7,6 +7,8 @@ import { getStartableStoppable } from "../../../../../common/utils/get-startable import processCheckingForUpdatesInjectable from "../../../main/process-checking-for-updates.injectable"; import withOrphanPromiseInjectable from "../../../../../common/utils/with-orphan-promise/with-orphan-promise.injectable"; +const TWO_HOURS = 1000 * 60 * 60 * 2; + const periodicalCheckForUpdatesInjectable = getInjectable({ id: "periodical-check-for-updates", @@ -15,12 +17,9 @@ const periodicalCheckForUpdatesInjectable = getInjectable({ const processCheckingForUpdates = withOrphanPromise(di.inject(processCheckingForUpdatesInjectable)); return getStartableStoppable("periodical-check-for-updates", () => { - const TWO_HOURS = 1000 * 60 * 60 * 2; - processCheckingForUpdates("periodic"); const intervalId = setInterval(() => { - processCheckingForUpdates("periodic"); }, TWO_HOURS); diff --git a/src/features/application-update/child-features/periodical-checking-of-updates/main/stop-checking-for-updates.injectable.ts b/src/features/application-update/child-features/periodical-checking-of-updates/main/stop-checking-for-updates.injectable.ts index ff7607e7db..6e58d7dd77 100644 --- a/src/features/application-update/child-features/periodical-checking-of-updates/main/stop-checking-for-updates.injectable.ts +++ b/src/features/application-update/child-features/periodical-checking-of-updates/main/stop-checking-for-updates.injectable.ts @@ -14,10 +14,12 @@ const stopCheckingForUpdatesInjectable = getInjectable({ return { id: "stop-checking-for-updates", - run: async () => { + run: () => { if (periodicalCheckForUpdates.started) { - await periodicalCheckForUpdates.stop(); + periodicalCheckForUpdates.stop(); } + + return undefined; }, }; }, diff --git a/src/features/application-update/main/watch-if-update-should-happen-on-quit/stop-watching-if-update-should-happen-on-quit.injectable.ts b/src/features/application-update/main/watch-if-update-should-happen-on-quit/stop-watching-if-update-should-happen-on-quit.injectable.ts index f68edacefb..faf67b4ffc 100644 --- a/src/features/application-update/main/watch-if-update-should-happen-on-quit/stop-watching-if-update-should-happen-on-quit.injectable.ts +++ b/src/features/application-update/main/watch-if-update-should-happen-on-quit/stop-watching-if-update-should-happen-on-quit.injectable.ts @@ -14,9 +14,7 @@ const stopWatchingIfUpdateShouldHappenOnQuitInjectable = getInjectable({ return { id: "stop-watching-if-update-should-happen-on-quit", - run: () => { - watchIfUpdateShouldHappenOnQuit.stop(); - }, + run: () => void watchIfUpdateShouldHappenOnQuit.stop(), }; }, diff --git a/src/main/app-paths/setup-app-paths.injectable.ts b/src/main/app-paths/setup-app-paths.injectable.ts index 842eed89c7..54bc0ea2ba 100644 --- a/src/main/app-paths/setup-app-paths.injectable.ts +++ b/src/main/app-paths/setup-app-paths.injectable.ts @@ -44,6 +44,9 @@ const setupAppPathsInjectable = getInjectable({ ) as AppPaths; appPathsState.set(appPaths); + + // NOTE: this is the worse of two evils. This makes sure that `RunnableSync` always is sync + return undefined; }, }; }, diff --git a/src/main/catalog-sync-to-renderer/catalog-sync-to-renderer.injectable.ts b/src/main/catalog-sync-to-renderer/catalog-sync-to-renderer.injectable.ts index 7e588481a8..a9ba676bf9 100644 --- a/src/main/catalog-sync-to-renderer/catalog-sync-to-renderer.injectable.ts +++ b/src/main/catalog-sync-to-renderer/catalog-sync-to-renderer.injectable.ts @@ -13,8 +13,9 @@ const catalogSyncToRendererInjectable = getInjectable({ instantiate: (di) => { const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable); - return getStartableStoppable("catalog-sync", () => - startCatalogSyncToRenderer(catalogEntityRegistry), + return getStartableStoppable( + "catalog-sync", + () => startCatalogSyncToRenderer(catalogEntityRegistry), ); }, diff --git a/src/main/catalog-sync-to-renderer/stop-catalog-sync.injectable.ts b/src/main/catalog-sync-to-renderer/stop-catalog-sync.injectable.ts index fcd294fe02..353790d8b2 100644 --- a/src/main/catalog-sync-to-renderer/stop-catalog-sync.injectable.ts +++ b/src/main/catalog-sync-to-renderer/stop-catalog-sync.injectable.ts @@ -14,10 +14,12 @@ const stopCatalogSyncInjectable = getInjectable({ return { id: "stop-catalog-sync", - run: async () => { + run: () => { if (catalogSyncToRenderer.started) { - await catalogSyncToRenderer.stop(); + catalogSyncToRenderer.stop(); } + + return undefined; }, }; }, diff --git a/src/main/electron-app/features/sync-theme-from-operating-system.injectable.ts b/src/main/electron-app/features/sync-theme-from-operating-system.injectable.ts index fa2f8e335e..818bf938ec 100644 --- a/src/main/electron-app/features/sync-theme-from-operating-system.injectable.ts +++ b/src/main/electron-app/features/sync-theme-from-operating-system.injectable.ts @@ -18,9 +18,7 @@ const syncThemeFromOperatingSystemInjectable = getInjectable({ return getStartableStoppable("sync-theme-from-operating-system", () => { const updateThemeState = () => { - const newTheme = getElectronTheme(); - - currentThemeState.set(newTheme); + currentThemeState.set(getElectronTheme()); }; nativeTheme.on("updated", updateThemeState); diff --git a/src/main/electron-app/runnables/clean-up-deep-linking.injectable.ts b/src/main/electron-app/runnables/clean-up-deep-linking.injectable.ts index 9943516f72..b5088a667a 100644 --- a/src/main/electron-app/runnables/clean-up-deep-linking.injectable.ts +++ b/src/main/electron-app/runnables/clean-up-deep-linking.injectable.ts @@ -14,9 +14,7 @@ const cleanUpDeepLinkingInjectable = getInjectable({ return { id: "clean-up-deep-linking", - run: () => { - lensProtocolRouterMain.cleanup(); - }, + run: () => void lensProtocolRouterMain.cleanup(), }; }, diff --git a/src/main/electron-app/runnables/dock-visibility/hide-dock-for-last-closed-window.injectable.ts b/src/main/electron-app/runnables/dock-visibility/hide-dock-for-last-closed-window.injectable.ts index d7fd4bdcb2..5586c93586 100644 --- a/src/main/electron-app/runnables/dock-visibility/hide-dock-for-last-closed-window.injectable.ts +++ b/src/main/electron-app/runnables/dock-visibility/hide-dock-for-last-closed-window.injectable.ts @@ -23,6 +23,8 @@ const hideDockForLastClosedWindowInjectable = getInjectable({ if (isEmpty(visibleWindows)) { app.dock?.hide(); } + + return undefined; }, }; }, diff --git a/src/main/electron-app/runnables/enforce-single-application-instance.injectable.ts b/src/main/electron-app/runnables/enforce-single-application-instance.injectable.ts index de192e3372..f69036ffed 100644 --- a/src/main/electron-app/runnables/enforce-single-application-instance.injectable.ts +++ b/src/main/electron-app/runnables/enforce-single-application-instance.injectable.ts @@ -20,6 +20,8 @@ const enforceSingleApplicationInstanceInjectable = getInjectable({ if (!requestSingleInstanceLock()) { exitApp(); } + + return undefined; }, }; }, diff --git a/src/main/electron-app/runnables/setup-application-name.injectable.ts b/src/main/electron-app/runnables/setup-application-name.injectable.ts index 8bafc3fe8b..fd47480f09 100644 --- a/src/main/electron-app/runnables/setup-application-name.injectable.ts +++ b/src/main/electron-app/runnables/setup-application-name.injectable.ts @@ -18,6 +18,8 @@ const setupApplicationNameInjectable = getInjectable({ id: "setup-application-name", run: () => { app.setName(appName); + + return undefined; }, }; }, diff --git a/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts b/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts index 13650605fb..fe501d4750 100644 --- a/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts +++ b/src/main/electron-app/runnables/setup-runnables-after-window-is-opened.injectable.ts @@ -13,15 +13,14 @@ const setupRunnablesAfterWindowIsOpenedInjectable = getInjectable({ instantiate: (di) => { const afterWindowIsOpened = runManyFor(di)(afterWindowIsOpenedInjectionToken); + const app = di.inject(electronAppInjectable); return { id: "setup-runnables-after-window-is-opened", run: () => { - const app = di.inject(electronAppInjectable); + app.on("browser-window-created", () => afterWindowIsOpened); - app.on("browser-window-created", async () => { - await afterWindowIsOpened(); - }); + return undefined; }, }; }, diff --git a/src/main/electron-app/runnables/setup-runnables-before-closing-of-application.injectable.ts b/src/main/electron-app/runnables/setup-runnables-before-closing-of-application.injectable.ts index 5e8b24c2d8..c0bc3ae620 100644 --- a/src/main/electron-app/runnables/setup-runnables-before-closing-of-application.injectable.ts +++ b/src/main/electron-app/runnables/setup-runnables-before-closing-of-application.injectable.ts @@ -15,24 +15,16 @@ const setupRunnablesBeforeClosingOfApplicationInjectable = getInjectable({ id: "setup-closing-of-application", instantiate: (di) => { - const runMany = runManySyncFor(di); - - const runRunnablesBeforeQuitOfFrontEnd = runMany( - beforeQuitOfFrontEndInjectionToken, - ); - - const runRunnablesBeforeQuitOfBackEnd = runMany( - beforeQuitOfBackEndInjectionToken, - ); + const runManySync = runManySyncFor(di); + const runRunnablesBeforeQuitOfFrontEnd = runManySync(beforeQuitOfFrontEndInjectionToken); + const runRunnablesBeforeQuitOfBackEnd = runManySync(beforeQuitOfBackEndInjectionToken); + const app = di.inject(electronAppInjectable); + const isIntegrationTesting = di.inject(isIntegrationTestingInjectable); + const autoUpdater = di.inject(autoUpdaterInjectable); return { id: "setup-closing-of-application", run: () => { - const app = di.inject(electronAppInjectable); - - const isIntegrationTesting = di.inject(isIntegrationTestingInjectable); - const autoUpdater = di.inject(autoUpdaterInjectable); - let isAutoUpdating = false; autoUpdater.on("before-quit-for-update", () => { @@ -51,6 +43,8 @@ const setupRunnablesBeforeClosingOfApplicationInjectable = getInjectable({ event.preventDefault(); } }); + + return undefined; }, }; }, diff --git a/src/main/start-main-application/runnable-tokens/before-electron-is-ready-injection-token.ts b/src/main/start-main-application/runnable-tokens/before-electron-is-ready-injection-token.ts index 08173ebef2..4bdef1ff90 100644 --- a/src/main/start-main-application/runnable-tokens/before-electron-is-ready-injection-token.ts +++ b/src/main/start-main-application/runnable-tokens/before-electron-is-ready-injection-token.ts @@ -5,7 +5,6 @@ import { getInjectionToken } from "@ogre-tools/injectable"; import type { RunnableSync } from "../../../common/runnable/run-many-sync-for"; -export const beforeElectronIsReadyInjectionToken = - getInjectionToken({ - id: "before-electron-is-ready", - }); +export const beforeElectronIsReadyInjectionToken = getInjectionToken({ + id: "before-electron-is-ready", +}); diff --git a/src/main/start-main-application/runnable-tokens/before-quit-of-back-end-injection-token.ts b/src/main/start-main-application/runnable-tokens/before-quit-of-back-end-injection-token.ts index bdb1d1e1be..d11ecf57d2 100644 --- a/src/main/start-main-application/runnable-tokens/before-quit-of-back-end-injection-token.ts +++ b/src/main/start-main-application/runnable-tokens/before-quit-of-back-end-injection-token.ts @@ -5,7 +5,6 @@ import { getInjectionToken } from "@ogre-tools/injectable"; import type { RunnableSync } from "../../../common/runnable/run-many-sync-for"; -export const beforeQuitOfBackEndInjectionToken = - getInjectionToken({ - id: "before-quit-of-back-end", - }); +export const beforeQuitOfBackEndInjectionToken = getInjectionToken({ + id: "before-quit-of-back-end", +}); diff --git a/src/main/start-main-application/runnable-tokens/before-quit-of-front-end-injection-token.ts b/src/main/start-main-application/runnable-tokens/before-quit-of-front-end-injection-token.ts index 2327688cb3..0a45a684cd 100644 --- a/src/main/start-main-application/runnable-tokens/before-quit-of-front-end-injection-token.ts +++ b/src/main/start-main-application/runnable-tokens/before-quit-of-front-end-injection-token.ts @@ -5,7 +5,6 @@ import { getInjectionToken } from "@ogre-tools/injectable"; import type { RunnableSync } from "../../../common/runnable/run-many-sync-for"; -export const beforeQuitOfFrontEndInjectionToken = - getInjectionToken({ - id: "before-quit-of-front-end", - }); +export const beforeQuitOfFrontEndInjectionToken = getInjectionToken({ + id: "before-quit-of-front-end", +}); diff --git a/src/main/start-main-application/runnables/clean-up-shell-sessions.injectable.ts b/src/main/start-main-application/runnables/clean-up-shell-sessions.injectable.ts index 40d50530ad..46afa5e692 100644 --- a/src/main/start-main-application/runnables/clean-up-shell-sessions.injectable.ts +++ b/src/main/start-main-application/runnables/clean-up-shell-sessions.injectable.ts @@ -11,9 +11,7 @@ const cleanUpShellSessionsInjectable = getInjectable({ instantiate: () => ({ id: "clean-up-shell-sessions", - run: () => { - ShellSession.cleanup(); - }, + run: () => void ShellSession.cleanup(), }), injectionToken: beforeQuitOfBackEndInjectionToken, diff --git a/src/main/start-main-application/runnables/emit-close-to-event-bus.injectable.ts b/src/main/start-main-application/runnables/emit-close-to-event-bus.injectable.ts index dc9c04771e..e1da8c1d67 100644 --- a/src/main/start-main-application/runnables/emit-close-to-event-bus.injectable.ts +++ b/src/main/start-main-application/runnables/emit-close-to-event-bus.injectable.ts @@ -16,6 +16,8 @@ const emitCloseToEventBusInjectable = getInjectable({ id: "emit-close-to-event-bus", run: () => { emitAppEvent({ name: "app", action: "close" }); + + return undefined; }, }; }, diff --git a/src/main/start-main-application/runnables/flag-renderer/flag-renderer-as-not-loaded.injectable.ts b/src/main/start-main-application/runnables/flag-renderer/flag-renderer-as-not-loaded.injectable.ts index 8b0a4b8161..d5f7444232 100644 --- a/src/main/start-main-application/runnables/flag-renderer/flag-renderer-as-not-loaded.injectable.ts +++ b/src/main/start-main-application/runnables/flag-renderer/flag-renderer-as-not-loaded.injectable.ts @@ -20,6 +20,8 @@ const flagRendererAsNotLoadedInjectable = getInjectable({ // Todo: remove this kludge which enables out-of-place temporal dependency. lensProtocolRouterMain.rendererLoaded = false; }); + + return undefined; }, }; }, diff --git a/src/main/start-main-application/runnables/kube-config-sync/stop-kube-config-sync.injectable.ts b/src/main/start-main-application/runnables/kube-config-sync/stop-kube-config-sync.injectable.ts index 77e987effc..4cb5a98a3f 100644 --- a/src/main/start-main-application/runnables/kube-config-sync/stop-kube-config-sync.injectable.ts +++ b/src/main/start-main-application/runnables/kube-config-sync/stop-kube-config-sync.injectable.ts @@ -14,9 +14,7 @@ const stopKubeConfigSyncInjectable = getInjectable({ return { id: "stop-kube-config-sync", - run: () => { - kubeConfigSyncManager.stopSync(); - }, + run: () => void kubeConfigSyncManager.stopSync(), }; }, diff --git a/src/main/start-main-application/runnables/sentry/setup.injectable.ts b/src/main/start-main-application/runnables/sentry/setup.injectable.ts index 9db6991fea..6d4111ae78 100644 --- a/src/main/start-main-application/runnables/sentry/setup.injectable.ts +++ b/src/main/start-main-application/runnables/sentry/setup.injectable.ts @@ -15,7 +15,7 @@ const setupSentryInjectable = getInjectable({ return { id: "setup-sentry", - run: () => initializeSentryReportingWith(initializeSentryOnMain), + run: () => void initializeSentryReportingWith(initializeSentryOnMain), }; }, injectionToken: beforeElectronIsReadyInjectionToken, diff --git a/src/main/start-main-application/runnables/setup-hardware-acceleration.injectable.ts b/src/main/start-main-application/runnables/setup-hardware-acceleration.injectable.ts index cbb9b940cb..905cb9e130 100644 --- a/src/main/start-main-application/runnables/setup-hardware-acceleration.injectable.ts +++ b/src/main/start-main-application/runnables/setup-hardware-acceleration.injectable.ts @@ -20,6 +20,8 @@ const setupHardwareAccelerationInjectable = getInjectable({ if (hardwareAccelerationShouldBeDisabled) { disableHardwareAcceleration(); } + + return undefined; }, }; }, diff --git a/src/main/start-main-application/runnables/setup-immer.injectable.ts b/src/main/start-main-application/runnables/setup-immer.injectable.ts index 1d03bd8e9d..61420cf35b 100644 --- a/src/main/start-main-application/runnables/setup-immer.injectable.ts +++ b/src/main/start-main-application/runnables/setup-immer.injectable.ts @@ -16,6 +16,8 @@ const setupImmerInjectable = getInjectable({ // Required in `utils/storage-helper.ts` Immer.setAutoFreeze(false); // allow to merge mobx observables Immer.enableMapSet(); // allow to merge maps and sets + + return undefined; }, }), diff --git a/src/main/start-main-application/runnables/setup-mobx.injectable.ts b/src/main/start-main-application/runnables/setup-mobx.injectable.ts index 350911fecd..d13021cdc6 100644 --- a/src/main/start-main-application/runnables/setup-mobx.injectable.ts +++ b/src/main/start-main-application/runnables/setup-mobx.injectable.ts @@ -21,6 +21,8 @@ const setupMobxInjectable = getInjectable({ // reactionRequiresObservable: true, // observableRequiresReaction: true, }); + + return undefined; }, }), diff --git a/src/main/start-main-application/runnables/setup-proxy-env.injectable.ts b/src/main/start-main-application/runnables/setup-proxy-env.injectable.ts index bc709f1f72..0541c2cfda 100644 --- a/src/main/start-main-application/runnables/setup-proxy-env.injectable.ts +++ b/src/main/start-main-application/runnables/setup-proxy-env.injectable.ts @@ -34,6 +34,8 @@ const setupProxyEnvInjectable = getInjectable({ if (getCommandLineSwitch("proxy-server") !== "") { process.env.HTTPS_PROXY = getCommandLineSwitch("proxy-server"); } + + return undefined; }, }; }, diff --git a/src/main/start-main-application/runnables/stop-cluster-manager.injectable.ts b/src/main/start-main-application/runnables/stop-cluster-manager.injectable.ts index f8d6c0bdc7..c0a39c51ae 100644 --- a/src/main/start-main-application/runnables/stop-cluster-manager.injectable.ts +++ b/src/main/start-main-application/runnables/stop-cluster-manager.injectable.ts @@ -16,13 +16,13 @@ const stopClusterManagerInjectable = getInjectable({ id: "stop-cluster-manager", run: () => { clusterManager.stop(); + + return undefined; }, }; }, injectionToken: beforeQuitOfFrontEndInjectionToken, - - causesSideEffects: true, }); export default stopClusterManagerInjectable; diff --git a/src/main/theme/broadcast-theme-change/stop-broadcasting-theme-change.injectable.ts b/src/main/theme/broadcast-theme-change/stop-broadcasting-theme-change.injectable.ts index 81f530ad9b..ede38cb4f1 100644 --- a/src/main/theme/broadcast-theme-change/stop-broadcasting-theme-change.injectable.ts +++ b/src/main/theme/broadcast-theme-change/stop-broadcasting-theme-change.injectable.ts @@ -14,9 +14,7 @@ const stopBroadcastingThemeChangeInjectable = getInjectable({ return { id: "stop-broadcasting-theme-change", - run: async () => { - await broadcastThemeChange.stop(); - }, + run: () => void broadcastThemeChange.stop(), }; }, diff --git a/src/main/theme/sync-theme-from-os/stop-syncing-theme-from-operating-system.injectable.ts b/src/main/theme/sync-theme-from-os/stop-syncing-theme-from-operating-system.injectable.ts index 8a11042883..b45184a3bd 100644 --- a/src/main/theme/sync-theme-from-os/stop-syncing-theme-from-operating-system.injectable.ts +++ b/src/main/theme/sync-theme-from-os/stop-syncing-theme-from-operating-system.injectable.ts @@ -14,9 +14,7 @@ const stopSyncingThemeFromOperatingSystemInjectable = getInjectable({ return { id: "stop-syncing-theme-from-operating-system", - run: async () => { - await syncTheme.stop(); - }, + run: () => void syncTheme.stop(), }; }, diff --git a/src/main/tray/electron-tray/stop-tray.injectable.ts b/src/main/tray/electron-tray/stop-tray.injectable.ts index babf687772..d2e58be039 100644 --- a/src/main/tray/electron-tray/stop-tray.injectable.ts +++ b/src/main/tray/electron-tray/stop-tray.injectable.ts @@ -15,10 +15,7 @@ const stopTrayInjectable = getInjectable({ return { id: "stop-tray", - run: () => { - electronTray.stop(); - }, - + run: () => void electronTray.stop(), runAfter: di.inject(stopReactiveTrayMenuItemsInjectable), }; }, diff --git a/src/main/tray/menu-icon/stop-reactivity.injectable.ts b/src/main/tray/menu-icon/stop-reactivity.injectable.ts index b43661807d..94e91ec607 100644 --- a/src/main/tray/menu-icon/stop-reactivity.injectable.ts +++ b/src/main/tray/menu-icon/stop-reactivity.injectable.ts @@ -14,9 +14,7 @@ const stopReactiveTrayMenuIconInjectable = getInjectable({ return { id: "stop-reactive-tray-menu-icon", - run: async () => { - await reactiveTrayMenuIcon.stop(); - }, + run: () => void reactiveTrayMenuIcon.stop(), }; }, diff --git a/src/main/tray/reactive-tray-menu-items/reactive-tray-menu-items.injectable.ts b/src/main/tray/reactive-tray-menu-items/reactive-tray-menu-items.injectable.ts index 145cc1e870..378bceafd9 100644 --- a/src/main/tray/reactive-tray-menu-items/reactive-tray-menu-items.injectable.ts +++ b/src/main/tray/reactive-tray-menu-items/reactive-tray-menu-items.injectable.ts @@ -19,10 +19,8 @@ const reactiveTrayMenuItemsInjectable = getInjectable({ return getStartableStoppable("reactive-tray-menu-items", () => reaction( - (): MinimalTrayMenuItem[] => reactiveItems.get().map(toNonReactiveItem), - + () => reactiveItems.get().map(toNonReactiveItem), (nonReactiveItems) => electronTray.setMenuItems(nonReactiveItems), - { fireImmediately: true, }, diff --git a/src/main/tray/reactive-tray-menu-items/stop-reactive-tray-menu-items.injectable.ts b/src/main/tray/reactive-tray-menu-items/stop-reactive-tray-menu-items.injectable.ts index dbf5753c23..122e9c059a 100644 --- a/src/main/tray/reactive-tray-menu-items/stop-reactive-tray-menu-items.injectable.ts +++ b/src/main/tray/reactive-tray-menu-items/stop-reactive-tray-menu-items.injectable.ts @@ -14,9 +14,7 @@ const stopReactiveTrayMenuItemsInjectable = getInjectable({ return { id: "stop-reactive-tray-menu-items", - run: async () => { - await reactiveTrayMenuItems.stop(); - }, + run: () => void reactiveTrayMenuItems.stop(), }; }, diff --git a/src/main/utils/channel/channel-listeners/start-listening-on-channels.injectable.ts b/src/main/utils/channel/channel-listeners/start-listening-on-channels.injectable.ts index d1cf5d68d6..ce6008add4 100644 --- a/src/main/utils/channel/channel-listeners/start-listening-on-channels.injectable.ts +++ b/src/main/utils/channel/channel-listeners/start-listening-on-channels.injectable.ts @@ -16,9 +16,9 @@ const startListeningOnChannelsInjectable = getInjectable({ return { id: "start-listening-on-channels-main", - run: async () => { - await listeningOnMessageChannels.start(); - await listeningOnRequestChannels.start(); + run: () => { + listeningOnMessageChannels.start(); + listeningOnRequestChannels.start(); }, }; },