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

mobql

v0.1.1

Published

A data manager built on MobX that loads your data from your GraphQL API as you need it

Downloads

1

Readme

MobQL

This is a little beta side project I've been working on. It allows you to define your data and how to get it from your GraphQL schema, then it will load properties as you access them, allowing you to not need to worry about designing your queries. No more having to modify your query to include a new property and update your code to use it. You just use it and it will load anything it needs to from the server. Best part, the cache can still be updated just like normal MobX objects, allowing you to use whatever event system you want to update your cache in real time.

So how do I use it?

Install it with yarn or npm

npm install mobql --save

yarn add mobql

Then follow the steps below to get your data ready to go. You can also take a look at the two quick example projects in the /examples directory. (Store.ts in each of these is the important bit).

Step 1 - Define your data

Define you data as a class, generally you'll be extending DataLoadedListEntry as that represents an instance of an object like a User or Post with a unique ID. DataLoadedObject is used for a static set of properties such as a global config where there's only once instance of that object on the API. NestedObject is used for when you have nested data that isn't considered to be a part of another object, something like name { first, last } on a User.

class Continent extends DataLoadedListEntry {
  name: string | null = null;
  code: string;
  @MobQLArrayListObject("Country")
  countries: Country[] = [];

  constructor(id: string, manager: DataLoadedListEntryManager<any>) {
    super(manager);
    this.code = id;
  }

  getId(): string {
    return this.code;
  }
}

When referencing another DataLoaded... thing in a property, make sure to decorate it so that MobQL knows what to look for.

(!) Make sure to initialize any NestedObjects in your class's constructor, as well as intialize any arrays of DataLoadedListEntrys as empty arrays, everything else should be type | null = null. This allows you to access the properties right away.

(!) Extremely important: Do not make any properties optional as this causes issues with the reflection used to set up the objects

Step 2 - Make your data loader

This package doesn't require the use of any specific graphql client, all you need to do is make a DataLoader that will take a query and variables then return the result that your graphql library gives.

class MyDataLoader extends DataLoader {
  async runQuery(query: string, variables: any): Promise<any> {
    let output;
    try {
      output = await request(
        "https://countries.trevorblades.com/graphql",
        query,
        variables
      );
    } catch (e) {
      console.log(e);
    }
    // Make sure that your output puts the data in the data property of the return value, in the future other properties will be used for other data
    return { data: output };
  }
}

In the example I use graphql-request for a quick and simple query runner.

Step 3 - Register your models

You'll now register all your models with an ObjectManager, this is what allows your objects to reference each other as well as handles creation and serving of these object for you.

const objectManager = new ObjectManager(dataLoader);

objectManager.registerListType(Continent, "continent", "Continent", "code");
objectManager.registerListType(Country, "country", "Country", "code");

(!) Important note: Make sure you give the ObjectManager the proper name for the id property of each object if it doesn't use id, otherwise this will cause issues

Step 4 - Use the data!

You just grab the items from your object manager and start using them like you would any other MobX object. For things like grabbing a list from search, use a normal gql query and have it only return the ids of the objects, then fetch those all from the ObjectManager and use the data you want, any data not yet loaded will be grabbed from the server automatically. This does split it into two network requests, however the first request will be smaller and the second request will potentially save a lot of data if a lot of the objects are cached.

const continentRepo = objectManager.getList(Continent);
const continentNorthAmerica = continentRepo.get("NA");

autorun(() => {
  console.log(continentNorthAmerica.name);
  console.log(" Countries:");
  continentNorthAmerica.countries.map((country) => {
    console.log("  ", country.code, "-", country.name, country.emoji);
  });
});