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 🙏

© 2025 – Pkg Stats / Ryan Hefner

fronto-connect

v1.2.0

Published

Toolsets for retrieving data from a remote source

Readme

Fronto Connect

Toolset for helping connecting to remote data sources like a restful api.

Videos

Intro Part 1 (11:06) | Intro Part 2 (8:03) | Writing Custom Scopes (6:45)

Basic Usage

Create a store class and that extends from connect.

import { Connect } from 'fronto-connect'

class Posts extends Connect { 
  namespace = 'api/v1';
  resource = 'posts';
}

Once you create your class you will need to mix it with some scopes as well.

Scopes

Scopes are basic instance level functions that will tell connect how to process responses from your server. Fronto Connect comes with some basic scopes you can use, however feel free to create your own scopes. Here is an example of a scope.

const readable = {
  find() { this.findBy(); },
  findBy(parameters) {
    this.setIsLoading(true);
    this.clearSelected();
    this.call({ parameters, type: 'get' }, {
      200: this.setSelected
    });
  },
  findAll(parameters) {
    this.setIsLoading(true);
    this.clearCollection();
    this.call({ parameters, type: 'get' }, {
      200: this.setCollection 
    });
  },
}

export default { readable };

To use this set of scope on our Post class we can use the mixer tool, like so.

import { Connect, mix } from 'fronto-connect'
import scopes from './scopes'

class Posts extends Connect {
// ... 
}

mix(Posts, scopes.readable)

export default Posts

Our class is now complete and we can use it in our app. Lets try it out!

import Posts from './Posts'
import api from 'fronto-api';

const endpoint = api({
  endpoint: 'http://example.com',
  header: (h) => {
    const token = localStorage.getItem('token')
    h.append('Authorization', token);
  }
})

const posts = new Posts(endpoint);

posts.findAll(); 
// this will make a call to GET http://example.com/api/v1/posts and call 
// the #index action of the posts_controller and populate the posts.collection 
// with the data from the endpoint. Obviously it depends on how you implement
// your endpoint.

Once we make the call to the network we can use the collection to iterate and render out each post.

render() {
  const { collection, isLoading } = this.props.posts;

  if (isLoading) { return 'Loading...'; }

  return (
    <div>
      {collection.map(post => 
        <div key={post.id}>
          <h1>
            <a href={posts.route({ id: post.slug })}>{post.title}</a>
          </h1>
        </div>
      )}
    </div>
  )
}

URL Generation

You'll notice that we are using the posts.route({ id: post.slug }) this will generate the route for our post object like so /posts/whatever-the-slug-happens-to-be

You'll also notice that in the posts.findAll function we can pass in parameters, we can use parameters to generate url for us, here are some examples.

posts.findAll({ channel_id: channel.slug });
// will call http://example.com/api/v1/channels/the-slug-of-the-channel/posts 

posts.findAll({ search: true, channel_id: channel.slug });
// will call http://example.com/api/v1/search/channels/the-slug-of-the-channel/posts

Sometimes you want the url to be query parameter you can modify your findAll function like so.

findAll(parameters) {
  this.setIsLoading(true);
  this.clearCollection();
  this.call({ parameters, type: 'get', query: true }, {
    200: this.setCollection 
  });
}

We added the query: true option to the this.call what this will do is the following.

posts.findAll({ search: true, channel_id: channel.slug });
// will call http://example.com/api/v1/posts/search/channels/slug-of-the-channel

This concept applies to findBy as well.

You can also use posts.source({ id: post.slug }) will return the full source path like so /api/v1/posts/slug-of-the-post

Callbacks

If you are planning on building your own scopes you will need to understand the callback structure.

this.call({ parameters, type: 'get', query: true }, {
  200: this.setCollection 
});

That is the part that makes the network call. the 200 refers to the status from the server, so if your server responds with 200 it will call that callback, you can specify your own callback. It will give you a response json object. So you can write your own.

this.call({ parameters, type: 'get', query: true }, {
  200: (response) => this.setCollection(response.data),
  422: (response) => this.handleError(response.error) 
});

TODO

  • [ ] Add some tests
  • [ ] Convert to TypeScript?
  • [x] Documentation on basic usage
  • [x] Documentation on url generation
  • [ ] More documentation on this.call
  • [ ] Add Documentation on error handling
  • [ ] Documentation on pagination