generated from Alorel/basic-library-template-repo
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Closes #35
- Loading branch information
Showing
11 changed files
with
165 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import {takeUntil} from 'rxjs'; | ||
import {take} from 'rxjs/operators'; | ||
import type {WorkflowStep} from '../../lib/data/workflow-step.mjs'; | ||
import type {Workflow} from '../../lib/data/workflow.mjs'; | ||
import {WorkflowExecution} from '../../lib/execution/workflow-execution.mjs'; | ||
import {InternalCategory} from '../../lib/registries/action-registry.mjs'; | ||
import WorkflowRegistry from '../../lib/registries/workflow-registry.mjs'; | ||
import {defineLocalAction} from '../../lib/util/define-local.mjs'; | ||
import {memoOutput} from '../../lib/util/memo.mjs'; | ||
import type {Obj} from '../../public_api'; | ||
import {mainIcon} from '../../ui/ui.mjs'; | ||
import ActionId from '../action-id.mjs'; | ||
|
||
interface Props { | ||
name: string; | ||
stop: StopCondition; | ||
} | ||
|
||
const enum StopCondition { | ||
NextStepTrigger = 's', | ||
WorkflowCompletion = 'w', | ||
} | ||
|
||
const reduceWorkflowNames = (acc: Obj<string>, {name}: Workflow): Obj<string> => { | ||
acc[name] = name; | ||
|
||
return acc; | ||
}; | ||
const getWorkflowNames = memoOutput((): Obj<string> => ( | ||
WorkflowRegistry.inst.workflows.reduce(reduceWorkflowNames, {}) | ||
)); | ||
|
||
defineLocalAction<Props>({ | ||
category: InternalCategory.CORE, | ||
execute({name, stop}) { | ||
const reg = WorkflowRegistry.inst; | ||
const workflow = reg.workflows.find(wf => wf.name === name); | ||
|
||
if (!workflow) { | ||
throw new Error(`Workflow not found: ${name}`); | ||
} | ||
|
||
switch (stop) { | ||
case StopCondition.WorkflowCompletion: | ||
return new WorkflowExecution(workflow); | ||
case StopCondition.NextStepTrigger: { | ||
const exec = reg.primaryExecution; | ||
if (!exec) { | ||
throw new Error('There is no primary execution running'); | ||
} | ||
|
||
const activeIdx = exec.activeStepIdx; | ||
const steps = exec.workflow.steps; | ||
|
||
let nextStep: WorkflowStep | undefined = steps[activeIdx + 1]; | ||
if (!nextStep) { // Check for "jump to step" action | ||
const currStep = steps[activeIdx]; | ||
if (!currStep) { | ||
throw new Error('Screwy primary execution: current step not found in steps array'); | ||
} | ||
|
||
const jumpToStepAction = currStep.actions.find(a => ( | ||
|
||
// @ts-expect-error | ||
a.action.id === ActionId.CoreSetStepIdx | ||
)); | ||
if (!jumpToStepAction) { | ||
throw new Error('There is no next step'); | ||
} | ||
|
||
const tryIdx: number | undefined = jumpToStepAction.opts.idx; | ||
if (typeof tryIdx !== 'number') { | ||
throw new Error('Can\'t resolve next step: jump to step index not a number'); | ||
} | ||
|
||
nextStep = steps[tryIdx]; | ||
if (!nextStep) { | ||
throw new Error('Can\'t resolve next step: jump to step index leads to nothing'); | ||
} | ||
} | ||
|
||
return new WorkflowExecution(workflow).pipe( | ||
takeUntil(nextStep.trigger.listen().pipe(take(1))) | ||
); | ||
} | ||
default: | ||
throw new Error(`Unknown stop condition: ${stop}`); | ||
} | ||
}, | ||
id: ActionId.ExecWorkflow, | ||
initOptions: () => ({stop: StopCondition.NextStepTrigger}), | ||
label: 'Execute workflow', | ||
media: mainIcon, | ||
options: [ | ||
{ | ||
enum: getWorkflowNames, | ||
id: 'name', | ||
label: 'Name', | ||
required: true, | ||
type: String, | ||
}, | ||
{ | ||
description: '"Workflow completion" will execute the inner workflow until it\'s done; "Next step\'s trigger" will execute it until it completes or until the trigger for the next step fires. You CAN use a "Jump to step" action immediately following this one with the "next step trigger" option.', | ||
enum: { | ||
[StopCondition.NextStepTrigger]: 'Next step\'s trigger', | ||
[StopCondition.WorkflowCompletion]: 'Workflow completion', | ||
}, | ||
id: 'stop', | ||
label: 'Stop condition', | ||
required: true, | ||
type: String, | ||
}, | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {isEqual} from 'lodash-es'; | ||
|
||
type This<T> = T extends (this: infer E) => any ? E : never; | ||
|
||
/** | ||
* Returns the previously returned object if calling the function again yields the same output | ||
* @param fn The function | ||
* @param checkFn Function used for output equality checking | ||
*/ | ||
export function memoOutput<T extends(...args: any[]) => any>( | ||
fn: T, | ||
checkFn: (a: ReturnType<T>, b: ReturnType<T>) => boolean = isEqual | ||
): T { | ||
let prevReturn: ReturnType<T>; | ||
|
||
return function memoOutputFn(this: This<T>): ReturnType<T> { | ||
const out = fn.apply(this, arguments as unknown as Parameters<T>); | ||
if (checkFn(out, prevReturn)) { | ||
return prevReturn; | ||
} | ||
|
||
prevReturn = out; | ||
return out; | ||
} as T; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export function objectFromArray<T extends string>(values: T[]): Record<T, T> { | ||
const out: Record<T, T> = {} as any; | ||
for (const v of values) { | ||
out[v] = v; | ||
} | ||
|
||
return out; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters