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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@grafoo/core

v1.4.2

Published

grafoo client core

Readme

@grafoo/core

Install

$ npm i @grafoo/core && npm i -D @grafoo/babel-plugin

Setup

Assuming you already have babel installed, the only additional step required to build an application with Grafoo is to configure @grafoo/babel-plugin. The options it accepts are idFields - the fields Grafoo will take to build unique identifiers, and schema, which is a relative path to your schema file.

{
  "plugins": [
    [
      "@grafoo/babel-plugin",
      {
        "schema": "schema.graphql",
        "idFields": ["id"]
      }
    ]
  ]
}

API

@grafoo/core consists of a module that exports as default function a factory to create the client intance and a submodule that exports that graphql template tag.

graphql template tag

From @grafoo/core/tag is exported the graphql or gql tag that you'll use to create your queries. On build time every time you use that tag it will be replace with a special object that assists the client on the caching process. It is a dummy module and if you do not have @grafoo/babel-plugin it will thow you an error.

Example

import gql from "@grafoo/core/tag";

const USER_QUERY = gql`
  query($id: ID!) {
    user(id: $id) {
      name
    }
  }
`;

// will be transformed to this on build time

const USER_QUERY = {
  query: "query($id: ID!) { user(id: $id) { name id } }"
  paths: {
    "user(id:$id){name id}": {
      name: "user",
      args: ["id"]
    }
  }
}

createClient factory

createClient accepts as arguments a transport function to comunicate with your GraphQL API and an options object. This options are:

| Option | Type | Required | Description | | ------------ | -------- | -------- | ------------------------------------------------------------------------------------- | | idFields | string[] | false | fields Grafoo takes to build unique identifiers | | initialState | object | false | a initial state to hydrate the cache. It can be produced by the flush client method |

Example

import createClient from "@grafoo/core";

function fetchQuery(query, variables) {
  const init = {
    method: "POST",
    body: JSON.stringify({ query, variables }),
    headers: {
      "content-type": "application/json"
    }
  };

  return fetch("http://some.graphql.api", init).then(res => res.json());
}

const client = createClient(fetchQuery);

IdFields

IdFields is homologous to the @grafoo/babel-plugin option with the same name. You don't have much to worry about it because it's automatically inserted by @grafoo/babel-plugin on every client instantiation. It is an array of fields that Grafoo will take to build unique identifiers.

Say you want to consume a query like so:

{
  me {
    name
  }
}

If idFields is configured with ["id"]. This query will be transformed to this:

{
  me {
    name
    id
  }
}

Then the client, when caching this data, will use this id field to store it.

Example

const client = createClient(fetchQuery, {
  idFields: ["id", "__typename"]
});

GrafooClient

the createClient factory returns a client instance with some methods:

| Name | Description | | ------- | ------------------------------------------------------ | | execute | executes queries | | read | reads queries from the cache | | write | writes queries to the cache | | listen | takes a listener callback and notify for cache changes | | flush | dumps the internal state of the instance cache |

GrafooClient.execute

This method receives as arguments a query object created with the @grafoo/core/tag template tag and optionally a GraphQL variables object. It returns a promise that will resolve with the data requested or reject with a list of GraphQL errors.

Example

const variables = { id: 123 };

client.execute(USER_QUERY, variables).then(data => {
  console.log(data); // { "user": { "name": "John Doe", "id": "123" } }
});

GrafooClient.write

The write method as the name implies writes to the cache. It takes as argumets the query object, an optional variables object and the data to be stored.

Example

client.execute(USER_QUERY, variables).then(data => {
  client.write(USER_QUERY, variables, data);
});

GrafooClient.read

The read method takes as arguments the query object and optionally a variables object. It returns an object with three properties: data, a tree structured object shaped according to your query tree, objects a flat structured object containing every node on your query indexed by a unique id created with the idProps option passed on client instantiation and a partial property that flags if the data is partially cached or not.

Example

client.read(USER_QUERY, variables);
// {
//   "data": {
//     "user": {
//       "name": "John Doe",
//       "id": "123"
//     }
//   },
//   "objects": {
//     "123": {
//       "name": "John Doe",
//       "id": "123"
//     }
//   },
//   partial: false
// }

GrafooClient.listen

listen takes a listener callback as argument. Whenever the cache is updated that listener is called with the objects that were inserted, modified or removed.

Example

function listener(objects) {
  console.log(objects);
}

const unlisten = client.listen();

client.write(USER_QUERY, variables, data);

unlisten(); // detaches the listener from the client

GrafooClient.flush

The flush method dumps all of the data inside the cache in it's raw state, producing a snapshot. It is to be used in mainly on the server producing, a initial state that can be passed as an option to createClient on client side.

Example

// server.js
app.get("/", (req, res) => {
  res.send(`<script>_GRAFOO_INITIAL_STATE_=${JSON.stringify(client.flush())}_</script>`);
});

// client.js
const client = createClient(fetchQuery, {
  initialState: window._GRAFOO_INITIAL_STATE_
});

LICENSE

MIT