{"id":14384658,"url":"https://github.com/blue-chip-js/blue-chip","last_synced_at":"2025-08-23T17:33:08.743Z","repository":{"id":33719866,"uuid":"137639656","full_name":"blue-chip-js/blue-chip","owner":"blue-chip-js","description":"Normalizes GraphQL and JSON:API payloads into your state management system and provides ORM selectors to prepare data to be consumed by components","archived":false,"fork":false,"pushed_at":"2023-07-10T03:09:01.000Z","size":12856,"stargazers_count":331,"open_issues_count":17,"forks_count":12,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-05-18T18:03:22.588Z","etag":null,"topics":["mobx","react","redux","state-management"],"latest_commit_sha":null,"homepage":"https://bluechip.gitbook.io/project/","language":"JavaScript","has_issues":true,"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/blue-chip-js.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-06-17T08:23:57.000Z","updated_at":"2024-04-12T04:24:00.000Z","dependencies_parsed_at":"2024-04-20T17:53:27.478Z","dependency_job_id":null,"html_url":"https://github.com/blue-chip-js/blue-chip","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blue-chip-js%2Fblue-chip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blue-chip-js%2Fblue-chip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blue-chip-js%2Fblue-chip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blue-chip-js%2Fblue-chip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blue-chip-js","download_url":"https://codeload.github.com/blue-chip-js/blue-chip/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230716607,"owners_count":18269805,"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":["mobx","react","redux","state-management"],"created_at":"2024-08-28T18:01:33.393Z","updated_at":"2024-12-21T12:30:49.610Z","avatar_url":"https://github.com/blue-chip-js.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# [BlueChip](https://bluechip.gitbook.io/project/) \u0026middot; [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mfpiccolo/blue-chip/blob/master/LICENSE.md) [![npm version](https://badge.fury.io/js/blue-chip.svg)](https://badge.fury.io/js/blue-chip) [![Docs API](https://img.shields.io/badge/Docs-API-brightgreen.svg)](https://bluechip.gitbook.io/project/api) [![Build Status](https://travis-ci.org/blue-chip-js/blue-chip.svg?branch=master)](https://travis-ci.org/blue-chip-js/blue-chip) [![Coverage Status](https://coveralls.io/repos/github/mfpiccolo/blue-chip/badge.svg?branch=master)](https://coveralls.io/github/mfpiccolo/blue-chip?branch=master) [![Created_By FullStack_Labs](https://img.shields.io/badge/Created_By-FullStack_Labs-blue.svg)](https://fullstacklabs.co)\n\nBlueChip accepts payloads from GraphQL or JsonAPI servers, normalizes them into your store and provides an ORM like syntax for retrieving the data for use.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cstrong\u003eTable of Contents\u003c/strong\u003e\u003c/summary\u003e\n\u003c!-- toc --\u003e\n\n- [The Basics](#the-basics)\n- [What BlueChip Is](#what-bluechip-is)\n  - [State API](#state-api)\n  - [Selector API](#selector-api)\n- [What BlueChip Is Not ](#what-bluechip-is-not)\n  - [Fetching](#fetching)\n  - [Client Side Store](#client-side-store)\n- [Why BlueChip?](#why-bluechip)\n- [Demos](#demos)\n  - [Redux Demo](#redux-demo)\n  - [MobX Demo](#mobx-demo)\n  - [React setState Demo](#react-setstate-demo)\n  - [Unstated Demo](#unstated-demo)\n- [Getting Started](#getting-started)\n  - [Adapters](#adapters)    \n  - [Configuration](#configuration)\n- [Redux](#redux)\n  - [Actions](#actions)\n  - [Update a Single Resource](#update-a-single-resource)\n  - [Reducers](#reducers)\n  - [Models](#models)\n  - [Containers](#containers)\n  - [Store Structure](#store-structure)\n- [Project Status](#project-status)\n- [Roadmap](#roadmap)\n\n\u003c!-- tocstop --\u003e\n\u003c/details\u003e\n\n## The Basics \nThere are only two things that BlueChip does.\n\n1. Normalize data and organize it in a store.\n2. Retrieve the data from the store and prepare it for use.\n\n## What BlueChip Is \n### State API\nBlueChip will take your data, normalize it and place it into a shared resources store. The API on this side is pretty minimal.\n\n* `updateResources()` Takes an entire payload of resources, normalize it and merge it into the store.\n* `updateResource()`  Merges in a single resource into your store\n* `removeResources()` Removes a list of resource from the store\n* `removeResource()`  Removes a single resource from the store\n* `clearResources()`  Clears a resource store by types\n\nAnd that is it for the State API.\n\n### Selector API  \nThis is the meat of BlueChip. The selector API is how you prepare your data to be consumed by components. To select data, BlueChip offers a robust ORM-style syntax complete with models, relationships, filtering, includes and more. You only needs access to the resources store to be able to use the selector api. \n\nHere is an example of using the ORM syntax to select from the store\n```javascript\nChecklist.query(resources)\n  .where({ active: true })\n  .includes(['tasks'])\n  .toObjects()\n```\n\n## What BlueChip Is Not \n### Fetching\nBlueChip is not interested in how you get your data. Fetch it, mock it, import it. However you get your data that is your business. The only requirement is that your data is formatted according to one of the adapters (JsonAPI, GraphQL). If it is not formatted you can write a custom adapter to normalize it.\n\n### Client Side Store \nBlueChip is agnostic to which client-side state management library you choose to use (Redux, Mobx, Vuex, other). You only need access to a shared resources store for BlueChip to work.\n\n## Why BlueChip?\n1. You have multiple data sources (or multiple projects with different data sources) and want to consistently interact with all of them in the same way in your client-side state management systems.  You can easily normalize and connect components from GraphQL, JsonAPI and custom formatted API's.\n\n2. You would like to keep resources unnessted in your stores for ease of updating, simplicity of mutation schema and ability to easily share resources across your application.\n\n3. You already have a state manager that you like or is a requirement of a project and do not want to adopt multiple to handle both GraphQL and JSON Rest data.\n\nYou are familiar with and prefer using ORM's when querying and working with data. \n\n## Demos\n\n### Redux Demo\n[Demo BlueChip/Redux Applicaiton](https://codesandbox.io/s/l5j9qk86q7)\n### MobX Demo\n[Demo BlueChip/Mobx Application](https://codesandbox.io/s/1qpv9r03qj)\n### React setState Demo\n[Demo BlueChip/React setState Application](https://codesandbox.io/s/4z5xw80q8w)\n### Unstated Demo\n[Demo Unstated Application](https://codesandbox.io/s/xjl733kjq4)\n\n## Getting Started \nTo start, choose your state management flavor. This is an example using Redux.\n\n`$ npm i -S @blue-chip/core`\n`$ npm i -S @blue-chip/redux-adapter`\n\nOr\n\n`yarn add @blue-chip/core`\n`yarn add @blue-chip/redux-adapter`\n\n### Adapters\n\nTo ensure that BlueChip is as flexible as possible, the state managment layer is implemented as adapters. These adapters are what do the work to mutate the state managment stores while BlueChip is in charge of delegating.  To use the adapters you will need to setup a configuration file.\n\n### Configuration\n\nThe configuration file needs to be setup so that you can import and use the mutator actions.\n\n```\nimport { Actions } from \"@blue-chip/core\";\nimport reduxAdapter from \"@blue-chip/redux-adapter\";\nimport store from \"./store\";\n\nexport const actions = Actions.config({\n  adapter: reduxAdapter,\n  mutator: store.dispatch\n});\n```\n\n## Redux\n\n### Actions\nBatch update resources:\n```javascript\nimport { actions } from \"../BlueChipConfig\";\n\nexport const fetchChecklists = async (dispatch, state) =\u003e {\n  dispatch({ type: \"LOADING_DATA\" });\n  try {\n    const response = await fetch(\"/checklists.json\", {\n      headers: {\n        \"content-type\": \"application/json\"\n      }\n    });\n    const payload = await response.json();\n\n    actions.updateResources(payload);\n    dispatch({ type: \"LOADING_SUCCESS\" });\n  } catch (error) {\n    console.log(\"error\", error);\n    dispatch({ type: \"LOADING_ERROR\" });\n  }\n};\n```\n### Update a single resource\n```javascript\nimport { actions } from \"../BlueChipConfig\";\n\nexport const updateTask = ({ id, ...attributes }) =\u003e {\n  actions.updateResource({ id, attributes, type: \"tasks\" });\n};\n```\n### Reducers\n```javascript\nimport { combineReducers } from \"redux\";\nimport reduxAdapter from \"@blue-chip/redux-adapter\";\n\nexport default combineReducers({\n  resources: reduxAdapter.resourcesReducer\n});\n```\n### Models\nJust like any other ORM you will be defining model classes:\n```javascript\nimport { BaseModel } from \"@blue-chip/core\";\nimport Task from \"./Task\";\n\nexport default class Checklist extends BaseModel {\n  static get hasMany() {\n    return [Task];\n  }\n}\n```\n```javascript\nimport { BaseModel } from \"@blue-chip/core\";\nimport Checklist from \"./Checklist\";\n\nexport default class Task extends BaseModel {\n  static get belongsTo() {\n    return [Checklist];\n  }\n}\n```\n### Containers\n```javascript\nconst mapStateToProps = state =\u003e { \n  const { resources } = state; \n  return { \n    checklists: Checklist.query(resources) \n                  .all() \n                  .includes([\"tasks\"]) \n                  .toObjects() \n  };\n};\n\nconst mapDispatchToProps = dispatch =\u003e ({ \n  updateTask: task =\u003e updateTask(dispatch, task)\n});\n\nexport default connect(mapStateToProps, mapDispatchToProps)(Container);\n```\n### Store Structure\nThe resources store is structured as an object with top-level keys as pluralized resource names.\n```javascript\nconst store = {\n  resources: {\n    checklists: {},\n    tasks: {}\n  }\n};\n```\nEach resource key points to an object that contains ids as keys and an JSON api object as a value.\n```javascript\nconst store = {\n  checklists: {\n    1: {\n      id: 1,\n      attributes: { name: \"Oboarding\" },\n      links: { self: \"http://example.com/checklists/1\" },\n      relationships: {\n        tasks: {\n         data: [{ id: 1, type: \"tasks: }, { id: 2, type: \"tasks: }],\n       },\n       type: \"checklists\"\n    }\n  },\n  tasks: {\n  ...\n}  \n```\n## Project Status\nThis project is currently in Alpha/Experimental phase.  The APIs will almost assuredly change prior to 1.0.  It is not ready for production yet, so use at your own risk.\n\n## RoadMap\n1. Increase Test Coverage\n2. Setup tests on CI\n3. More tests and examples with a diverse range of GraphQL and JsonAPI payloads.\n4. Refactor state managment to be an adapter as an external packages\n5. Add Vue and Vuex\n6. Allow for configurable and custom normailzers so you can use ANY api and spec.\n7. Bundle optimization\n8. belongsTo relationship\n9. Memoization\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblue-chip-js%2Fblue-chip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblue-chip-js%2Fblue-chip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblue-chip-js%2Fblue-chip/lists"}