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

reference-fetcher

v3.2.0

Published

Simple and easy entity references fetcher

Downloads

41

Readme

Reference-Fetcher

ReferenceFetcher is a simple-to-use JS library to fetch entity references.

Travis Build Version Code Coverage

Installation

npm install --save reference-fetcher

Documentation

ReferenceFetcher is an algorithm useful for retrieving multiple referenced entity from a database.

Imagine we have this kind of database:

Reddit Base

Posts is the key database table here. A post has 3 references; a tag, a creator and a subreddit which correspond to IDs that we can find in the corresponding database tables.

Note: ReferenceFetcher is made to work with only unique references up to now, do not use it to fetch an array of reference (i.e. a Post should have only one tag, one creator and one subreddit in our example). Array may come as a feature in the near future.

Our workflow is to get a particular set of Posts (to feed a page or whatever) and its references but we do not want the Back-End to populate them for us for three reasons:

  1. This could create a massive request that take times to compute with a considerable payload (hurting our First Meaningful Paint time).
  2. It will probably contains duplication of the same entity (multiple posts can have the same creator, tag or subreddit).
  3. We usually prefer to keep our Front-End stores as flat as possible. Using deeply nested data is often very difficult to use in JavaScript applications, especially for those using Flux or Redux

That's where ReferenceFetcher shines. Thanks to a configuration object, we can declare what references we want to fetch and it will call our Promises with the correct parameters plus taking care of duplication. Then it is up to us to populate correctly our store with our Promises results. At Wing we use Redux dispatch from our Promises (which are actions) result to populate our stores. Promises must always returns their results after the operation you have done.

import referenceFetcher from 'reference-fetcher'

const configuration = {
  entity: 'posts',
  fetch: () => getPosts(),
  rootNoCache: true,
  refs: [{
    entity: 'subreddit',
    fetch: subredditId => getSubreddit(subredditId),
  }, {
    entity: 'subscribers',
    relationName: 'creator',
    batch: true,
    fetch: subscribersIds => getSubscribers(subscribersIds),
    refs: [{
      entity: 'stats',
      relationName: 'stat',
      batch: true,
      fetch: getStats,
    }]
  }, {
    entity: 'tag',
    noCache: true,
    fetch: getTag,
  }],
  sides: [{ // Optional: useful to retrieve entity by post ids
    entity: 'notLinked',  
    fetch: postIds => getNotLinkedEntity(postIds),
  }]
}

referenceFetcher(configuration)

Example of actions used:

const getPosts = () => new Promise((resolve, reject) => {
  // Retrieve posts from your api
  fetch(`${APIURL}/posts`).then(response => {
    // Populate your store
    postsStore.push(...response.posts)
    // Return the response allowing to fetch underneath references
    // and chain our promise
    return response.posts
  })
})
const getSubreddit = subredditId => new Promise((resolve, reject) => {
  fetch(`${APIURL}/subreddits/${subredditId}`).then(response => {
    subredditsStore.push(response.subreddit)
    return response.subreddit
  })
})
const getSubscribers = subscribersId => new Promise((resolve, reject) => {
  // A POST method to get a batch of subscribers, because you can
  fetch(`${APIURL}/subscribers`, {
    method: 'POST',
    body: subscribersId
  }).then(response => {
    subscribersStore.push(...response.subscribers)
    return response.subscribers
  })
})

Arguments

  • entity (String): The name that will be used to retrieve data from the Promise result. These data will then be used to retrieve our underneath refs. Omit this argument if your API response contains directly the desired result.
  • fetch (Promise): The Promise that will be called to get our particular entity. fetch is called with no parameters if it is the root Object (Post in our example) or is called multiple times with a String representing the ID to fetch (getSubreddit in our example) or is called once with an Array of ID to fetch (getSubscribers in our example). The promise must return its results if we want lower refs to work.
  • relationName (String): Only for refs The name of the attribute in the parent object where we can find the ID to fetch. Default to entity.
  • batch (Boolean): Only for refs Default value: false. Set to true if you want your fetchcalled only once with the array of ID to retrieve.
  • optional (Boolean): Only for refs Default value: false. Set to true if the entity could not be in the object you fetched.
  • noCache (Boolean): Only for refs Default value: false. Set to true if you want to bypass the already fetched watcher. It means that if the entity we want to retrieve was already retrieved earlier, ReferenceFetcher will still call our fetch with the unique IDs it finds in the parent Object.
  • rootNoCache (Boolean): Only for root Default value: false. Set to true if you want to bypass the caching on the root fetch. It means that if we call our referenceFetcher with the same root fetch function, it will recall it each time we call the referenceFetcher
  • sides (Array): An array composed of object of type: ({ entity: string, fetch: function }). Used to fetch entities that are not linked to a parent. Will use the cache.

Returns

ReferenceFetcher returns nothing, its objective is only to correctly call the different Promises. We need to feed our store directly from the Promises.

Change Log

This project adheres to Semantic Versioning.

You can find every release documented on the Releases page.

License

MIT