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..15400bf5cb 100644 --- a/src/common/runnable/run-many-sync-for.test.ts +++ b/src/common/runnable/run-many-sync-for.test.ts @@ -152,7 +152,7 @@ describe("runManySyncFor", () => { ); 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-sync-for.ts b/src/common/runnable/run-many-sync-for.ts index 1d3dcec2c5..5156b7c2e1 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; @@ -16,33 +15,34 @@ export interface RunnableSync { type RunSync = (parameter: Param) => void; -export type RunManySync = ( - injectionToken: InjectionToken, void> -) => RunSync; +export type RunManySync = (injectionToken: InjectionToken, void>) => RunSync; + +function runCompositeRunnableSyncs(param: Param, composite: Composite>) { + composite.value.run(param); + composite.children.map(composite => runCompositeRunnableSyncs(param, composite)); +} export function runManySyncFor(di: DiContainerForInjection): RunManySync { - 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 = ( - runAfterRunnable: RunnableSync | undefined = undefined, - ) => - pipeline( - allRunnables, - - tap(runnables => forEach(throwWithIncorrectHierarchy, runnables)), - - filter((runnable) => runnable.runAfter === runAfterRunnable), - - map((runnable) => { - runnable.run(parameter); - - recursedRun(runnable); - }), - ); - - recursedRun(); + runCompositeRunnableSyncs(param, composite); }; }