mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Refactor runnables (#6528)
* Convert runManyFor to use composite Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert runManySyncFor to use composite and to enfore sync-ness Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove dead code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert getStartableStoppable to be always sync as it is never used in an async fashion Signed-off-by: Sebastian Malton <sebastian@malton.name> * Convert all sync runnables to comply with new checks for sync-ness Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
82ab60d544
commit
b498f12186
@ -223,7 +223,7 @@ describe("runManyFor", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return expect(() => runMany()).rejects.toThrow(
|
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"/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -2,13 +2,10 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* 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 type {
|
import type { Composite } from "../utils/composite/get-composite/get-composite";
|
||||||
DiContainerForInjection,
|
import { getCompositeFor } from "../utils/composite/get-composite/get-composite";
|
||||||
InjectionToken,
|
import * as uuid from "uuid";
|
||||||
} from "@ogre-tools/injectable";
|
|
||||||
import { filter, forEach, map, tap } from "lodash/fp";
|
|
||||||
import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for";
|
|
||||||
|
|
||||||
export interface Runnable<TParameter = void> {
|
export interface Runnable<TParameter = void> {
|
||||||
id: string;
|
id: string;
|
||||||
@ -18,35 +15,34 @@ export interface Runnable<TParameter = void> {
|
|||||||
|
|
||||||
type Run<Param> = (parameter: Param) => Promise<void> | void;
|
type Run<Param> = (parameter: Param) => Promise<void> | void;
|
||||||
|
|
||||||
export type RunMany = <Param>(
|
export type RunMany = <Param>(injectionToken: InjectionToken<Runnable<Param>, void>) => Run<Param>;
|
||||||
injectionToken: InjectionToken<Runnable<Param>, void>
|
|
||||||
) => Run<Param>;
|
async function runCompositeRunnables<Param>(param: Param, composite: Composite<Runnable<Param>>) {
|
||||||
|
await composite.value.run(param);
|
||||||
|
await Promise.all(composite.children.map(composite => runCompositeRunnables(param, composite)));
|
||||||
|
}
|
||||||
|
|
||||||
export function runManyFor(di: DiContainerForInjection): RunMany {
|
export function runManyFor(di: DiContainerForInjection): RunMany {
|
||||||
return (injectionToken) => async (parameter) => {
|
return <Param>(injectionToken: InjectionToken<Runnable<Param>, void>) => async (param: Param) => {
|
||||||
const allRunnables = di.injectMany(injectionToken);
|
const allRunnables = di.injectMany(injectionToken);
|
||||||
|
const rootId = uuid.v4();
|
||||||
|
const getCompositeRunnables = getCompositeFor<Runnable<Param>>({
|
||||||
|
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);
|
await runCompositeRunnables(param, composite);
|
||||||
|
|
||||||
const recursedRun = async (
|
|
||||||
runAfterRunnable: Runnable<any> | 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();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,7 +69,7 @@ describe("runManySyncFor", () => {
|
|||||||
|
|
||||||
instantiate: (di) => ({
|
instantiate: (di) => ({
|
||||||
id: "some-injectable-1",
|
id: "some-injectable-1",
|
||||||
run: () => runMock("third-level-run"),
|
run: () => void runMock("third-level-run"),
|
||||||
runAfter: di.inject(someInjectable2),
|
runAfter: di.inject(someInjectable2),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ describe("runManySyncFor", () => {
|
|||||||
|
|
||||||
instantiate: (di) => ({
|
instantiate: (di) => ({
|
||||||
id: "some-injectable-2",
|
id: "some-injectable-2",
|
||||||
run: () => runMock("second-level-run"),
|
run: () => void runMock("second-level-run"),
|
||||||
runAfter: di.inject(someInjectable3),
|
runAfter: di.inject(someInjectable3),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ describe("runManySyncFor", () => {
|
|||||||
id: "some-injectable-3",
|
id: "some-injectable-3",
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: "some-injectable-3",
|
id: "some-injectable-3",
|
||||||
run: () => runMock("first-level-run"),
|
run: () => void runMock("first-level-run"),
|
||||||
}),
|
}),
|
||||||
injectionToken: someInjectionTokenForRunnables,
|
injectionToken: someInjectionTokenForRunnables,
|
||||||
});
|
});
|
||||||
@ -151,13 +151,13 @@ describe("runManySyncFor", () => {
|
|||||||
someInjectionToken,
|
someInjectionToken,
|
||||||
);
|
);
|
||||||
|
|
||||||
return expect(() => runMany()).rejects.toThrow(
|
return expect(() => runMany()).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"/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when running many with parameter", () => {
|
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(() => {
|
beforeEach(() => {
|
||||||
const rootDi = createContainer("irrelevant");
|
const rootDi = createContainer("irrelevant");
|
||||||
@ -175,7 +175,7 @@ describe("runManySyncFor", () => {
|
|||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: "some-runnable-1",
|
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,
|
injectionToken: someInjectionTokenForRunnablesWithParameter,
|
||||||
@ -186,7 +186,7 @@ describe("runManySyncFor", () => {
|
|||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: "some-runnable-2",
|
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,
|
injectionToken: someInjectionTokenForRunnablesWithParameter,
|
||||||
|
|||||||
@ -2,11 +2,10 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* 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 type { DiContainerForInjection, InjectionToken } from "@ogre-tools/injectable";
|
||||||
import { filter, forEach, map, tap } from "lodash/fp";
|
import type { Composite } from "../utils/composite/get-composite/get-composite";
|
||||||
import type { Runnable } from "./run-many-for";
|
import { getCompositeFor } from "../utils/composite/get-composite/get-composite";
|
||||||
import { throwWithIncorrectHierarchyFor } from "./throw-with-incorrect-hierarchy-for";
|
import * as uuid from "uuid";
|
||||||
|
|
||||||
export interface RunnableSync<TParameter = void> {
|
export interface RunnableSync<TParameter = void> {
|
||||||
id: string;
|
id: string;
|
||||||
@ -14,35 +13,43 @@ export interface RunnableSync<TParameter = void> {
|
|||||||
runAfter?: RunnableSync<TParameter>;
|
runAfter?: RunnableSync<TParameter>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunSync<Param> = (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<T>`) can
|
||||||
|
* coerce to it.
|
||||||
|
*/
|
||||||
|
type RunSync<Param> = (parameter: Param) => undefined;
|
||||||
|
|
||||||
export type RunManySync = <Param>(
|
export type RunManySync = <Param>(injectionToken: InjectionToken<RunnableSync<Param>, void>) => RunSync<Param>;
|
||||||
injectionToken: InjectionToken<Runnable<Param>, void>
|
|
||||||
) => RunSync<Param>;
|
function runCompositeRunnableSyncs<Param>(param: Param, composite: Composite<RunnableSync<Param>>): undefined {
|
||||||
|
composite.value.run(param);
|
||||||
|
composite.children.map(composite => runCompositeRunnableSyncs(param, composite));
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export function runManySyncFor(di: DiContainerForInjection): RunManySync {
|
export function runManySyncFor(di: DiContainerForInjection): RunManySync {
|
||||||
return (injectionToken) => async (parameter) => {
|
return <Param>(injectionToken: InjectionToken<RunnableSync<Param>, void>) => (param: Param): undefined => {
|
||||||
const allRunnables = di.injectMany(injectionToken);
|
const allRunnables = di.injectMany(injectionToken);
|
||||||
|
const rootId = uuid.v4();
|
||||||
|
const getCompositeRunnables = getCompositeFor<RunnableSync<Param>>({
|
||||||
|
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);
|
return runCompositeRunnableSyncs(param, composite);
|
||||||
|
|
||||||
const recursedRun = (
|
|
||||||
runAfterRunnable: RunnableSync<any> | undefined = undefined,
|
|
||||||
) =>
|
|
||||||
pipeline(
|
|
||||||
allRunnables,
|
|
||||||
|
|
||||||
tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)),
|
|
||||||
|
|
||||||
filter((runnable) => runnable.runAfter === runAfterRunnable),
|
|
||||||
|
|
||||||
map((runnable) => {
|
|
||||||
runnable.run(parameter);
|
|
||||||
|
|
||||||
recursedRun(runnable);
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
recursedRun();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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<any>[] | RunnableSync<any>[]) => (
|
|
||||||
(runnable: Runnable<any> | RunnableSync<any>) => {
|
|
||||||
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.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@ -2,21 +2,17 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import type { AsyncFnMock } from "@async-fn/jest";
|
import type { StartableStoppable } from "./get-startable-stoppable";
|
||||||
import asyncFn from "@async-fn/jest";
|
|
||||||
import { getStartableStoppable } 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", () => {
|
describe("getStartableStoppable", () => {
|
||||||
let stopMock: AsyncFnMock<() => Promise<void>>;
|
let stopMock: jest.MockedFunction<() => void>;
|
||||||
let startMock: AsyncFnMock<() => Promise<() => Promise<void>>>;
|
let startMock: jest.MockedFunction<() => () => void>;
|
||||||
let actual: { stop: () => Promise<void>; start: () => Promise<void>; started: boolean };
|
let actual: StartableStoppable;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
stopMock = asyncFn();
|
stopMock = jest.fn();
|
||||||
startMock = asyncFn();
|
startMock = jest.fn().mockImplementation(() => stopMock);
|
||||||
|
|
||||||
actual = getStartableStoppable("some-id", startMock);
|
actual = getStartableStoppable("some-id", startMock);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -29,7 +25,7 @@ describe("getStartableStoppable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("when stopping before ever starting, throws", () => {
|
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", () => {
|
it("is not started", () => {
|
||||||
@ -37,199 +33,30 @@ describe("getStartableStoppable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("when started", () => {
|
describe("when started", () => {
|
||||||
let startPromise: Promise<void>;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
startPromise = actual.start();
|
actual.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("starts starting", () => {
|
it("calls start function", () => {
|
||||||
expect(startMock).toHaveBeenCalled();
|
expect(startMock).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("starting does not resolve yet", async () => {
|
it("is started", () => {
|
||||||
const promiseStatus = await getPromiseStatus(startPromise);
|
expect(actual.started).toBe(true);
|
||||||
|
|
||||||
expect(promiseStatus.fulfilled).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is not started yet", () => {
|
describe("when stopped", () => {
|
||||||
expect(actual.started).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when started again before the start has finished", () => {
|
|
||||||
let error: Error;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
startMock.mockClear();
|
actual.stop();
|
||||||
|
|
||||||
actual.start().catch((e) => { error = e; });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not start starting again", () => {
|
it("calls stop function", () => {
|
||||||
expect(startMock).not.toHaveBeenCalled();
|
expect(stopMock).toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("throws", () => {
|
it("is stopped", () => {
|
||||||
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<void>;
|
|
||||||
|
|
||||||
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<void>;
|
|
||||||
|
|
||||||
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", () => {
|
|
||||||
expect(actual.started).toBe(false);
|
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,58 +3,43 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type Stopper = () => Promise<void> | void;
|
export type Stopper = () => void;
|
||||||
type Starter = () => Promise<Stopper> | Stopper;
|
export type Starter = () => Stopper;
|
||||||
|
|
||||||
export const getStartableStoppable = (
|
export interface StartableStoppable {
|
||||||
id: string,
|
readonly started: boolean;
|
||||||
startAndGetStopCallback: Starter,
|
start: () => void;
|
||||||
) => {
|
stop: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type StartableStoppableState = "stopped" | "started" | "starting";
|
||||||
|
|
||||||
|
export function getStartableStoppable(id: string, startAndGetStopper: Starter): StartableStoppable {
|
||||||
let stop: Stopper;
|
let stop: Stopper;
|
||||||
let stopped = false;
|
let state: StartableStoppableState = "stopped";
|
||||||
let started = false;
|
|
||||||
let starting = false;
|
|
||||||
let startingPromise: Promise<Stopper> | Stopper;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
get started() {
|
get started() {
|
||||||
return started;
|
return state === "started";
|
||||||
},
|
},
|
||||||
|
|
||||||
start: async () => {
|
start: () => {
|
||||||
if (starting) {
|
if (state !== "stopped") {
|
||||||
throw new Error(`Tried to start "${id}", but it is already being started.`);
|
throw new Error(`Tried to start "${id}", but it is already ${state}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
starting = true;
|
state = "starting";
|
||||||
|
stop = startAndGetStopper();
|
||||||
if (started) {
|
state = "started";
|
||||||
throw new Error(`Tried to start "${id}", but it has already started.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
startingPromise = startAndGetStopCallback();
|
|
||||||
stop = await startingPromise;
|
|
||||||
|
|
||||||
stopped = false;
|
|
||||||
started = true;
|
|
||||||
starting = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: async () => {
|
stop: () => {
|
||||||
await startingPromise;
|
if (state !== "started") {
|
||||||
|
throw new Error(`Tried to stop "${id}", but it is already ${state}.`);
|
||||||
if (stopped) {
|
|
||||||
throw new Error(`Tried to stop "${id}", but it has already stopped.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!started) {
|
stop();
|
||||||
throw new Error(`Tried to stop "${id}", but it has not started yet.`);
|
state = "stopped";
|
||||||
}
|
|
||||||
|
|
||||||
await stop();
|
|
||||||
|
|
||||||
started = false;
|
|
||||||
stopped = true;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|||||||
@ -15,8 +15,9 @@ const applicationMenuReactivityInjectable = getInjectable({
|
|||||||
const applicationMenuItemComposite = di.inject(applicationMenuItemCompositeInjectable);
|
const applicationMenuItemComposite = di.inject(applicationMenuItemCompositeInjectable);
|
||||||
const populateApplicationMenu = di.inject(populateApplicationMenuInjectable);
|
const populateApplicationMenu = di.inject(populateApplicationMenuInjectable);
|
||||||
|
|
||||||
return getStartableStoppable("application-menu-reactivity", () =>
|
return getStartableStoppable(
|
||||||
autorun(() => populateApplicationMenu(applicationMenuItemComposite.get()), {
|
"application-menu-reactivity",
|
||||||
|
() => autorun(() => populateApplicationMenu(applicationMenuItemComposite.get()), {
|
||||||
delay: 100,
|
delay: 100,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,15 +10,11 @@ const stopApplicationMenuInjectable = getInjectable({
|
|||||||
id: "stop-application-menu",
|
id: "stop-application-menu",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const applicationMenu = di.inject(
|
const applicationMenu = di.inject(applicationMenuReactivityInjectable);
|
||||||
applicationMenuReactivityInjectable,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-application-menu",
|
id: "stop-application-menu",
|
||||||
run: async () => {
|
run: () => void applicationMenu.stop(),
|
||||||
await applicationMenu.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { getStartableStoppable } from "../../../../../common/utils/get-startable
|
|||||||
import processCheckingForUpdatesInjectable from "../../../main/process-checking-for-updates.injectable";
|
import processCheckingForUpdatesInjectable from "../../../main/process-checking-for-updates.injectable";
|
||||||
import withOrphanPromiseInjectable from "../../../../../common/utils/with-orphan-promise/with-orphan-promise.injectable";
|
import withOrphanPromiseInjectable from "../../../../../common/utils/with-orphan-promise/with-orphan-promise.injectable";
|
||||||
|
|
||||||
|
const TWO_HOURS = 1000 * 60 * 60 * 2;
|
||||||
|
|
||||||
const periodicalCheckForUpdatesInjectable = getInjectable({
|
const periodicalCheckForUpdatesInjectable = getInjectable({
|
||||||
id: "periodical-check-for-updates",
|
id: "periodical-check-for-updates",
|
||||||
|
|
||||||
@ -15,12 +17,9 @@ const periodicalCheckForUpdatesInjectable = getInjectable({
|
|||||||
const processCheckingForUpdates = withOrphanPromise(di.inject(processCheckingForUpdatesInjectable));
|
const processCheckingForUpdates = withOrphanPromise(di.inject(processCheckingForUpdatesInjectable));
|
||||||
|
|
||||||
return getStartableStoppable("periodical-check-for-updates", () => {
|
return getStartableStoppable("periodical-check-for-updates", () => {
|
||||||
const TWO_HOURS = 1000 * 60 * 60 * 2;
|
|
||||||
|
|
||||||
processCheckingForUpdates("periodic");
|
processCheckingForUpdates("periodic");
|
||||||
|
|
||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
|
|
||||||
processCheckingForUpdates("periodic");
|
processCheckingForUpdates("periodic");
|
||||||
}, TWO_HOURS);
|
}, TWO_HOURS);
|
||||||
|
|
||||||
|
|||||||
@ -14,10 +14,12 @@ const stopCheckingForUpdatesInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-checking-for-updates",
|
id: "stop-checking-for-updates",
|
||||||
run: async () => {
|
run: () => {
|
||||||
if (periodicalCheckForUpdates.started) {
|
if (periodicalCheckForUpdates.started) {
|
||||||
await periodicalCheckForUpdates.stop();
|
periodicalCheckForUpdates.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopWatchingIfUpdateShouldHappenOnQuitInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-watching-if-update-should-happen-on-quit",
|
id: "stop-watching-if-update-should-happen-on-quit",
|
||||||
run: () => {
|
run: () => void watchIfUpdateShouldHappenOnQuit.stop(),
|
||||||
watchIfUpdateShouldHappenOnQuit.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,9 @@ const setupAppPathsInjectable = getInjectable({
|
|||||||
) as AppPaths;
|
) as AppPaths;
|
||||||
|
|
||||||
appPathsState.set(appPaths);
|
appPathsState.set(appPaths);
|
||||||
|
|
||||||
|
// NOTE: this is the worse of two evils. This makes sure that `RunnableSync` always is sync
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,8 +13,9 @@ const catalogSyncToRendererInjectable = getInjectable({
|
|||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||||
|
|
||||||
return getStartableStoppable("catalog-sync", () =>
|
return getStartableStoppable(
|
||||||
startCatalogSyncToRenderer(catalogEntityRegistry),
|
"catalog-sync",
|
||||||
|
() => startCatalogSyncToRenderer(catalogEntityRegistry),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -14,10 +14,12 @@ const stopCatalogSyncInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-catalog-sync",
|
id: "stop-catalog-sync",
|
||||||
run: async () => {
|
run: () => {
|
||||||
if (catalogSyncToRenderer.started) {
|
if (catalogSyncToRenderer.started) {
|
||||||
await catalogSyncToRenderer.stop();
|
catalogSyncToRenderer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -18,9 +18,7 @@ const syncThemeFromOperatingSystemInjectable = getInjectable({
|
|||||||
|
|
||||||
return getStartableStoppable("sync-theme-from-operating-system", () => {
|
return getStartableStoppable("sync-theme-from-operating-system", () => {
|
||||||
const updateThemeState = () => {
|
const updateThemeState = () => {
|
||||||
const newTheme = getElectronTheme();
|
currentThemeState.set(getElectronTheme());
|
||||||
|
|
||||||
currentThemeState.set(newTheme);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeTheme.on("updated", updateThemeState);
|
nativeTheme.on("updated", updateThemeState);
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const cleanUpDeepLinkingInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "clean-up-deep-linking",
|
id: "clean-up-deep-linking",
|
||||||
run: () => {
|
run: () => void lensProtocolRouterMain.cleanup(),
|
||||||
lensProtocolRouterMain.cleanup();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,8 @@ const hideDockForLastClosedWindowInjectable = getInjectable({
|
|||||||
if (isEmpty(visibleWindows)) {
|
if (isEmpty(visibleWindows)) {
|
||||||
app.dock?.hide();
|
app.dock?.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -20,6 +20,8 @@ const enforceSingleApplicationInstanceInjectable = getInjectable({
|
|||||||
if (!requestSingleInstanceLock()) {
|
if (!requestSingleInstanceLock()) {
|
||||||
exitApp();
|
exitApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -18,6 +18,8 @@ const setupApplicationNameInjectable = getInjectable({
|
|||||||
id: "setup-application-name",
|
id: "setup-application-name",
|
||||||
run: () => {
|
run: () => {
|
||||||
app.setName(appName);
|
app.setName(appName);
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,15 +13,14 @@ const setupRunnablesAfterWindowIsOpenedInjectable = getInjectable({
|
|||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const afterWindowIsOpened = runManyFor(di)(afterWindowIsOpenedInjectionToken);
|
const afterWindowIsOpened = runManyFor(di)(afterWindowIsOpenedInjectionToken);
|
||||||
|
const app = di.inject(electronAppInjectable);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "setup-runnables-after-window-is-opened",
|
id: "setup-runnables-after-window-is-opened",
|
||||||
run: () => {
|
run: () => {
|
||||||
const app = di.inject(electronAppInjectable);
|
app.on("browser-window-created", () => afterWindowIsOpened);
|
||||||
|
|
||||||
app.on("browser-window-created", async () => {
|
return undefined;
|
||||||
await afterWindowIsOpened();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -15,24 +15,16 @@ const setupRunnablesBeforeClosingOfApplicationInjectable = getInjectable({
|
|||||||
id: "setup-closing-of-application",
|
id: "setup-closing-of-application",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const runMany = runManySyncFor(di);
|
const runManySync = runManySyncFor(di);
|
||||||
|
const runRunnablesBeforeQuitOfFrontEnd = runManySync(beforeQuitOfFrontEndInjectionToken);
|
||||||
const runRunnablesBeforeQuitOfFrontEnd = runMany(
|
const runRunnablesBeforeQuitOfBackEnd = runManySync(beforeQuitOfBackEndInjectionToken);
|
||||||
beforeQuitOfFrontEndInjectionToken,
|
const app = di.inject(electronAppInjectable);
|
||||||
);
|
const isIntegrationTesting = di.inject(isIntegrationTestingInjectable);
|
||||||
|
const autoUpdater = di.inject(autoUpdaterInjectable);
|
||||||
const runRunnablesBeforeQuitOfBackEnd = runMany(
|
|
||||||
beforeQuitOfBackEndInjectionToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "setup-closing-of-application",
|
id: "setup-closing-of-application",
|
||||||
run: () => {
|
run: () => {
|
||||||
const app = di.inject(electronAppInjectable);
|
|
||||||
|
|
||||||
const isIntegrationTesting = di.inject(isIntegrationTestingInjectable);
|
|
||||||
const autoUpdater = di.inject(autoUpdaterInjectable);
|
|
||||||
|
|
||||||
let isAutoUpdating = false;
|
let isAutoUpdating = false;
|
||||||
|
|
||||||
autoUpdater.on("before-quit-for-update", () => {
|
autoUpdater.on("before-quit-for-update", () => {
|
||||||
@ -51,6 +43,8 @@ const setupRunnablesBeforeClosingOfApplicationInjectable = getInjectable({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
||||||
|
|
||||||
export const beforeElectronIsReadyInjectionToken =
|
export const beforeElectronIsReadyInjectionToken = getInjectionToken<RunnableSync>({
|
||||||
getInjectionToken<RunnableSync>({
|
id: "before-electron-is-ready",
|
||||||
id: "before-electron-is-ready",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
||||||
|
|
||||||
export const beforeQuitOfBackEndInjectionToken =
|
export const beforeQuitOfBackEndInjectionToken = getInjectionToken<RunnableSync>({
|
||||||
getInjectionToken<RunnableSync>({
|
id: "before-quit-of-back-end",
|
||||||
id: "before-quit-of-back-end",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
import type { RunnableSync } from "../../../common/runnable/run-many-sync-for";
|
||||||
|
|
||||||
export const beforeQuitOfFrontEndInjectionToken =
|
export const beforeQuitOfFrontEndInjectionToken = getInjectionToken<RunnableSync>({
|
||||||
getInjectionToken<RunnableSync>({
|
id: "before-quit-of-front-end",
|
||||||
id: "before-quit-of-front-end",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -11,9 +11,7 @@ const cleanUpShellSessionsInjectable = getInjectable({
|
|||||||
|
|
||||||
instantiate: () => ({
|
instantiate: () => ({
|
||||||
id: "clean-up-shell-sessions",
|
id: "clean-up-shell-sessions",
|
||||||
run: () => {
|
run: () => void ShellSession.cleanup(),
|
||||||
ShellSession.cleanup();
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: beforeQuitOfBackEndInjectionToken,
|
injectionToken: beforeQuitOfBackEndInjectionToken,
|
||||||
|
|||||||
@ -16,6 +16,8 @@ const emitCloseToEventBusInjectable = getInjectable({
|
|||||||
id: "emit-close-to-event-bus",
|
id: "emit-close-to-event-bus",
|
||||||
run: () => {
|
run: () => {
|
||||||
emitAppEvent({ name: "app", action: "close" });
|
emitAppEvent({ name: "app", action: "close" });
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -20,6 +20,8 @@ const flagRendererAsNotLoadedInjectable = getInjectable({
|
|||||||
// Todo: remove this kludge which enables out-of-place temporal dependency.
|
// Todo: remove this kludge which enables out-of-place temporal dependency.
|
||||||
lensProtocolRouterMain.rendererLoaded = false;
|
lensProtocolRouterMain.rendererLoaded = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopKubeConfigSyncInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-kube-config-sync",
|
id: "stop-kube-config-sync",
|
||||||
run: () => {
|
run: () => void kubeConfigSyncManager.stopSync(),
|
||||||
kubeConfigSyncManager.stopSync();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const setupSentryInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "setup-sentry",
|
id: "setup-sentry",
|
||||||
run: () => initializeSentryReportingWith(initializeSentryOnMain),
|
run: () => void initializeSentryReportingWith(initializeSentryOnMain),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
injectionToken: beforeElectronIsReadyInjectionToken,
|
injectionToken: beforeElectronIsReadyInjectionToken,
|
||||||
|
|||||||
@ -20,6 +20,8 @@ const setupHardwareAccelerationInjectable = getInjectable({
|
|||||||
if (hardwareAccelerationShouldBeDisabled) {
|
if (hardwareAccelerationShouldBeDisabled) {
|
||||||
disableHardwareAcceleration();
|
disableHardwareAcceleration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -16,6 +16,8 @@ const setupImmerInjectable = getInjectable({
|
|||||||
// Required in `utils/storage-helper.ts`
|
// Required in `utils/storage-helper.ts`
|
||||||
Immer.setAutoFreeze(false); // allow to merge mobx observables
|
Immer.setAutoFreeze(false); // allow to merge mobx observables
|
||||||
Immer.enableMapSet(); // allow to merge maps and sets
|
Immer.enableMapSet(); // allow to merge maps and sets
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,8 @@ const setupMobxInjectable = getInjectable({
|
|||||||
// reactionRequiresObservable: true,
|
// reactionRequiresObservable: true,
|
||||||
// observableRequiresReaction: true,
|
// observableRequiresReaction: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,8 @@ const setupProxyEnvInjectable = getInjectable({
|
|||||||
if (getCommandLineSwitch("proxy-server") !== "") {
|
if (getCommandLineSwitch("proxy-server") !== "") {
|
||||||
process.env.HTTPS_PROXY = getCommandLineSwitch("proxy-server");
|
process.env.HTTPS_PROXY = getCommandLineSwitch("proxy-server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -16,13 +16,13 @@ const stopClusterManagerInjectable = getInjectable({
|
|||||||
id: "stop-cluster-manager",
|
id: "stop-cluster-manager",
|
||||||
run: () => {
|
run: () => {
|
||||||
clusterManager.stop();
|
clusterManager.stop();
|
||||||
|
|
||||||
|
return undefined;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
injectionToken: beforeQuitOfFrontEndInjectionToken,
|
injectionToken: beforeQuitOfFrontEndInjectionToken,
|
||||||
|
|
||||||
causesSideEffects: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default stopClusterManagerInjectable;
|
export default stopClusterManagerInjectable;
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopBroadcastingThemeChangeInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-broadcasting-theme-change",
|
id: "stop-broadcasting-theme-change",
|
||||||
run: async () => {
|
run: () => void broadcastThemeChange.stop(),
|
||||||
await broadcastThemeChange.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopSyncingThemeFromOperatingSystemInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-syncing-theme-from-operating-system",
|
id: "stop-syncing-theme-from-operating-system",
|
||||||
run: async () => {
|
run: () => void syncTheme.stop(),
|
||||||
await syncTheme.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -15,10 +15,7 @@ const stopTrayInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-tray",
|
id: "stop-tray",
|
||||||
run: () => {
|
run: () => void electronTray.stop(),
|
||||||
electronTray.stop();
|
|
||||||
},
|
|
||||||
|
|
||||||
runAfter: di.inject(stopReactiveTrayMenuItemsInjectable),
|
runAfter: di.inject(stopReactiveTrayMenuItemsInjectable),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopReactiveTrayMenuIconInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-reactive-tray-menu-icon",
|
id: "stop-reactive-tray-menu-icon",
|
||||||
run: async () => {
|
run: () => void reactiveTrayMenuIcon.stop(),
|
||||||
await reactiveTrayMenuIcon.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,8 @@ const reactiveTrayMenuItemsInjectable = getInjectable({
|
|||||||
|
|
||||||
return getStartableStoppable("reactive-tray-menu-items", () =>
|
return getStartableStoppable("reactive-tray-menu-items", () =>
|
||||||
reaction(
|
reaction(
|
||||||
(): MinimalTrayMenuItem[] => reactiveItems.get().map(toNonReactiveItem),
|
() => reactiveItems.get().map(toNonReactiveItem),
|
||||||
|
|
||||||
(nonReactiveItems) => electronTray.setMenuItems(nonReactiveItems),
|
(nonReactiveItems) => electronTray.setMenuItems(nonReactiveItems),
|
||||||
|
|
||||||
{
|
{
|
||||||
fireImmediately: true,
|
fireImmediately: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,9 +14,7 @@ const stopReactiveTrayMenuItemsInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "stop-reactive-tray-menu-items",
|
id: "stop-reactive-tray-menu-items",
|
||||||
run: async () => {
|
run: () => void reactiveTrayMenuItems.stop(),
|
||||||
await reactiveTrayMenuItems.stop();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -16,9 +16,9 @@ const startListeningOnChannelsInjectable = getInjectable({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
id: "start-listening-on-channels-main",
|
id: "start-listening-on-channels-main",
|
||||||
run: async () => {
|
run: () => {
|
||||||
await listeningOnMessageChannels.start();
|
listeningOnMessageChannels.start();
|
||||||
await listeningOnRequestChannels.start();
|
listeningOnRequestChannels.start();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user