es2015/object-store/query-engine.js
function runQuery(cursorFactory, filter, comparator, offset, limit, callback) {
  let records = []
  let recordIndex = -1

  return cursorFactory((cursor) => {
    if (!filter && offset && ((recordIndex + 1) < offset)) {
      recordIndex = offset - 1
      cursor.advance(offset)
      return
    }
    
    let primaryKey = cursor.primaryKey
    if (filter && !filter(cursor.record, primaryKey)) {
      cursor.continue()
      return
    }
    
    if (comparator) {
      insertSorted(records, cursor.record, primaryKey, comparator)
      if (offset || limit) {
        if (records.length > (offset + limit)) {
          records.pop()
        }
      }
      
      cursor.continue()
      return
    }
    
    recordIndex++
    if (recordIndex < offset) {
      cursor.continue()
      return
    }
    
    callback(cursor.record, primaryKey)
    
    if (!limit || ((recordIndex + 1) < (offset + limit))) {
      cursor.continue()
    }
  }).then(() => {
    if (!comparator) {
      return
    }
    
    records = records.slice(offset)
    for (let { record, primaryKey } of records) {
      callback(record, primaryKey)
    }
  })
}
function runQuery(cursorFactory, filter, comparator, offset, limit, callback) {
  let records = []
  let recordIndex = -1

  return cursorFactory((cursor) => {
    if (!filter && offset && ((recordIndex + 1) < offset)) {
      recordIndex = offset - 1
      cursor.advance(offset)
      return
    }
    
    let primaryKey = cursor.primaryKey
    if (filter && !filter(cursor.record, primaryKey)) {
      cursor.continue()
      return
    }
    
    if (comparator) {
      insertSorted(records, cursor.record, primaryKey, comparator)
      if (offset || limit) {
        if (records.length > (offset + limit)) {
          records.pop()
        }
      }
      
      cursor.continue()
      return
    }
    
    recordIndex++
    if (recordIndex < offset) {
      cursor.continue()
      return
    }
    
    callback(cursor.record, primaryKey)
    
    if (!limit || ((recordIndex + 1) < (offset + limit))) {
      cursor.continue()
    }
  }).then(() => {
    if (!comparator) {
      return
    }
    
    records = records.slice(offset)
    for (let { record, primaryKey } of records) {
      callback(record, primaryKey)
    }
  })
}
Executes the specified query using the provided cursor factory.

Note that the callback will be executed on the records only after all
records have been populated if the comparator if a function so the records
are passed to the callback in the right order.

@param {function(function(ReadyOnlyCursor)): number} cursorFactory The
cursor factory to use to create a cursor for executing the query.
@param {?function(*, (number|string|Date|Array)): boolean} filter Optional
custom filter callback.
@param {?function(*, *): number} comparator Optional record comparator to
use to sort the records in the result.
@param {number} offset The index of the first record to include in the
result. The records are numbered from {@code 0}, the offset must be
a non-negative integer.
@param {?number} limit The maximum number of records to return as a result.
The limit must be a positive integer, or {@code null} if no limit
should be imposed.
@param {function(*, (number|string|Date|Array))} callback Callback to
execute on every iterated record that matches the query.
@return {PromiseSync<undefined>} A promise that resolves when the query has
been executed.