docs: def node(self, fields, subscribe_to=None, entry_point=False, ignore=None,
               **wrapper_options):
          '''\
          Decorate a function to make it a node.
  
          .. note::
             decorating as a node changes the function signature. Nodes should
             accept a single argument, which will be a
             :py:class:`emit.message.Message`. Nodes can be called directly by
             providing a dictionary argument or a set of keyword arguments. Other
             uses will raise a ``TypeError``.
  
          :param fields: fields that this function returns
          :type fields: ordered iterable of :py:class:`str`
          :param subscribe_to: functions in the graph to subscribe to. These
                               indicators can be regular expressions.
          :type subscribe_to: :py:class:`str` or iterable of :py:class:`str`
          :param ignore: functions in the graph to ignore (also uses regular
                         expressions.) Useful for ignoring specific functions in
                         a broad regex.
          :type ignore: :py:class:`str` or iterable of :py:class:`str`
          :param entry_point: Set to ``True`` to mark this as an entry point -
                              that is, this function will be called when the
                              router is called directly.
          :type entry_point: :py:class:`bool`
  
          In addition to all of the above, you can define a ``wrap_node``
          function on a subclass of Router, which will need to receive node and
          an options dictionary. Any extra options passed to node will be passed
          down to the options dictionary. See
          :py:class:`emit.router.CeleryRouter.wrap_node` as an example.
  
          :returns: decorated and wrapped function, or decorator if called directly
          '''
          def outer(func):
              'outer level function'
              # create a wrapper function
              self.logger.debug('wrapping %s', func)
              wrapped = self.wrap_as_node(func)
  
              if hasattr(self, 'wrap_node'):
                  self.logger.debug('wrapping node "%s" in custom wrapper', wrapped)
                  wrapped = self.wrap_node(wrapped, wrapper_options)
  
              # register the task in the graph
              name = self.get_name(func)
              self.register(
                  name, wrapped, fields, subscribe_to, entry_point, ignore
              )
  
              return wrapped
  
          return outer