Skip to content
Draft
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
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,29 @@ jobs:
- name: Run Tests with coverage
run: npm run testonly:cover

generated-coverage:
name: Run generated executor coverage
runs-on: ubuntu-latest
permissions:
contents: read # for actions/checkout
steps:
- name: Checkout repo
uses: actions/checkout@v6
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v6
with:
cache: npm
node-version-file: '.node-version'

- name: Install Dependencies
run: npm ci --ignore-scripts

- name: Run generated executor coverage
run: npm run generate:coverage

codeql:
name: Run CodeQL security scan
runs-on: ubuntu-latest
Expand Down
53 changes: 53 additions & 0 deletions benchmark/compile/compiled-async-root-fields-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';

const fieldCount = 1000;
const fieldNames = Array.from(
{ length: fieldCount },
(_, index) => `f${index}`,
);

const schema = buildSchema(
`type Query { ${fieldNames.map((fieldName) => `${fieldName}: Int`).join(' ')} }`,
{ assumeValid: true },
);

const document = parse(`{ ${fieldNames.join(' ')} }`);

const rootValue = Object.fromEntries(
fieldNames.map((fieldName, index) => [
fieldName,
() => Promise.resolve(index),
]),
);

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

export const benchmark = {
name: 'Compiled Asynchronous Root Fields',
measure: () => {
const runtimeArgs = { rootValue };
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute(runtimeArgs)
: compiled.executeRootSelectionSet(runtimeArgs);
}

const validatedArgs = execution.validateExecutionArgs({
schema,
document,
...runtimeArgs,
});
if (!('schema' in validatedArgs)) {
throw validatedArgs[0];
}
return execution.executeRootSelectionSet(validatedArgs);
},
};
96 changes: 96 additions & 0 deletions benchmark/compile/compiled-field-argument-values-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';

const fieldCount = 100;
const fieldNames = Array.from(
{ length: fieldCount },
(_, index) => `f${index}`,
);

const schema = buildSchema(
`
input FieldInput {
enabled: Boolean
value: Int
}

type Query {
${fieldNames
.map(
(fieldName) => `
${fieldName}(
value: Int!
enabled: Boolean
input: FieldInput
list: [Int]
): Int
`,
)
.join('\n')}
}
`,
{ assumeValid: true },
);

const document = parse(`
query CompiledArgumentValues($value: Int!, $enabled: Boolean!) {
${fieldNames
.map(
(fieldName, index) => `
${fieldName}(
value: $value
enabled: $enabled
input: { enabled: $enabled, value: ${index} }
list: [${index}, $value]
)
`,
)
.join('\n')}
}
`);

const rootValue = Object.fromEntries(
fieldNames.map((fieldName, index) => [
fieldName,
(args) => args.value + args.input.value + args.list[0] + index,
]),
);

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

let value = 0;
let enabled = false;

export const benchmark = {
name: 'Compiled Field Argument Values',
measure: () => {
value = (value + 1) % 10;
enabled = !enabled;
const runtimeArgs = {
rootValue,
variableValues: { value, enabled },
};
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute(runtimeArgs)
: compiled.executeRootSelectionSet(runtimeArgs);
}

const validatedArgs = execution.validateExecutionArgs({
schema,
document,
...runtimeArgs,
});
if (!('schema' in validatedArgs)) {
throw validatedArgs[0];
}
return execution.executeRootSelectionSet(validatedArgs);
},
};
30 changes: 30 additions & 0 deletions benchmark/compile/compiled-introspectionFromSchema-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';
import { getIntrospectionQuery } from 'graphql/utilities/getIntrospectionQuery.js';

import { bigSchemaSDL } from '../fixtures.js';

const schema = buildSchema(bigSchemaSDL, { assumeValid: true });
const document = parse(getIntrospectionQuery());

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

export const benchmark = {
name: 'Compiled Execute Introspection Query',
measure: () => {
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute()
: compiled.executeRootSelectionSet();
}

return execution.executeSync({ schema, document });
},
};
48 changes: 48 additions & 0 deletions benchmark/compile/compiled-list-async-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';

const schema = buildSchema('type Query { listField: [String] }', {
assumeValid: true,
});
const document = parse('{ listField }');

function listField() {
const results = [];
for (let index = 0; index < 1000; index++) {
results.push(Promise.resolve(index));
}
return results;
}

const rootValue = { listField };

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

export const benchmark = {
name: 'Compiled Asynchronous List Field',
measure: () => {
const runtimeArgs = { rootValue };
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute(runtimeArgs)
: compiled.executeRootSelectionSet(runtimeArgs);
}

const validatedArgs = execution.validateExecutionArgs({
schema,
document,
...runtimeArgs,
});
if (!('schema' in validatedArgs)) {
throw validatedArgs[0];
}
return execution.executeRootSelectionSet(validatedArgs);
},
};
48 changes: 48 additions & 0 deletions benchmark/compile/compiled-list-async-non-null-items-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';

const schema = buildSchema('type Query { listField: [String!] }', {
assumeValid: true,
});
const document = parse('{ listField }');

function listField() {
const results = [];
for (let index = 0; index < 1000; index++) {
results.push(Promise.resolve(index));
}
return results;
}

const rootValue = { listField };

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

export const benchmark = {
name: 'Compiled Asynchronous Non-Null List Items',
measure: () => {
const runtimeArgs = { rootValue };
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute(runtimeArgs)
: compiled.executeRootSelectionSet(runtimeArgs);
}

const validatedArgs = execution.validateExecutionArgs({
schema,
document,
...runtimeArgs,
});
if (!('schema' in validatedArgs)) {
throw validatedArgs[0];
}
return execution.executeRootSelectionSet(validatedArgs);
},
};
48 changes: 48 additions & 0 deletions benchmark/compile/compiled-list-sync-benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as execution from 'graphql/execution/index.js';
import { parse } from 'graphql/language/parser.js';
import { buildSchema } from 'graphql/utilities/buildASTSchema.js';

const schema = buildSchema('type Query { listField: [String] }', {
assumeValid: true,
});
const document = parse('{ listField }');

function listField() {
const results = [];
for (let index = 0; index < 1000; index++) {
results.push(index);
}
return results;
}

const rootValue = { listField };

const compiled =
typeof execution.compileExecution === 'function'
? execution.compileExecution({ schema, document })
: undefined;
if (Array.isArray(compiled)) {
throw compiled[0];
}

export const benchmark = {
name: 'Compiled Synchronous List Field',
measure: () => {
const runtimeArgs = { rootValue };
if (compiled !== undefined) {
return 'execute' in compiled
? compiled.execute(runtimeArgs)
: compiled.executeRootSelectionSet(runtimeArgs);
}

const validatedArgs = execution.validateExecutionArgs({
schema,
document,
...runtimeArgs,
});
if (!('schema' in validatedArgs)) {
throw validatedArgs[0];
}
return execution.executeRootSelectionSet(validatedArgs);
},
};
Loading
Loading