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

derby-view

v0.3.10

Published

Derby plugin for creating map/reduce -style views and queries of those views

Downloads

6

Readme

derby-view

Derby plugin for creating map/reduce -style views and queries of those views

Why

Because model.filter is rather limited at the moment, and the only way to create any sort of more complex structure without keeping track of all events/reactivity oneself. A better way which makes it more aligned with an MVC structure also facilitates better structure (not a lot of business logic easily tend to end up inside the components, or possible, routes).

How to use

Add derby-view as a derby plugin in the top of your application (before the app is created);

var derby = require('derby');

derby.use(require('derby-view'));

...

Then, you can create views, and subsequently ref or create queries on top of those views. See API docs below for examples.

API docs

view = model.view(collection, mapFn)

Views are ordered, possibly filtered lists based on a map function, looped over a collection. A map function is called for each item (reactively kept up to date) and possibly emits one or more keys (or none), each paired with one path (defaults to the current item’s path - NOTE! Currently not implemented!) which points to an item (or it could probably be whatever). The order is based upon the lexographical order. Internally, a view consists of three data structures. One array which contains all emitted keys (ordered), and one collection/hashmap which maps the keys to their respective emitted path. Additionally, one keeps track of which docs emitted which key/path-pairs, for internal use for cleanups.

Note: Currently, mapFn needs to be a named fn in Derby, i.e. create using model.fn, like for example:

model.fn('myViewFn', function (emit, doc) {
  emit(key, path);
});

Note 2: Currently, all paths are automatically turned into refs, for simpler access in views.

Example:

var view = model.view('myCollection', 'myViewFn');

A view does not necessarily in of itself do anything - it just enables certain methods.

view.ref('myPath')

A view can be ref'd in two ways. Either it can be used as a simple connection/hashmap, simply by ref'ing it. On the path, each item can be accessed by using the emitted key. E.g.

{{myPath[key].somePropertyOnDocOfPath}}

view.query(path, [start], [end], [options])

view.refList(path, ...) -- really just another name for query

[options.include_end] [options.descending]

It can also be used as a refList (i.e. a better, more performant and general version of filter). This type can also be delimited based on start and end inputs (delimiting the keys to be within the start and end), and a view can be delimited an infinite amount of times with different input (i.e. using it as a query) to different paths.

Note: Options are not currently implemented Note 2: Currently, a path is not needed to be specified, but you have to ref it using myQuery.ref(path) instead.

view.queryPerLevel(path)

In some scenarios, one would like to combine a multi level organization of items with a list for each category (i.e. first level) of items. It's tedious to manually maintain all these queries, and ensure new one categories are created and old ones removed. Because of that, there's a convenience fn which automatically creates a query for each unique first level, and maintains this for you. Basically, you'll use it like this:

var view = ...
view.queryPerLevel('_page.allMyQueries');

var allItemsForASepcificCategory = model.root.get('_page.allmyQueries.<category key>');

// allItemsForASepcificCategory = [item1, item2]

BELOW METHODS ARE NOT YET IMPLEMENTED!

view.subscribe(callback)

view.fetch(callback)

Moreover, a view can be used to ensure joining data is fetched or subscribed to. This is assuming the paths emitted from the view are on the form of .. As the view is updated it keeps track of all the ids from each collection and ensures all of those documents are fetched or subscribed (depending on which method called).

Implementation details of this one needs to be considered carefully for performance reason. In general, it might be quite tough on the performance. So far, there is internal tracking of all the ids fetched (and probably also subscribed to) so obviously the implementation should only consider the new ones (and possibly cleaning up old, no longer in used ids automatically). Further, there should probably be done kind of batching it something to reduce the amount of times the db is called (e.g. so that a new call is made for each emit, or something else).

TODO

See index.js for a TODO list and read through the API docs to ensure everything is covered in a good way.

Kudos

To PouchDB/CouchDB for inspiration.