Skip to content

Commit 2e2127f

Browse files
committed
early result
1 parent cba0e69 commit 2e2127f

File tree

3 files changed

+63
-26
lines changed

3 files changed

+63
-26
lines changed

packages/core/src/orchestrator.ts

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,11 @@ export function createEnvelopOrchestrator<PluginsContext extends DefaultContext>
572572
return async (params, contextExtension) => {
573573
const context = await contextFactory(contextExtension);
574574

575+
let result: AsyncIterableIteratorOrValue<ExecutionResult> | null = null;
576+
575577
const doneFns: OnPerformDoneHook[] = [];
576578
for (const onPerform of beforeCallbacks.perform) {
577-
const result = await onPerform({
579+
const after = await onPerform({
578580
context,
579581
extendContext: extension => {
580582
Object.assign(context, extension);
@@ -583,38 +585,47 @@ export function createEnvelopOrchestrator<PluginsContext extends DefaultContext>
583585
setParams: newParams => {
584586
params = newParams;
585587
},
588+
setResult: earlyResult => {
589+
result = earlyResult;
590+
},
586591
});
587592

588-
result?.onPerformDone && doneFns.push(result.onPerformDone);
593+
after?.onPerformDone && doneFns.push(after.onPerformDone);
589594
}
590595

591-
let document;
592-
try {
593-
document = parse(params.query);
594-
} catch (err) {
595-
return { errors: [err] };
596-
}
596+
if (!result) {
597+
let document;
598+
try {
599+
document = parse(params.query);
600+
} catch (err) {
601+
return { errors: [err] };
602+
}
603+
604+
const validationErrors = validate(schema, document);
605+
if (validationErrors.length) {
606+
return { errors: validationErrors };
607+
}
597608

598-
const validationErrors = validate(schema, document);
599-
if (validationErrors.length) {
600-
return { errors: validationErrors };
609+
if (isSubscriptionOperation(document, params.operationName)) {
610+
result = await customSubscribe({
611+
document,
612+
schema,
613+
variableValues: params.variables,
614+
contextValue: context,
615+
});
616+
} else {
617+
result = await customExecute({
618+
document,
619+
schema,
620+
variableValues: params.variables,
621+
contextValue: context,
622+
});
623+
}
601624
}
602625

603-
let result;
604-
if (isSubscriptionOperation(document, params.operationName)) {
605-
result = await customSubscribe({
606-
document,
607-
schema,
608-
variableValues: params.variables,
609-
contextValue: context,
610-
});
611-
} else {
612-
result = await customExecute({
613-
document,
614-
schema,
615-
variableValues: params.variables,
616-
contextValue: context,
617-
});
626+
if (!result) {
627+
// should never happen
628+
throw new Error('Result not available');
618629
}
619630

620631
for (const doneFn of doneFns) {

packages/core/test/perform.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,26 @@ describe('perform', () => {
189189

190190
expect(result).toBe(replacedResult);
191191
});
192+
193+
it('should early result in onPerform plugin', async () => {
194+
const earlyResult = { data: { hi: 'hello' } };
195+
196+
const getEnveloped = envelop({
197+
...graphqlFuncs,
198+
plugins: [
199+
useSchema(schema),
200+
{
201+
onPerform: ({ setResult }) => {
202+
setResult(earlyResult);
203+
},
204+
},
205+
],
206+
});
207+
208+
const { perform } = getEnveloped();
209+
const result = await perform({ query: '{ hello }' });
210+
assertSingleExecutionValue(result);
211+
212+
expect(result).toBe(earlyResult);
213+
});
192214
});

packages/types/src/hooks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,10 @@ export type OnPerformEventPayload<ContextType> = {
524524
extendContext: (contextExtension: Partial<ContextType>) => void;
525525
params: PerformParams;
526526
setParams: (newParams: PerformParams) => void;
527+
/**
528+
* Set an early result which will be immediatelly returned. Useful for cached results.
529+
*/
530+
setResult: (newResult: AsyncIterableIteratorOrValue<ExecutionResult>) => void;
527531
};
528532

529533
export type OnPerformDoneEventPayload = {

0 commit comments

Comments
 (0)