Skip to content

Commit 466ac0a

Browse files
committed
refactor(graphql): extract graphql() logic into graphql$UCCF to support the basic reactive programming
1 parent bb7cd7c commit 466ac0a

File tree

1 file changed

+56
-19
lines changed

1 file changed

+56
-19
lines changed

src/graphql.js

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ import { parse } from './language/parser';
1313
import { validate } from './validation/validate';
1414
import { execute } from './execution/execute';
1515
import type { GraphQLSchema } from './type/schema';
16-
import type { ExecutionResult } from './execution/execute';
16+
// import type { ExecutionResult } from './execution/execute';
1717

18+
type onNextBlock = (any) => void;
19+
type onError = (Error, boolean) => void;
20+
type onEnd = (any) => void;
21+
22+
type UniversalCallbackFunction =
23+
(onNext: onNextBlock, onError: onError, onEnd: onEnd) => void;
1824

1925
/**
2026
* This is the primary entry point function for fulfilling GraphQL operations
@@ -40,33 +46,64 @@ import type { ExecutionResult } from './execution/execute';
4046
* possible operations. Can be omitted if requestString contains only
4147
* one operation.
4248
*/
43-
export function graphql(
49+
export function graphql$UCCF(
4450
schema: GraphQLSchema,
4551
requestString: string,
4652
rootValue?: mixed,
4753
contextValue?: mixed,
4854
variableValues?: ?{[key: string]: mixed},
4955
operationName?: ?string
50-
): Promise<ExecutionResult> {
51-
return new Promise(resolve => {
56+
): UniversalCallbackFunction {
57+
58+
return function (onNext) {
5259
const source = new Source(requestString || '', 'GraphQL request');
5360
const documentAST = parse(source);
5461
const validationErrors = validate(schema, documentAST);
5562
if (validationErrors.length > 0) {
56-
resolve({ errors: validationErrors });
57-
} else {
58-
resolve(
59-
execute(
60-
schema,
61-
documentAST,
62-
rootValue,
63-
contextValue,
64-
variableValues,
65-
operationName
66-
)
67-
);
63+
onNext({ errors: validationErrors });
64+
return;
65+
}
66+
try {
67+
// !!!:
68+
// Currently, although graphql$UCCF adopts UCC design, the graphql$UCCF is
69+
// not reactive due to the upstream (execute) isn't reactive (as Promise).
70+
// We'll refactor `execute()` later.
71+
execute(
72+
schema,
73+
documentAST,
74+
rootValue,
75+
contextValue,
76+
variableValues,
77+
operationName
78+
).then(data => {
79+
onNext(data);
80+
});
81+
} catch (error) {
82+
onNext({ errors: [ error ] });
6883
}
69-
}).then(undefined, error => {
70-
return { errors: [ error ] };
71-
});
84+
};
85+
}
86+
87+
/**
88+
* Turn a UCC function into a Promise.
89+
*
90+
* @see https://gist.github.com/xareelee/e85c8b2134ff1805ab1ab2f1c8a037ce
91+
*/
92+
function promisify(uccf) {
93+
return function (...args: any[]) {
94+
return new Promise((resolve, reject) => {
95+
uccf(...args)(
96+
x => resolve(x),
97+
err => reject(err),
98+
end => resolve(end)
99+
);
100+
});
101+
};
72102
}
103+
104+
/**
105+
* We export `graphql` as a Promise from `graphql$UCCF`.
106+
*
107+
* @see graphql$UCCF
108+
*/
109+
export const graphql = promisify(graphql$UCCF);

0 commit comments

Comments
 (0)