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

relay-fns

v1.4.0

Published

Relay functions

Downloads

5

Readme

relay-fns

Functions for Relay

Installation

Using npm:

$ npm install --save relay-fns

Using yarn:

$ yarn add relay-fns

Then with a module bundler like webpack, use as you would anything else:

// Using ES6 Modules
import {useCommitMutation} from 'relay-fns';
// using CommonJS modules
const useCommitMutation = require('relay-fns').useCommitMutation;

Usage


It is required to pass down the Environment via Context on the top-level.
Why? Passing environment as a parameter to every function polludes the API.

import {EnvironmentProvider} from 'relay-fns';
import MyApp from './MyApp';

function MyAppContext({children}) {
  return (
    <EnvironmentProvider environment={environment}>
      <MyApp />
    </EnvironmentProvider>
  );
}

Injecting Environment

// With a hook
import {useEnvironment} from 'relay-fns';

function MyComponent() {
  const environment = useEnvironment();
  return (
    // Use Environment for something
  );
}

// With a hoc
import {withEnvironment} from 'relay-fns';

@withEnvironment
class MyComponent extends React.Component {
  render() {
    return (
      // this.props.environment
      // Use Environment for something
    );
  }
}

FetchQuery

Provides FetchQuery with Environment pre-applied.

// With a hook
import {useFetchQuery} from 'relay-fns';

function MyComponent() {
  const fetchQuery = useFetchQuery();
  useEffect(() => {
    // Fetch some data
    fetchQuery(QUERY, VARIABLES);
  });
}

// With a hoc
import {withFetchQuery} from 'relay-fns';

@withFetchQuery
class MyComponent extends React.Component {
  componentDidMount() {
    // Fetch some data
    this.props.fetchQuery(QUERY, VARIABLES);
  }
}

CommitMutation

Provides CommitMutation with Environment pre-applied, and returns a promise. Once the mutation is done, the promise is resolved. The promise is rejected if:

  • onError is called
  • onCompleted returns errors in the second argument
  • The response contains a key named errors - which holds a non-empty value.
// With a hook
import {useCommitMutation} from 'relay-fns';

function MyComponent() {
  const commitMutation = useCommitMutation();
  function runSomeMutation() {
    commitMutation(MUTATION, INPUT, CONFIG)
      .then(() => console.log('Well done!'))
      .catch(() => console.error('You broke it!'));
  }
}

// With a hoc
import {withCommitMutation} from 'relay-fns';

@withCommitMutation
class MyComponent extends React.Component {
  runSomeMutation() {
    this.props
      .commitMutation(MUTATION, INPUT, CONFIG)
      .then(() => console.log('Well done!'))
      .catch(() => console.error('You broke it!'));
  }
}

Create

If you create an item which resides in a list that isn't a connection, Relay is unable to put the item from the mutation payload, into your list.

To resolve the list, a config is required.

  • listName The name of the list in GraphQL
  • listArgs Any arguments required to resolve the list
  • parentID Name of the parent, which holds the list.
  • rootField Can be provided instead of parentID. Equivalent to store.getRoot().getLinkedRecord(rootField)
  • payloadName Provided, if the name of your payload, does not follow the createdObject naming convention.
  • mutationName Provided, if the name of your mutation, does not follow the create[Type] naming convention.

Assuming the query looks like this:

query MyQuery {
	viewer {
		todos {
			...TodoFragment
		}
	}
}

And the mutation looks like this:

mutation MyMutation($input: CreateTodoInput!) {
	createTodo(input: $input) {
		createdObject {
			...TodoFragment
		}
	}
}

The config would look like this:

{
	listName: "todos",
	rootField: "viewer"
}

In practice, it could be used like this:

// With a hook
import {useCreateMutation} from 'relay-fns';

function MyComponent() {
  const createTodo = useCreateMutation('Todo');
  function runSomeMutation(input) {
    createTodo(MUTATION, input, CONFIG)
      .then(() => console.log('Todo created'))
      .catch(() => console.error('Failed to create todo'));
  }
}

// With a hoc
import {withCreateMutation} from 'relay-fns';

@withCreateMutation("Todo")
class MyComponent extends React.Component {
  runSomeMutation(input) {
    this.props
      .createMutation(MUTATION, input, CONFIG)
      .then(() => console.log('Todo created'))
      .catch(() => console.error('Failed to create todo'));
  }
}

Update

If you update an item, waiting for the server to respond isn't always necessary. We may set the values on the object in the Relay Store optimistically.

If Id is not included in your input, you will need to provide it in the config, via the dataID property.

// With a hook
import {useUpdateMutation} from 'relay-fns';

function MyComponent() {
  const updateTodo = useUpdateMutation('Todo');
  function runSomeMutation(input) {
    updateTodo(MUTATION, input, CONFIG)
      .then(() => console.log('Todo updated'))
      .catch(() => console.error('Failed to update todo'));
  }
}

// With a hoc
import {withUpdateMutation} from 'relay-fns';

@withUpdateMutation("Todo")
class MyComponent extends React.Component {
  runSomeMutation(input) {
    this.props
      .updateMutation(MUTATION, input, CONFIG)
      .then(() => console.log('Todo updated'))
      .catch(() => console.error('Failed to update todo'));
  }
}

Delete

When you delete an item in a list which is not a connection, the optimistic cleanup can be tedious. This function provides you with this functionality.

To resolve the list, a config is required.

  • dataID Required, if the Id property does not exist in your input.
  • listName The name of the list in GraphQL
  • listArgs Any arguments required to resolve the list
  • parentID Name of the parent, which holds the list.
  • rootField Can be provided instead of parentID. Equivalent to store.getRoot().getLinkedRecord(rootField)
// With a hook
import {useDeleteMutation} from 'relay-fns';

function MyComponent() {
  const deleteTodo = useDeleteMutation('Todo');
  function runSomeMutation(input) {
    deleteTodo(MUTATION, input, CONFIG)
      .then(() => console.log('Todo deleted'))
      .catch(() => console.error('Failed to delete todo'));
  }
}

// With a hoc
import {withDeleteMutation} from 'relay-fns';

@withDeleteMutation("Todo")
class MyComponent extends React.Component {
  runSomeMutation(input) {
    this.props
      .deleteMutation(MUTATION, input, CONFIG)
      .then(() => console.log('Todo deleted'))
      .catch(() => console.error('Failed to delete todo'));
  }
}

Utility HOCs

  • fragment = createFragmentContainer
  • refetch = createRefetchContainer
  • pagination = createPaginationContainer
import {fragment} from 'relay-fns';

@fragment({ todo: graphql`...` })
class MyComponent extends React.Component {
  ...
}

import {refetch} from 'relay-fns';

@refetch({ todo: graphql`...` }, graphql``)
class MyComponent extends React.Component {
  ...
}

import {pagination} from 'relay-fns';

@pagination({ todo: graphql`...` }, { ...PaginationProps })
class MyComponent extends React.Component {
  ...
}

Executables

relay-fns-enums Parameters:

  • --schema Path to schema.graphql
  • --output Output file

Add it to scripts in package.json Or run it from the terminal:

$ ./node_modules/.bin/relay-fns-enums --schema ./schema.graphql --output ./src/Enums.js

It will generate a file with enums from your graphql schema.

export const MyEnum = {
  Enum1: 'Enum1',
  Enum2: 'Enum2',
};

Development

  1. Clone the repository

  2. Install dependencies npm|yarn install

  3. Build and watch for changes npm|yarn run watch

Credits

relay-fns is built and maintained by babangsund.

@blog.
@github.
@twitter.