Skip to content

get defer/stream from graphql-js #4796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Nov 1, 2022
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
6 changes: 6 additions & 0 deletions .changeset/@graphql-tools_executor-4796-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@graphql-tools/executor': patch
---
dependencies updates:
- Added dependency [`@repeaterjs/[email protected]` ↗︎](https://www.npmjs.com/package/@repeaterjs/repeater/v/3.0.4) (to `dependencies`)
- Added dependency [`[email protected]` ↗︎](https://www.npmjs.com/package/value-or-promise/v/1.0.1) (to `dependencies`)
5 changes: 5 additions & 0 deletions .changeset/chatty-worms-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/utils': minor
---

add `@defer` directive
5 changes: 5 additions & 0 deletions .changeset/quick-clocks-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/executor': patch
---

get defer stream from graphql-js
5 changes: 5 additions & 0 deletions .changeset/spotty-maps-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/utils': minor
---

export collect field helpers
5 changes: 5 additions & 0 deletions .changeset/spotty-suns-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-tools/utils': minor
---

add `@stream` directive
7 changes: 7 additions & 0 deletions .changeset/warm-bags-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-tools/utils': major
'@graphql-tools/delegate': patch
'@graphql-tools/stitch': patch
---

update `collectFields` to support collecting deffered values
8 changes: 7 additions & 1 deletion packages/batch-delegate/tests/basic.example.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { execute } from '@graphql-tools/executor';
import { execute, isIncrementalResult } from '@graphql-tools/executor';
import { OperationTypeNode, parse } from 'graphql';

import { makeExecutableSchema } from '@graphql-tools/schema';
Expand Down Expand Up @@ -89,6 +89,9 @@ describe('batch delegation within basic stitching example', () => {
const result = await execute({ schema: stitchedSchema, document: parse(query) });

expect(numCalls).toEqual(1);

if (isIncrementalResult(result)) throw Error('result is incremental');

expect(result.errors).toBeUndefined();
const chirps: any = result.data!['trendingChirps'];
expect(chirps[0].chirpedAtUser.email).not.toBe(null);
Expand Down Expand Up @@ -182,6 +185,9 @@ describe('batch delegation within basic stitching example', () => {

const result = await execute({ schema: stitchedSchema, document: parse(query) });
expect(numCalls).toEqual(1);

if (isIncrementalResult(result)) throw Error('result is incremental');

expect(result.data).toEqual({
users: [
{
Expand Down
3 changes: 2 additions & 1 deletion packages/batch-delegate/tests/withTransforms.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { execute } from '@graphql-tools/executor';
import { execute, isIncrementalResult } from '@graphql-tools/executor';
import { GraphQLList, GraphQLObjectType, Kind, OperationTypeNode, parse } from 'graphql';

import { makeExecutableSchema } from '@graphql-tools/schema';
Expand Down Expand Up @@ -121,6 +121,7 @@ describe('works with complex transforms', () => {
`;

const result = await execute({ schema: stitchedSchema, document: parse(query) });
if (isIncrementalResult(result)) throw Error('result is incremental');

expect(result.errors).toBeUndefined();
expect(result.data).toEqual({
Expand Down
4 changes: 2 additions & 2 deletions packages/batch-execute/tests/batchExecute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { parse, print, OperationDefinitionNode, validate } from 'graphql';
import { makeExecutableSchema } from '@graphql-tools/schema';
import { createBatchingExecutor } from '@graphql-tools/batch-execute';
import { ExecutionResult, Executor } from '@graphql-tools/utils';
import { execute } from '@graphql-tools/executor';
import { normalizedExecutor } from '@graphql-tools/executor';

describe('batch execution', () => {
let executorCalls = 0;
Expand Down Expand Up @@ -41,7 +41,7 @@ describe('batch execution', () => {
if (errors.length > 0) {
return { errors };
}
return execute({
return normalizedExecutor({
schema,
document,
variableValues: executorVariables,
Expand Down
11 changes: 3 additions & 8 deletions packages/delegate/src/delegateToSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { Subschema } from './Subschema.js';
import { createRequest, getDelegatingOperation } from './createRequest.js';
import { Transformer } from './Transformer.js';
import { applySchemaTransforms } from './applySchemaTransforms.js';
import { ExecutionArgs, execute, subscribe } from '@graphql-tools/executor';
import { normalizedExecutor } from '@graphql-tools/executor';

export function delegateToSchema<
TContext extends Record<string, any> = Record<string, any>,
Expand Down Expand Up @@ -219,18 +219,13 @@ function getExecutor<TContext extends Record<string, any>>(

export const createDefaultExecutor = memoize1(function createDefaultExecutor(schema: GraphQLSchema): Executor {
return function defaultExecutor(request: ExecutionRequest) {
const executionArgs: ExecutionArgs = {
return normalizedExecutor({
schema,
document: request.document,
rootValue: request.rootValue,
contextValue: request.context,
variableValues: request.variables,
operationName: request.operationName,
};
const operationType = request.operationType || getOperationASTFromRequest(request).operation;
if (operationType === 'subscription') {
return subscribe(executionArgs);
}
return execute(executionArgs);
});
};
});
12 changes: 2 additions & 10 deletions packages/delegate/src/mergeFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,9 @@ async function executeDelegationStage(
source = error;
}
if (source instanceof Error || source == null) {
const fieldNodeResponseKeyMap = collectFields(
schema,
EMPTY_OBJECT,
EMPTY_OBJECT,
type,
selectionSet,
new Map(),
new Set()
);
const { fields } = collectFields(schema, EMPTY_OBJECT, EMPTY_OBJECT, type, selectionSet);
const nullResult = {};
for (const [responseKey, fieldNodes] of fieldNodeResponseKeyMap) {
for (const [responseKey, fieldNodes] of fields) {
const combinedPath = [...path, responseKey];
if (source instanceof GraphQLError) {
nullResult[responseKey] = relocatedError(source, combinedPath);
Expand Down
4 changes: 3 additions & 1 deletion packages/executor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
"definition": "dist/typings/index.d.ts"
},
"dependencies": {
"@repeaterjs/repeater": "3.0.4",
"@graphql-tools/utils": "8.13.1",
"@graphql-typed-document-node/core": "3.1.1"
"@graphql-typed-document-node/core": "3.1.1",
"value-or-promise": "1.0.1"
},
"devDependencies": {
"graphql": "^16.6.0",
Expand Down
22 changes: 22 additions & 0 deletions packages/executor/src/__testUtils__/expectEqualPromisesOrValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { isPromise, MaybePromise } from '@graphql-tools/utils';
import { expectJSON } from './expectJSON.js';

export function expectMatchingValues<T>(values: ReadonlyArray<T>): T {
const [firstValue, ...remainingValues] = values;
for (const value of remainingValues) {
expectJSON(value).toDeepEqual(firstValue);
}
return firstValue;
}

export function expectEqualPromisesOrValues<T>(items: ReadonlyArray<MaybePromise<T>>): MaybePromise<T> {
const [firstItem, ...remainingItems] = items;
if (isPromise(firstItem)) {
if (remainingItems.every(isPromise)) {
return Promise.all(items).then(expectMatchingValues);
}
} else if (remainingItems.every(item => !isPromise(item))) {
return expectMatchingValues(items);
}
throw new Error('Cannot compare promises and values');
}
22 changes: 22 additions & 0 deletions packages/executor/src/__testUtils__/expectPromise.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { isPromise } from '@graphql-tools/utils';

export function expectPromise(maybePromise: unknown) {
expect(isPromise(maybePromise)).toBeTruthy();

return {
toResolve() {
return maybePromise;
},
async toRejectWith(message: string) {
let caughtError: Error | undefined;
try {
await maybePromise;
} catch (error) {
caughtError = error as Error;
}

expect(caughtError).toBeInstanceOf(Error);
expect(caughtError).toHaveProperty('message', message);
},
};
}
Loading