Skip to content

Commit

Permalink
Subscriptions are added with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mrspartak committed May 18, 2020
1 parent d2d91a3 commit 771d97c
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 6 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,35 @@ result = {
}
}
*/


//subscription
let unsub = om.subscribe({
user: {
where: {
is_live: {
_eq: true
}
},
limit: 10,
order_by: {
rating: 'desc'
}
},
pets: {
where: {
type: {
_eq: 'dog'
}
},
fields: `
id
name
`
}
}, ([err, data]) => {
//so data will come in the same format as the query
})
```

The only control you have is fragments. So this library provides base fragments with all table fields without relations. Of course you need them, so you have many ways to do so.
Expand Down
54 changes: 53 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
}
},
"dependencies": {
"axios": "^0.19.2"
"axios": "^0.19.2",
"subscriptions-transport-ws": "^0.9.16",
"ws": "^7.3.0"
},
"devDependencies": {
"ava": "^3.8.2",
Expand Down
72 changes: 72 additions & 0 deletions src/hasura/wsgql.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const __ = require('../utils/helpers');
const ws = require('ws');
const { SubscriptionClient } = require('subscriptions-transport-ws');

class WsGql {
constructor(params) {
const defaultParams = {
wsUrl: null,
adminSecret: null,
reconnect: true,
lazy: true,
};
this.params = Object.assign({}, defaultParams, params);

this.client = new SubscriptionClient(
this.params.wsUrl,
{
reconnect: this.params.reconnect,
lazy: this.params.lazy,
connectionParams: {
headers: {
'X-Hasura-Role': 'admin',
'x-hasura-admin-secret': this.params.adminSecret,
},
},
},
ws,
);

/* this.client.on('connected', (data) => {
console.log('client connected', data)
})
this.client.on('reconnected', (data) => {
console.log('client reconnected', data)
})
this.client.on('connecting', (data) => {
console.log('client connecting', data)
})
this.client.on('reconnecting', (data) => {
console.log('client reconnecting', data)
})
this.client.on('disconnected', (data) => {
console.log('client disconnected', data)
})
this.client.on('error', (data) => {
console.log('client error', data.message)
}) */
}

async run({ query, variables, callback, settings } = {}) {
let { subscribe } = this.client.request({
query,
variables,
});

let { unsubscribe } = subscribe({
next(data) {
callback([null, settings.flatOne ? data.data[settings.flatOne] : data.data]);
},
error(err) {
callback([err]);
},
complete() {
//console.log('SUB COMPLETED')
},
});

return unsubscribe;
}
}

module.exports = WsGql;
30 changes: 27 additions & 3 deletions src/orm/hasura.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const Sql = require('../hasura/sql');
const Gql = require('../hasura/gql');
const WsGql = require('../hasura/wsgql');
const Table = require('./table');
const __ = require('../utils/helpers');

Expand All @@ -8,6 +9,7 @@ class Hasura {
const defaultParams = {
graphqlUrl: null,
queryUrl: null,
wsUrl: null,
adminSecret: null,
};
this.params = Object.assign({}, defaultParams, params);
Expand All @@ -18,9 +20,11 @@ class Hasura {
if (!this.params.adminSecret) throw new Error('adminSecret is required');

if (!this.params.queryUrl) this.params.queryUrl = this.params.graphqlUrl.replace('/v1/graphql', '/v1/query');
if (!this.params.wsUrl) this.params.wsUrl = this.params.graphqlUrl.replace('http://', 'ws://').replace('https://', 'wss://');

this.$sql = new Sql(this.params);
this.$gql = new Gql(this.params);
this.$ws = new WsGql(this.params);

this.INITIATED = false;
this.tables = {};
Expand Down Expand Up @@ -132,7 +136,7 @@ class Hasura {
return [null, response];
}

buildQuery(params) {
buildQuery(params, queryType = 'query') {
let tables = Object.keys(params);

let queryName = [],
Expand All @@ -143,9 +147,10 @@ class Hasura {

let builds = [];
tables.forEach((tableName) => {
let built = this.tables[tableName].buildQuery({
let built = this.table(tableName).buildQuery({
...params[tableName],
tableName,
queryType,
});

queryName.push(built.query.name);
Expand All @@ -157,7 +162,7 @@ class Hasura {

let query = `
${Object.values(queryFragments).join('\n')}
query ${queryName.join('_')} ${queryVariables.length ? '(' + queryVariables.join(', ') + ')' : ''} {
${queryType} ${queryName.join('_')} ${queryVariables.length ? '(' + queryVariables.join(', ') + ')' : ''} {
${queryFields.join('\n')}
}
`;
Expand Down Expand Up @@ -259,6 +264,25 @@ class Hasura {

return [query, variables, queryFlatSetting];
}

subscribe(params, callback, { flatOne = true } = {}) {
try {
var [query, variables] = this.buildQuery(params, 'subscription');
} catch (err) {
return [err];
}

var unsub = this.$ws.run({
query,
variables,
callback,
settings: {
flatOne: Object.keys(params).length == 1 && flatOne ? Object.keys(params)[0] : false,
},
});

return unsub; //unsubscribe
}
}

module.exports = Hasura;
4 changes: 3 additions & 1 deletion src/orm/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,11 @@ class Table {
}
});

//building for query or subscription
let queryLiteral = params.queryType == 'query' ? 'Q' : 'S';
return {
query: {
name: `Q${this.params.name}`,
name: `${queryLiteral}_${this.params.name}`,
variables: query_variables,
fields: `
${this.params.name} ${query_field_variables.length ? '(' + query_field_variables.join(', ') + ')' : ''} {
Expand Down
Loading

0 comments on commit 771d97c

Please sign in to comment.