{"id":13431192,"url":"https://github.com/levelgraph/levelgraph","last_synced_at":"2025-12-12T04:29:51.251Z","repository":{"id":383897,"uuid":"9695623","full_name":"levelgraph/levelgraph","owner":"levelgraph","description":"Graph database JS style for Node.js and the Browser. Built upon LevelUp and LevelDB.","archived":false,"fork":false,"pushed_at":"2024-05-28T14:40:42.000Z","size":1883,"stargazers_count":1472,"open_issues_count":49,"forks_count":121,"subscribers_count":68,"default_branch":"master","last_synced_at":"2024-10-29T15:04:52.711Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/levelgraph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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}},"created_at":"2013-04-26T13:14:22.000Z","updated_at":"2024-10-21T14:43:54.000Z","dependencies_parsed_at":"2024-05-09T12:54:44.687Z","dependency_job_id":"b4c71e03-e611-43f3-ba5f-d8e186da85cf","html_url":"https://github.com/levelgraph/levelgraph","commit_stats":{"total_commits":357,"total_committers":30,"mean_commits":11.9,"dds":"0.38095238095238093","last_synced_commit":"9d4c89adeb25598d965a58842f95bd168ca1087b"},"previous_names":["mcollina/levelgraph"],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levelgraph%2Flevelgraph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levelgraph%2Flevelgraph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levelgraph%2Flevelgraph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levelgraph%2Flevelgraph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/levelgraph","download_url":"https://codeload.github.com/levelgraph/levelgraph/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247664154,"owners_count":20975540,"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":[],"created_at":"2024-07-31T02:01:01.211Z","updated_at":"2025-12-12T04:29:46.221Z","avatar_url":"https://github.com/levelgraph.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","Databases"],"sub_categories":["Data Cube extensions"],"readme":"LevelGraph\n===========\n\n\u003c!-- \u0026nbsp;\u0026nbsp;\u0026nbsp;[![Dependency Status](https://david-dm.org/levelgraph/levelgraph.svg?theme=shields.io)](https://david-dm.org/levelgraph/levelgraph) --\u003e\n\n![Logo](https://raw.githubusercontent.com/levelgraph/levelgraph/master/logo.png)\n\n[![NPM](https://nodei.co/npm/levelgraph.png)](https://nodei.co/npm/levelgraph/)\n\n__LevelGraph__ is a Graph Database. Unlike many other graph database,\n__LevelGraph__ is built on the uber-fast key-value store\n[LevelDB][gh:google/leveldb] through the powerful [level][gh:level/level]\nlibrary. You can use it inside your node.js application or in any\nIndexedDB-powered Browser.\n\n__LevelGraph__ loosely follows the __Hexastore__ approach as presented in the\narticle: [Hexastore: sextuple indexing for semantic web data management C Weiss,\nP Karras, A Bernstein - Proceedings of the VLDB Endowment,\n2008](https://sci-hub.se/10.14778/1453856.1453965).\nFollowing this approach, __LevelGraph__ uses six indices for every triple, in\norder to access them as fast as it is possible.\n\n__LevelGraph__ was presented in the paper [Graph databases in the browser: using\nLevelGraph to explore New Delhi - A. Maccioni, M. Collina - Proceedings of the\nVLDB Endowment, 2016](http://www.vldb.org/pvldb/vol9/p1469-maccioni.pdf).\n\nCheck out a [slideshow](http://nodejsconfit.levelgraph.io) that introduces you\nto LevelGraph by [@matteocollina][x:matteocollina] at http://nodejsconf.it.\n\nAlso, give the [LevelGraph Playground][http:playground] to get a quick feel for\nadding JSON-LD and N3/Turtle documents to a filter-able subject, predicate,\nobject table. The `db` variable in the browser console is very useful for\nchecking out the full power of LevelGraph.\n\n**LevelGraph** is an **OPEN Open Source Project**, see the\n[Contributing](#contributing) section to find out what this means.\n\n## Table of Contents\n\n* [Install](#install)\n* [Usage](#usage)\n  * [Get and Put](#get-and-put)\n    * [Triple Properties](#triple-properties)\n    * [Limit and Offset](#limit-and-offset)\n    * [Reverse Order](#reverse-order)\n    * [Updating](#updating)\n    * [Multiple Puts](#multiple-puts)\n  * [Deleting](#deleting)\n  * [Searches](#searches)\n    * [Search Without Streams](#search-without-streams)\n    * [Triple Generation](#triple-generation)\n    * [Limit and Offset](#limit-and-offset-1)\n  * [Filtering](#filtering)\n  * [Putting and Deleting through Streams](#putting-and-deleting-through-streams)\n  * [Generate batch operations](#generate-batch-operations)\n  * [Generate level-read-stream query](#generate-level-read-stream-query)\n* [Navigator API](#navigator-api)\n* [Plugin integration](#plugin-integration)\n* [Browser usage](#browser-usage)\n* [RDF support](#rdf-support)\n* [Extensions](#extensions)\n* [TODO](#todo)\n* [Contributing](#contributing)\n* [Credits](#credits)\n* [Contributors](#contributors)\n* [LICENSE - \"MIT License\"](#license---mit-license)\n\n\n## Install\n\n### On Node.JS\n\n```\nnpm install --save levelgraph\n```\n\nTesting of levelgraph is only done using Node.JS 18 and 20. Other versions may\nbe supported, but your mileage may vary.\n\n### In the Browser\n\nJust download [levelgraph.min.js](build/levelgraph.min.js) and you are done!\n\nAlternatively, you could load levelgraph in your project and bundle using\n[browserify](https://browserify.org/) or [esbuild](https://esbuild.github.io/).\n\n## Usage\n\nThe LevelGraph API remains the same for Node.JS and the browsers, however the\ninitialization change slightly.\n\nInitializing a database is very easy:\n\n```javascript\nvar { Level }  = require(\"level\");\nvar levelgraph = require(\"levelgraph\");\n\n// just use this in the browser with the provided bundle\nvar db = levelgraph(new Level(\"yourdb\"));\n```\n\n### Get and Put\n\nInserting a triple in the database is extremely easy:\n\n```javascript\nvar triple = { subject: \"a\", predicate: \"b\", object: \"c\" };\ndb.put(triple, function(err) {\n  // do something after the triple is inserted\n});\n```\n\nRetrieving it through pattern-matching is extremely easy:\n```javascript\ndb.get({ subject: \"a\" }, function(err, list) {\n  console.log(list);\n});\n```\n\nIt even supports a Stream interface:\n\n```javascript\nvar stream = db.getStream({ predicate: \"b\" });\nstream.on(\"data\", function(data) {\n  console.log(data);\n});\n```\n\n#### Triple Properties\n\nLevelGraph supports adding properties to triples with very little overhead\n(apart from storage costs). It is very easy:\n\n```javascript\nvar triple = { subject: \"a\", predicate: \"b\", object: \"c\", \"someStuff\": 42 };\ndb.put(triple, function() {\n  db.get({ subject: \"a\" }, function(err, list) {\n    console.log(list);\n  });\n});\n```\n\n#### Limit and Offset\n\nIt is possible to implement pagination of get results by using `'offset'` and\n`'limit'`, like so:\n\n```javascript\ndb.get({ subject: \"a\", limit: 4, offset: 2}, function(err, list) {\n  console.log(list);\n});\n```\n\n#### Reverse Order\n\nIt is possible to get results in reverse lexicographical order using the\n`'reverse'` option. This option is only supported by `get()` and `getStream()`\nand not available in `search()`.\n\n```javascript\ndb.get({ predicate: \"b\", reverse: true }, function (err, list) {\n  console.log(list);\n});\n```\n\n#### Updating\n\n__LevelGraph__ does not support in-place update, as there are no constraint in\nthe graph. In order to update a triple, you should first delete it:\n\n```javascript\nvar triple = { subject: \"a\", predicate: \"b\", object: \"c\" };\ndb.put(triple, function(err) {\n  db.del(triple, function(err) {\n    triple.object = 'd';\n    db.put(triple, function(err) {\n      // do something with your update\n    });\n  });\n});\n```\n\n#### Multiple Puts\n\n__LevelGraph__ also supports putting multiple triples:\n\n```javascript\nvar triple1 = { subject: \"a1\", predicate: \"b\", object: \"c\" };\nvar triple2 = { subject: \"a2\", predicate: \"b\", object: \"d\" };\ndb.put([triple1, triple2],  function(err) {\n  // do something after the triples are inserted\n});\n```\n\n### Deleting\n\nDeleting is easy too:\n\n```javascript\nvar triple = { subject: \"a\", predicate: \"b\", object: \"c\" };\ndb.del(triple, function(err) {\n  // do something after the triple is deleted\n});\n```\n\n### Searches\n\n__LevelGraph__ also supports searches:\n\n```javascript\ndb.put([{\n  subject: \"matteo\",\n  predicate: \"friend\",\n  object: \"daniele\"\n}, {\n  subject: \"daniele\",\n  predicate: \"friend\",\n  object: \"matteo\"\n}, {\n  subject: \"daniele\",\n  predicate: \"friend\",\n  object: \"marco\"\n}, {\n  subject: \"lucio\",\n  predicate: \"friend\",\n  object: \"matteo\"\n}, {\n  subject: \"lucio\",\n  predicate: \"friend\",\n  object: \"marco\"\n}, {\n  subject: \"marco\",\n  predicate: \"friend\",\n  object: \"davide\"\n}], function () {\n\n  var stream = db.searchStream([{\n    subject: \"matteo\",\n    predicate: \"friend\",\n    object: db.v(\"x\")\n  }, {\n    subject: db.v(\"x\"),\n    predicate: \"friend\",\n    object: db.v(\"y\")\n  }, {\n    subject: db.v(\"y\"),\n    predicate: \"friend\",\n    object: \"davide\"\n  }]);\n\n  stream.on(\"data\", function(data) {\n    // this will print \"{ x: 'daniele', y: 'marco' }\"\n    console.log(data);\n  });\n});\n```\n\n#### Search Without Streams\n\nIt also supports a similar API without streams:\n\n```javascript\ndb.put([{\n //...\n}], function () {\n\n  db.search([{\n    subject: \"matteo\",\n    predicate: \"friend\",\n    object: db.v(\"x\")\n  }, {\n    subject: db.v(\"x\"),\n    predicate: \"friend\",\n    object: db.v(\"y\")\n  }, {\n    subject: db.v(\"y\"),\n    predicate: \"friend\",\n    object: \"davide\"\n  }], function(err, results) {\n    // this will print \"[{ x: 'daniele', y: 'marco' }]\"\n    console.log(results);\n  });\n});\n```\n\n#### Triple Generation\n\nIt also allows to generate a stream of triples, instead of a solution:\n```javascript\n  db.search([{\n    subject: db.v(\"a\"),\n    predicate: \"friend\",\n    object: db.v(\"x\")\n  }, {\n    subject: db.v(\"x\"),\n    predicate: \"friend\",\n    object: db.v(\"y\")\n  }, {\n    subject: db.v(\"y\"),\n    predicate: \"friend\",\n    object: db.v(\"b\")\n  }], {\n    materialized: {\n      subject: db.v(\"a\"),\n      predicate: \"friend-of-a-friend\",\n      object: db.v(\"b\")\n    }\n  }, function(err, results) {\n    // this will print all the 'friend of a friend triples..'\n    // like so: {\n    //   subject: \"lucio\",\n    //   predicate: \"friend-of-a-friend\",\n    //   object: \"daniele\"\n    // }\n  });\n```\n\n#### Limit and Offset\n\nIt is possible to implement pagination of search results by using `'offset'` and\n`'limit'`, like so:\n\n```javascript\ndb.search([{\n    subject: db.v(\"a\"),\n    predicate: \"friend\",\n    object: db.v(\"x\")\n  }, {\n    subject: db.v(\"x\"),\n    predicate: \"friend\",\n    object: db.v(\"y\")\n  }], { limit: 4, offset: 2 }, function(err, list) {\n\n  console.log(list);\n});\n```\n\n### Filtering\n\n__LevelGraph__ supports filtering of triples when calling `get()` and solutions\nwhen calling `search()`, and streams are supported too.\n\nIt is possible to filter the matching triples during a `get()`:\n\n```javascript\ndb.get({\n    subject: 'matteo'\n  , predicate: 'friend'\n  , filter: function filter(triple) {\n      return triple.object !== 'daniele';\n    }\n}, function process(err, results) {\n  // results will not contain any triples that\n  // have 'daniele' as object\n});\n```\n\nMoreover, it is possible to filter the triples during a `search()`\n\n```javascript\ndb.search({\n    subject: 'matteo'\n  , predicate: 'friend'\n  , object: db.v('x')\n  , filter: function filter(triple) {\n      return triple.object !== 'daniele';\n    }\n}, function process(err, solutions) {\n  // results will not contain any solutions that\n  // have { x: 'daniele' }\n});\n```\n\nFinally, __LevelGraph__ supports filtering full solutions:\n\n```javascript\ndb.search({\n    subject: 'matteo'\n  , predicate: 'friend'\n  , object: db.v('x')\n}, {\n    filter: function filter(solution, callback) {\n      if (solution.x !== 'daniele') {\n        // confirm the solution\n        callback(null, solution);\n      } else {\n        // refute the solution\n        callback(null);\n      }\n    }\n}, function process(err, solutions) {\n  // results will not contain any solutions that\n  // have { x: 'daniele' }\n});\n```\n\nThanks to solultion filtering, it is possible to implement a negation:\n\n```javascript\ndb.search({\n    subject: 'matteo'\n  , predicate: 'friend'\n  , object: db.v('x')\n}, {\n    filter: function filter(solution, callback) {\n      db.get({\n          subject: solution.x\n        , predicate: 'friend'\n        , object: 'marco'\n      }, function (err, results) {\n        if (err) {\n          callback(err);\n          return;\n        }\n        if (results.length \u003e 0) {\n          // confirm the solution\n          callback(null, solution);\n        } else {\n          // refute the solution\n          callback();\n        }\n      });\n    }\n}, function process(err, solutions) {\n  // results will not contain any solutions that\n  // do not satisfy the filter\n});\n```\n\nThe heavier method is filtering solutions, so we recommend filtering the\ntriples whenever possible.\n\n### Putting and Deleting through Streams\n\nIt is also possible to `put` or `del` triples from the store using a `Stream2`\ninterface:\n\n```javascript\nvar t1 = { subject: \"a\", predicate: \"b\", object: \"c\" };\nvar t2 = { subject: \"a\", predicate: \"b\", object: \"d\" };\nvar stream = db.putStream();\n\nstream.write(t1);\nstream.end(t2);\n\nstream.on(\"close\", function() {\n  // do something, the writes are done\n});\n```\n\n### Generate batch operations\n\nYou can also generate a `put` and `del` batch, so you can manage the batching\nyourself:\n\n```javascript\nvar triple = { subject: \"a\", predicate: \"b\", object: \"c\" };\n\n// Produces a batch of put operations\nvar putBatch = db.generateBatch(triple);\n\n// Produces a batch of del operations\nvar delBatch = db.generateBatch(triple, 'del');\n```\n\n### Generate level-read-stream query\n\nReturn the leveldb query for the given triple.\n\n```javascript\nvar { ValueStream } = require(\"level-read-stream\");\nvar query           = db.createQuery({ predicate: \"b\"});\n\nvar stream = new ValueStream(leveldb, query);\n```\n\n## Navigator API\n\nThe Navigator API is a fluent API for LevelGraph, loosely inspired by\n[Gremlin](http://markorodriguez.com/2011/06/15/graph-pattern-matching-with-gremlin-1-1/)\nIt allows to specify how to search our graph in a much more compact way and\nnavigate between vertexes.\n\nHere is an example, using the same dataset as before:\n\n```javascript\ndb.nav(\"matteo\").archIn(\"friend\").archOut(\"friend\").\n  solutions(function(err, results) {\n  // prints:\n  // [ { x0: 'daniele', x1: 'marco' },\n  //   { x0: 'daniele', x1: 'matteo' },\n  //   { x0: 'lucio', x1: 'marco' },\n  //   { x0: 'lucio', x1: 'matteo' } ]\n  console.log(results);\n});\n```\n\nThe above example match the same triples of:\n\n```javascript\ndb.search([{\n  subject: db.v(\"x0\"),\n  predicate: 'friend',\n  object: 'matteo'\n}, {\n  subject: db.v(\"x0\"),\n  predicate: 'friend',\n  object: db.v(\"x1\")\n}], function(err, results) {\n  // prints:\n  // [ { x0: 'daniele', x1: 'marco'  },\n  //   { x0: 'daniele', x1: 'matteo' },\n  //   { x0: 'lucio'  , x1: 'marco'  },\n  //   { x0: 'lucio'  , x1: 'matteo' } ]\n  console.log(results);\n});\n```\n\nIt allows to see just the last reached vertex:\n\n```javascript\n    db.nav(\"matteo\").archIn(\"friend\").archOut(\"friend\").\n      values(function(err, results) {\n      // prints [ 'marco', 'matteo' ]\n      console.log(results);\n    });\n```\n\nVariable names can also be specified, like so:\n\n```javascript\ndb.nav(\"marco\").archIn(\"friend\").as(\"a\").archOut(\"friend\").archOut(\"friend\").as(\"a\").\n      solutions(function(err, friends) {\n\n  console.log(friends); // will print [{ a: \"daniele\" }]\n});\n```\n\nVariables can also be bound to a specific value, like so:\n\n```javascript\ndb.nav(\"matteo\").archIn(\"friend\").bind(\"lucio\").archOut(\"friend\").bind(\"marco\").\n      values(function(err, friends) {\n  console.log(friends); // this will print ['marco']\n});\n```\n\nA materialized search can also be produced, like so:\n\n```javascript\ndb.nav(\"matteo\").archOut(\"friend\").bind(\"lucio\").archOut(\"friend\").bind(\"marco\").\n      triples({:\n        materialized: {\n        subject: db.v(\"a\"),\n        predicate: \"friend-of-a-friend\",\n        object: db.v(\"b\")\n      }\n    }, function(err, results) {\n\n  // this will return all the 'friend of a friend triples..'\n  // like so: {\n  //   subject: \"lucio\",\n  //   predicate: \"friend-of-a-friend\",\n  //   object: \"daniele\"\n  // }\n\n  console.log(results);\n});\n```\n\nIt is also possible to change the current vertex:\n\n```javascript\ndb.nav(\"marco\").archIn(\"friend\").as(\"a\").go(\"matteo\").archOut(\"friend\").as(\"b\").\n      solutions(function(err, solutions) {\n\n   //  solutions is: [{\n   //    a: \"daniele\",\n   //    b: \"daniele\"\n   //   }, {\n   //     a: \"lucio\",\n   //     b: \"daniele\"\n   //   }]\n\n});\n```\n\n## Plugin integration\n\nLevelGraph allows to leverage the full power of all [level][gh:level/level]\nplugins.\n\nInitializing a database with plugin support is very easy:\n\n```javascript\nvar { Level }  = require(\"level\");\nvar levelgraph = require(\"levelgraph\");\nvar db         = levelgraph(new Level(\"yourdb\"));\n```\n\n### Usage with sublevels\n\nAn extremely powerful usage of LevelGraph is to partition your LevelDB using\nsublevels, somewhat resembling tables in a relational database.\n\n```javascript\nvar { Level }  = require(\"level\");\nvar levelgraph = require(\"levelgraph\");\nvar db         = new Level(\"yourdb\");\nvar graph      = levelgraph(db.sublevel('graph'));\n```\n\n## Browser usage\n\nYou can use [browserify](https://browserify.org/) or\n[esbuild](https://esbuild.github.io/) to bundle your module and all it's\ndependencies, including levelgraph, into a single script-tag friendly js file\nfor use in webpages. For the convenience of people unfamiliar with browserify or\nesbuild, a pre-bundled version of levelgraph is included in the build folder in\nthis repository.\n\nSimply `require(\"levelgraph\")` in your browser modules:\n\n```javascript\nvar levelgraph = require(\"levelgraph\");\nvar { Level }  = require(\"level\");\n\nvar db = levelgraph(new Level(\"yourdb\"));\n```\n\n### Testling\n\nFollow the [Testling install instructions](https://github.com/substack/testling#install) and run `testling` in the levelgraph directory to run the test suite against a headless browser using level.js\n\n## RDF support\n\n__LevelGraph__ does not support out of the box loading serialized RDF or storing it. Such functionality is provided by extensions:\n* [LevelGraph-N3](https://github.com/levelgraph/levelgraph-n3) - __N3/Turtle__\n* [LevelGraph-JSONLD](https://github.com/levelgraph/levelgraph-jsonld) - __JSON-LD__\n\n## Extensions\n\nYou can use multiple extensions at the same time. Just check if one depends on another one\nto nest them in correct order! *(LevelGraph-N3 and LevelGraph-JSONLD are\nindependent)*\n\n```javascript\nvar lg       = require('levelgraph');\nvar lgN3     = require('levelgraph-n3');\nvar lgJSONLD = require('levelgraph-jsonld');\n\nvar db = lgJSONLD(lgN3(lg(\"yourdb\")));\n// gives same result as\nvar db = lgN3(lgJSONLD(lg(\"yourdb\")));\n```\n\n## TODO\n\nThere are plenty of things that this library is missing.\nIf you feel you want a feature added, just do it and __submit a\npull-request__.\n\nHere are some ideas:\n\n* [x] Return the matching triples in the search results.\n* [x] Support for Query Planning in search.\n* [x] Added a Sort-Join algorithm.\n* [ ] Add more database operators (grouping, filtering).\n* [x] Browser support\n  [#10](https://github.com/levelgraph/levelgraph/issues/10)\n* [ ] Live searches\n  [#3](https://github.com/levelgraph/node-levelgraph/issues/3)\n* Extensions\n  * [ ] RDFa\n  * [ ] RDF/XML\n  * [ ] Microdata\n\n## Contributing\n\nLevelGraph is an **OPEN Open Source Project**. This means that:\n\n\u003e Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.\n\nSee the [CONTRIBUTING.md](https://github.com/levelgraph/levelgraph/blob/master/CONTRIBUTING.md) file for more details.\n\n## Credits\n\n*LevelGraph builds on the excellent work on both the level community and the\nLevelDB and Snappy teams from Google and additional contributors. LevelDB and\nSnappy are both issued under the\n[New BSD Licence](http://opensource.org/licenses/BSD-3-Clause).*\n\n## Contributors\n\nLevelGraph is only possible due to the excellent work of the following\ncontributors:\n\n| Name           | Github                          | Twitter/X                         |\n|:-------------- | ------------------------------- | --------------------------------- |\n| Matteo Collina | [mcollina][gh:mcollina]         | [@matteocollina][x:matteocollina] |\n| Jeremy Taylor  | [jez0990][gh:jez0990]           |                                   |\n| Elf Pavlik     | [elf-pavlik][gh:elf-pavlik]     | [@elfpavlik][x:elfpavlik]         |\n| Riceball LEE   | [snowyu][gh:snowyu]             |                                   |\n| Brian Woodward | [doowb][gh:doowb]               | [@doowb][x:doowb]                 |\n| Leon Chen      | [transcranial][gh:transcranial] | [@transcranial][x:transcranial]   |\n| Yersa Nordman  | [finwo][gh:finwo]               |                                   |\n\n## LICENSE - \"MIT License\"\n\nCopyright (c) 2013-2024 Matteo Collina and LevelGraph Contributors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n\n[http:playground]: http://wileylabs.github.io/levelgraph-playground\n[gh:google/leveldb]: https://github.com/google/leveldb\n[gh:level/level]: https://github.com/level/level\n[gh:doowb]: https://github.com/doowb\n[gh:elf-pavlik]: https://github.com/elf-pavlik\n[gh:finwo]: https://github.com/finwo\n[gh:jez0990]: https://github.com/jez0990\n[gh:mcollina]: https://github.com/mcollina\n[gh:snowyu]: https://github.com/snowyu\n[gh:transcranial]: https://github.com/transcranial\n[x:doowb]: https://twitter.com/doowb\n[x:elfpavlik]: https://twitter.com/elfpavlik\n[x:matteocollina]: https://twitter.com/matteocollina\n[x:transcranial]: https://twitter.com/transcranial\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevelgraph%2Flevelgraph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flevelgraph%2Flevelgraph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevelgraph%2Flevelgraph/lists"}