Skip to content

Commit

Permalink
refresh for new major version (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
garbados committed Nov 19, 2023
1 parent 19cb57f commit 2232b7f
Show file tree
Hide file tree
Showing 6 changed files with 4,170 additions and 2,607 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
node: [12,14,16]
couchdb: ["2.3", "3.1"]
node: [16, 18, 20]
couchdb: ["2.3", "3.3"]
steps:
- uses: iamssen/couchdb-github-action@master
with:
Expand Down
73 changes: 9 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![NPM Version](https://img.shields.io/npm/v/pouchdb-paginators.svg?style=flat-square)](https://www.npmjs.com/package/pouchdb-paginators)
[![JS Standard Style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)

A plugin that causes the `db.allDocs()`, `db.query()`, and `db.find()` methods to return paginators instead of promises, allowing you to page through large result sets confidently.
A plugin that adds to PouchDB methods like `.paginateAllDocs()` which return paginators over results. Paginators can be iterated over without loading all results into memory, and they effectively coordinate per-page query settings with usual options like `reduce: false` or `include_docs: true`.

Pagination in PouchDB and CouchDB is rather unintuitive, especially for map/reduce views. This plugin intends to make it easy and reliable. For example:

Expand All @@ -15,9 +15,8 @@ const PouchDB = require('pouchdb')
PouchDB.plugin(require('pouchdb-paginators'))

const db = new PouchDB('...')
db.paginate() // setup paginators

const pager = db.query('queries/example')
const pager = db.paginateQuery('queries/example')
// now you can page through results
for await (const results of pager.pages()) {
// do what thou wilt
Expand All @@ -28,77 +27,23 @@ for await (const results of pager.reverses()) {
}
```

You can disable pagination if you prefer:

```js
const results = await db.query('queries/example', { paginate: false })
console.log(results)
// {
// total_rows: N,
// rows: [
// ...
// ]
// }
```

You can even turn off pagination globally.

```js
PouchDB.unpaginate()
const results = await db.query('queries/example')
console.log(results)
// {
// total_rows: N,
// rows: [
// ...
// ]
// }
```

## Compatibility Note

Pagination using `db.find()` only works with a PouchDB instance representing a connection to a CouchDB installation. Otherwise, because [PouchDB does not currently support bookmarks](https://github.com/pouchdb/pouchdb/issues/8497), your paginators will always return the same page. If you are using PouchDB with any non-CouchDB storage backend, like leveldb or indexeddb, you should initialize the plugin like so to only paginate the primary index (`db.allDocs()`) and view queries:

```js
db.paginateAllDocs()
db.paginateQuery()
```

This will only cause calls to `db.allDocs()` and `db.query()` to return paginators, while `db.find()` will return results normally.
Pagination using `db.find()` only works with a PouchDB instance representing a connection to a CouchDB installation. Otherwise, because [PouchDB does not currently support bookmarks](https://github.com/pouchdb/pouchdb/issues/8497), your paginators will always return the same page. If you are using PouchDB with any non-CouchDB storage backend, like leveldb or indexeddb, `.paginateFind()` will not be able to page forward.

## Usage

### PouchDB.unpaginate()

Removes the paginating methods from PouchDB instances and restores them to their non-paginating originals.

### db.paginate()

Sets up pagination. Until this is run, query and find methods will not return paginators.

### db.paginateAllDocs()

Sets up pagination on `db.allDocs()` calls.

### db.paginateQuery()

Sets up pagination on `db.query()` calls.

### db.paginateFind()

Sets up pagination on `db.find()` calls if the `pouchdb-find` plugin has already been applied.

### db.query(name, opts)

Unless `opt.paginate` is equal to `false`, this method will now return a paginator. If it is true, this method will return results normally.
### New Methods

### db.find(opts)
The plugin adds three methods which mirror existing query methods, accepting all the same options, but which return paginators:

If you have set up Mango queries with [pouchdb-find](https://pouchdb.com/guides/mango-queries.html), then adding this plugin will cause the `db.find()` method to return a paginator. You may disable pagination and return normal results by setting `opts.paginate` to false.
- `db.paginateAllDocs()` mirrors `db.allDocs()`.
- `db.paginateQuery()` mirrors `db.query()`.
- `db.paginateFind()` mirrors `db.find()`.

### Paginator

Paginators for both `db.query()` and `db.find()` have the same API. The pages that paginators return have a default limit of 20 results.
All paginators have the same API. The pages that paginators return have a default limit of 20 results.

#### paginator.hasPrevPage

Expand Down
72 changes: 15 additions & 57 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,65 +131,23 @@ class MangoPaginator extends BasePaginator {
}
}

module.exports = function (PouchDB) {
let allDocs
const query = PouchDB.prototype.query
const find = PouchDB.prototype.find

PouchDB.prototype.paginateAllDocs = function () {
allDocs = this.allDocs
this.allDocs = function paginatedAllDocs (opts = {}) {
if (opts.paginate === false) {
delete opts.paginate
return allDocs.call(this, opts)
}
const allDocsFun = async (subOpts) => {
return allDocs.call(this, { ...opts, ...subOpts })
}
return new ViewPaginator(allDocsFun, opts)
}
}

PouchDB.prototype.paginateQuery = function () {
this.query = function paginatedQuery (name, opts = {}) {
if (opts.paginate === false) {
delete opts.paginate
return query.apply(this, arguments)
}
const queryFun = async (subOpts) => {
return query.call(this, name, { ...opts, ...subOpts })
}
return new ViewPaginator(queryFun, opts)
module.exports = {
paginateAllDocs: function (opts = {}) {
const allDocsFun = async (subOpts) => {
return this.allDocs({ ...opts, ...subOpts })
}
}

PouchDB.prototype.paginateFind = function () {
if (this.find) {
this.find = function paginatedFind (opts) {
if (opts.paginate === false) {
delete opts.paginate
return find.apply(this, arguments)
}
const findFun = async (subOpts) => {
return find.call(this, { ...opts, ...subOpts })
}
return new MangoPaginator(findFun)
}
return new ViewPaginator(allDocsFun, opts)
},
paginateQuery: function (name, opts = {}) {
const queryFun = async (subOpts) => {
return this.query(name, { ...opts, ...subOpts })
}
}

PouchDB.prototype.paginate = function () {
this.paginateAllDocs()
this.paginateQuery()
this.paginateFind()
}

PouchDB.unpaginate = function () {
if (allDocs) {
this.prototype.allDocs = allDocs
allDocs = undefined
return new ViewPaginator(queryFun, opts)
},
paginateFind: function (opts = {}) {
const findFun = async (subOpts) => {
return this.find({ ...opts, ...subOpts })
}
this.prototype.query = query
this.prototype.find = find
return new MangoPaginator(findFun)
}
}

0 comments on commit 2232b7f

Please sign in to comment.