function parseAction(actionString) {
  // keep full action string
  // used later on when executing actions
  let fullActionString = actionString

  // get command
  let command = actionString.match(/#(\w+)/g)[0]

  // remove command from string
  actionString = actionString.substring(command.length + 1, actionString.length - 1)

  // remove # from command string
  command = command.substring(1)

  // split action string into components
  let actionComponents = actionString.split(/(?![^(]*\)),/g)

  // get condition string
  let conditionString = actionComponents[0]

  // extract placeholders in condition
  let conditionPlaceholders = Placeholders.extractPlaceholders(conditionString)

  // get params
  actionComponents.shift()
  let params = actionComponents.map(paramString => {
    // get placeholders in param
    let paramPlaceholders = Placeholders.extractPlaceholders(paramString)

    // return complete param object with placeholders
    return {
      string: paramString.trim(),
      placeholders: paramPlaceholders
    }
  })

  // prepare action
  let action = {
    string: fullActionString,
    command: command,
    condition: {
      string: conditionString,
      placeholders: conditionPlaceholders
    },
    params: params
  }

  return action
}
Parses the action string, #run({firstName}.length > 3, fnToRun)

@param {String} actionString
@returns {Object}

returned action: {
  string: {String},
  command: {String},
  condition: {
    string: {String},
    placeholders: [{
        string: {String},
        keypath: {String},
        filters: {Array},
        substitute: {String},
        placeholders: {Array}
      }]
  },
  params: [{
    string: {String},
    placeholders: {Array as for condition},
  }]
}