es2015/object-store/RecordList.js
function fetchNextPage(storageFactory, keyRange, cursorDirection, unique,
    firstPrimaryKey, filter, pageSize) {
  let storage = storageFactory()

  let nextItems = []

  return new Promise((resolve, reject) => {
    let idb = idbProvider()
    let cursorFactory = storage.createCursorFactory(
      keyRange,
      cursorDirection,
      unique
    )

    cursorFactory((cursor) => {
      if (!unique) {
        let shouldSkip =
          (
            (cursorDirection === CursorDirection.NEXT) &&
            (idb.cmp(firstPrimaryKey, cursor.primaryKey) > 0)
          ) || (
            (cursorDirection === CursorDirection.PREVIOUS) &&
            (idb.cmp(firstPrimaryKey, cursor.primaryKey) < 0)
          )

        if (shouldSkip) {
          cursor.continue()
          return
        }
      }

      if (!filter || filter(cursor.record, cursor.primaryKey, cursor.key)) {
        if (nextItems.length === pageSize) {
          finalize(true, cursor.key, cursor.primaryKey)
          return
        } else {
          nextItems.push(cursor.record)
        }
      }

      cursor.continue()
    }).then(() => finalize(false, null, null)).catch(error => reject(error))

    function finalize(hasNextPage, nextKey, nextPrimaryKey) {
      resolve(new RecordList(nextItems, storageFactory, nextKey,
          nextPrimaryKey, cursorDirection, unique, filter, pageSize,
          hasNextPage))
    }
  })
}
function fetchNextPage(storageFactory, keyRange, cursorDirection, unique,
    firstPrimaryKey, filter, pageSize) {
  let storage = storageFactory()

  let nextItems = []

  return new Promise((resolve, reject) => {
    let idb = idbProvider()
    let cursorFactory = storage.createCursorFactory(
      keyRange,
      cursorDirection,
      unique
    )

    cursorFactory((cursor) => {
      if (!unique) {
        let shouldSkip =
          (
            (cursorDirection === CursorDirection.NEXT) &&
            (idb.cmp(firstPrimaryKey, cursor.primaryKey) > 0)
          ) || (
            (cursorDirection === CursorDirection.PREVIOUS) &&
            (idb.cmp(firstPrimaryKey, cursor.primaryKey) < 0)
          )

        if (shouldSkip) {
          cursor.continue()
          return
        }
      }

      if (!filter || filter(cursor.record, cursor.primaryKey, cursor.key)) {
        if (nextItems.length === pageSize) {
          finalize(true, cursor.key, cursor.primaryKey)
          return
        } else {
          nextItems.push(cursor.record)
        }
      }

      cursor.continue()
    }).then(() => finalize(false, null, null)).catch(error => reject(error))

    function finalize(hasNextPage, nextKey, nextPrimaryKey) {
      resolve(new RecordList(nextItems, storageFactory, nextKey,
          nextPrimaryKey, cursorDirection, unique, filter, pageSize,
          hasNextPage))
    }
  })
}
Fetches the next page of records in a new ready-only transaction and
resolves into a record list containing the fetched records.

@param {function(): AbstractReadOnlyStorage} storageFactory A function that
creates a new read-only transaction and returns this storage accessor
each time it is invoked.
@param {IDBKeyRange} keyRange The key range to use when opening the cursor
in order to skip most of the records traversed previously.
@param {CursorDirection} cursorDirection The direction in which the records
of the storage are traversed.
@param {boolean} unique Set to {@code true} if the key used by the storage
to organize records has a unique value for each record.
@param {(number|string|Date|Array)} firstPrimaryKey The primary key of the
first record to include to the result.
@param {(undefined|function(*, (number|string|Date|Array), (number|string|Date|Array)): boolean)} filter
The filter function restricting the records that will be listed.
If a function is provided, the first argument will be set to the
record, the second argument will be set to the primary key of the
record, and the third argument will be set to the key referencing the
record (the primary key if traversing an object store).
@param {number} pageSize The maximum number of records per page. Must be a
positive integer.
@return {Promise<RecordList<*>>} A promise that resolves to the next page of
records.