graphql-jit 0.9.3 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,7 @@ const GLOBAL_RUNTIME_NAME = "__context.rt";
19
19
  const graphql_1 = require("graphql");
20
20
  const ast_js_1 = require("./ast.js");
21
21
  const error_js_1 = require("./error.js");
22
+ const compile_input_js_1 = require("./compile-input.js");
22
23
  const inspect_js_1 = __importDefault(require("./inspect.js"));
23
24
  const json_js_1 = require("./json.js");
24
25
  const non_null_js_1 = require("./non-null.js");
@@ -31,6 +32,8 @@ const SAFETY_CHECK_PREFIX = "__validNode";
31
32
  const GLOBAL_DATA_NAME = "__context.data";
32
33
  const GLOBAL_ERRORS_NAME = "__context.errors";
33
34
  const GLOBAL_NULL_ERRORS_NAME = "__context.nullErrors";
35
+ // Key in `literals` of the check for errors that null the whole response.
36
+ const NULLS_RESPONSE_LITERAL = "nullsResponse";
34
37
  const GLOBAL_ROOT_NAME = "__context.rootValue";
35
38
  exports.GLOBAL_VARIABLES_NAME = "__context.variables";
36
39
  const GLOBAL_CONTEXT_NAME = "__context.context";
@@ -211,6 +214,7 @@ function compileOperation(context, type, fieldMap) {
211
214
  "use strict";
212
215
  `;
213
216
  if (serialExecution) {
217
+ context.literals[NULLS_RESPONSE_LITERAL] = (0, non_null_js_1.createRootNullChecker)(context);
214
218
  body += `${GLOBAL_EXECUTION_CONTEXT}.queue = [];`;
215
219
  }
216
220
  body += generateUniqueDeclarations(context, true);
@@ -220,8 +224,12 @@ function compileOperation(context, type, fieldMap) {
220
224
  body += `
221
225
  ${GLOBAL_EXECUTION_CONTEXT}.finalResolve = () => {};
222
226
  ${GLOBAL_RESOLVE} = (context) => {
223
- if (context.jobCounter >= context.queue.length) {
224
- // All mutations have finished
227
+ // Stop when all mutations have finished, or when an error in a non-null
228
+ // field has nulled the whole response.
229
+ if (
230
+ context.jobCounter >= context.queue.length ||
231
+ context.literals.${NULLS_RESPONSE_LITERAL}(context.nullErrors)
232
+ ) {
225
233
  context.finalResolve(context);
226
234
  return;
227
235
  }
@@ -300,7 +308,10 @@ function compileDeferredField(context, deferredField, appendix) {
300
308
  }
301
309
  }
302
310
  );
303
- }`;
311
+ }${
312
+ // Invalid arguments skip the resolver and its handler, which is also what
313
+ // advances a serial (mutation) queue.
314
+ appendix ? ` else {${appendix}}` : ""}`;
304
315
  context.hoistedFunctions.push(`
305
316
  function ${resolverHandler}(${GLOBAL_EXECUTION_CONTEXT}, ${GLOBAL_PARENT_NAME}, ${jsFieldName}, ${parentIndexes}) {
306
317
  ${generateUniqueDeclarations(subContext)}
@@ -717,72 +728,6 @@ function compileListType(context, parentType, type, fieldNodes, originalObjectPa
717
728
  return `(typeof ${name} === "string" || typeof ${name}[Symbol.iterator] !== "function") ? ${errorCase} :
718
729
  ${GLOBAL_SAFE_MAP_NAME}(${GLOBAL_EXECUTION_CONTEXT}, ${name}, ${safeMapHandler}, ${parentIndexes})`;
719
730
  }
720
- /**
721
- * Whether the value cannot be written into source as a literal: a bigint,
722
- * symbol, function, or any object other than a plain object, array or Date.
723
- */
724
- function isUnserializable(value) {
725
- switch (typeof value) {
726
- case "bigint":
727
- case "symbol":
728
- case "function":
729
- return true;
730
- case "object": {
731
- if (value === null) {
732
- return false;
733
- }
734
- const proto = Object.getPrototypeOf(value);
735
- if (Array.isArray(value)) {
736
- return proto !== Array.prototype;
737
- }
738
- if (value instanceof Date) {
739
- return proto !== Date.prototype;
740
- }
741
- return proto !== null && proto !== Object.prototype;
742
- }
743
- default:
744
- return false;
745
- }
746
- }
747
- /**
748
- * Serializes an argument value to a JS expression. Unserializable values are
749
- * stored via `hoist` and referenced from `context.literals`.
750
- */
751
- function objectStringify(val, hoist) {
752
- if (isUnserializable(val)) {
753
- return `${GLOBAL_EXECUTION_CONTEXT}.literals.${hoist(val)}`;
754
- }
755
- if (typeof val === "number") {
756
- // JSON.stringify would turn NaN/Infinity into null
757
- return Number.isFinite(val) ? JSON.stringify(val) : String(val);
758
- }
759
- if (val === undefined) {
760
- return "undefined";
761
- }
762
- if (val === null || typeof val !== "object") {
763
- return JSON.stringify(val);
764
- }
765
- if (val instanceof Date) {
766
- return `new Date(${val.getTime()})`;
767
- }
768
- if (Array.isArray(val)) {
769
- const items = [];
770
- for (let i = 0; i < val.length; ++i) {
771
- items.push(i in val ? objectStringify(val[i], hoist) : "null");
772
- }
773
- return `[${items.join(",")}]`;
774
- }
775
- const props = [];
776
- for (const key of Object.keys(val)) {
777
- if (val[key] === undefined) {
778
- continue;
779
- }
780
- // a computed key stops "__proto__" from setting the prototype
781
- const name = JSON.stringify(key);
782
- props.push(`${key === "__proto__" ? `[${name}]` : name}:${objectStringify(val[key], hoist)}`);
783
- }
784
- return `{${props.join(",")}}`;
785
- }
786
731
  /**
787
732
  * Calculates a GraphQLResolveInfo object for the resolver calls.
788
733
  *
@@ -843,14 +788,18 @@ function objectPath(topLevel, path) {
843
788
  * @returns {string}
844
789
  */
845
790
  function compileArguments(context, args, topLevelArg, validArgs, returnType, path) {
791
+ const bind = (value) => {
792
+ const key = `literal${context.literalCount.value++}`;
793
+ context.literals[key] = value;
794
+ return `${GLOBAL_EXECUTION_CONTEXT}.literals.${key}`;
795
+ };
796
+ const valuesExpression = `{${Object.keys(args.values)
797
+ .map((name) => `${JSON.stringify(name)}:${(0, compile_input_js_1.compileInputValue)(args.values[name], args.types[name], bind)}`)
798
+ .join(",")}}`;
846
799
  // default to assuming arguments are valid
847
800
  let body = `
848
801
  let ${validArgs} = true;
849
- const ${topLevelArg} = ${objectStringify(args.values, (value) => {
850
- const key = `literal${Object.keys(context.literals).length}`;
851
- context.literals[key] = value;
852
- return key;
853
- })};
802
+ const ${topLevelArg} = ${valuesExpression};
854
803
  `;
855
804
  const errorDestination = getErrorDestination(returnType);
856
805
  for (const variable of args.missing) {
@@ -1065,6 +1014,7 @@ function buildCompilationContext(schema, document, options, operationName) {
1065
1014
  isTypeOfs: {},
1066
1015
  resolveInfos: {},
1067
1016
  literals: {},
1017
+ literalCount: { value: 0 },
1068
1018
  hoistedFunctions: [],
1069
1019
  hoistedFunctionNames: new Map(),
1070
1020
  leafErrHandlerCache: new Map(),