grafast 0.1.1-beta.2 → 0.1.1-beta.21

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.
Files changed (157) hide show
  1. package/README.md +2 -3
  2. package/dist/args.d.ts +4 -7
  3. package/dist/args.js +53 -38
  4. package/dist/assert.js +2 -3
  5. package/dist/bucket.d.ts +1 -89
  6. package/dist/config.d.ts +0 -17
  7. package/dist/config.js +1 -95
  8. package/dist/constraints.d.ts +15 -1
  9. package/dist/constraints.js +41 -3
  10. package/dist/deferred.js +1 -2
  11. package/dist/dev.d.ts +1 -4
  12. package/dist/dev.js +18 -3
  13. package/dist/engine/LayerPlan.d.ts +21 -111
  14. package/dist/engine/LayerPlan.js +196 -78
  15. package/dist/engine/OperationPlan.d.ts +30 -104
  16. package/dist/engine/OperationPlan.js +763 -471
  17. package/dist/engine/OutputPlan.d.ts +9 -20
  18. package/dist/engine/OutputPlan.js +432 -444
  19. package/dist/engine/StepTracker.d.ts +1 -95
  20. package/dist/engine/StepTracker.js +94 -20
  21. package/dist/engine/executeBucket.d.ts +5 -7
  22. package/dist/engine/executeBucket.js +646 -244
  23. package/dist/engine/executeOutputPlan.d.ts +0 -53
  24. package/dist/engine/executeOutputPlan.js +7 -2
  25. package/dist/engine/lib/defaultPlanResolver.d.ts +6 -0
  26. package/dist/engine/lib/defaultPlanResolver.js +11 -0
  27. package/dist/engine/lib/withGlobalLayerPlan.d.ts +2 -0
  28. package/dist/engine/lib/withGlobalLayerPlan.js +7 -4
  29. package/dist/engine/lock.d.ts +4 -0
  30. package/dist/engine/lock.js +82 -0
  31. package/dist/envelop.js +5 -4
  32. package/dist/error.d.ts +18 -49
  33. package/dist/error.js +50 -39
  34. package/dist/establishOperationPlan.js +57 -42
  35. package/dist/execute.d.ts +5 -4
  36. package/dist/execute.js +31 -15
  37. package/dist/exportAs.d.ts +1 -18
  38. package/dist/exportAs.js +2 -3
  39. package/dist/global.js +2 -3
  40. package/dist/grafastGraphql.d.ts +6 -1
  41. package/dist/grafastGraphql.js +35 -16
  42. package/dist/grafastPrint.d.ts +3 -0
  43. package/dist/grafastPrint.js +67 -6
  44. package/dist/graphqlCollectFields.d.ts +7 -34
  45. package/dist/graphqlCollectFields.js +24 -13
  46. package/dist/graphqlMergeSelectionSets.js +1 -2
  47. package/dist/index.d.ts +44 -29
  48. package/dist/index.js +91 -18
  49. package/dist/input.d.ts +1 -9
  50. package/dist/input.js +75 -28
  51. package/dist/inspect.d.ts +9 -3
  52. package/dist/inspect.js +3 -3
  53. package/dist/interfaces.d.ts +238 -93
  54. package/dist/interfaces.js +20 -3
  55. package/dist/makeGrafastSchema.d.ts +21 -9
  56. package/dist/makeGrafastSchema.js +353 -133
  57. package/dist/mermaid.d.ts +0 -17
  58. package/dist/mermaid.js +131 -19
  59. package/dist/middleware.d.ts +7 -0
  60. package/dist/middleware.js +24 -0
  61. package/dist/multistep.d.ts +19 -0
  62. package/dist/multistep.js +54 -0
  63. package/dist/operationPlan-input.d.ts +5 -4
  64. package/dist/operationPlan-input.js +140 -368
  65. package/dist/planJSONInterfaces.d.ts +12 -2
  66. package/dist/polymorphic.js +4 -5
  67. package/dist/prepare.d.ts +1 -7
  68. package/dist/prepare.js +100 -74
  69. package/dist/step.d.ts +118 -172
  70. package/dist/step.js +262 -183
  71. package/dist/steps/__flag.d.ts +65 -0
  72. package/dist/steps/__flag.js +261 -0
  73. package/dist/steps/__inputDefault.d.ts +14 -0
  74. package/dist/steps/__inputDefault.js +48 -0
  75. package/dist/steps/__inputDynamicScalar.d.ts +4 -6
  76. package/dist/steps/__inputDynamicScalar.js +4 -2
  77. package/dist/steps/__inputList.d.ts +5 -9
  78. package/dist/steps/__inputList.js +4 -1
  79. package/dist/steps/__inputObject.d.ts +7 -11
  80. package/dist/steps/__inputObject.js +49 -3
  81. package/dist/steps/__inputStaticLeaf.d.ts +2 -4
  82. package/dist/steps/__inputStaticLeaf.js +3 -1
  83. package/dist/steps/__item.d.ts +10 -12
  84. package/dist/steps/__item.js +8 -2
  85. package/dist/steps/__trackedValue.d.ts +7 -55
  86. package/dist/steps/__trackedValue.js +69 -8
  87. package/dist/steps/__value.d.ts +5 -4
  88. package/dist/steps/__value.js +5 -4
  89. package/dist/steps/access.d.ts +10 -10
  90. package/dist/steps/access.js +50 -17
  91. package/dist/steps/applyInput.d.ts +44 -0
  92. package/dist/steps/applyInput.js +206 -0
  93. package/dist/steps/applyTransforms.d.ts +2 -25
  94. package/dist/steps/applyTransforms.js +53 -31
  95. package/dist/steps/bakedInput.d.ts +23 -0
  96. package/dist/steps/bakedInput.js +90 -0
  97. package/dist/steps/condition.d.ts +31 -0
  98. package/dist/steps/condition.js +94 -0
  99. package/dist/steps/connection.d.ts +56 -42
  100. package/dist/steps/connection.js +97 -44
  101. package/dist/steps/constant.d.ts +7 -7
  102. package/dist/steps/constant.js +86 -7
  103. package/dist/steps/each.d.ts +3 -3
  104. package/dist/steps/each.js +2 -3
  105. package/dist/steps/error.d.ts +4 -4
  106. package/dist/steps/error.js +7 -6
  107. package/dist/steps/filter.d.ts +3 -2
  108. package/dist/steps/filter.js +1 -2
  109. package/dist/steps/first.d.ts +10 -9
  110. package/dist/steps/first.js +9 -13
  111. package/dist/steps/graphqlResolver.d.ts +3 -76
  112. package/dist/steps/graphqlResolver.js +89 -72
  113. package/dist/steps/groupBy.d.ts +3 -2
  114. package/dist/steps/groupBy.js +1 -2
  115. package/dist/steps/index.d.ts +12 -3
  116. package/dist/steps/index.js +48 -6
  117. package/dist/steps/lambda.d.ts +9 -9
  118. package/dist/steps/lambda.js +18 -9
  119. package/dist/steps/last.d.ts +9 -8
  120. package/dist/steps/last.js +7 -6
  121. package/dist/steps/list.d.ts +20 -9
  122. package/dist/steps/list.js +56 -13
  123. package/dist/steps/listTransform.d.ts +18 -22
  124. package/dist/steps/listTransform.js +58 -27
  125. package/dist/steps/listen.d.ts +6 -11
  126. package/dist/steps/listen.js +14 -16
  127. package/dist/steps/load.d.ts +42 -33
  128. package/dist/steps/load.js +60 -27
  129. package/dist/steps/node.d.ts +17 -10
  130. package/dist/steps/node.js +18 -6
  131. package/dist/steps/object.d.ts +33 -27
  132. package/dist/steps/object.js +53 -32
  133. package/dist/steps/partitionByIndex.d.ts +3 -2
  134. package/dist/steps/partitionByIndex.js +1 -2
  135. package/dist/steps/polymorphicBranch.d.ts +27 -0
  136. package/dist/steps/polymorphicBranch.js +62 -0
  137. package/dist/steps/proxy.d.ts +11 -12
  138. package/dist/steps/proxy.js +8 -5
  139. package/dist/steps/remapKeys.d.ts +10 -10
  140. package/dist/steps/remapKeys.js +14 -7
  141. package/dist/steps/reverse.d.ts +8 -8
  142. package/dist/steps/reverse.js +10 -7
  143. package/dist/steps/setter.d.ts +9 -18
  144. package/dist/steps/setter.js +24 -14
  145. package/dist/steps/sideEffect.d.ts +28 -0
  146. package/dist/steps/sideEffect.js +44 -0
  147. package/dist/stringifyPayload.js +1 -2
  148. package/dist/stripAnsi.js +2 -2
  149. package/dist/subscribe.d.ts +7 -1
  150. package/dist/subscribe.js +24 -9
  151. package/dist/thereCanBeOnlyOne.js +1 -1
  152. package/dist/timeSource.d.ts +0 -1
  153. package/dist/utils.d.ts +56 -55
  154. package/dist/utils.js +179 -59
  155. package/dist/version.d.ts +1 -1
  156. package/dist/version.js +1 -1
  157. package/package.json +5 -8
@@ -1,80 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getChildBucketAndIndex = exports.nonNullError = exports.coerceError = exports.OutputPlan = void 0;
3
+ exports.OutputPlan = void 0;
4
+ exports.coerceError = coerceError;
5
+ exports.nonNullError = nonNullError;
6
+ exports.getChildBucketAndIndex = getChildBucketAndIndex;
4
7
  const tslib_1 = require("tslib");
5
8
  const lru_1 = tslib_1.__importDefault(require("@graphile/lru"));
6
9
  const graphql = tslib_1.__importStar(require("graphql"));
7
10
  const tamedevil_1 = tslib_1.__importStar(require("tamedevil"));
8
11
  const assert = tslib_1.__importStar(require("../assert.js"));
9
12
  const dev_js_1 = require("../dev.js");
10
- const error_js_1 = require("../error.js");
11
13
  const index_js_1 = require("../index.js");
12
14
  const inspect_js_1 = require("../inspect.js");
13
15
  const interfaces_js_1 = require("../interfaces.js");
14
16
  const polymorphic_js_1 = require("../polymorphic.js");
15
17
  const access_js_1 = require("../steps/access.js");
16
18
  const { executeSync, GraphQLBoolean, GraphQLError, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLString, isObjectType, Kind, OperationTypeNode, } = graphql;
17
- const ref_$$error = tamedevil_1.default.ref(error_js_1.$$error, "$$error");
18
- const ref_coerceError = tamedevil_1.default.ref(coerceError, "coerceError");
19
- const ref_nonNullError = tamedevil_1.default.ref(nonNullError, "nonNullError");
20
- const ref_stringifyString = tamedevil_1.default.ref(tamedevil_1.stringifyString, "stringifyString");
21
- const ref_stringifyJSON = tamedevil_1.default.ref(tamedevil_1.stringifyJSON, "stringifyJSON");
22
- const ref_isPolymorphicData = tamedevil_1.default.ref(polymorphic_js_1.isPolymorphicData, "isPolymorphicData");
23
- const ref_$$concreteType = tamedevil_1.default.ref(interfaces_js_1.$$concreteType, "$$concreteType");
24
- const ref_assert = tamedevil_1.default.ref(assert, "assert");
25
- const ref_getChildBucketAndIndex = tamedevil_1.default.ref(getChildBucketAndIndex, "getChildBucketAndIndex");
26
- const ref_inspect = tamedevil_1.default.ref(inspect_js_1.inspect, "inspect");
27
- const ref_$$streamMore = tamedevil_1.default.ref(interfaces_js_1.$$streamMore, "$$streamMore");
28
- const te_String = (0, tamedevil_1.default) `String`;
29
- const te_nullIsFineComment = (0, tamedevil_1.default) `// root/introspection, null is fine`;
30
- const te_nullString = (0, tamedevil_1.default) `"null"`;
31
- const te_null = (0, tamedevil_1.default) `null`;
32
- const te_childBucket = (0, tamedevil_1.default) `childBucket`;
33
- const te_childBucketIndex = (0, tamedevil_1.default) `childBucketIndex`;
34
- const te_executeString = (0, tamedevil_1.default) `executeString`;
35
- const te_execute = (0, tamedevil_1.default) `execute`;
36
- const te_polymorphic = (0, tamedevil_1.default) `polymorphic`;
37
- const te_letStringLbrace = (0, tamedevil_1.default) `let string = "{";`;
38
- const te_stringPlusEquals = (0, tamedevil_1.default) `string +=`;
39
- const te_stringPlusEqualsRbrace = (0, tamedevil_1.default) ` string += "}";\n`;
40
- const te_stringPlusEqualsRbracket = (0, tamedevil_1.default) ` string += "]";\n`;
41
- const te_constObjEqualsObjectCreateNull = (0, tamedevil_1.default) `const obj = Object.create(null);`;
42
- const te_comma = (0, tamedevil_1.default) `,`;
43
- const te_specDotLocationDetails = (0, tamedevil_1.default) `spec.locationDetails`;
44
- const te_thisDotLocationDetails = (0, tamedevil_1.default) `this.locationDetails`;
45
- const te_specDotOutputPlan = (0, tamedevil_1.default) `spec.outputPlan`;
46
- const te_bucket = (0, tamedevil_1.default) `bucket`;
47
- const te_bucketIndex = (0, tamedevil_1.default) `bucketIndex`;
48
- const te_handleDeferred = (0, tamedevil_1.default) `
49
- // Everything seems okay; queue any deferred payloads
50
- for (const defer of this.deferredOutputPlans) {
51
- root.queue.push({
52
- root,
53
- path: mutablePath.slice(1),
54
- bucket,
55
- bucketIndex,
56
- outputPlan: defer,
57
- label: defer.type.deferLabel,
58
- });
59
- }
60
- `;
61
- const te_string = (0, tamedevil_1.default) `string`;
62
- const te_object = (0, tamedevil_1.default) `object`;
63
- const te_obj = (0, tamedevil_1.default) `obj`;
64
- const te_data = (0, tamedevil_1.default) `data`;
65
- const te_commonErrorHandler = tamedevil_1.default.ref(commonErrorHandler, "handleError");
66
- const te_questionDot = (0, tamedevil_1.default) `?.`;
67
- const te_childBucketCBIDC = (0, tamedevil_1.default) `, childBucket, childBucketIndex, directChild`;
68
- const te_letString = (0, tamedevil_1.default) `let string;`;
69
- const te_constDataEqualsEmptyArray = (0, tamedevil_1.default) `const data = [];`;
70
- const te_stringEqualsEmptyArrayString = (0, tamedevil_1.default) ` string = "[]";`;
71
- const te_stringEqualsLeftSquareBraceString = (0, tamedevil_1.default) ` string = "[";\n`;
72
- const te_noopComment = (0, tamedevil_1.default) ` /* noop */`;
73
- const te_ifIGt0StrPlusEqualComma = (0, tamedevil_1.default) `\n if (i > 0) { string += ","; }\n`;
74
- const te_dataIEquals = (0, tamedevil_1.default) `data[i] =`;
75
- const te_childOutputPlan = (0, tamedevil_1.default) `childOutputPlan`;
76
- const te_underscoreNonNull = (0, tamedevil_1.default) `_nonNull`;
77
- const te_underscoreStream = (0, tamedevil_1.default) `_stream`;
78
19
  /**
79
20
  * Defines a way of taking a layerPlan and converting it into an output value.
80
21
  *
@@ -104,6 +45,8 @@ class OutputPlan {
104
45
  this.type = type;
105
46
  /**
106
47
  * Appended to the root step when accessed to avoid the need for AccessSteps
48
+ *
49
+ * @internal
107
50
  */
108
51
  this.processRoot = null;
109
52
  /**
@@ -128,6 +71,8 @@ class OutputPlan {
128
71
  layerPlan.operationPlan.stepTracker.addOutputPlan(this);
129
72
  this.childByTypeName =
130
73
  this.type.mode === "polymorphic" ? Object.create(null) : undefined;
74
+ // NOTE: this may be cleared during `this.finalize()`
75
+ this.sideEffectStep = layerPlan.latestSideEffectStep;
131
76
  }
132
77
  print() {
133
78
  const type = this.type;
@@ -160,7 +105,7 @@ class OutputPlan {
160
105
  }
161
106
  }
162
107
  toString() {
163
- return `OutputPlan<${this.type.mode}∈${this.layerPlan.id}!${this.rootStep.id}>`;
108
+ return `OutputPlan<${this.type.mode}${this.sideEffectStep ? `^${this.sideEffectStep.id}` : ""}∈${this.layerPlan.id}!${this.rootStep.id}>`;
164
109
  }
165
110
  addChild(type, key, child) {
166
111
  if (this.type.mode === "root" || this.type.mode === "object") {
@@ -253,7 +198,7 @@ class OutputPlan {
253
198
  // By just reusing the same path over and over we don't need to allocate
254
199
  // more memory for more arrays; but we must be _incredibly_ careful to
255
200
  // ensure any changes to it are reversed.
256
- _mutablePath, _bucket, _bucketIndex) {
201
+ _mutablePath, _bucket, _bucketIndex, _rawBucketRootValue, _bucketRootFlags) {
257
202
  throw new Error(`OutputPlan.execute has yet to be built!`);
258
203
  }
259
204
  // This gets replaced with a mode-specific executor
@@ -261,16 +206,25 @@ class OutputPlan {
261
206
  // By just reusing the same path over and over we don't need to allocate
262
207
  // more memory for more arrays; but we must be _incredibly_ careful to
263
208
  // ensure any changes to it are reversed.
264
- _mutablePath, _bucket, _bucketIndex) {
209
+ _mutablePath, _bucket, _bucketIndex, _rawBucketRootValue, _bucketRootFlags) {
265
210
  throw new Error(`OutputPlan.executeString has yet to be built!`);
266
211
  }
267
212
  optimize() {
213
+ // This optimization works by ridding us of access steps at the very end of
214
+ // paths and just accessing properties directly. In rare circumstances
215
+ // involving untethered side effects in earlier versions this could lead to
216
+ // errors being skipped and data generated previous to the error being
217
+ // returned; but OutputPlans now check the latestSideEffectStep so this
218
+ // should be safe aga.
268
219
  const $root = this.layerPlan.operationPlan.dangerouslyGetStep(this.rootStep.id);
269
- if ($root instanceof index_js_1.AccessStep && $root.fallback === undefined) {
220
+ if ($root instanceof index_js_1.AccessStep &&
221
+ $root.fallback === undefined &&
222
+ $root.implicitSideEffectStep === null &&
223
+ (!this.sideEffectStep || !(0, index_js_1.stepADependsOnStepB)($root, this.sideEffectStep))) {
270
224
  const expressionDetails = $root.unbatchedExecute[access_js_1.expressionSymbol];
271
225
  if (expressionDetails !== undefined) {
272
226
  // @ts-ignore
273
- const $parent = $root.getDep(0);
227
+ const { step: $parent } = $root.getDepOptions(0);
274
228
  this.layerPlan.operationPlan.stepTracker.setOutputPlanRootStep(this, $parent);
275
229
  const [path, fallback] = expressionDetails;
276
230
  withFastExpression(path, fallback, (fn) => {
@@ -280,6 +234,19 @@ class OutputPlan {
280
234
  }
281
235
  }
282
236
  finalize() {
237
+ // Clear the sideEffectStep if the rootStep explicitly depends on it.
238
+ // NOTE: this occurs here since more dependencies could have been added to
239
+ // $root after `this` was created.
240
+ const $sideEffect = this.sideEffectStep;
241
+ if ($sideEffect) {
242
+ const $root = this.rootStep;
243
+ if ($root === $sideEffect ||
244
+ $root.implicitSideEffectStep === $sideEffect ||
245
+ (0, index_js_1.stepADependsOnStepB)($root, $sideEffect)) {
246
+ // It's marked readonly, but we override it anyway
247
+ this.sideEffectStep = null;
248
+ }
249
+ }
283
250
  // Build the executor
284
251
  switch (this.type.mode) {
285
252
  case "null": {
@@ -372,12 +339,8 @@ class OutputPlan {
372
339
  spec.outputPlan.layerPlan.id === this.layerPlan.id,
373
340
  };
374
341
  }
375
- makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", false, (fn) => {
376
- this.execute = fn;
377
- });
378
- makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", true, (fn) => {
379
- this.executeString = fn;
380
- });
342
+ this.execute = makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", false);
343
+ this.executeString = makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", true);
381
344
  break;
382
345
  }
383
346
  default: {
@@ -399,10 +362,9 @@ function coerceError(error, locationDetails, path) {
399
362
  }
400
363
  }
401
364
  else {
402
- return new GraphQLError(error.message, locationDetails.node, null, null, path, error, null);
365
+ return new GraphQLError(error?.message ?? String(error), locationDetails.node, null, null, path, error, null);
403
366
  }
404
367
  }
405
- exports.coerceError = coerceError;
406
368
  function nonNullError(locationDetails, path) {
407
369
  const { parentTypeName, fieldName, node } = locationDetails;
408
370
  if (!parentTypeName || !fieldName) {
@@ -410,7 +372,6 @@ function nonNullError(locationDetails, path) {
410
372
  }
411
373
  return new GraphQLError(`Cannot return null for non-nullable field ${parentTypeName}.${fieldName}.`, node, null, null, path, null, null);
412
374
  }
413
- exports.nonNullError = nonNullError;
414
375
  /**
415
376
  * We're currently running OutputPlan `outputPlan` in bucket `bucket` at index
416
377
  * `bucketIndex`. If this is an array OutputPlan then we're looping over the
@@ -422,17 +383,20 @@ exports.nonNullError = nonNullError;
422
383
  *
423
384
  * @internal
424
385
  */
425
- function getChildBucketAndIndex(childOutputPlan, outputPlan, bucket, bucketIndex, arrayIndex = null) {
386
+ function getChildBucketAndIndex(layerPlan, outputPlan, bucket, bucketIndex, arrayIndex = null) {
387
+ if (bucket.layerPlan === layerPlan) {
388
+ return [bucket, bucketIndex];
389
+ }
426
390
  if ((arrayIndex == null) ===
427
391
  (outputPlan != null && outputPlan.type.mode === "array")) {
428
392
  throw new Error("GrafastInternalError<83d0e3cc-7eec-4185-85b4-846540288162>: arrayIndex must be supplied iff outputPlan is an array");
429
393
  }
430
- if (outputPlan && childOutputPlan.layerPlan === bucket.layerPlan) {
394
+ if (outputPlan != null && layerPlan === bucket.layerPlan) {
431
395
  // Same layer; straightforward
432
396
  return [bucket, bucketIndex];
433
397
  }
434
- const reversePath = [childOutputPlan.layerPlan];
435
- let current = childOutputPlan.layerPlan;
398
+ const reversePath = [layerPlan];
399
+ let current = layerPlan;
436
400
  while (!bucket.children[current.id]) {
437
401
  current = current.parentLayerPlan;
438
402
  if (!current) {
@@ -485,71 +449,112 @@ function getChildBucketAndIndex(childOutputPlan, outputPlan, bucket, bucketIndex
485
449
  }
486
450
  return [currentBucket, currentIndex];
487
451
  }
488
- exports.getChildBucketAndIndex = getChildBucketAndIndex;
489
- function makeExecutorExpression(options) {
490
- const { inner, nameExtra, asString, skipNullHandling = false, preamble = tamedevil_1.default.blank, } = options;
491
- return (0, tamedevil_1.default) `\
492
- (function compiledOutputPlan${asString ? te_String : tamedevil_1.default.blank}_${nameExtra}(
493
- root,
494
- mutablePath,
495
- bucket,
496
- bucketIndex,
497
- rawBucketRootValue = bucket.store.get(this.rootStep.id)[bucketIndex]
498
- ) {
499
- const bucketRootValue = this.processRoot !== null ? this.processRoot(rawBucketRootValue) : rawBucketRootValue;
500
- ${preamble}\
501
- ${skipNullHandling
502
- ? dev_js_1.isDev
503
- ? te_nullIsFineComment
504
- : tamedevil_1.default.blank
505
- : (0, tamedevil_1.default) `if (bucketRootValue == null) return ${asString ? te_nullString : te_null};`}
506
- if (bucketRootValue${skipNullHandling ? te_questionDot : tamedevil_1.default.blank}[${ref_$$error}]) {
507
- throw ${ref_coerceError}(bucketRootValue.originalError, this.locationDetails, mutablePath.slice(1));
508
- }
509
- ${inner}
510
- })`;
452
+ function makeExecutor(config) {
453
+ const { preamble = null, inner, asString, nameExtra, skipNullHandling = false, } = config;
454
+ const fn = function (root, mutablePath, bucket, bucketIndex, rawBucketRootValue = bucket.store.get(this.rootStep.id).at(bucketIndex), bucketRootFlags = bucket.store.get(this.rootStep.id)._flagsAt(bucketIndex)) {
455
+ if (this.sideEffectStep !== null) {
456
+ const sideEffectBucketDetails = getChildBucketAndIndex(this.sideEffectStep.layerPlan, null, bucket, bucketIndex);
457
+ if (sideEffectBucketDetails) {
458
+ const [sideEffectBucket, sideEffectBucketIndex] = sideEffectBucketDetails;
459
+ const ev = sideEffectBucket.store.get(this.sideEffectStep.id);
460
+ if (!ev) {
461
+ throw new Error(`GrafastInternalError<da9cc5a0-23bf-4af8-a103-92f995795398>: ${(0, index_js_1.stripAnsi)(String(this.sideEffectStep))} has no entry in ${bucket}`);
462
+ }
463
+ const seFlags = ev._flagsAt(sideEffectBucketIndex);
464
+ if (seFlags & interfaces_js_1.FLAG_ERROR) {
465
+ const seVal = ev.at(sideEffectBucketIndex);
466
+ throw coerceError(seVal, this.locationDetails, mutablePath.slice(1));
467
+ }
468
+ }
469
+ }
470
+ if (bucketRootFlags & interfaces_js_1.FLAG_ERROR) {
471
+ throw coerceError(rawBucketRootValue, this.locationDetails, mutablePath.slice(1));
472
+ }
473
+ const bucketRootValue = this.processRoot !== null
474
+ ? this.processRoot(rawBucketRootValue, bucketRootFlags)
475
+ : rawBucketRootValue;
476
+ const earlyReturn = preamble?.call(this, bucketRootValue);
477
+ if (earlyReturn !== undefined) {
478
+ return earlyReturn;
479
+ }
480
+ if (!skipNullHandling) {
481
+ if (bucketRootValue == null)
482
+ return (asString ? "null" : null);
483
+ }
484
+ return inner.call(this, bucketRootValue, root, mutablePath, bucket, bucketIndex, rawBucketRootValue, bucketRootFlags);
485
+ };
486
+ fn.displayName = `outputPlan${asString ? "String" : ""}_${nameExtra}`;
487
+ return fn;
511
488
  }
512
- function makeExecutor(options, callback) {
513
- const expression = makeExecutorExpression(options);
514
- if (callback !== undefined) {
515
- tamedevil_1.default.runInBatch(expression, callback);
516
- }
517
- else {
518
- return tamedevil_1.default.run((0, tamedevil_1.default) `return ${expression}`);
489
+ function executeChildPlan(that, locationDetails, childOutputPlan, isNonNull, asString, childBucket, childBucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags) {
490
+ const $sideEffect = childOutputPlan.layerPlan.parentSideEffectStep;
491
+ if ($sideEffect !== null) {
492
+ // Check if there's an error
493
+ const sideEffectBucketDetails = getChildBucketAndIndex($sideEffect.layerPlan, null, bucket, bucketIndex);
494
+ if (sideEffectBucketDetails) {
495
+ const [sideEffectBucket, sideEffectBucketIndex] = sideEffectBucketDetails;
496
+ const ev = sideEffectBucket.store.get($sideEffect.id);
497
+ if (!ev) {
498
+ throw new Error(`GrafastInternalError<d18d52b5-f5bf-42df-a2dd-80e522310b8e>: ${(0, index_js_1.stripAnsi)(String($sideEffect))} has no entry in ${bucket}`);
499
+ }
500
+ const flags = ev._flagsAt(sideEffectBucketIndex);
501
+ if (flags & interfaces_js_1.FLAG_ERROR) {
502
+ const e = coerceError(ev.at(sideEffectBucketIndex), locationDetails, mutablePath.slice(1));
503
+ if (isNonNull) {
504
+ throw e;
505
+ }
506
+ else {
507
+ const streamCount = root.streams.length;
508
+ const queueCount = root.queue.length;
509
+ commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, root, streamCount, queueCount);
510
+ return asString ? "null" : null;
511
+ }
512
+ }
513
+ }
519
514
  }
520
- }
521
- function makeExecuteChildPlanCode(setTargetOrReturn, locationDetails, childOutputPlan, isNonNull, asString, childBucket = te_childBucket, childBucketIndex = te_childBucketIndex) {
522
- const te_childOutputPlanExecute = (0, tamedevil_1.default) `${childOutputPlan}.${asString ? te_executeString : te_execute}(root, mutablePath, ${childBucket}, ${childBucketIndex}, ${childBucket}.rootStep === this.rootStep ? rawBucketRootValue : undefined)`;
523
515
  // This is the code that changes based on if the field is nullable or not
524
516
  if (isNonNull) {
525
517
  // No need to catch error
526
- return (0, tamedevil_1.default) `\
527
- ${childBucket === te_bucket
528
- ? tamedevil_1.default.blank
529
- : (0, tamedevil_1.default) `if (${childBucket} == null) {
530
- throw ${ref_nonNullError}(${locationDetails}, mutablePath.slice(1));
531
- }
532
- `}fieldResult = ${te_childOutputPlanExecute};
533
- if (fieldResult == ${asString ? te_nullString : te_null}) {
534
- throw ${ref_nonNullError}(${locationDetails}, mutablePath.slice(1));
535
- }
536
- ${setTargetOrReturn} fieldResult;`;
518
+ if (childBucket === bucket) {
519
+ //noop
520
+ }
521
+ else {
522
+ if (childBucket == null) {
523
+ throw nonNullError(locationDetails, mutablePath.slice(1));
524
+ }
525
+ }
526
+ const fieldResult = childOutputPlan[asString ? "executeString" : "execute"](root, mutablePath, childBucket, childBucketIndex,
527
+ // NOTE: the previous code may have had a bug here, it referenced childBucket.rootStep
528
+ childOutputPlan.rootStep === that.rootStep
529
+ ? rawBucketRootValue
530
+ : undefined, childOutputPlan.rootStep === that.rootStep ? bucketRootFlags : undefined);
531
+ if (fieldResult == (asString ? "null" : null)) {
532
+ throw nonNullError(locationDetails, mutablePath.slice(1));
533
+ }
534
+ return fieldResult;
537
535
  }
538
536
  else {
539
537
  // Need to catch error and set null
540
- return (0, tamedevil_1.default) `\
541
- {
542
- const streamCount = root.streams.length;
543
- const queueCount = root.queue.length;
544
- try {
545
- ${setTargetOrReturn} ${childBucket === te_bucket
546
- ? tamedevil_1.default.blank
547
- : (0, tamedevil_1.default) `${childBucket} == null ? ${asString ? te_nullString : te_null} : `}${te_childOutputPlanExecute};
548
- } catch (e) {
549
- ${te_commonErrorHandler}(e, ${locationDetails}, mutablePath, mutablePathIndex, root, streamCount, queueCount);
550
- ${setTargetOrReturn} ${asString ? te_nullString : te_null};
551
- }
552
- }`;
538
+ const streamCount = root.streams.length;
539
+ const queueCount = root.queue.length;
540
+ try {
541
+ if (childBucket !== bucket && childBucket == null) {
542
+ return asString ? "null" : null;
543
+ }
544
+ else {
545
+ return childOutputPlan[asString ? "executeString" : "execute"](root, mutablePath, childBucket, childBucketIndex,
546
+ // NOTE: the previous code may have had a bug here, it referenced childBucket.rootStep
547
+ childOutputPlan.rootStep === that.rootStep
548
+ ? rawBucketRootValue
549
+ : undefined, childOutputPlan.rootStep === that.rootStep
550
+ ? bucketRootFlags
551
+ : undefined);
552
+ }
553
+ }
554
+ catch (e) {
555
+ commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, root, streamCount, queueCount);
556
+ return asString ? "null" : null;
557
+ }
553
558
  }
554
559
  }
555
560
  function commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, root, streamCount, queueCount) {
@@ -567,97 +572,94 @@ function commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, r
567
572
  }
568
573
  root.errors.push(error);
569
574
  }
570
- /*
571
- * Below here we create the executors that can be shared across many different
572
- * OutputPlans without having to be recreated (thus saving significant memory,
573
- * and increasing the probability of optimization).
574
- */
575
575
  const nullExecutor = makeExecutor({
576
- inner: tamedevil_1.default.cache ` return null;`,
577
- nameExtra: tamedevil_1.default.cache `null`,
576
+ inner: () => null,
577
+ nameExtra: "null",
578
578
  asString: false,
579
579
  });
580
580
  const nullExecutorString = makeExecutor({
581
- inner: tamedevil_1.default.cache ` return "null";`,
582
- nameExtra: tamedevil_1.default.cache `null`,
581
+ inner: () => "null",
582
+ nameExtra: `null`,
583
583
  asString: true,
584
584
  });
585
585
  /* This is what leafExecutor should use if insideGraphQL (which isn't currently
586
- * supported)
587
- `\
588
- if (root.insideGraphQL) {
589
- // Don't serialize to avoid the double serialization problem
590
- return bucketRootValue;
591
- } else {
592
- return this.type.graphqlType.serialize(bucketRootValue);
593
- }
594
- ` */
586
+ * supported)
587
+ `\
588
+ if (root.insideGraphQL) {
589
+ // Don't serialize to avoid the double serialization problem
590
+ return bucketRootValue;
591
+ } else {
592
+ return this.type.graphqlType.serialize(bucketRootValue);
593
+ }
594
+ ` */
595
595
  const leafExecutor = makeExecutor({
596
- inner: (0, tamedevil_1.default) `\
597
- return this.type.graphqlType.serialize(bucketRootValue);
598
- `,
599
- nameExtra: tamedevil_1.default.cache `leaf`,
596
+ inner(bucketRootValue) {
597
+ return this.type.graphqlType.serialize(bucketRootValue);
598
+ },
599
+ nameExtra: `leaf`,
600
600
  asString: false,
601
601
  });
602
602
  const leafExecutorString = makeExecutor({
603
- inner: (0, tamedevil_1.default) `\
604
- return ${ref_stringifyJSON}(this.type.graphqlType.serialize(bucketRootValue));
605
- `,
606
- nameExtra: tamedevil_1.default.cache `leaf`,
603
+ inner(bucketRootValue) {
604
+ return (0, tamedevil_1.stringifyJSON)(this.type.graphqlType.serialize(bucketRootValue));
605
+ },
606
+ nameExtra: `leaf`,
607
607
  asString: true,
608
608
  });
609
609
  const booleanLeafExecutorString = makeExecutor({
610
- inner: (0, tamedevil_1.default) `\
611
- const val = this.type.graphqlType.serialize(bucketRootValue);
612
- return val === true ? 'true' : 'false';
613
- `,
614
- nameExtra: tamedevil_1.default.cache `booleanLeaf`,
610
+ inner(bucketRootValue) {
611
+ const val = this.type.graphqlType.serialize(bucketRootValue);
612
+ return val === true ? "true" : "false";
613
+ },
614
+ nameExtra: `booleanLeaf`,
615
615
  asString: true,
616
616
  skipNullHandling: false,
617
- preamble: (0, tamedevil_1.default) `\
618
- if (bucketRootValue === true) return 'true';
619
- if (bucketRootValue === false) return 'false';
620
- `,
617
+ preamble(bucketRootValue) {
618
+ if (bucketRootValue === true)
619
+ return "true";
620
+ if (bucketRootValue === false)
621
+ return "false";
622
+ },
621
623
  });
622
624
  const intLeafExecutorString = makeExecutor({
623
- inner: (0, tamedevil_1.default) `\
624
- return '' + this.type.graphqlType.serialize(bucketRootValue);
625
- `,
626
- nameExtra: tamedevil_1.default.cache `intLeaf`,
625
+ inner(bucketRootValue) {
626
+ return "" + this.type.graphqlType.serialize(bucketRootValue);
627
+ },
628
+ nameExtra: `intLeaf`,
627
629
  asString: true,
628
630
  skipNullHandling: false,
629
631
  // Fast check to see if number is 32 bit integer
630
- preamble: (0, tamedevil_1.default) `\
631
- if ((bucketRootValue | 0) === bucketRootValue) {
632
- return '' + bucketRootValue;
633
- }
634
- `,
632
+ preamble(bucketRootValue) {
633
+ if ((bucketRootValue | 0) === bucketRootValue) {
634
+ return "" + bucketRootValue;
635
+ }
636
+ },
635
637
  });
636
638
  const floatLeafExecutorString = makeExecutor({
637
- inner: (0, tamedevil_1.default) `\
638
- return String(this.type.graphqlType.serialize(bucketRootValue));
639
- `,
640
- nameExtra: tamedevil_1.default.cache `floatLeaf`,
639
+ inner(bucketRootValue) {
640
+ return String(this.type.graphqlType.serialize(bucketRootValue));
641
+ },
642
+ nameExtra: `floatLeaf`,
641
643
  asString: true,
642
644
  skipNullHandling: false,
643
- preamble: (0, tamedevil_1.default) `\
644
- if (Number.isFinite(bucketRootValue)) {
645
- return '' + bucketRootValue;
646
- }
647
- `,
645
+ preamble(bucketRootValue) {
646
+ if (Number.isFinite(bucketRootValue)) {
647
+ return "" + bucketRootValue;
648
+ }
649
+ },
648
650
  });
649
651
  const stringLeafExecutorString = makeExecutor({
650
- inner: (0, tamedevil_1.default) `\
651
- return ${ref_stringifyString}(this.type.graphqlType.serialize(bucketRootValue));
652
- `,
653
- nameExtra: tamedevil_1.default.cache `stringLeaf`,
652
+ inner(bucketRootValue) {
653
+ return (0, tamedevil_1.stringifyString)(this.type.graphqlType.serialize(bucketRootValue));
654
+ },
655
+ nameExtra: `stringLeaf`,
654
656
  asString: true,
655
657
  skipNullHandling: false,
656
- preamble: (0, tamedevil_1.default) `\
657
- if (typeof bucketRootValue === 'string') {
658
- return ${ref_stringifyString}(bucketRootValue);
659
- }
660
- `,
658
+ preamble(bucketRootValue) {
659
+ if (typeof bucketRootValue === "string") {
660
+ return (0, tamedevil_1.stringifyString)(bucketRootValue);
661
+ }
662
+ },
661
663
  });
662
664
  // NOTE: the reference to $$concreteType here is a (temporary) optimization; it
663
665
  // should be `resolveType(bucketRootValue)` but it's not worth the function
@@ -665,53 +667,32 @@ const stringLeafExecutorString = makeExecutor({
665
667
  // store.
666
668
  function makePolymorphicExecutor(asString) {
667
669
  return makeExecutor({
668
- inner: (0, tamedevil_1.default) `\
669
- ${dev_js_1.isDev
670
- ? (0, tamedevil_1.default) `\
671
- if (!${ref_isPolymorphicData}(bucketRootValue)) {
672
- throw ${ref_coerceError}(
673
- new Error(
674
- "GrafastInternalError<db7fcda5-dc39-4568-a7ce-ee8acb88806b>: Expected polymorphic data",
675
- ),
676
- this.locationDetails,
677
- mutablePath.slice(1),
678
- );
679
- }
680
- `
681
- : tamedevil_1.default.blank}\
682
- const typeName = bucketRootValue[${ref_$$concreteType}];
683
- const childOutputPlan = this.childByTypeName[typeName];
684
- ${dev_js_1.isDev
685
- ? (0, tamedevil_1.default) `{
686
- ${ref_assert}.ok(
687
- typeName,
688
- "GrafastInternalError<fd3f3cf0-0789-4c74-a6cd-839c808896ed>: Could not determine concreteType for object",
689
- );
690
- ${ref_assert}.ok(
691
- childOutputPlan,
692
- \`GrafastInternalError<a46999ef-41ff-4a22-bae9-fa37ff6e5f7f>: Could not determine the OutputPlan to use for '\${typeName}' from '\${bucket.layerPlan}'\`,
693
- );
694
- }`
695
- : tamedevil_1.default.blank}
696
-
697
- const directChild = bucket.children[childOutputPlan.layerPlan.id];
698
- if (directChild !== undefined) {
699
- return childOutputPlan.${asString ? te_executeString : te_execute}(root, mutablePath, directChild.bucket, directChild.map.get(bucketIndex));
700
- } else {
701
- const c = ${ref_getChildBucketAndIndex}(
702
- childOutputPlan,
703
- this,
704
- bucket,
705
- bucketIndex,
706
- );
707
- if (!c) {
708
- throw new Error("GrafastInternalError<691509d8-31fa-4cfe-a6df-dcba21bd521f>: polymorphic executor couldn't determine child bucket");
709
- }
710
- const [childBucket, childBucketIndex] = c;
711
- return childOutputPlan.${asString ? te_executeString : te_execute}(root, mutablePath, childBucket, childBucketIndex);
712
- }
713
- `,
714
- nameExtra: te_polymorphic,
670
+ inner(bucketRootValue, root, mutablePath, bucket, bucketIndex) {
671
+ if (dev_js_1.isDev) {
672
+ if (!(0, polymorphic_js_1.isPolymorphicData)(bucketRootValue)) {
673
+ throw coerceError(new Error("GrafastInternalError<db7fcda5-dc39-4568-a7ce-ee8acb88806b>: Expected polymorphic data"), this.locationDetails, mutablePath.slice(1));
674
+ }
675
+ }
676
+ const typeName = bucketRootValue[interfaces_js_1.$$concreteType];
677
+ const childOutputPlan = this.childByTypeName[typeName];
678
+ if (dev_js_1.isDev) {
679
+ assert.ok(typeName, "GrafastInternalError<fd3f3cf0-0789-4c74-a6cd-839c808896ed>: Could not determine concreteType for object");
680
+ assert.ok(childOutputPlan, `GrafastInternalError<a46999ef-41ff-4a22-bae9-fa37ff6e5f7f>: Could not determine the OutputPlan to use for '${typeName}' from '${bucket.layerPlan}'`);
681
+ }
682
+ const directChild = bucket.children[childOutputPlan.layerPlan.id];
683
+ if (directChild !== undefined) {
684
+ return childOutputPlan[asString ? "executeString" : "execute"](root, mutablePath, directChild.bucket, directChild.map.get(bucketIndex));
685
+ }
686
+ else {
687
+ const c = getChildBucketAndIndex(childOutputPlan.layerPlan, this, bucket, bucketIndex);
688
+ if (!c) {
689
+ throw new Error("GrafastInternalError<691509d8-31fa-4cfe-a6df-dcba21bd521f>: polymorphic executor couldn't determine child bucket");
690
+ }
691
+ const [childBucket, childBucketIndex] = c;
692
+ return childOutputPlan[asString ? "executeString" : "execute"](root, mutablePath, childBucket, childBucketIndex);
693
+ }
694
+ },
695
+ nameExtra: "polymorphic",
715
696
  asString,
716
697
  });
717
698
  }
@@ -719,75 +700,94 @@ const polymorphicExecutor = makePolymorphicExecutor(false);
719
700
  const polymorphicExecutorString = makePolymorphicExecutor(true);
720
701
  function makeArrayExecutor(childIsNonNull, canStream, asString) {
721
702
  return makeExecutor({
722
- inner: (0, tamedevil_1.default) `\
723
- if (!Array.isArray(bucketRootValue)) {
724
- console.warn(\`Hit fallback for value \${${ref_inspect}(bucketRootValue)} coercion to mode 'array'\`);
725
- return ${asString ? te_nullString : te_null};
726
- }
727
-
728
- const childOutputPlan = this.child;
729
- const l = bucketRootValue.length;
730
- let fieldResult;
731
- ${asString ? te_letString : te_constDataEqualsEmptyArray}
732
- if (l === 0) {
733
- ${asString ? te_stringEqualsEmptyArrayString : te_noopComment}
734
- } else {
735
- ${asString ? te_stringEqualsLeftSquareBraceString : tamedevil_1.default.blank}\
736
- const mutablePathIndex = mutablePath.push(-1) - 1;
737
-
738
- // Now to populate the children...
739
- const directChild = bucket.children[childOutputPlan.layerPlan.id];
740
- let childBucket, childBucketIndex, lookup;
741
- if (directChild !== undefined) {
742
- childBucket = directChild.bucket;
743
- lookup = directChild.map.get(bucketIndex)
744
- }
745
- for (let i = 0; i < l; i++) {
746
- if (directChild !== undefined) {
747
- childBucketIndex = lookup[i];
748
- } else {
749
- const c = ${ref_getChildBucketAndIndex}(
750
- childOutputPlan,
751
- this,
752
- bucket,
753
- bucketIndex,
754
- i,
755
- );
756
- if (c !== null) {
757
- ([childBucket, childBucketIndex] = c);
758
- } else {
759
- childBucket = childBucketIndex = null;
760
- }
761
- }
762
-
763
- mutablePath[mutablePathIndex] = i;
764
- ${asString ? te_ifIGt0StrPlusEqualComma : tamedevil_1.default.blank}
765
- ${makeExecuteChildPlanCode(asString ? te_stringPlusEquals : te_dataIEquals, te_thisDotLocationDetails, te_childOutputPlan, childIsNonNull, asString)}
766
- }
767
-
768
- mutablePath.length = mutablePathIndex;
769
- ${asString ? te_stringPlusEqualsRbracket : tamedevil_1.default.blank}
770
- }
771
- ${canStream
772
- ? (0, tamedevil_1.default) `\
773
- const stream = bucketRootValue[${ref_$$streamMore}] /* as | AsyncIterableIterator<any> | undefined*/;
774
- if (stream !== undefined) {
775
- root.streams.push({
776
- root,
777
- path: mutablePath.slice(1),
778
- bucket,
779
- bucketIndex,
780
- outputPlan: childOutputPlan,
781
- label: childOutputPlan.layerPlan.reason.stream?.label,
782
- stream,
783
- startIndex: bucketRootValue.length,
784
- });
785
- }`
786
- : tamedevil_1.default.blank}
787
-
788
- return ${asString ? te_string : te_data};
789
- `,
790
- nameExtra: (0, tamedevil_1.default) `array${childIsNonNull ? te_underscoreNonNull : tamedevil_1.default.blank}${canStream ? te_underscoreStream : tamedevil_1.default.blank}`,
703
+ inner(bucketRootValue, root, mutablePath, bucket, bucketIndex, rawBucketRootValue, bucketRootFlags) {
704
+ if (!Array.isArray(bucketRootValue)) {
705
+ console.warn(`Hit fallback for value ${(0, inspect_js_1.inspect)(bucketRootValue)} coercion to mode 'array'`);
706
+ return (asString ? "null" : null);
707
+ }
708
+ if (this.child === null) {
709
+ throw new Error(`GrafastInternalError<365fd45e-2939-411b-92a6-4f6875d8fbd3>: ${this} has no child output plan?!`);
710
+ }
711
+ const childOutputPlan = this.child;
712
+ const l = bucketRootValue.length;
713
+ let string;
714
+ let data;
715
+ if (l === 0) {
716
+ if (asString) {
717
+ string = "[]";
718
+ }
719
+ else {
720
+ data = [];
721
+ }
722
+ }
723
+ else {
724
+ if (asString) {
725
+ string = "[";
726
+ }
727
+ else {
728
+ data = [];
729
+ }
730
+ const mutablePathIndex = mutablePath.push(-1) - 1;
731
+ // Now to populate the children...
732
+ const directChild = bucket.children[childOutputPlan.layerPlan.id];
733
+ let childBucket, childBucketIndex, lookup;
734
+ if (directChild !== undefined) {
735
+ childBucket = directChild.bucket;
736
+ lookup = directChild.map.get(bucketIndex);
737
+ }
738
+ for (let i = 0; i < l; i++) {
739
+ if (directChild !== undefined) {
740
+ childBucketIndex = lookup[i];
741
+ }
742
+ else {
743
+ const c = getChildBucketAndIndex(childOutputPlan.layerPlan, this, bucket, bucketIndex, i);
744
+ if (c !== null) {
745
+ [childBucket, childBucketIndex] = c;
746
+ }
747
+ else {
748
+ childBucket = childBucketIndex = null;
749
+ }
750
+ }
751
+ mutablePath[mutablePathIndex] = i;
752
+ if (asString) {
753
+ if (i > 0) {
754
+ string += ",";
755
+ }
756
+ }
757
+ const val = executeChildPlan(this, this.locationDetails, childOutputPlan, childIsNonNull, asString, childBucket, childBucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags);
758
+ if (asString) {
759
+ string += val;
760
+ }
761
+ else {
762
+ data[i] = val;
763
+ }
764
+ }
765
+ mutablePath.length = mutablePathIndex;
766
+ if (asString) {
767
+ string += "]";
768
+ }
769
+ }
770
+ if (canStream) {
771
+ const stream = bucketRootValue[interfaces_js_1.$$streamMore];
772
+ if (stream !== undefined) {
773
+ const labelStepId = childOutputPlan.layerPlan.reason.stream?.labelStepId;
774
+ root.streams.push({
775
+ root,
776
+ path: mutablePath.slice(1),
777
+ bucket,
778
+ bucketIndex,
779
+ outputPlan: childOutputPlan,
780
+ label: labelStepId != null
781
+ ? bucket.store.get(labelStepId)?.unaryValue()
782
+ : undefined,
783
+ stream,
784
+ startIndex: bucketRootValue.length,
785
+ });
786
+ }
787
+ }
788
+ return (asString ? string : data);
789
+ },
790
+ nameExtra: `array${childIsNonNull ? "_nonNull" : ""}${canStream ? "_stream" : ""}`,
791
791
  asString,
792
792
  });
793
793
  }
@@ -807,7 +807,7 @@ const arrayExecutorString_nonNullable_streaming = makeArrayExecutor(true, true,
807
807
  *
808
808
  * ENHANCE: write our own introspection execution!
809
809
  */
810
- const introspect = (root, outputPlan, mutablePath, asString) => {
810
+ function introspect(root, outputPlan, mutablePath, asString) {
811
811
  const { locationDetails } = outputPlan;
812
812
  const { field: rawField, introspectionCacheByVariableValues, variableNames, } = outputPlan.type;
813
813
  const field = {
@@ -840,7 +840,7 @@ const introspect = (root, outputPlan, mutablePath, asString) => {
840
840
  const canonical = JSON.stringify(variableValues);
841
841
  const cached = introspectionCacheByVariableValues.get(canonical);
842
842
  if (cached !== undefined) {
843
- return asString ? JSON.stringify(cached) : cached;
843
+ return (asString ? JSON.stringify(cached) : cached);
844
844
  }
845
845
  const graphqlResult = executeSync({
846
846
  schema: outputPlan.layerPlan.operationPlan.schema,
@@ -861,167 +861,155 @@ const introspect = (root, outputPlan, mutablePath, asString) => {
861
861
  }
862
862
  const result = graphqlResult.data.a;
863
863
  introspectionCacheByVariableValues.set(canonical, result);
864
- return asString ? JSON.stringify(result) : result;
865
- };
866
- const ref_introspect = tamedevil_1.default.ref(introspect, "introspect");
864
+ return (asString ? JSON.stringify(result) : result);
865
+ }
867
866
  const introspectionExecutor = makeExecutor({
868
- inner: (0, tamedevil_1.default) ` return ${ref_introspect}(root, this, mutablePath, false)`,
869
- nameExtra: tamedevil_1.default.cache `introspection`,
867
+ inner(_bucketRootValue, root, mutablePath) {
868
+ return introspect(root, this, mutablePath, false);
869
+ },
870
+ nameExtra: `introspection`,
870
871
  asString: false,
871
872
  skipNullHandling: true,
872
873
  });
873
874
  const introspectionExecutorString = makeExecutor({
874
- inner: (0, tamedevil_1.default) ` return ${ref_introspect}(root, this, mutablePath, true)`,
875
- nameExtra: tamedevil_1.default.cache `introspection`,
875
+ inner(_bucketRootValue, root, mutablePath) {
876
+ return introspect(root, this, mutablePath, true);
877
+ },
878
+ nameExtra: `introspection`,
876
879
  asString: true,
877
880
  skipNullHandling: true,
878
881
  });
879
882
  const SAFE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
880
883
  function makeObjectExecutor(typeName, fieldTypes, hasDeferredOutputPlans,
881
884
  // this.type.mode === "root",
882
- isRoot, asString, callback) {
885
+ isRoot, asString) {
883
886
  if (!SAFE_NAME.test(typeName)) {
884
887
  throw new Error(`Unsafe type name: ${typeName}; doesn't conform to 'Name' in the GraphQL spec`);
885
888
  }
886
- const keys = [];
887
- const fieldSpecs = [];
888
- let signature = (asString ? "s" : "o") +
889
- (isRoot ? "r" : "") +
890
- (hasDeferredOutputPlans ? "d" : "");
891
- let hasChildBucketReference = false;
892
- for (const [key, fieldSpec] of Object.entries(fieldTypes)) {
893
- if (!SAFE_NAME.test(key)) {
889
+ if (dev_js_1.isDev) {
890
+ if (Object.getPrototypeOf(fieldTypes) !== null) {
891
+ throw new Error(`GrafastInternalError<3d8e3547-d818-44e1-a076-16b828e3a34d>: fieldTypes must have a null prototype`);
892
+ }
893
+ }
894
+ const fieldDigests = Object.entries(fieldTypes).map(([responseKey, fieldSpec], i) => {
895
+ // NOTE: this code relies on the fact that fieldName and typeName do
896
+ // not require any quoting in JSON/JS - they must conform to GraphQL
897
+ // `Name`.
898
+ if (!SAFE_NAME.test(responseKey)) {
894
899
  // This should not be able to happen if the GraphQL operation is valid
895
- throw new Error(`Unsafe key: ${key}; doesn't conform to 'Name' in the GraphQL spec`);
900
+ throw new Error(`Unsafe key: ${responseKey}; doesn't conform to 'Name' in the GraphQL spec`);
896
901
  }
897
- keys.push(key);
898
- fieldSpecs.push(fieldSpec);
899
902
  const { fieldType, sameBucket } = fieldSpec;
903
+ const addComma = asString && i > 0;
900
904
  switch (fieldType) {
901
905
  case "__typename": {
902
- signature += "_";
903
- break;
906
+ return {
907
+ isTypeName: true,
908
+ addComma,
909
+ responseKey,
910
+ stringValue: asString ? `"${responseKey}":"${typeName}"` : null,
911
+ };
904
912
  }
913
+ case "outputPlan!":
905
914
  case "outputPlan?": {
906
- signature += "?";
907
- break;
908
- }
909
- case "outputPlan!": {
910
- signature += "!";
911
- break;
915
+ return {
916
+ isTypeName: false,
917
+ addComma,
918
+ responseKey,
919
+ stringPrefix: asString ? `"${responseKey}":` : null,
920
+ sameBucket,
921
+ isNonNull: fieldType === "outputPlan!",
922
+ };
912
923
  }
913
924
  default: {
914
925
  const never = fieldType;
915
- throw new Error(`Unsupported field type '${never}'`);
926
+ throw new Error(`GrafastInternalError<879082f4-fe6f-4112-814f-852b9932ca83>: unsupported key type ${never}`);
916
927
  }
917
928
  }
918
- if (!sameBucket) {
919
- hasChildBucketReference = true;
920
- signature += "~";
921
- }
922
- }
923
- withObjectExecutorFactory(signature, fieldSpecs, hasDeferredOutputPlans, isRoot, asString, hasChildBucketReference, (factory) => {
924
- const fn = factory(typeName, ...keys);
925
- callback(fn);
926
929
  });
927
- }
928
- const makeObjectExecutorCache = new lru_1.default({
929
- maxLength: 1000,
930
- });
931
- const makingObjectExecutorCallbacks = new Map();
932
- function withObjectExecutorFactory(signature, fieldSpecs, hasDeferredOutputPlans, isRoot, asString, hasChildBucketReference, callback) {
933
- const fn = makeObjectExecutorCache.get(signature);
934
- if (fn !== undefined) {
935
- return callback(fn);
936
- }
937
- const building = makingObjectExecutorCallbacks.get(signature);
938
- if (building !== undefined) {
939
- building.push(callback);
940
- return;
941
- }
942
- const callbacks = [callback];
943
- makingObjectExecutorCallbacks.set(signature, callbacks);
944
- const inner = (0, tamedevil_1.default) `\
945
- ${asString ? te_letStringLbrace : te_constObjEqualsObjectCreateNull}
946
- const { keys } = this;
947
- const mutablePathIndex = mutablePath.push("!") - 1;
948
- let spec${hasChildBucketReference ? te_childBucketCBIDC : tamedevil_1.default.blank}, fieldResult;
949
-
950
- ${tamedevil_1.default.join(fieldSpecs.map(({ fieldType, sameBucket }, i) => {
951
- const te_fieldNameI = tamedevil_1.default.identifier(`fieldName_${i}`);
952
- switch (fieldType) {
953
- case "__typename": {
954
- if (asString) {
955
- // NOTE: this code relies on the fact that fieldName and typeName do
956
- // not require any quoting in JSON/JS - they must conform to GraphQL
957
- // `Name`.
958
- return (0, tamedevil_1.default) ` string += \`${i === 0 ? tamedevil_1.default.blank : te_comma}"\${${te_fieldNameI}}":"\${typeName}"\`;\n`;
930
+ return makeExecutor({
931
+ inner(bucketRootValue, root, mutablePath, bucket, bucketIndex, rawBucketRootValue, bucketRootFlags) {
932
+ let string = asString ? "{" : undefined;
933
+ const obj = asString
934
+ ? undefined
935
+ : Object.create(null);
936
+ const keys = this.keys;
937
+ const mutablePathIndex = mutablePath.push("!") - 1;
938
+ for (const digest of fieldDigests) {
939
+ if (digest.addComma) {
940
+ string += ",";
941
+ }
942
+ const responseKey = digest.responseKey;
943
+ if (digest.isTypeName) {
944
+ if (asString) {
945
+ string += digest.stringValue;
946
+ }
947
+ else {
948
+ obj[responseKey] = typeName;
949
+ }
959
950
  }
960
951
  else {
961
- return (0, tamedevil_1.default) ` obj[${te_fieldNameI}] = typeName;\n`;
952
+ mutablePath[mutablePathIndex] = responseKey;
953
+ const spec = keys[responseKey];
954
+ if (digest.sameBucket) {
955
+ const val = executeChildPlan(this, spec.locationDetails, spec.outputPlan, digest.isNonNull, asString, bucket, bucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags);
956
+ if (asString) {
957
+ string += digest.stringPrefix;
958
+ string += val;
959
+ }
960
+ else {
961
+ obj[responseKey] = val;
962
+ }
963
+ }
964
+ else {
965
+ const directChild = bucket.children[spec.outputPlan.layerPlan.id];
966
+ let childBucket, childBucketIndex;
967
+ if (directChild !== undefined) {
968
+ childBucket = directChild.bucket;
969
+ childBucketIndex = directChild.map.get(bucketIndex);
970
+ }
971
+ else {
972
+ const c = getChildBucketAndIndex(spec.outputPlan.layerPlan, this, bucket, bucketIndex);
973
+ if (c !== null) {
974
+ [childBucket, childBucketIndex] = c;
975
+ }
976
+ else {
977
+ childBucket = childBucketIndex = null;
978
+ }
979
+ }
980
+ const val = executeChildPlan(this, spec.locationDetails, spec.outputPlan, digest.isNonNull, asString, childBucket, childBucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags);
981
+ if (asString) {
982
+ string += digest.stringPrefix;
983
+ string += val;
984
+ }
985
+ else {
986
+ obj[responseKey] = val;
987
+ }
988
+ }
962
989
  }
963
990
  }
964
- case "outputPlan!":
965
- case "outputPlan?": {
966
- return (0, tamedevil_1.default) `\
967
- mutablePath[mutablePathIndex] = ${te_fieldNameI};
968
- spec = keys[${te_fieldNameI}];
969
- ${asString
970
- ? (0, tamedevil_1.default) ` string += \`${i === 0 ? tamedevil_1.default.blank : te_comma}"\${${te_fieldNameI}}":\`;
971
- `
972
- : tamedevil_1.default.blank}\
973
- ${sameBucket
974
- ? (0, tamedevil_1.default) `\
975
- ${makeExecuteChildPlanCode(asString ? te_stringPlusEquals : (0, tamedevil_1.default) `obj[${te_fieldNameI}] =`, te_specDotLocationDetails, te_specDotOutputPlan, fieldType === "outputPlan!", asString, te_bucket, te_bucketIndex)}`
976
- : (0, tamedevil_1.default) `\
977
- directChild = bucket.children[spec.outputPlan.layerPlanId];
978
- if (directChild !== undefined) {
979
- childBucket = directChild.bucket;
980
- childBucketIndex = directChild.map.get(bucketIndex);
981
- } else {
982
- const c = ${ref_getChildBucketAndIndex}(
983
- spec.outputPlan,
984
- this,
985
- bucket,
986
- bucketIndex,
987
- );
988
- if (c !== null) {
989
- ([childBucket, childBucketIndex] = c);
990
- } else {
991
- childBucket = childBucketIndex = null;
992
- }
993
- }
994
- ${makeExecuteChildPlanCode(asString ? te_stringPlusEquals : (0, tamedevil_1.default) `obj[${te_fieldNameI}] =`, te_specDotLocationDetails, te_specDotOutputPlan, fieldType === "outputPlan!", asString)}`}
995
- `;
991
+ mutablePath.length = mutablePathIndex;
992
+ if (asString) {
993
+ string += "}";
996
994
  }
997
- default: {
998
- const never = fieldType;
999
- throw new Error(`GrafastInternalError<879082f4-fe6f-4112-814f-852b9932ca83>: unsupported key type ${never}`);
995
+ if (hasDeferredOutputPlans) {
996
+ // Everything seems okay; queue any deferred payloads
997
+ for (const defer of this.deferredOutputPlans) {
998
+ root.queue.push({
999
+ root,
1000
+ path: mutablePath.slice(1),
1001
+ bucket,
1002
+ bucketIndex,
1003
+ outputPlan: defer,
1004
+ label: defer.type.deferLabel,
1005
+ });
1006
+ }
1000
1007
  }
1001
- }
1002
- }), "\n")}
1003
-
1004
- mutablePath.length = mutablePathIndex;
1005
- ${asString ? te_stringPlusEqualsRbrace : tamedevil_1.default.blank}\
1006
- ${hasDeferredOutputPlans ? te_handleDeferred : tamedevil_1.default.blank}
1007
- return ${asString ? te_string : te_obj};`;
1008
- const executorExpression = makeExecutorExpression({
1009
- inner: inner,
1010
- nameExtra: te_object,
1008
+ return (asString ? string : obj);
1009
+ },
1010
+ nameExtra: "object",
1011
1011
  asString,
1012
1012
  skipNullHandling: isRoot,
1013
- preamble: tamedevil_1.default.blank,
1014
- });
1015
- const factoryExpression = (0, tamedevil_1.default) `\
1016
- function objectExecutorFactory(typeName${tamedevil_1.default.join(fieldSpecs.map((_, i) => (0, tamedevil_1.default) `, ${tamedevil_1.default.identifier(`fieldName_${i}`)}`), "")}) {
1017
- return ${executorExpression};
1018
- }`;
1019
- tamedevil_1.default.runInBatch(factoryExpression, (factory) => {
1020
- makeObjectExecutorCache.set(signature, factory);
1021
- makingObjectExecutorCallbacks.delete(signature);
1022
- for (const callback of callbacks) {
1023
- callback(factory);
1024
- }
1025
1013
  });
1026
1014
  }
1027
1015
  const makeCache = new lru_1.default({