{"id":26267345,"url":"https://github.com/oslabs-beta/lightql","last_synced_at":"2025-04-30T19:08:32.752Z","repository":{"id":63002612,"uuid":"561924426","full_name":"oslabs-beta/LightQL","owner":"oslabs-beta","description":"A lightspeed, lightweight client-side cache for GraphQL.","archived":false,"fork":false,"pushed_at":"2023-03-06T21:59:34.000Z","size":61061,"stargazers_count":56,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"dev","last_synced_at":"2025-04-30T19:07:27.718Z","etag":null,"topics":["cache","client-side-caching","graphql","nodejs","typescript"],"latest_commit_sha":null,"homepage":"https://www.lightql.com/","language":"TypeScript","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/oslabs-beta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"open-source-labs","custom":["https://donorbox.org/donations-to-oslabs-inc"]}},"created_at":"2022-11-04T20:09:54.000Z","updated_at":"2025-01-16T21:10:08.000Z","dependencies_parsed_at":"2025-04-30T19:07:31.186Z","dependency_job_id":null,"html_url":"https://github.com/oslabs-beta/LightQL","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oslabs-beta%2FLightQL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oslabs-beta%2FLightQL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oslabs-beta%2FLightQL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oslabs-beta%2FLightQL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oslabs-beta","download_url":"https://codeload.github.com/oslabs-beta/LightQL/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251767187,"owners_count":21640469,"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":["cache","client-side-caching","graphql","nodejs","typescript"],"created_at":"2025-03-14T04:16:33.953Z","updated_at":"2025-04-30T19:08:32.716Z","avatar_url":"https://github.com/oslabs-beta.png","language":"TypeScript","funding_links":["https://github.com/sponsors/open-source-labs","https://donorbox.org/donations-to-oslabs-inc"],"categories":[],"sub_categories":[],"readme":"\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/oslabs-beta/LightQL\"\u003e\n    \u003cimg src=\"./src/assets/LightQL.png\" alt=\"Logo\" width=\"200\" height=\"200\"\u003e\n  \u003c/a\u003e\n\n\u003ch3 align=\"center\"\u003eLightQL\u003c/h3\u003e\n\n  \u003cp align=\"center\"\u003e\n    Welcome to LightQL. A lightspeed, lightweight client-side cache for GraphQL.\n    \u003cbr /\u003e\n    \u003ca href=\"https://lightql.com/docs\"\u003e\u003cstrong\u003eExplore the docs »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://lightql.com\"\u003eView Demo\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e \u003ca href=\"#overview\"\u003eOverview\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#built-with\"\u003eBuilt With\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#demo\"\u003eDemo\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#how-lightql-works\"\u003eHow LightQL works\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#roadmap\"\u003eRoadmap\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#authors\"\u003eAuthors\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n\n## Overview\n\nLightQL is an easy-to-use super fast and lightweight Javascript library providing a client-side caching solution for GraphQL. Use LightQL for extremely low latency retrieval of persistent cache data.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n## Built With\n\n- GraphQL\n- Typescript\n- Node/Express\n- React\n- Chart.js\n- Jest\n- Supertest\n- AWS RDS\n- Webpack\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- GETTING STARTED --\u003e\n\n## Prerequisites\n\n- All developers will have to integrate GraphQL into their functionality. This means setting up your GraphQL schemas and resolvers as well as your database.\n- Our package is intended to work in tandem with a full-stack application where the frontend makes query requests to the backend, so please set this up as well before using our package.\n\n## Demo\n\n- Head over to the home page of our website ([lightql.com](https://www.lightql.com/))\n- Using our demo is a simple 2-step process.\n- First, press the “Run the demo” button to see the resulting GraphQL query\n  result. If you divert your attention to the metrics box down below you\n  will see an uncached run time populate. This statistic represents the\n  time it took to make a GraphQL fetch and receive the response data. You\n  can also see the spike in time upwards on the graph provided on the\n  right.\n- If you press the run query button again you will notice that your\n  cached run time metric will now render. The graph on the right will also\n  dive down as the response time has significantly decreased. The uncached run time should never change after this, as we are now retrieving your data from the cache every instance forward showing our super lightning speed of retrieval!\n\n  \\*A small disclaimer: It should be noted that your first query will have a significantly higher runtime than the other first queries because it is establishing a connection.\n\n## Installation\n\n1. If this is your first time using LightQL, run the following command in your terminal:\n2. ```sh\n   npm install lightql-cache\n   ```\n3. In your frontend app’s file (e.g. your filename.js file), you want to import our LightQL module to handle GraphQL requests using the ES6 module format. This can also be done in your React (.jsx), Typescript (.ts and .tsx), and similar file formats.\n   ```js\n   import { LRUCache, DoublyLinkedList, DLLNode } from ‘lightql-cache’;\n   ```\n4. Next, create an instance of a cache using the de-structured LRUCache object, passing in a capacity as the first argument. The capacity must be an integer and greater than zero. You must also pass in a valid GraphQL endpoint as a string as the second argument. We have set a capacity of 3 in our example below:\n   ```js\n   const cache = new LRUCache(3, 'http://localhost:3000/graphql');\n   ```\n5. Now, to make your first query to the cache, you create a GraphQL formatted query string based on your requirements, for example:\n   ```js\n   const graphqlQueryStr = `\t{\n   \tuser {\n   \t\tuser_name,\n   \t\tsong_name,\n   \t\tmovie_name\n   \t}\n   }`;\n   ```\n6. Next, we invoke the get function associated with the named variable you have for the LRUCache, and pass in your query string and associate variables if necessary. The get function always returns a promise, therefore it is best to generate an async function that leverages the await syntax to resolve the data returned from the cache.\n   ```js\n   const callLightQL = async () =\u003e {\n     const cacheGet = await cache.get(graphqlQueryStr, variables);\n   };\n   ```\n7. Now, you are properly set up and can use the data as you wish!\n8. A quick example: imagine you had a React app that included Chart.js functionality that you wanted to display on a specific page. You could import LightQL cache to effectively retrieve your data from your database, and then store it in your client-side LightQL caching solution. Then, every time you wanted to display the correct chart.js data, you could grab the correct information from your LightQL cache with extremely low latency time. Example code below:\n\n\u003cimg src=\"./src/assets/docs-example.png\" alt=\"Logo\" width=\"auto\" height=\"auto\"\u003e\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- USAGE EXAMPLES --\u003e\n\n## How LightQL works\n\nLightQL caches responses to GraphQL formatted queries as key-value object representations of the graph’s nodes, making it possible to satisfy GraphQL queries from a cached data store.\n\nWhen your application needs data, it checks the cache first to determine whether the data is available. If the data is available (a cache hit), the cached data is returned, and the response is issued to the user. If the data isn’t available (a cache miss), the database is queried for the data. The cache is then populated with the data that is retrieved from the database, and the data is returned to the user. The benefit of this strategy is that the cache contains only data that the application actually requests, keeping the cache size cost-effective. Further, this increases cache hits, reduces network calls, and significantly reduces the overall runtime and latency.\n\nLightQL’s LRUCache function creates an instance of the LightQL cache. A capacity and GraphQL endpoint are the two necessary arguments to pass in to this function. The LRUCache consists of a HashMap and Doubly-Linked List to store GraphQL query responses. The combination of these two data structures offer best-case scenario time complexity (O(1)) for insertion, deletion, and lookup.\n\n```js\nfunction LRUCache(capacity, graphqlEndpoint) {\n  this.capacity = Math.floor(capacity);\n  this.map = new Map();\n  this.dll = new DoublyLinkedList();\n  this.graphqlEndpoint = graphqlEndpoint;\n}\n```\n\nLightQL leverages localForage and IndexedDB to persist cached data between sessions. localForage is a fast and simple storage library for Javascript. localForage leverages asynchronous storage through IndexedDB, a JS-based object-oriented database that runs in your browser, with a simple, localStorage-like API. Whenever you run a query through LightQL, the capacity, HashMap, Doubly-Linked List, and graphqlEndpoint are loaded into memory if available through the localForage setItem method:\n\n```js\nlocalforage.setItem();\n```\n\nAdditionally, before returning data to users, LightQL writes our cache data structures and graphqlEndpoint to our persistent memory in IndexedDB through the localForage getItem method:\n\n```js\nlocalforage.getItem();\n```\n\nDevelopers can entrust LightQL to handle their GraphQL caching needs simply and effectively, so they can focus on working what matters most.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- ROADMAP --\u003e\n\n## Roadmap\n\nUpcoming planned features:\n\n- Caching of query mutations\n- Cache pruning/invalidation strategy\n- Partial retrieval\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- CONTRIBUTING --\u003e\n\n## Contributing\n\nHere at LightQL we created our open-source project with the intention to further expand upon and improve this tool for years to come.\n\nThat's where the community comes in! If you have an idea that might make LightQL better we always encourage contributions. Simply follow the steps below to submit the changes you would make.\n\n- Fork LightQL\n- Pull down our dev branch with command (`git pull origin dev`)\n- Create your own Feature Branch with the command (`git checkout -b \u003cyourFeatureName\u003e`)\n- Add your changes with the command (`git add .`)\n- Stage and commit your changes with the command (`git commit -m \"\u003cyour comment\u003e\"`)\n- Merge your branch with the dev branch locally with the command (`git merge dev`)\n- Resolve any merge conflicts\n- Push up your branch with the command (`git push origin \u003cyour feature branch name\u003e`)\n- Open a pull request\n- Don't forget to star this repo! We look forward to your contributions!\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- LICENSE --\u003e\n\n## License\n\nDistributed under the MIT License. See `LICENSE.txt` for more information.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- CONTACT --\u003e\n\n## Contact\n\nVisit https://lightql.com/aboutus to reach out to the team!\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- ACKNOWLEDGMENTS --\u003e\n\n## Authors\n\n- Cassidy Johnson\n- Cyrus Yari\n- Drew Tucker\n- Pierce Heska\n- Rhea Wu\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foslabs-beta%2Flightql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foslabs-beta%2Flightql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foslabs-beta%2Flightql/lists"}