{"id":13437907,"url":"https://github.com/gyzerok/adrenaline","last_synced_at":"2025-03-19T18:31:07.301Z","repository":{"id":57173664,"uuid":"39194973","full_name":"gyzerok/adrenaline","owner":"gyzerok","description":"Simple Relay alternative","archived":true,"fork":false,"pushed_at":"2017-02-14T14:11:42.000Z","size":504,"stargazers_count":718,"open_issues_count":5,"forks_count":26,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-03-12T14:48:43.558Z","etag":null,"topics":["graphql","react","relay"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gyzerok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-16T12:13:44.000Z","updated_at":"2024-12-10T14:09:52.000Z","dependencies_parsed_at":"2022-08-24T13:31:02.609Z","dependency_job_id":null,"html_url":"https://github.com/gyzerok/adrenaline","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyzerok%2Fadrenaline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyzerok%2Fadrenaline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyzerok%2Fadrenaline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyzerok%2Fadrenaline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyzerok","download_url":"https://codeload.github.com/gyzerok/adrenaline/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244483201,"owners_count":20460074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphql","react","relay"],"created_at":"2024-07-31T03:01:01.103Z","updated_at":"2025-03-19T18:31:06.852Z","avatar_url":"https://github.com/gyzerok.png","language":"JavaScript","funding_links":[],"categories":["Uncategorized","Code Design","Libraries","JavaScript","Marks"],"sub_categories":["Uncategorized","Communication with server","JavaScript Libraries","[React - A JavaScript library for building user interfaces](http://facebook.github.io/react)"],"readme":"# Adrenaline\n\n[![build status](https://img.shields.io/travis/gyzerok/adrenaline/master.svg?style=flat-square)](https://travis-ci.org/gyzerok/adrenaline)\n[![npm version](https://img.shields.io/npm/v/adrenaline.svg?style=flat-square)](https://www.npmjs.com/package/adrenaline)\n[![npm downloads](https://img.shields.io/npm/dm/adrenaline.svg?style=flat-square)](https://www.npmjs.com/package/adrenaline)\n\nThis library provides a subset of [Relay](https://github.com/facebook/relay)'s behaviour with a cleaner API.\n\n## Why?\n\nRelay is a great framework with exciting ideas behind it. The downside is that in order to get all the cool features, you need to deal with a complex API. Relay provides you a lot of tricky optimizations which probably are more suitable for huge projects. In small, medium and even large ones you would prefer to have better developer experience while working with a simple, minimalistic set of APIs.\n\nAdrenaline intends to provide you Relay-like ability to describe your components with declarative data requirements, while keeping the API as simple as possible. You are free to use it with different libraries like Redux, React Router, etc.\n\n## When not to use it?\n\n- You have a huge project and highly need tricky optimisations to reduce client-server traffic.\n- When you don't understand why you should prefer Adrenaline to Relay.\n\n## Installation\n\n`npm install --save adrenaline`\n\nAdrenaline requires **React 15.0 or later.**\n\nAdrenaline uses `fetch` under the hood so you need to install the [polyfill](https://github.com/github/fetch) by yourself.\n\n`npm install --save whatwg-fetch`\n\nand then import it at the very top of your entry JavaScript file:\n\n```js\nimport 'whatwg-fetch';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Adrenaline } from 'adrenaline';\n\nimport App from './components/App';\n\nReactDOM.render(\n  \u003cAdrenaline\u003e\n    \u003cApp /\u003e\n  \u003c/Adrenaline\u003e,\n  document.getElementById('root')\n)\n```\n\n## API\n\nAdrenaline follows the idea of [Presentational and Container Components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0#.b5g7ctse2)\n\n### `\u003cAdrenaline endpoint /\u003e`\n\nRoot of your application should be wrapped with Adrenaline component. This component is a provider component which injects some helpful stuff into your React application.\n\nprop name | type   | default/required | purpose\n----------|--------|------------------|--------\nendpoint  | string | \"/graphql\"       | URI of your GraphQL endpoint\n\n### `container({ variables, query })(Component)`\n\nIn Adrenaline, you create container components mostly for your route handlers. The purpose of containers is to collect data requirements from presentation components in a single GraphQL query. They also behave like view controllers and are able to speak to the outside world using mutations.\n\nkey       | type                     | default/required | purpose\n----------|--------------------------|------------------|--------\nvariables | (props: Props) =\u003e Object | () =\u003e ({})       | describe query variables as a pure function of props\nquery     | string                   | **required**     | your GraphQL query for this container\n\n\n```javascript\nimport React, { Component, PropTypes } from 'react';\nimport { container } from 'adrenaline';\nimport TodoList from './TodoList';\n\nclass UserItem extends Component {\n  static propTypes = {\n    viewer: PropTypes.object.isRequired,\n  }\n  /* ... */\n}\n\nexport default container({\n  variables: (props) =\u003e ({\n    id: props.userId,\n  }),\n  query: `\n    query ($id: ID!) {\n      viewer(id: $id) {\n        id,\n        name,\n        ${TodoList.getFragment('todos')}\n      }\n    }\n  `,\n})(UserItem);\n```\n\nContainers may also pass 2 additional properties to your component: `mutate` and `isFetching`.\n\n* `mutate({ mutation: String, variables: Object = {}, invalidate: boolean = true }): Promise`: You need to use this function in order to perform mutations. `invalidate` argument means you need to resolve data declarations after mutation.\n* `isFetching: boolean`: This property helps you understand if your component is in the middle of resolving data.\n\n### `presenter({ fragments })(Component)`\n\nAs in the [presentational components idea](https://github.com/rackt/react-redux#dumb-components-are-unaware-of-redux), all your dumb components may be declared as simple React components. But if you want to declare your data requirements in a way similar to Relay, you can use the `presenter()` higher-order component.\n\n```javascript\nimport React, { Component } from 'react';\nimport { presenter } from 'adrenaline';\n\nclass TodoList extends Component {\n  /* ... */\n}\n\nexport default presenter({\n  fragments: {\n    todos: `\n      fragment on User {\n        todos {\n          id,\n          text\n        }\n      }\n    `,\n  },\n})(TodoList);\n```\n\n\n## Using ES7 decorators\nAdrenaline works as higher-order components, so you can decorate your container components using ES7 decorators\n\n```javascript\nimport { container } from 'adrenaline'\n\n@container({\n  variables: (props) =\u003e ({\n    id: props.userId,\n  }),\n  query: `\n    query ($id: ID!) {\n      viewer(id: $id) {\n        id,\n        name,\n        ${TodoList.getFragment('todos')}\n      }\n    }\n  `\n})\nexport default class extends Component {\n  static propTypes = {\n    viewer: PropTypes.object.isRequired,\n  }\n  /* ... */\n}\n```\n\n\n### Mutations\n\nYou can declare your mutations as simple as:\n\n```javascript\nconst createTodo = `\n  mutation ($text: String, $owner: ID) {\n    createTodo(text: $text, owner: $owner) {\n      id,\n      text,\n      owner {\n        id\n      }\n    }\n  }\n`;\n```\n\nThen you can use this mutation with your component:\n\n```javascript\nimport React, { Component, PropTypes } from 'react';\nimport { createSmartComponent } from 'adrenaline';\n\nclass UserItem extends Component {\n  static propTypes = {\n    viewer: PropTypes.object.isRequired,\n  }\n\n  onSomeButtonClick() {\n    this.props.mutate({\n      mutation: createTodo,\n      variables: {\n        text: hello,\n        owner: this.props.viewer.id\n      },\n    });\n  }\n\n  render() {\n    /* render some stuff */\n  }\n}\n```\n\n### Testing\n\nThere is a common problem I've discovered so far while developing applications. When you change the GraphQL schema, you'd like to know which particular subtrees in your applications need to be fixed. And you probably do not want to check this by running your application and going through it by hand.\n\nFor this case, Adrenaline provides you helper utilities for integration testing (currently for `expect` only). You can use `toBeValidAgainst` for checking your components' data requirements against your schema with GraphQL validation mechanism.\n\n```js\nimport expect from 'expect';\nimport TestUtils from 'adrenaline/lib/test';\n\nimport schema from 'path/to/schema';\n// TodoApp is a container component\nimport TodoApp from 'path/to/TodoApp';\n\nexpect.extend(TestUtils.expect);\n\ndescribe('Queries regression', () =\u003e {\n  it('for TodoApp', () =\u003e {\n    expect(TodoApp).toBeValidAgainst(schema);\n  });\n});\n```\n\n![Image](https://raw.githubusercontent.com/gyzerok/adrenaline/master/images/resgression-example.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyzerok%2Fadrenaline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyzerok%2Fadrenaline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyzerok%2Fadrenaline/lists"}