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

@ra5mus/eb-datastore

v0.1.1

Published

Fetch-and-cache module designed to enable simple and flexible access to server-side APIs

Downloads

2

Readme

eb-datastore

The DataStore is both a way to handle network requests againts server-side APIs – and an offline cache on the user-side. It's AJAX, indexedDB and localStorage combined.

The cache will attempt to use indexedDB, but will degrade gracefully and fall back to using localStorage or no offline cache at all – as determined by the capabilities of the user's browser.

All fetch() methods will return a Promise object as a way of handling the asynchronous nature of both netowrking and indexedDB. All watch() methods till return an Observer object, on which the method notify() will be called, whenever the cached data expires and is refreshed automatically from the server-side state.

##Useage

The DS object wrap the to main classes, API and Endpoint. the API class is more of a convenience than anything else – a way of bundling multiple Endpoint objects together, but Endpoint objects can be used just fine on their own. There are even some convenience methods you can use directly on the DS module without instantiating anything, though they offer less flexibility.

Example using API class

  var weatherAPI = new DS.API({
    baseUrl: 'http://vejretapi.ekstrabladet.dk/v2/'
  });

  weatherAPI.defineEndpoint({
    name:'weather',
    url:'{baseUrl}weather/{geoid}[/{days}][/{intervals}]',
    validfor: 10 * DS.MINUTES
  });

  weatherAPI.weather.fetch({
    geoid: 2618425,
    days: '1-7',
    intervals: 24
  }).then(function(data){
    console.log(data);
  });

Okay, so a few things are going on here, which we'll go through.

First we create an API instance and add some properties to it – the most useful one will probably be baseUrl, the naming is entirely optional as long as you're consistent.

Next we define an Endpoint on our API instance by way of the defineEndpoint method. The properties name and url are mandatory while validfor (which determines for how long the object will be cached on the client) will default to ten minutes if not specified. The url property string is in a template format, which works much like other template strings – the curly braces contain variable names that will get replaced with values on initiating the network request. The variables come from the combined options of the call to fetch(options), the options given to the defineEndpoint method AND the options from the initial instantiation of the API object. Values in the fetch(options) will overwrite those in the Endpoint and API, values in the Endpoint will overwrite those in the API. So in our case, the combined options are:

{
  baseUrl:   'http://vejretapi.ekstrabladet.dk/v2/',             // <-- weatherAPI
  name:      'weather',                                          // <-- weather Endpoint
  url:       '{baseUrl}weather/{geoid}[/{days}][/{intervals}]',  // <-- weather Endpoint
  validfor:  10 * DS.MINUTES,                                    // <-- weather Endpoint
  geoid:     2618425,                                            // <-- call to fetch
  days:      '1-7',                                              // <-- call to fetch
  intervals: 24                                                  // <-- call to fetch
}

So upon interpolation, the finished url will become:

http://vejretapi.ekstrabladet.dk/v2/weather/2618425/1-7/24

Now, the square brackets around some of the interpolation expressions, like [/{days}] for instance, simply mean that if the days variable cannot be resolved, everything in the scope of the square brackets will be omitted from the result. In this case it just means that the initial / would also be omitted from the final url string. This is convenient in some apis.

The main advantage to using the API class and adding Endpoint objects to it via the defineEndpoint() method is that the resulting weatherAPI object becomes a single “thing” you can pass around inside your app – all the endpoints are accessible directly from this single object. You could have just as easily made a simple object like var a = {} and added your endpoints directly to that, so using the API class is just a convenience pattern.

Example using observe() method

The DataStore also has a mechanism for polling the server for its current state. It's done almost identically to a fetch(), but the returned object, instead of being a Promise with a then() method, it's an Observer with a notify() method. Basic Observer Pattern.


myObserver = weatherAPI.weather.observe({
  geoid: 2618425,
  days: 0,
  intervals: 24,
  validfor: 5 * DS.MINUTES
})
.notify(function(data){
  // This is called everytime the data updates from
  // the server. In this case every five minutes.
});