-
Notifications
You must be signed in to change notification settings - Fork 341
WIP: Continue work to support new graphql-js
#133
Conversation
…ibe from `graphql-js` with support for AsyncIterable execute
@dotansimha awesome!! also adding @NeoPhi for the review |
src/utils/promise-to-iterable.ts
Outdated
|
||
return promise | ||
.then(value => ({ value, done: false })) | ||
.catch(error => this.throw(error)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems pretty strange - are you sure this is doing what you expect? The return()
and throw()
API on AsyncIterator are intended to be called by the consumer, not internally.
Since an AsyncIterator yields Promises, I would expect that it would simply return the wrapped promise once.
I would expect:
import { $$asyncIterator } from 'iterall';
export function createIterableFromPromise<T>(promise: Promise<T>): AsyncIterator<T> {
let isComplete = false;
return {
next() {
if (!isComplete) {
isComplete = true;
return promise.then(value => { value, done: false });
}
return Promise.resolve({ value: undefined, done: true });
},
return() {
isComplete = true;
return Promise.resolve({ value: undefined, done: true });
},
throw(e: Error) {
isComplete = true;
return Promise.reject(e);
},
[$$asyncIterator]() {
return this;
},
};
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense. I will change it and added unit tests
src/utils/rejection-iterable.ts
Outdated
return this.throw(error); | ||
}, | ||
return() { | ||
return this.throw(error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be return Promise.resolve({ done: true, value: undefined })
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
src/utils/rejection-iterable.ts
Outdated
export const createRejectionIterable = (error: Error): AsyncIterator<any> => { | ||
return { | ||
next() { | ||
return this.throw(error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit confusing to have this call itself - perhaps just return Promise.reject(error)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed! Thanks @leebyron
rootValue?: any, | ||
contextValue?: any, | ||
variableValues?: { [key: string]: any }, | ||
operationName?: string) => Promise<ExecutionResult> | AsyncIterator<ExecutionResult>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is attempting to model graphql-js's execute function, that always returns a Promise. Only subscribe returns an AsyncIterator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leebyron
Yeah, the original execute
of graphql-js
returns a Promise
.
I talked to @DxCx and we think that if we allow execute
to return AsyncIterator
in this package, we can also support Hagai's implementation for reactive graphql (#108 (comment))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leebyron this is done to allow execution of reactive directives as well (@live
) for example, if one uses vanilla graphQL he will get the standard execute..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leebyron I wanted to make sure that anyone who uses this package and expects graohql-js's execute will get exactly that. It almost won't effect you and the docs will be focused on that. But at the same time, if you want to use a separate, experimental package, it won't block you from it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds great, just wanted to make sure it wasn't a mistake :)
src/server.ts
Outdated
} | ||
} | ||
forAwaitEach( | ||
createAsyncIterator<ExecutionResult>(executionIterable as any) as any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why so many casting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed!
export function createIterableFromPromise<T>(promise: Promise<T>): AsyncIterator<T> { | ||
let isResolved = false; | ||
|
||
return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dotansimha since promise have only 1 result anyway,
shouldn't you return value, done: true on next()
and use return as teardown function (which doesn't do anything since promises are not cancelable)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return
of AsyncIterator
should not return a value, only done=false
.
If setting done=true
while the Promise is resolved, the value ignored and then the iterator is done.
This is all looking great. |
* Pass meteor login token in Authorization header * Use passHeader method * update changelog * Fix lint rules
Continue #108
As discussed in the previous PR:
Observable
implementation, and replace it withAsyncIterator
, removingObservable
code completely.execute
returnPromise
, along withexecute
that returnsAsyncIterator
to support reactive data sources.SubscriptionManager
toAsyncIterator
to support oldgraphql-subscriptions
API.graphql-js
withAsyncIterator
upgradeReq
(changed since ws@3.0.0).Still WIP:
subscribe
executor)@Urigo @DxCx @mistic
TODO: