cult-of-coders / apollo-live-server Goto Github PK
View Code? Open in Web Editor NEWA set of tools to enable reactivity in Apollo alongside Meteor
License: MIT License
A set of tools to enable reactivity in Apollo alongside Meteor
License: MIT License
If i'm requesting:
query {
user {
billingProfile { status }
}
}
and a subscription with the same pattern.
The subscription needs to be intelligent enough to detect that it uses links.
apollo-live-server is kinda constructed around Meteor either way. But with this approach we're gonna introduce a dependency on Grapher. Which I think is ok, better to be in one ecosystem than deal with 4 diff packages.
So the logic would be that we don't have reactivity for underlying data, we have only for the parent.
This means that added() events should trigger a graph run for that item.
And changed() needs to detect whether a link storage field has changed that is related to a certain sub-collection so we can requery it.
This need to happen automatically without any other configuration such as hooking into resolve() and applying it based on the changed events.
astToFields({ metadata: { field1, field2 })
should return { "metadata.field1": 1, "metadata.field2" : 1 }
.
Right now it returns { metadata : { field1: 1, field2 :1 }
and this is trowing the error "Object in field".
Hi guys,
After hours of trying pretty much everything I could come up with, I gave up for now - I can't get GraphQL subscriptions to work reliably. Randomly it kinda works, most of the time it does not.
Following setup:
What do I want to achieve (for now): Just load some items from a collection with a limit and skip (pagination). If something changes in the currently loaded (e.g. 20) items, the subscription should update the items - obviously. ๐
some code:
SERVER:
load({
typeDefs: `
type Query {
lists(listId: ID, limit: Int, skip: Int): [List]
}
type List @mongo(name: "listsbody") {
_id: ID
itemId: ID,
listItem: ListItem @link(field: "itemId")
list_id: ID
row_id: Int
}
type ListItem @mongo(name: "items") {
_id: ID
created_at: String
supplier_id: ID,
item_name: String
}
type Subscription {
lists(listId: ID, limit: Int, skip: Int): SubscriptionEvent
}
`,
// https://github.com/cult-of-coders/grapher/blob/master/docs/graphql.md
resolvers: {
Query: {
lists(_, {listId, limit, skip}, { db }, ast) {
return db.listsbody.astToQuery(ast, {
$filters: { list_id: listId },
$options: { limit, skip, sort: { row_id: 1 } }
}).fetch();
},
},
List: {
listItem(parent, args, { db }, ast) {
return parent.listItem;
},
},
Subscription: {
lists: {
resolve: ({event, doc}, args, { db }, ast) => {
if(event === Event.CHANGED) {
Object.assign(doc, {
listItem: db.items.findOne({ _id: doc.itemId })
});
// this is very infrequently called, for some reason this is NOT called everytime I change something in the DB, sometimes it is but after a verly large delay of many seconds.
}
console.log('resolve() doc:', doc);
return {event, doc};
},
subscribe(_, {listId, limit, skip}, { db }, ast) {
console.log('params', {listId, limit, skip});
const observer = db.listsbody.find({ list_id: listId }, { limit, skip, sort: { row_id: 1 } });
console.log('FETCH!', observer.fetch()); // again, this is sometimes called, sometimes it is not, sometimes with a very big delay ...
return asyncIterator(observer);
}
}
}
},
});
initialize();
Any my Client:
const GET_LIST = gql`
query($listId: ID, $limit: Int, $skip: Int) {
lists(listId: $listId, limit: $limit, skip: $skip) {
_id
list_id
row_id
itemId
}
}
`
const SUBSCRIBE_LIST = gql`
subscription($listId: ID, $limit: Int, $skip: Int) {
lists(listId: $listId, limit: $limit, skip: $skip) {
event
doc
}
}
`
class Test extends React.Component {
constructor() {
super();
this.state = {
page: 1
}
}
prevPage = () => {
this.setState({ page: this.state.page - 1 });
}
nextPage = () => {
this.setState({ page: this.state.page + 1 });
}
// https://www.apollographql.com/docs/react/v2.5/api/react-apollo/#optionsfetchpolicy
render(){
const {page} = this.state;
const variables = {listId: "pshLYD4optX3yj9Pw", limit: 20, skip: (page-1)*20};
console.log('variables', variables);
return (
<Fragment>
<ul>
<ReactiveQuery
query={GET_LIST}
variables={variables}
subscription={SUBSCRIBE_LIST}
fetchPolicy='no-cache'
>
{
({ loading, error, data }) => {
if(loading) return <h2>loading</h2>
if(error) {
console.log(error)
return <h2>Error</h2>
}
let { lists } = data;
console.log(lists);
lists = lists.map(list => (
<li key={list._id}>
{list._id} - {list.itemId} - { list.listItem && list.listItem.item_name ||ย 'N/A' } : {list.row_id}
</li>
));
// this is NOT working at all - no reloads, no updates, no nothing when I change anything in the DB - basically the subscription is dead alltogether
return lists
}
}
</ReactiveQuery>
</ul>
<br />
Seite {this.state.page}
<button onClick={this.prevPage}><</button>
<button onClick={this.nextPage}>></button>
</Fragment>
)
}
}
I really really hope someone can help. I would be glad to even pay for maybe 30min - 1h of your time. I am pretty desperate right now, as I think my setup is pretty basic and it is not working at all.
Thanks a bunch for any help in advance! Cheers, Patrick
I noticed that this package uses the default PuBSub which I believe is not recommended for production. Is there a facility to specify a different PubSub, or is this handled somewhere else in the cult-of-coders/apollo package?
W20180326-16:27:07.173(3)? (STDERR) (node:48927) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 removeListener listenersadded. Use emitter.setMaxListeners() to increase limit
type Subscription {
notificationsCount: Int
}
Subscription: {
notificationsCount: {
resolve: payload => payload,
subscribe(_, args, { db }, ast) {
return asyncIteratorInterval(() => return db.notifications.find().count(), 1000);
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.