docs: function factoryGraph(ParentClass) {
    
    if (!ParentClass) {
      var ParentClass = class {}
    }
    
    /**
     * Class to inherit. Class with methods for control links in graph.
     * Must be completed for adaptation to a particular database.
     * 
     * @class
     * @description `import { Graph } from 'ancient-graph';`
     */
    class Graph extends ParentClass {
      
      /**
       * Construct new graph and checks for required adaptation methods.
       * @throws {Error} if the adapter methods is not complete
       * 
       * @param {} collection - A pointer to the collection dannymineobhodimye daapteru to work with the graph. This may be a connection to the SQL database and table name, for example, or a collection of Mongo. 
       * @param {Object.<string, string>} fields - Comparison of the data in the collection of data in the graph. It is necessary for the adapter.
       * @param {Object} [config] - Additional config.
       * @param {Object} [config.aliases]
       * @param {String} [config.aliases.$]
       */
      constructor(collection, fields, config) {
        super(...arguments);
        this.collection = collection;
        this.fields = fields;
        if (typeof(config) != 'object') var config = {};
        this.config = config;
        if (typeof(config.aliases) != 'object') config.aliases = {};
        for (var f in fields) {
          if (!config.aliases[f]) config.aliases[f] = f;
        }
        this.config._aliases = {};
        for (var a in this.config.aliases) {
          this.config._aliases[this.config.aliases[a]] = a;
        }
        if (this.insert == Graph.prototype.insert) {
          throw new Error('Method `insert` is not adapted.');
        }
        if (this.update == Graph.prototype.update) {
          throw new Error('Method `update` is not adapted.');
        }
        if (this.remove == Graph.prototype.remove) {
          throw new Error('Method `remove` is not adapted.');
        }
        if (this.query == Graph.prototype.query) {
          throw new Error('Method `query` is not adapted.');
        }
        if (this.options == Graph.prototype.options) {
          throw new Error('Method `options` is not adapted.');
        }
        if (this.fetch == Graph.prototype.fetch) {
          throw new Error('Method `fetch` is not adapted.');
        }
        if (this.get == Graph.prototype.get) {
          throw new Error('Method `get` is not adapted.');
        }
        if (this.each == Graph.prototype.each) {
          throw new Error('Method `each` is not adapted.');
        }
        if (this.map == Graph.prototype.map) {
          throw new Error('Method `map` is not adapted.');
        }
        if (this.count == Graph.prototype.count) {
          throw new Error('Method `count` is not adapted.');
        }
        if (this.on == Graph.prototype.on) {
          throw new Error('Method `on` is not adapted.');
        }
      }
      
      /**
       * Should insert new link into graph.
       * If the database allows, it is recommended to return a synchronous result. This can be useful in your application. But for writing generic code, it is recommended to only use the callback result.
       * 
       * @param {Link} link
       * @param {Graph~insertCallback} [callback]
       * @param {Object} [context]
       * @return {string} [id]
       */
      insert(link, callback, context) {}
      
      /**
       * Optional callback. If present, called with an error object as the first argument and, if no error, the unique id of inserted link as the second.
       *
       * @callback Graph~insertCallback
       * @param {Error} [error]
       * @param {string} [id]
       */
      
      /**
       * Should update to new state of modifier object link by unique id or by link query object.
       * If the database allows, it is recommended to return a synchronous result. This can be useful in your application. But for writing generic code, it is recommended to only use the callback result.
       * 
       * @param {string|LinkSelector} selector
       * @param {LinkModifier} modifier
       * @param {Graph~updateCallback} [callback]
       * @param {Object} [context]
       * @return {number} [count]
       */
      update(selector, modifier, callback, context) {}
      
      /**
       * Optional callback. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
       *
       * @callback Graph~updateCallback
       * @param {Error} [error]
       * @param {number} [count]
       */
      
      /**
       * Should remove link by unique id or by link query object.
       * 
       * @param {string|LinkSelector} selector
       * @param {Graph~removeCallback} [callback]
       * @param {Object} [context]
       */
      remove(selector, callback, context) {}
      
      /**
       * Optional callback. If present, called with an error object as the first argument.
       *
       * @callback Graph~removeCallback
       * @param {Error} [error]
       * @param {number} [count]
       */
      
      /**
       * Should generate adapter for database query for links search by unique id or by link query object.
       * 
       * @param {string|LinkSelector} selector
       * @return {*} query
       */
      query(selector) {}
      
      /**
       * Should generate adapter for database options. 
       * 
       * @param {Object} [options]
       * @return {*} options - a options suitable for the database
       */
      options(options) {}
      
      /**
       * Find and all matching links as an Array.
       * 
       * @param {string|LinkSelector} selector
       * @param {SelectOptions} [options]
       * @param {Graph~fetchCallback} [callback]
       * @return {Link[]} links - result links objects in array
       */
      fetch(selector, options, callback) {}
      
      /**
       * Optional callback. If present, called with an error object as the first argument and, if no error, the result links objects in array.
       *
       * @callback Graph~fetchCallback
       * @param {Error} [error]
       * @param {Link[]} [links]
       */
      
      /**
       * Get one first matching link.
       * 
       * @param {string|LinkSelector} selector
       * @param {SelectOptions} [options]
       * @param {Graph~getCallback} [callback]
       * @return {Link} link - result link object
       */
      get(selector, options, callback) {}
      
      /**
       * Optional callback. If present, called with an error object as the first argument and, if no error, the result link object.
       *
       * @callback Graph~getCallback
       * @param {Error} [error]
       * @param {Link} [link]
       */
      
      /**
       * Should call callback once for each matching document, sequentially and synchronously.
       * 
       * @param {string|LinkSelector} selector
       * @param {SelectOptions} [options]
       * @param {Graph~eachCallback} [callback]
       */
      each(selector, options, callback) {}
      
      /**
       * @callback Graph~eachCallback
       * @param {Link} [link]
       */
      
      /**
       * Should map callback over all matching documents. Returns an Array.
       * 
       * @param {string|LinkSelector} selector
       * @param {SelectOptions} [options]
       * @param {Graph~mapCallback} [callback]
       * @return {Array} results
       */
      map(selector, options, callback) {}
      
      /**
       * @callback Graph~mapCallback
       * @param {Link} [link]
       * @return {*} result
       */
      
      /**
       * Should count all matching documents.
       * 
       * @param {string|LinkSelector} selector
       * @param {SelectOptions} [options]
       * @param {Graph~countCallback} [callback]
       * @return {number} [count]
       */
      count(selector, options, callback) {}
      
      /**
       * @callback Graph~countCallback
       * @param {Error} [error]
       * @param {number} [count]
       */
      
      /**
       * Should subscribe to the events: link, unlink, insert, update, remove.
       * 
       * @param {string} event - One event name
       * @param {Graph~onCallback} callback
       * @returns {Function} Stops event subscription.
       * @example
       * var counter = 0;
       * var stop = graph.on('update', (oldData, newData) => {
       *   if (oldData.id == '1') console.log(oldData.id, 'is changed');
       *   counter++;
       *   if (counter == 3) stop();
       * });
       */
      on(event, callback) {}
      
      /**
       * @callback Graph~onCallback
       * @param {Link} [oldLink] - can be undefined on link and insert events
       * @param {Link} [newLink] - can be undefined on unlink and remove events
       * @param {Object} [context] - additional app information, such as context.userId
       */
    };
    
    return Graph;
  }