npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pouchdb-jsonviews

v1.2.1

Published

A plugin that adds a JSON-based map/reduce view interface to PouchDB and CouchDB.

Downloads

10

Readme

PouchDB-JsonViews

CI Coverage Status Stability NPM Version JS Standard Style

A plugin that adds a JSON-based map/reduce view interface to PouchDB and CouchDB.

Here is an example:

const PouchDB = require('pouchdb')
PouchDB.plugin(require('pouchdb-jsonviews'))

const db = new PouchDB('your_cool_project')

// add a jsonview with this convenience method.
// it just creates a design doc: `_design/my_doc_name`.
// and in it, creates a view: `my_view_name`.
// the map function is templated using the jsonview.
await db.addJsonView('my_doc_name', 'my_view_name', {
  map: {
    key: [
      // [date, username, time] for a daily digest timeline
      { access: 'created_at', transform: 'date' },
      'username',
      { access: 'created_at', transform: 'time' }
    ],
    value: 'status'
  },
  reduce: '_count'
})

// then you can just query it like any other view!
const { rows } = await db.query('my_doc_name/my_view_name', {
  group: true,
  group_level: 2
})
console.log(rows)
> {
>   "rows": [
>     {
>       "key": ['YYYY-MM-DD', 'garbados'],
>       "value": 12
>     },
>     ...
>   ]
> }

Why?

Although Mango is a powerful query language in its own right -- and PouchDB-JsonViews is not intended as a competitor or replacement! -- it does not allow you to use a reduce function. This forces certain classes of queries to occur in-memory, on-demand, page by page, which is simply not tenable for certain scales of data.

However, the alternative of writing JavaScript views lends itself to the worse of our tendencies as programmers: to inefficient mutations of data that are impossible to examine or debug. These can create showstopping problems as datasets scale, as the size of indices may explode out of control due to errors and oversights. It is unwise to permit ourselves so much room for failure, grateful for it though we may be from time to time.

Usually, a view just emits a certain number of keys and a value, and maybe specifies a reduce function. PouchDB-JsonViews uses a simple access syntax to specify document attributes for keys and values, and exposes a small number of transforms which convert a value in some way (such as generating a time or date string from a timestamp, with date and time). In this way, much as Mango simplifies queries with selectors, this plugin does the same with what it calls JsonViews.

Install

Install this plugin in your JavaScript project with NPM:

$ npm i pouchdb-jsonviews

Then attach it to PouchDB like so:

const PouchDB = require('pouchdb')
PouchDB.plugin(require('pouchdb-jsonviews'))

Usage, API

This plugin adds some new methods to PouchDB instances:

  • .interpretJsonView(jsonview)
  • .addView(ddocName, viewName, view)
  • .putView(ddocName, viewName, view)
  • .addJsonView(ddocName, viewName, jsonview)
  • .putJsonView(ddocName, viewName, jsonview)
  • .removeView(ddocName, viewName).

These common parameters are defined as such:

  • ddocName: The part of a design document's _id that follows _design/. For example, the ddocName of _design/hello-world is hello-world.
  • viewName: The name of a view.
  • view: A normal JavaScript view.
  • jsonview: An object describing a JsonView, which this plugin can compile to a JavaScript view for the purpose of querying. See Usage, JsonViews for more information.

db.interpretJsonView(jsonview)

A convenience method that returns the JavaScript view compiled from a given jsonview. Used internally, but might be of interest to the curious user.

async db.addView(ddocName, viewName, view)

A convenience method that adds a view to a design document, creating it if necessary. If a view already exists by this name, the method will throw an error.

Returns as though you had run db.put().

async db.putView(ddocName, viewName, view)

A convenience method that adds a view to a design document, creating that document if necessary. If a view already exists by this name, the view will be overwritten.

Returns as though you had run db.put().

async db.addJsonView(ddocName, viewName, jsonview)

Compiles a JsonView to a JavaScript view and adds it to a design document, using db.addView under the hood.

async db.putJsonView(ddocName, viewName, jsonview)

Compiles a JsonView to a JavaScript view and adds it to a design document, using db.putView under the hood.

async db.removeView(ddocName, viewName)

Removes a view from a design document.

Returns as though you had run db.put().

Usage, JsonViews

A JsonView is a JavaScript object with two properties:

  • map: A description of the map function to use.
  • map.key: An access parameter or an array of access parameters, which are interpreted and emitted as a key or keys.
  • map.value: An access parameter, which is interpreted and emitted as a value.

An access parameter is a string or object that describes how to access and interpret a property on a document. In its simplest form, it is the string value of that property's key. The access parameter to access doc.foo would be 'foo'.

You can access nested properties using dots as separators. For example, you can access doc.foo.bar with 'foo.bar'.

An access parameter may also be an object. In its object form, it may have these properties:

  • access: A string access parameter, such as 'foo' or 'foo.bar'.
  • transform: The string name of a transform helper, such as date or time.
  • splay: When used with an array, emits one row per entry in the array. Otherwise, the whole array is emitted in just one row. For example, for a news website, you might emit one row per tag per article, rather than emitting the whole list of tags in one row per article.
  • flatten: When used with an array, flatten: true flattens the array into each row's keys rather than emitting the whole array as a single key.
  • emit: An access parameter with emit: true will only emit a row if the document contains the accessed property. For example, { access: 'some_field', emit: true } will only emit rows if the some_field property exists and is truthy. Properties accessed this way are not emitted as part of the key. emit does nothing when used to calculate a value.
  • equals: Used with emit: true, this property allows you to specify a value to which the accessed property should be compared. For example, { access: 'type', emit: true, equals: 'entry' } will only emit rows if the property type equals 'entry'.
  • invert: Used with emit: true, this property inverts the accessed property so that rows are emitted only if it is falsy. Can be used with equals to indicate that something should not be equal to a given value.

These are the currently available transforms:

  • date: Converts a Unix timestamp or other Date initialization parameter(s) into an array of the form [year, month, day].
  • year: Converts a Unix timestamp or other Date initialization parameter(s) into a N-length string, representing the timestamp's year.
  • month: Converts a Unix timestamp or other Date initialization parameter(s) into a 2-length string, representing the timestamp's month in the year.
  • year-month: Converts a Unix timestamp or other Date initialization parameter(s) into an array of the form [year, month].
  • day: Converts a Unix timestamp or other Date initialization parameter(s) into a 2-length string, representing the timestamp's day in the month.
  • time: Converts a Unix timestamp or other Date initialization parameter(s) into an array of the form [hour, minute, second, millisecond].
  • hour: Converts a Unix timestamp or other Date initialization parameter(s) into a 2-length string, representing the timestamp's hour in 24-hour time.
  • minute: Converts a Unix timestamp or other Date initialization parameter(s) into a 2-length string, representing the timestamp's minute in a 60-minute hour.
  • datetime: Converts a Unix timestamp or other Date initialization parameter(s) into an array of the form [year, month, day, hour, minute, second, millisecond].
  • words: Split a text field on whitespace and quotations, into an array of strings. Useful with splay.

Note that because the datetime utilities use an ISO representation of dates internally, all times use UTC+0 as their timezone and all years are Gregorian.

Development

If you encounter a bug or would like to request a feature, please file an issue!

If you are submitting a patch, please be a good neighbor and include tests!

To hack on this project locally, first get its source and install its dependencies:

$ git clone [email protected]:garbados/pouchdb-jsonviews.git
$ cd pouchdb-jsonviews
$ npm i

Then you can run the test suite:

$ npm test

License

Apache License 2.0