@mat3ra/wode 2025.10.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +17 -0
- package/LICENSE.md +15 -0
- package/README.md +164 -0
- package/assets/subworkflows/deepmd/deepmd.yml +31 -0
- package/assets/subworkflows/deepmd/espresso_cp_md.yml +16 -0
- package/assets/subworkflows/espresso/average_electrostatic_potential_find_minima.yml +27 -0
- package/assets/subworkflows/espresso/average_electrostatic_potential_via_band_structure.yml +67 -0
- package/assets/subworkflows/espresso/band_gap.yml +21 -0
- package/assets/subworkflows/espresso/band_gap_hse_dos.yml +30 -0
- package/assets/subworkflows/espresso/band_structure.yml +26 -0
- package/assets/subworkflows/espresso/band_structure_dos.yml +34 -0
- package/assets/subworkflows/espresso/band_structure_hse.yml +30 -0
- package/assets/subworkflows/espresso/band_structure_magn.yml +31 -0
- package/assets/subworkflows/espresso/band_structure_soc.yml +30 -0
- package/assets/subworkflows/espresso/dielectric_tensor.yml +35 -0
- package/assets/subworkflows/espresso/dos.yml +24 -0
- package/assets/subworkflows/espresso/electronic_density_mesh.yml +19 -0
- package/assets/subworkflows/espresso/esm.yml +14 -0
- package/assets/subworkflows/espresso/esm_relax.yml +14 -0
- package/assets/subworkflows/espresso/espresso_extract_kpoints.yml +16 -0
- package/assets/subworkflows/espresso/espresso_xml_get_qpt_irr.yml +12 -0
- package/assets/subworkflows/espresso/fixed_cell_relaxation.yml +16 -0
- package/assets/subworkflows/espresso/gw_band_structure_band_gap_full_frequency.yml +22 -0
- package/assets/subworkflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +22 -0
- package/assets/subworkflows/espresso/hubbard_u_hp.yml +21 -0
- package/assets/subworkflows/espresso/kpoint_convergence.yml +86 -0
- package/assets/subworkflows/espresso/neb.yml +16 -0
- package/assets/subworkflows/espresso/ph_init_qpoints.yml +14 -0
- package/assets/subworkflows/espresso/ph_single_irr_qpt.yml +14 -0
- package/assets/subworkflows/espresso/phonon_dispersions.yml +29 -0
- package/assets/subworkflows/espresso/phonon_dos.yml +29 -0
- package/assets/subworkflows/espresso/phonon_dos_dispersion.yml +34 -0
- package/assets/subworkflows/espresso/phonon_reduce.yml +29 -0
- package/assets/subworkflows/espresso/post_processor.yml +14 -0
- package/assets/subworkflows/espresso/pre_processor.yml +14 -0
- package/assets/subworkflows/espresso/pw_scf.yml +16 -0
- package/assets/subworkflows/espresso/recalculate_bands.yml +19 -0
- package/assets/subworkflows/espresso/surface_energy.yml +16 -0
- package/assets/subworkflows/espresso/total_energy.yml +16 -0
- package/assets/subworkflows/espresso/valence_band_offset_calc_from_previous_esp_vbm.yml +35 -0
- package/assets/subworkflows/espresso/variable_cell_relaxation.yml +18 -0
- package/assets/subworkflows/espresso/zero_point_energy.yml +19 -0
- package/assets/subworkflows/jupyterLab/jupyter_notebook.yml +17 -0
- package/assets/subworkflows/nwchem/total_energy.yml +16 -0
- package/assets/subworkflows/python/ml/classification_tail.yml +56 -0
- package/assets/subworkflows/python/ml/clustering_tail.yml +62 -0
- package/assets/subworkflows/python/ml/regression_tail.yml +56 -0
- package/assets/subworkflows/python/ml/train_head.yml +61 -0
- package/assets/subworkflows/python/python_script.yml +14 -0
- package/assets/subworkflows/shell/batch_espresso_pwscf.yml +14 -0
- package/assets/subworkflows/shell/hello_world.yml +14 -0
- package/assets/subworkflows/vasp/band_gap.yml +21 -0
- package/assets/subworkflows/vasp/band_structure.yml +21 -0
- package/assets/subworkflows/vasp/band_structure_dos.yml +23 -0
- package/assets/subworkflows/vasp/dos.yml +18 -0
- package/assets/subworkflows/vasp/fixed_cell_relaxation.yml +16 -0
- package/assets/subworkflows/vasp/initial_final_total_energies.yml +25 -0
- package/assets/subworkflows/vasp/kpoint_convergence.yml +89 -0
- package/assets/subworkflows/vasp/neb_subworkflow.yml +16 -0
- package/assets/subworkflows/vasp/prepare_images.yml +16 -0
- package/assets/subworkflows/vasp/recalculate_bands.yml +16 -0
- package/assets/subworkflows/vasp/surface_energy.yml +18 -0
- package/assets/subworkflows/vasp/total_energy.yml +16 -0
- package/assets/subworkflows/vasp/variable_cell_relaxation.yml +18 -0
- package/assets/subworkflows/vasp/zero_point_energy.yml +16 -0
- package/assets/workflows/deepmd/deepmd_md.yml +6 -0
- package/assets/workflows/espresso/band_gap.yml +4 -0
- package/assets/workflows/espresso/band_gap_dos_hse.yml +4 -0
- package/assets/workflows/espresso/band_structure.yml +4 -0
- package/assets/workflows/espresso/band_structure_dos.yml +4 -0
- package/assets/workflows/espresso/band_structure_hse.yml +14 -0
- package/assets/workflows/espresso/band_structure_magn.yml +7 -0
- package/assets/workflows/espresso/band_structure_soc.yml +7 -0
- package/assets/workflows/espresso/dielectric_tensor.yml +4 -0
- package/assets/workflows/espresso/dos.yml +4 -0
- package/assets/workflows/espresso/electronic_density_mesh.yml +4 -0
- package/assets/workflows/espresso/esm.yml +4 -0
- package/assets/workflows/espresso/esm_relax.yml +4 -0
- package/assets/workflows/espresso/fixed_cell_relaxation.yml +4 -0
- package/assets/workflows/espresso/gw_band_structure_band_gap_full_frequency.yml +4 -0
- package/assets/workflows/espresso/gw_band_structure_band_gap_plasmon_pole.yml +4 -0
- package/assets/workflows/espresso/hubbard_u_hp.yml +7 -0
- package/assets/workflows/espresso/kpoint_convergence.yml +4 -0
- package/assets/workflows/espresso/neb.yml +4 -0
- package/assets/workflows/espresso/phonon_dispersions.yml +4 -0
- package/assets/workflows/espresso/phonon_dos.yml +4 -0
- package/assets/workflows/espresso/phonon_dos_dispersion.yml +4 -0
- package/assets/workflows/espresso/phonon_map.yml +28 -0
- package/assets/workflows/espresso/recalculate_bands.yml +4 -0
- package/assets/workflows/espresso/surface_energy.yml +4 -0
- package/assets/workflows/espresso/total_energy.yml +4 -0
- package/assets/workflows/espresso/valence_band_offset.yml +171 -0
- package/assets/workflows/espresso/variable_cell_relaxation.yml +4 -0
- package/assets/workflows/espresso/zero_point_energy.yml +4 -0
- package/assets/workflows/jupyterLab/jupyter_notebook.yml +4 -0
- package/assets/workflows/nwchem/total_energy.yml +4 -0
- package/assets/workflows/python/ml/classification_workflow.yml +9 -0
- package/assets/workflows/python/ml/clustering_workflow.yml +9 -0
- package/assets/workflows/python/ml/regression_workflow.yml +9 -0
- package/assets/workflows/python/python_script.yml +4 -0
- package/assets/workflows/shell/batch_espresso_pwscf.yml +4 -0
- package/assets/workflows/shell/hello_world.yml +4 -0
- package/assets/workflows/vasp/band_gap.yml +4 -0
- package/assets/workflows/vasp/band_structure.yml +4 -0
- package/assets/workflows/vasp/band_structure_dos.yml +4 -0
- package/assets/workflows/vasp/dos.yml +4 -0
- package/assets/workflows/vasp/fixed_cell_relaxation.yml +4 -0
- package/assets/workflows/vasp/kpoint_convergence.yml +4 -0
- package/assets/workflows/vasp/neb.yml +8 -0
- package/assets/workflows/vasp/recalculate_bands.yml +4 -0
- package/assets/workflows/vasp/surface_energy.yml +4 -0
- package/assets/workflows/vasp/total_energy.yml +4 -0
- package/assets/workflows/vasp/variable_cell_relaxation.yml +4 -0
- package/assets/workflows/vasp/zero_point_energy.yml +4 -0
- package/build_workflows.js +65 -0
- package/dist/context/context.js +49 -0
- package/dist/context/mixins/ApplicationContextMixin.js +19 -0
- package/dist/context/mixins/JobContextMixin.js +39 -0
- package/dist/context/mixins/MaterialContextMixin.js +40 -0
- package/dist/context/mixins/MaterialsContextMixin.js +19 -0
- package/dist/context/mixins/MaterialsSetContextMixin.js +25 -0
- package/dist/context/mixins/MethodDataContextMixin.js +48 -0
- package/dist/context/mixins/WorkflowContextMixin.js +28 -0
- package/dist/context/providers/BoundaryConditionsFormDataProvider.js +86 -0
- package/dist/context/providers/CollinearMagnetizationContextProvider.js +113 -0
- package/dist/context/providers/HubbardContextProviderLegacy.js +81 -0
- package/dist/context/providers/HubbardJContextProvider.js +74 -0
- package/dist/context/providers/HubbardUContextProvider.js +77 -0
- package/dist/context/providers/HubbardVContextProvider.js +104 -0
- package/dist/context/providers/IonDynamicsContextProvider.js +62 -0
- package/dist/context/providers/MLSettingsContextProvider.js +52 -0
- package/dist/context/providers/MLTrainTestSplitContextProvider.js +48 -0
- package/dist/context/providers/NEBFormDataProvider.js +38 -0
- package/dist/context/providers/NonCollinearMagnetizationContextProvider.js +253 -0
- package/dist/context/providers/PlanewaveCutoffsContextProvider.js +67 -0
- package/dist/context/providers/PointsGridFormDataProvider.js +272 -0
- package/dist/context/providers/PointsPathFormDataProvider.js +155 -0
- package/dist/context/providers/by_application/ExecutableContextProvider.js +17 -0
- package/dist/context/providers/by_application/espresso/QENEBContextProvider.js +60 -0
- package/dist/context/providers/by_application/espresso/QEPWXContextProvider.js +149 -0
- package/dist/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +84 -0
- package/dist/context/providers/by_application/vasp/VASPContextProvider.js +64 -0
- package/dist/context/providers/by_application/vasp/VASPNEBContextProvider.js +56 -0
- package/dist/context/providers/settings.js +37 -0
- package/dist/context/providers.js +199 -0
- package/dist/enums.js +65 -0
- package/dist/index.js +64 -0
- package/dist/patch.js +19 -0
- package/dist/subworkflows/convergence/factory.js +35 -0
- package/dist/subworkflows/convergence/non_uniform_kgrid.js +31 -0
- package/dist/subworkflows/convergence/parameter.js +70 -0
- package/dist/subworkflows/convergence/uniform_kgrid.js +26 -0
- package/dist/subworkflows/convergence.js +189 -0
- package/dist/subworkflows/create.js +285 -0
- package/dist/subworkflows/dynamic/espresso/getQpointIrrep.js +34 -0
- package/dist/subworkflows/dynamic/index.js +19 -0
- package/dist/subworkflows/dynamic/surfaceEnergy.js +67 -0
- package/dist/subworkflows/index.js +19 -0
- package/dist/subworkflows/subworkflow.js +279 -0
- package/dist/units/assertion.js +37 -0
- package/dist/units/assignment.js +42 -0
- package/dist/units/base.js +91 -0
- package/dist/units/builders/AssertionUnitConfigBuilder.js +34 -0
- package/dist/units/builders/AssignmentUnitConfigBuilder.js +41 -0
- package/dist/units/builders/ExecutionUnitConfigBuilder.js +67 -0
- package/dist/units/builders/IOUnitConfigBuilder.js +54 -0
- package/dist/units/builders/UnitConfigBuilder.js +79 -0
- package/dist/units/builders/index.js +18 -0
- package/dist/units/condition.js +52 -0
- package/dist/units/execution.js +222 -0
- package/dist/units/factory.js +53 -0
- package/dist/units/index.js +82 -0
- package/dist/units/io.js +148 -0
- package/dist/units/map.js +38 -0
- package/dist/units/processing.js +41 -0
- package/dist/units/reduce.js +24 -0
- package/dist/units/subworkflow.js +23 -0
- package/dist/utils.js +92 -0
- package/dist/workflows/create.js +312 -0
- package/dist/workflows/default.js +41 -0
- package/dist/workflows/index.js +108 -0
- package/dist/workflows/relaxation.js +37 -0
- package/dist/workflows/workflow.js +303 -0
- package/package.json +94 -0
- package/src/context/context.js +47 -0
- package/src/context/mixins/ApplicationContextMixin.js +19 -0
- package/src/context/mixins/JobContextMixin.js +36 -0
- package/src/context/mixins/MaterialContextMixin.js +41 -0
- package/src/context/mixins/MaterialsContextMixin.js +18 -0
- package/src/context/mixins/MaterialsSetContextMixin.js +24 -0
- package/src/context/mixins/MethodDataContextMixin.js +48 -0
- package/src/context/mixins/WorkflowContextMixin.js +25 -0
- package/src/context/providers/BoundaryConditionsFormDataProvider.js +80 -0
- package/src/context/providers/CollinearMagnetizationContextProvider.js +117 -0
- package/src/context/providers/HubbardContextProviderLegacy.js +75 -0
- package/src/context/providers/HubbardJContextProvider.js +73 -0
- package/src/context/providers/HubbardUContextProvider.js +100 -0
- package/src/context/providers/HubbardVContextProvider.js +111 -0
- package/src/context/providers/IonDynamicsContextProvider.js +56 -0
- package/src/context/providers/MLSettingsContextProvider.js +48 -0
- package/src/context/providers/MLTrainTestSplitContextProvider.js +45 -0
- package/src/context/providers/NEBFormDataProvider.js +32 -0
- package/src/context/providers/NonCollinearMagnetizationContextProvider.js +269 -0
- package/src/context/providers/PlanewaveCutoffsContextProvider.js +68 -0
- package/src/context/providers/PointsGridFormDataProvider.js +285 -0
- package/src/context/providers/PointsPathFormDataProvider.js +165 -0
- package/src/context/providers/by_application/ExecutableContextProvider.js +10 -0
- package/src/context/providers/by_application/espresso/QENEBContextProvider.js +56 -0
- package/src/context/providers/by_application/espresso/QEPWXContextProvider.js +166 -0
- package/src/context/providers/by_application/nwchem/NWChemTotalEnergyContextProvider.js +86 -0
- package/src/context/providers/by_application/vasp/VASPContextProvider.js +56 -0
- package/src/context/providers/by_application/vasp/VASPNEBContextProvider.js +46 -0
- package/src/context/providers/settings.js +38 -0
- package/src/context/providers.js +140 -0
- package/src/enums.js +65 -0
- package/src/index.js +17 -0
- package/src/patch.js +12 -0
- package/src/subworkflows/convergence/factory.js +14 -0
- package/src/subworkflows/convergence/non_uniform_kgrid.js +28 -0
- package/src/subworkflows/convergence/parameter.js +58 -0
- package/src/subworkflows/convergence/uniform_kgrid.js +22 -0
- package/src/subworkflows/convergence.js +196 -0
- package/src/subworkflows/create.js +201 -0
- package/src/subworkflows/dynamic/espresso/getQpointIrrep.js +35 -0
- package/src/subworkflows/dynamic/index.js +8 -0
- package/src/subworkflows/dynamic/surfaceEnergy.js +124 -0
- package/src/subworkflows/index.js +2 -0
- package/src/subworkflows/subworkflow.js +329 -0
- package/src/units/assertion.js +29 -0
- package/src/units/assignment.js +34 -0
- package/src/units/base.js +97 -0
- package/src/units/builders/AssertionUnitConfigBuilder.js +28 -0
- package/src/units/builders/AssignmentUnitConfigBuilder.js +36 -0
- package/src/units/builders/ExecutionUnitConfigBuilder.js +59 -0
- package/src/units/builders/IOUnitConfigBuilder.js +53 -0
- package/src/units/builders/UnitConfigBuilder.js +86 -0
- package/src/units/builders/index.js +15 -0
- package/src/units/condition.js +47 -0
- package/src/units/execution.js +263 -0
- package/src/units/factory.js +53 -0
- package/src/units/index.js +25 -0
- package/src/units/io.js +163 -0
- package/src/units/map.js +33 -0
- package/src/units/processing.js +39 -0
- package/src/units/reduce.js +17 -0
- package/src/units/subworkflow.js +15 -0
- package/src/utils.js +73 -0
- package/src/workflows/create.js +222 -0
- package/src/workflows/default.js +39 -0
- package/src/workflows/index.js +99 -0
- package/src/workflows/relaxation.js +41 -0
- package/src/workflows/workflow.js +351 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { Template } from "@exabyte-io/ade.js";
|
|
2
|
+
import ApplicationRegistry from "@exabyte-io/ade.js/dist/js/ApplicationRegistry";
|
|
3
|
+
import { Utils } from "@mat3ra/utils";
|
|
4
|
+
import _ from "underscore";
|
|
5
|
+
|
|
6
|
+
import { BaseUnit } from "./base";
|
|
7
|
+
|
|
8
|
+
export class ExecutionUnit extends BaseUnit {
|
|
9
|
+
// keys to be omitted during toJSON
|
|
10
|
+
static omitKeys = [
|
|
11
|
+
"job",
|
|
12
|
+
"workflow",
|
|
13
|
+
"material",
|
|
14
|
+
"materials",
|
|
15
|
+
"model",
|
|
16
|
+
"methodData",
|
|
17
|
+
"hasRelaxation",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @override this method to provide entities from other sources
|
|
22
|
+
*/
|
|
23
|
+
_initApplication(config) {
|
|
24
|
+
this._application = ApplicationRegistry.createApplication(config.application);
|
|
25
|
+
this._executable = ApplicationRegistry.getExecutableByConfig(
|
|
26
|
+
this._application.name,
|
|
27
|
+
config.executable,
|
|
28
|
+
);
|
|
29
|
+
this._flavor = ApplicationRegistry.getFlavorByConfig(this._executable, config.flavor);
|
|
30
|
+
this._templates = this._flavor ? this._flavor.inputAsTemplates : [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @override this method to provide default executable from other source
|
|
35
|
+
*/
|
|
36
|
+
_getDefaultExecutable() {
|
|
37
|
+
return ApplicationRegistry.getExecutableByName(this.application.name);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @override this method to provide default flavor from other source
|
|
42
|
+
*/
|
|
43
|
+
_getDefaultFlavor() {
|
|
44
|
+
return ApplicationRegistry.getFlavorByName(this.executable.name);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @override this method to provide custom templates
|
|
49
|
+
*/
|
|
50
|
+
_getTemplatesFromInput() {
|
|
51
|
+
return this.getInput().map((i) => new Template(i));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @override this method to provide custom input from other sources
|
|
56
|
+
*/
|
|
57
|
+
_getInput() {
|
|
58
|
+
return (
|
|
59
|
+
this.input ||
|
|
60
|
+
ApplicationRegistry.getInputAsRenderedTemplates(
|
|
61
|
+
this.flavor,
|
|
62
|
+
this.getCombinedContext(),
|
|
63
|
+
) ||
|
|
64
|
+
[]
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @override this method to provide custom input as templates
|
|
70
|
+
*/
|
|
71
|
+
_getInputAsTemplates() {
|
|
72
|
+
return ApplicationRegistry.getInputAsTemplates(this.flavor);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
_initRuntimeItems(keys, config) {
|
|
76
|
+
this._initApplication(config);
|
|
77
|
+
super._initRuntimeItems(keys);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* @summary expects an array with elements containing field [{content: "..."}]
|
|
82
|
+
*/
|
|
83
|
+
get hashFromArrayInputContent() {
|
|
84
|
+
const objectForHashing = this._getInput().map((i) => {
|
|
85
|
+
return Utils.str.removeEmptyLinesFromString(
|
|
86
|
+
Utils.str.removeCommentsFromSourceCode(i.content),
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
return Utils.hash.calculateHashFromObject(objectForHashing);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get name() {
|
|
93
|
+
return this.prop("name", this.flavor.name);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get application() {
|
|
97
|
+
return this._application;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get executable() {
|
|
101
|
+
return this._executable;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get flavor() {
|
|
105
|
+
return this._flavor;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
get templates() {
|
|
109
|
+
return this._templates;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
setApplication(application, omitSettingExecutable = false) {
|
|
113
|
+
this._application = application;
|
|
114
|
+
this.setProp("application", application.toJSON());
|
|
115
|
+
if (!omitSettingExecutable) {
|
|
116
|
+
this.setExecutable(this._getDefaultExecutable());
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
setExecutable(executable) {
|
|
121
|
+
this._executable = executable;
|
|
122
|
+
this.setProp("executable", executable.toJSON());
|
|
123
|
+
this.setFlavor(this._getDefaultFlavor());
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
setFlavor(flavor) {
|
|
127
|
+
this._flavor = flavor;
|
|
128
|
+
this.setRuntimeItemsToDefaultValues();
|
|
129
|
+
this.setProp("flavor", flavor.toJSON());
|
|
130
|
+
this.setTemplates(this._getInputAsTemplates());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
setTemplates(templates) {
|
|
134
|
+
this._templates = templates;
|
|
135
|
+
this.render(this.context, true);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
setInput(input) {
|
|
139
|
+
this.setProp("input", input);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
get defaultResults() {
|
|
143
|
+
return this.flavor.results;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get defaultMonitors() {
|
|
147
|
+
return this.flavor.monitors;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
get defaultPostProcessors() {
|
|
151
|
+
return this.flavor.postProcessors;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
get allowedResults() {
|
|
155
|
+
return this.executable.results;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
get allowedMonitors() {
|
|
159
|
+
return this.executable.monitors;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
get allowedPostProcessors() {
|
|
163
|
+
return this.executable.postProcessors;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
get allContextProviders() {
|
|
167
|
+
const list = [];
|
|
168
|
+
// pass context below to keep UI changes
|
|
169
|
+
this.templates.forEach((i) =>
|
|
170
|
+
list.push(...i.getContextProvidersAsClassInstances(this.getCombinedContext())),
|
|
171
|
+
);
|
|
172
|
+
return list;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
get contextProviders() {
|
|
176
|
+
return this.allContextProviders.filter((p) => p.isUnitContextProvider);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
get input() {
|
|
180
|
+
return this.prop("input");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
get renderingContext() {
|
|
184
|
+
return this._renderingContext || {};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
set renderingContext(ctx) {
|
|
188
|
+
this._renderingContext = ctx;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// context to persist in toJSON
|
|
192
|
+
get storedContext() {
|
|
193
|
+
return _.omit(this.context, ...this.constructor.omitKeys);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// context to show to users with some extra keys omitted
|
|
197
|
+
get visibleRenderingContext() {
|
|
198
|
+
return _.omit(this.renderingContext, ...this.constructor.omitKeys);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static getSubworkflowContext(context) {
|
|
202
|
+
const { subworkflowContext } = context;
|
|
203
|
+
return subworkflowContext ? { subworkflowContext } : {};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Update rendering context and persistent context
|
|
207
|
+
* Note: this function is sometimes being called without passing a context!
|
|
208
|
+
* @param context
|
|
209
|
+
* @param fromTemplates
|
|
210
|
+
*/
|
|
211
|
+
render(context, fromTemplates = false) {
|
|
212
|
+
const newInput = [];
|
|
213
|
+
const newPersistentContext = {};
|
|
214
|
+
const newRenderingContext = {};
|
|
215
|
+
const renderingContext = { ...this.context, ...context };
|
|
216
|
+
this.updateContext(renderingContext); // update in-memory context to properly render templates from input below
|
|
217
|
+
(fromTemplates ? this.templates : this._getTemplatesFromInput()).forEach((t) => {
|
|
218
|
+
newInput.push(t.getRenderedJSON(renderingContext));
|
|
219
|
+
Object.assign(
|
|
220
|
+
newRenderingContext,
|
|
221
|
+
t.getDataFromProvidersForRenderingContext(renderingContext),
|
|
222
|
+
ExecutionUnit.getSubworkflowContext(renderingContext),
|
|
223
|
+
);
|
|
224
|
+
Object.assign(
|
|
225
|
+
newPersistentContext,
|
|
226
|
+
t.getDataFromProvidersForPersistentContext(renderingContext),
|
|
227
|
+
ExecutionUnit.getSubworkflowContext(renderingContext),
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
this.setInput(newInput);
|
|
231
|
+
this.renderingContext = newRenderingContext;
|
|
232
|
+
this.updatePersistentContext(newPersistentContext);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @summary Calculates hash on unit-specific fields.
|
|
237
|
+
* The meaningful fields of processing unit are operation, flavor and input at the moment.
|
|
238
|
+
*/
|
|
239
|
+
getHashObject() {
|
|
240
|
+
return {
|
|
241
|
+
...super.getHashObject(),
|
|
242
|
+
application: Utils.specific.removeTimestampableKeysFromConfig(
|
|
243
|
+
this.application.toJSON(),
|
|
244
|
+
),
|
|
245
|
+
executable: Utils.specific.removeTimestampableKeysFromConfig(this.executable.toJSON()),
|
|
246
|
+
flavor: Utils.specific.removeTimestampableKeysFromConfig(this.flavor.toJSON()),
|
|
247
|
+
input: this.hashFromArrayInputContent,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
toJSON() {
|
|
252
|
+
return this.clean({
|
|
253
|
+
...super.toJSON(),
|
|
254
|
+
executable: this.executable.toJSON(),
|
|
255
|
+
flavor: this.flavor.toJSON(),
|
|
256
|
+
input: this._getInput(),
|
|
257
|
+
// keys below are not propagated to the parent class on initialization of a new unit unless explicitly given
|
|
258
|
+
name: this.name,
|
|
259
|
+
// TODO: figure out the problem with storing context below
|
|
260
|
+
// context: this.storedContext,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../enums";
|
|
2
|
+
import { AssertionUnit } from "./assertion";
|
|
3
|
+
import { AssignmentUnit } from "./assignment";
|
|
4
|
+
import { BaseUnit } from "./base";
|
|
5
|
+
import { ConditionUnit } from "./condition";
|
|
6
|
+
import { ExecutionUnit } from "./execution";
|
|
7
|
+
import { IOUnit } from "./io";
|
|
8
|
+
import { MapUnit } from "./map";
|
|
9
|
+
import { ProcessingUnit } from "./processing";
|
|
10
|
+
import { SubworkflowUnit } from "./subworkflow";
|
|
11
|
+
|
|
12
|
+
export class UnitFactory {
|
|
13
|
+
static AssertionUnit = AssertionUnit;
|
|
14
|
+
|
|
15
|
+
static AssignmentUnit = AssignmentUnit;
|
|
16
|
+
|
|
17
|
+
static BaseUnit = BaseUnit;
|
|
18
|
+
|
|
19
|
+
static ConditionUnit = ConditionUnit;
|
|
20
|
+
|
|
21
|
+
static ExecutionUnit = ExecutionUnit;
|
|
22
|
+
|
|
23
|
+
static IOUnit = IOUnit;
|
|
24
|
+
|
|
25
|
+
static MapUnit = MapUnit;
|
|
26
|
+
|
|
27
|
+
static ProcessingUnit = ProcessingUnit;
|
|
28
|
+
|
|
29
|
+
static SubworkflowUnit = SubworkflowUnit;
|
|
30
|
+
|
|
31
|
+
static create(config) {
|
|
32
|
+
switch (config.type) {
|
|
33
|
+
case UNIT_TYPES.execution:
|
|
34
|
+
return new this.ExecutionUnit(config);
|
|
35
|
+
case UNIT_TYPES.assignment:
|
|
36
|
+
return new this.AssignmentUnit(config);
|
|
37
|
+
case UNIT_TYPES.condition:
|
|
38
|
+
return new this.ConditionUnit(config);
|
|
39
|
+
case UNIT_TYPES.io:
|
|
40
|
+
return new this.IOUnit(config);
|
|
41
|
+
case UNIT_TYPES.processing:
|
|
42
|
+
return new this.ProcessingUnit(config);
|
|
43
|
+
case UNIT_TYPES.map:
|
|
44
|
+
return new this.MapUnit(config);
|
|
45
|
+
case UNIT_TYPES.subworkflow:
|
|
46
|
+
return new this.SubworkflowUnit(config);
|
|
47
|
+
case UNIT_TYPES.assertion:
|
|
48
|
+
return new this.AssertionUnit(config);
|
|
49
|
+
default:
|
|
50
|
+
return new this.BaseUnit(config);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AssertionUnit } from "./assertion";
|
|
2
|
+
import { AssignmentUnit } from "./assignment";
|
|
3
|
+
import { BaseUnit } from "./base";
|
|
4
|
+
import { ConditionUnit } from "./condition";
|
|
5
|
+
import { ExecutionUnit } from "./execution";
|
|
6
|
+
import { UnitFactory } from "./factory";
|
|
7
|
+
import { IOUnit } from "./io";
|
|
8
|
+
import { MapUnit } from "./map";
|
|
9
|
+
import { ProcessingUnit } from "./processing";
|
|
10
|
+
import { ReduceUnit } from "./reduce";
|
|
11
|
+
import { SubworkflowUnit } from "./subworkflow";
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
BaseUnit,
|
|
15
|
+
AssertionUnit,
|
|
16
|
+
AssignmentUnit,
|
|
17
|
+
ConditionUnit,
|
|
18
|
+
ExecutionUnit,
|
|
19
|
+
IOUnit,
|
|
20
|
+
MapUnit,
|
|
21
|
+
ProcessingUnit,
|
|
22
|
+
ReduceUnit,
|
|
23
|
+
SubworkflowUnit,
|
|
24
|
+
UnitFactory,
|
|
25
|
+
};
|
package/src/units/io.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import lodash from "lodash";
|
|
2
|
+
|
|
3
|
+
import { IO_ID_COLUMN, UNIT_TYPES } from "../enums";
|
|
4
|
+
import { BaseUnit } from "./base";
|
|
5
|
+
|
|
6
|
+
export class IOUnit extends BaseUnit {
|
|
7
|
+
/**
|
|
8
|
+
* IO Unit Builder for Object Storage sources.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} config - config object with other parameters:
|
|
11
|
+
* @param {String} config.name - the name of the unit this builder is creating
|
|
12
|
+
* @param {String} config.subtype - "input", "output", or "dataframe"
|
|
13
|
+
* @param {Object} config.input - input containing information on the file to download
|
|
14
|
+
* @param {Boolean} config.enableRender - Whether to use Jinja templating at runtime
|
|
15
|
+
*/
|
|
16
|
+
constructor(config) {
|
|
17
|
+
super({ ...IOUnit.getIOConfig(), ...config });
|
|
18
|
+
this.initialize(config);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static getIOConfig() {
|
|
22
|
+
return {
|
|
23
|
+
name: UNIT_TYPES.io,
|
|
24
|
+
type: UNIT_TYPES.io,
|
|
25
|
+
subtype: "input",
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
initialize(config) {
|
|
30
|
+
this._materials = [];
|
|
31
|
+
this._defaultTargets = ["band_gaps:direct", "band_gaps:indirect"];
|
|
32
|
+
this._features = lodash.get(config, "input.0.endpoint_options.data.features", []);
|
|
33
|
+
this._targets = lodash.get(
|
|
34
|
+
config,
|
|
35
|
+
"input.0.endpoint_options.data.targets",
|
|
36
|
+
this._defaultTargets,
|
|
37
|
+
);
|
|
38
|
+
this._ids = lodash.get(config, "input.0.endpoint_options.data.ids", []);
|
|
39
|
+
this._jobId = null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
get materials() {
|
|
43
|
+
return this._materials || [];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get defaultTargets() {
|
|
47
|
+
return this._defaultTargets;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get features() {
|
|
51
|
+
return this._features;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get featuresWithoutId() {
|
|
55
|
+
return this.features.filter((x) => x !== IO_ID_COLUMN);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get availableFeatures() {
|
|
59
|
+
const { materials } = this;
|
|
60
|
+
return lodash.uniq(
|
|
61
|
+
lodash
|
|
62
|
+
.flatten(materials.map((x) => lodash.keys(x.propertiesDict())))
|
|
63
|
+
.concat(this.features),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get availableFeaturesWithoutId() {
|
|
68
|
+
return this.availableFeatures.filter((feature) => feature !== IO_ID_COLUMN);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get targets() {
|
|
72
|
+
return this._targets;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @summary Checks whether selected features contain only IO_ID_COLUMN ('exabyteId').
|
|
77
|
+
* Used to identify that no features are selected yet (features set always contains ID_COLUMN)
|
|
78
|
+
*/
|
|
79
|
+
get onlyIdFeatureSelected() {
|
|
80
|
+
return lodash.isEmpty(lodash.without(this.features, IO_ID_COLUMN));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @summary Returns object with targets as key and arrays of appropriate values.
|
|
85
|
+
* E.g. {'band_gap:indirect': [0.1, 0.3], 'pressure': [100, undefined]}
|
|
86
|
+
*/
|
|
87
|
+
get valuesByTarget() {
|
|
88
|
+
const values = this.dataGridValues;
|
|
89
|
+
const result = {};
|
|
90
|
+
this.targets.forEach((target) => {
|
|
91
|
+
result[target] = values.map((v) => v[target]);
|
|
92
|
+
});
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get dataFrameConfig() {
|
|
97
|
+
return {
|
|
98
|
+
subtype: "dataFrame",
|
|
99
|
+
source: "api",
|
|
100
|
+
input: [
|
|
101
|
+
{
|
|
102
|
+
endpoint: "dataframe",
|
|
103
|
+
endpoint_options: {
|
|
104
|
+
method: "POST",
|
|
105
|
+
data: {
|
|
106
|
+
targets: this._targets,
|
|
107
|
+
features: this._features,
|
|
108
|
+
ids: this._ids,
|
|
109
|
+
jobId: this._jobId,
|
|
110
|
+
},
|
|
111
|
+
headers: {},
|
|
112
|
+
params: {},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
get isDataFrame() {
|
|
120
|
+
return this.prop("subtype") === "dataFrame";
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
setMaterials(materials) {
|
|
124
|
+
this._materials = materials;
|
|
125
|
+
this._ids = materials.map((m) => m.exabyteId);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
addFeature(feature) {
|
|
129
|
+
// only add if not already present
|
|
130
|
+
if (this._features.indexOf(feature) === -1) this._features.push(feature);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
removeFeature(feature) {
|
|
134
|
+
if (this.featuresWithoutId.length === 1) {
|
|
135
|
+
throw new Error("At least one feature is required");
|
|
136
|
+
}
|
|
137
|
+
this._features = this._features.filter((x) => feature !== x && x !== IO_ID_COLUMN);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
addTarget(target) {
|
|
141
|
+
if (this._targets.indexOf(target) === -1) this._targets.push(target);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
removeTarget(target) {
|
|
145
|
+
if (this._targets.length === 1) {
|
|
146
|
+
throw new Error("At least one target is required");
|
|
147
|
+
}
|
|
148
|
+
this._targets = this._targets.filter((x) => target !== x);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
hasFeature(feature) {
|
|
152
|
+
return this._features.indexOf(feature) > -1;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
hasTarget(target) {
|
|
156
|
+
return this._targets.indexOf(target) > -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
toJSON() {
|
|
160
|
+
const config = this.isDataFrame ? this.dataFrameConfig : {};
|
|
161
|
+
return this.clean({ ...super.toJSON(), ...config });
|
|
162
|
+
}
|
|
163
|
+
}
|
package/src/units/map.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../enums";
|
|
2
|
+
import { BaseUnit } from "./base";
|
|
3
|
+
|
|
4
|
+
export const defaultMapConfig = {
|
|
5
|
+
name: UNIT_TYPES.map,
|
|
6
|
+
type: UNIT_TYPES.map,
|
|
7
|
+
workflowId: "",
|
|
8
|
+
input: {
|
|
9
|
+
target: "MAP_DATA",
|
|
10
|
+
scope: "global",
|
|
11
|
+
name: "",
|
|
12
|
+
values: [],
|
|
13
|
+
useValues: false,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class MapUnit extends BaseUnit {
|
|
18
|
+
constructor(config) {
|
|
19
|
+
super({ ...defaultMapConfig, ...config });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get input() {
|
|
23
|
+
return this.prop("input");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get workflowId() {
|
|
27
|
+
return this.prop("workflowId");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setWorkflowId(id) {
|
|
31
|
+
this.setProp("workflowId", id);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../enums";
|
|
2
|
+
import { BaseUnit } from "./base";
|
|
3
|
+
|
|
4
|
+
export class ProcessingUnit extends BaseUnit {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
super({ ...ProcessingUnit.getProcessingConfig(), ...config });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static getProcessingConfig() {
|
|
10
|
+
return {
|
|
11
|
+
name: UNIT_TYPES.processing,
|
|
12
|
+
type: UNIT_TYPES.processing,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setOperation(op) {
|
|
17
|
+
this.setProp("operation", op);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setOperationType(type) {
|
|
21
|
+
this.setProp("operationType", type);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setInput(input) {
|
|
25
|
+
this.setProp("input", input);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get operation() {
|
|
29
|
+
return this.prop("operation");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get operationType() {
|
|
33
|
+
return this.prop("operationType");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get input() {
|
|
37
|
+
return this.prop("input");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../enums";
|
|
2
|
+
import { BaseUnit } from "./base";
|
|
3
|
+
|
|
4
|
+
export class ReduceUnit extends BaseUnit {
|
|
5
|
+
constructor(unitName, mapUnit, input) {
|
|
6
|
+
super({ ...ReduceUnit.getReduceConfig(unitName, mapUnit, input) });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static getReduceConfig(unitName, mapUnit, input) {
|
|
10
|
+
return {
|
|
11
|
+
type: UNIT_TYPES.reduce,
|
|
12
|
+
name: unitName,
|
|
13
|
+
mapFlowchartId: mapUnit,
|
|
14
|
+
input,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { UNIT_TYPES } from "../enums";
|
|
2
|
+
import { BaseUnit } from "./base";
|
|
3
|
+
|
|
4
|
+
export class SubworkflowUnit extends BaseUnit {
|
|
5
|
+
constructor(config) {
|
|
6
|
+
super({ ...SubworkflowUnit.getSubworkflowConfig(), ...config });
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static getSubworkflowConfig() {
|
|
10
|
+
return {
|
|
11
|
+
name: "New Subworkflow",
|
|
12
|
+
type: UNIT_TYPES.subworkflow,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import lodash from "lodash";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @summary set the head of an array of units
|
|
5
|
+
* @param units
|
|
6
|
+
* @returns {Unit[]}
|
|
7
|
+
*/
|
|
8
|
+
export function setUnitsHead(units) {
|
|
9
|
+
if (units.length > 0) {
|
|
10
|
+
units[0].head = true;
|
|
11
|
+
lodash.tail(units).map((x) => (x.head = false));
|
|
12
|
+
}
|
|
13
|
+
return units;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// TODO: fix setNextLinks on unit removal and convergence logic.
|
|
17
|
+
/**
|
|
18
|
+
* @summary Re-establishes the linked `next => flowchartId` logic in an array of units
|
|
19
|
+
* @params units {Unit[]}
|
|
20
|
+
* @returns units {Unit[]}
|
|
21
|
+
*/
|
|
22
|
+
export function setNextLinks(units) {
|
|
23
|
+
const flowchartIds = units.map((u) => u.flowchartId);
|
|
24
|
+
for (let i = 0; i < units.length - 1; i++) {
|
|
25
|
+
if (!units[i].next) {
|
|
26
|
+
// newly added units don't have next set yet => set it
|
|
27
|
+
units[i].next = units[i + 1].flowchartId;
|
|
28
|
+
if (i > 0) units[i - 1].next = units[i].flowchartId;
|
|
29
|
+
} else if (!flowchartIds.includes(units[i].next)) {
|
|
30
|
+
// newly removed units may create broken next links => fix it
|
|
31
|
+
units[i].next = units[i + 1].flowchartId;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return units;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @summary Apply configuration data to an object
|
|
39
|
+
* @param obj {*} object / class containing methods or attributes to be set
|
|
40
|
+
* @param config { functions: {}, attributes: {} } functions to call and attributes to set
|
|
41
|
+
* @param callBuild {boolean} if true; call build between applying functions and attributes
|
|
42
|
+
* @returns {*} updated object
|
|
43
|
+
*/
|
|
44
|
+
export function applyConfig({ obj, config = {}, callBuild = false }) {
|
|
45
|
+
const { functions = {}, attributes = {} } = config;
|
|
46
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
47
|
+
for (const [func, args] of Object.entries(functions)) {
|
|
48
|
+
// eslint-disable-next-line no-nested-ternary
|
|
49
|
+
if (obj[func]) {
|
|
50
|
+
if (args) obj[func](args);
|
|
51
|
+
else obj[func]();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const modified = callBuild ? obj.build() : obj;
|
|
55
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
56
|
+
for (const [key, values] of Object.entries(attributes)) {
|
|
57
|
+
modified[key] = values;
|
|
58
|
+
}
|
|
59
|
+
return modified;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @summary Safely extract unit object from subworkflow data
|
|
64
|
+
* @param subworkflowData {Object} subworkflow data
|
|
65
|
+
* @param index {number} index of subworkflow unit
|
|
66
|
+
* @param type {string} type of subworkflow unit
|
|
67
|
+
* @returns {Object|null} subworkflow unit object (not a unit class instance!)
|
|
68
|
+
*/
|
|
69
|
+
export function findUnit({ subworkflowData, index, type }) {
|
|
70
|
+
const unit = subworkflowData.units[index];
|
|
71
|
+
if (unit.type !== type) throw new Error("findUnit() error: unit type does not match!");
|
|
72
|
+
return unit;
|
|
73
|
+
}
|