Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ node_modules
.env
.npmignore
coverage
.npmrc
.npmrc
.tmp
test/data.json
75 changes: 42 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,51 @@ Lightweight driven query language

Here's the first example to get you started. [Try it here](https://codepen.io/syarul/pen/xxmLMVP)—no build step required!

## Comparison to graphQL
## Features

| Feature | GraphQL | reQurse |
| --------------- | --------------------------------------------------------- | ----------------------------------------------------- |
| Query Syntax | ✅ Declarative queries as strings (SDL) | ✅ JSON object-based queries |
| Schema & Typing | ✅ Strongly typed schemas | ❌ No type enforcement (support GraphQL schema) |
| Resolvers | ✅ Defined server-side logic for each field | ✅ `methods` functions resolve keys |
| API Federation | ✅ Built-in with tools like Apollo Federation | ✅ Can compose multiple `rq()` into one federated API |
| Use Cases | ✅ Full APIs, strongly validated, efficient data fetching | ✅ Full APIs, Lightweight, data orchestration |
| Runtime | ✅ Client-server over HTTP | ✅ Client-server over HTTP/In-process library calls |
| Complexity | ❌ Requires schema + resolvers + server setup | ✅ Very light; no server setup |
| Feature | reQurse |
| --------------- | ----------------------------------------------------------------- |
| Query Syntax | ✅ JSON object-based queries |
| Schema & Typing | ❌ No type enforcement (support GraphQL schema) |
| Resolvers | ✅ `methods` functions resolve keys |
| API Federation | ✅ Can compose multiple instance of `rq()` into one federated API |
| Caching | ✅ Implemented (pass in options) |
| Use Cases | ✅ Full APIs, Lightweight, data orchestration |
| Runtime | ✅ Client-server over HTTP/In-process library calls |
| Complexity | ✅ Very light; no server setup |

As example using the [RandomDie](https://www.graphql-js.org/docs/object-types/) sample
As direct comparison with graphQL using the [RandomDie](https://www.graphql-js.org/docs/object-types/) sample

```js
// graphQL
const RandomDie = new GraphQLObjectType({
name: "RandomDie",
fields: {
numSides: {
type: new GraphQLNonNull(GraphQLInt),
resolve: (die) => die.numSides,
},
rollOnce: {
type: new GraphQLNonNull(GraphQLInt),
resolve: (die) => 1 + Math.floor(Math.random() * die.numSides),
},
roll: {
type: new GraphQLList(GraphQLInt),
args: {
numRolls: { type: new GraphQLNonNull(GraphQLInt) },
fields: () => {
const fields = {
numSides: {
type: new GraphQLNonNull(GraphQLInt),
resolve: (die) => die.numSides,
},
resolve: (die, { numRolls }) => {
const output = [];
for (let i = 0; i < numRolls; i++) {
output.push(1 + Math.floor(Math.random() * die.numSides));
}
return output;
rollOnce: {
type: new GraphQLNonNull(GraphQLInt),
resolve: (die) => 1 + Math.floor(Math.random() * die.numSides),
},
},
roll: {
type: new GraphQLList(GraphQLInt),
args: {
numRolls: { type: new GraphQLNonNull(GraphQLInt) },
},
resolve: (die, { numRolls }, ctx, info) => {
const rollOnceResolver = fields.rollOnce.resolve;
const output = [];
for (let i = 0; i < numRolls; i++) {
output.push(rollOnceResolver(die, {}, ctx, info));
}
return output;
},
},
};
return fields;
},
});

Expand Down Expand Up @@ -117,7 +122,7 @@ class RandomDie extends RqExtender {
for (let i = 0; i < numRolls; i++) {
// reuse rollOnce here
// context is using rq context
// {
// {
// query, // combine queryResult
// computes, // computed fields
// }
Expand Down Expand Up @@ -184,12 +189,16 @@ A basic usage of reQurse.
```javascript
import rq from "requrse";

rq(query, { methods, config });
rq(query, { methods, config, dataUrl, rootKey, cache, cacheDir });
```

- **query**: _(object)_ **_required_** JSON like query.
- **methods**: _(object)_ **_required_** define methods/computed fields that exist in the query.
- **config**: _(object)_ **_optional_** extend and added parameterize control over methods.
- **dataUrl**: _(string)_ **_optional_** resolve result to data url path.
- **rootKey**: _(string)_ **_optional_** graphQL root key if using graphQL query, default to 'data' if not given.
- **cache**: _(number)_ **_optional_** cache result in second(s).
- **cacheDir**: _(string)_ **_optional_** custom caching directory default is '.tmp'.

```js
await rq(
Expand Down
255 changes: 0 additions & 255 deletions README_OLD.md

This file was deleted.

9 changes: 7 additions & 2 deletions libs/arrayToObject.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const checkEntry = require("./checkEntry.cjs");
* @returns {Boolean}
*/
const checkUniq = (arr) => {
const check = arr.map((i) => i && i?.[0]).filter((f) => f !== undefined);
const check = arr
.map((/** @type {any[]} */ i) => i && i?.[0])
.filter((/** @type {any} */ f) => f !== undefined);
return check.length === [...new Set(check)].length;
};

Expand All @@ -17,7 +19,10 @@ const checkUniq = (arr) => {
* @returns
*/
const reducer = (unique) => {
return (acc, item) => {
return (
/** @type {Record<String, any>} */ acc,
/** @type {any[]} */ item,
) => {
if (item && item[0]) {
if (unique) {
acc[item[0]] = arrayToObject(item[1]);
Expand Down
Loading