grafast 0.1.1-beta.11 → 0.1.1-beta.13
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.
- package/README.md +0 -3
- package/dist/args.js +8 -2
- package/dist/constraints.d.ts +15 -1
- package/dist/constraints.js +40 -1
- package/dist/engine/LayerPlan.d.ts +1 -0
- package/dist/engine/LayerPlan.js +62 -9
- package/dist/engine/OperationPlan.js +372 -274
- package/dist/engine/OutputPlan.d.ts +6 -5
- package/dist/engine/OutputPlan.js +423 -444
- package/dist/engine/executeBucket.js +36 -77
- package/dist/error.d.ts +13 -0
- package/dist/grafastGraphql.d.ts +5 -5
- package/dist/graphqlCollectFields.d.ts +6 -0
- package/dist/graphqlCollectFields.js +14 -8
- package/dist/interfaces.d.ts +18 -0
- package/dist/interfaces.js +0 -2
- package/dist/mermaid.js +20 -11
- package/dist/operationPlan-input.js +8 -1
- package/dist/planJSONInterfaces.d.ts +2 -0
- package/dist/prepare.js +3 -3
- package/dist/step.d.ts +5 -5
- package/dist/step.js +53 -2
- package/dist/steps/__flag.d.ts +3 -2
- package/dist/steps/__inputObject.d.ts +1 -0
- package/dist/steps/__inputObject.js +36 -0
- package/dist/steps/__item.d.ts +3 -3
- package/dist/steps/__trackedValue.d.ts +8 -0
- package/dist/steps/__trackedValue.js +40 -0
- package/dist/steps/__value.d.ts +2 -1
- package/dist/steps/constant.d.ts +2 -0
- package/dist/steps/constant.js +12 -0
- package/dist/steps/graphqlResolver.js +8 -5
- package/dist/steps/listen.d.ts +2 -2
- package/dist/steps/object.d.ts +1 -1
- package/dist/steps/sideEffect.d.ts +0 -1
- package/dist/thereCanBeOnlyOne.js +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -13,66 +13,6 @@ const interfaces_js_1 = require("../interfaces.js");
|
|
|
13
13
|
const polymorphic_js_1 = require("../polymorphic.js");
|
|
14
14
|
const access_js_1 = require("../steps/access.js");
|
|
15
15
|
const { executeSync, GraphQLBoolean, GraphQLError, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLString, isObjectType, Kind, OperationTypeNode, } = graphql;
|
|
16
|
-
const ref_FLAG_ERROR = tamedevil_1.default.ref(interfaces_js_1.FLAG_ERROR, "FLAG_ERROR");
|
|
17
|
-
const ref_coerceError = tamedevil_1.default.ref(coerceError, "coerceError");
|
|
18
|
-
const ref_nonNullError = tamedevil_1.default.ref(nonNullError, "nonNullError");
|
|
19
|
-
const ref_stringifyString = tamedevil_1.default.ref(tamedevil_1.stringifyString, "stringifyString");
|
|
20
|
-
const ref_stringifyJSON = tamedevil_1.default.ref(tamedevil_1.stringifyJSON, "stringifyJSON");
|
|
21
|
-
const ref_isPolymorphicData = tamedevil_1.default.ref(polymorphic_js_1.isPolymorphicData, "isPolymorphicData");
|
|
22
|
-
const ref_$$concreteType = tamedevil_1.default.ref(interfaces_js_1.$$concreteType, "$$concreteType");
|
|
23
|
-
const ref_assert = tamedevil_1.default.ref(assert, "assert");
|
|
24
|
-
const ref_getChildBucketAndIndex = tamedevil_1.default.ref(getChildBucketAndIndex, "getChildBucketAndIndex");
|
|
25
|
-
const ref_inspect = tamedevil_1.default.ref(inspect_js_1.inspect, "inspect");
|
|
26
|
-
const ref_$$streamMore = tamedevil_1.default.ref(interfaces_js_1.$$streamMore, "$$streamMore");
|
|
27
|
-
const te_String = (0, tamedevil_1.default) `String`;
|
|
28
|
-
const te_nullIsFineComment = (0, tamedevil_1.default) `// root/introspection, null is fine`;
|
|
29
|
-
const te_nullString = (0, tamedevil_1.default) `"null"`;
|
|
30
|
-
const te_null = (0, tamedevil_1.default) `null`;
|
|
31
|
-
const te_childBucket = (0, tamedevil_1.default) `childBucket`;
|
|
32
|
-
const te_childBucketIndex = (0, tamedevil_1.default) `childBucketIndex`;
|
|
33
|
-
const te_executeString = (0, tamedevil_1.default) `executeString`;
|
|
34
|
-
const te_execute = (0, tamedevil_1.default) `execute`;
|
|
35
|
-
const te_polymorphic = (0, tamedevil_1.default) `polymorphic`;
|
|
36
|
-
const te_letStringLbrace = (0, tamedevil_1.default) `let string = "{";`;
|
|
37
|
-
const te_stringPlusEquals = (0, tamedevil_1.default) `string +=`;
|
|
38
|
-
const te_stringPlusEqualsRbrace = (0, tamedevil_1.default) ` string += "}";\n`;
|
|
39
|
-
const te_stringPlusEqualsRbracket = (0, tamedevil_1.default) ` string += "]";\n`;
|
|
40
|
-
const te_constObjEqualsObjectCreateNull = (0, tamedevil_1.default) `const obj = Object.create(null);`;
|
|
41
|
-
const te_comma = (0, tamedevil_1.default) `,`;
|
|
42
|
-
const te_specDotLocationDetails = (0, tamedevil_1.default) `spec.locationDetails`;
|
|
43
|
-
const te_thisDotLocationDetails = (0, tamedevil_1.default) `this.locationDetails`;
|
|
44
|
-
const te_specDotOutputPlan = (0, tamedevil_1.default) `spec.outputPlan`;
|
|
45
|
-
const te_bucket = (0, tamedevil_1.default) `bucket`;
|
|
46
|
-
const te_bucketIndex = (0, tamedevil_1.default) `bucketIndex`;
|
|
47
|
-
const te_handleDeferred = (0, tamedevil_1.default) `
|
|
48
|
-
// Everything seems okay; queue any deferred payloads
|
|
49
|
-
for (const defer of this.deferredOutputPlans) {
|
|
50
|
-
root.queue.push({
|
|
51
|
-
root,
|
|
52
|
-
path: mutablePath.slice(1),
|
|
53
|
-
bucket,
|
|
54
|
-
bucketIndex,
|
|
55
|
-
outputPlan: defer,
|
|
56
|
-
label: defer.type.deferLabel,
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
`;
|
|
60
|
-
const te_string = (0, tamedevil_1.default) `string`;
|
|
61
|
-
const te_object = (0, tamedevil_1.default) `object`;
|
|
62
|
-
const te_obj = (0, tamedevil_1.default) `obj`;
|
|
63
|
-
const te_data = (0, tamedevil_1.default) `data`;
|
|
64
|
-
const te_commonErrorHandler = tamedevil_1.default.ref(commonErrorHandler, "handleError");
|
|
65
|
-
const te_childBucketCBIDC = (0, tamedevil_1.default) `, childBucket, childBucketIndex, directChild`;
|
|
66
|
-
const te_letString = (0, tamedevil_1.default) `let string;`;
|
|
67
|
-
const te_constDataEqualsEmptyArray = (0, tamedevil_1.default) `const data = [];`;
|
|
68
|
-
const te_stringEqualsEmptyArrayString = (0, tamedevil_1.default) ` string = "[]";`;
|
|
69
|
-
const te_stringEqualsLeftSquareBraceString = (0, tamedevil_1.default) ` string = "[";\n`;
|
|
70
|
-
const te_noopComment = (0, tamedevil_1.default) ` /* noop */`;
|
|
71
|
-
const te_ifIGt0StrPlusEqualComma = (0, tamedevil_1.default) `\n if (i > 0) { string += ","; }\n`;
|
|
72
|
-
const te_dataIEquals = (0, tamedevil_1.default) `data[i] =`;
|
|
73
|
-
const te_childOutputPlan = (0, tamedevil_1.default) `childOutputPlan`;
|
|
74
|
-
const te_underscoreNonNull = (0, tamedevil_1.default) `_nonNull`;
|
|
75
|
-
const te_underscoreStream = (0, tamedevil_1.default) `_stream`;
|
|
76
16
|
/**
|
|
77
17
|
* Defines a way of taking a layerPlan and converting it into an output value.
|
|
78
18
|
*
|
|
@@ -102,6 +42,8 @@ class OutputPlan {
|
|
|
102
42
|
this.type = type;
|
|
103
43
|
/**
|
|
104
44
|
* Appended to the root step when accessed to avoid the need for AccessSteps
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
105
47
|
*/
|
|
106
48
|
this.processRoot = null;
|
|
107
49
|
/**
|
|
@@ -126,6 +68,8 @@ class OutputPlan {
|
|
|
126
68
|
layerPlan.operationPlan.stepTracker.addOutputPlan(this);
|
|
127
69
|
this.childByTypeName =
|
|
128
70
|
this.type.mode === "polymorphic" ? Object.create(null) : undefined;
|
|
71
|
+
// NOTE: this may be cleared during `this.finalize()`
|
|
72
|
+
this.sideEffectStep = layerPlan.latestSideEffectStep;
|
|
129
73
|
}
|
|
130
74
|
print() {
|
|
131
75
|
const type = this.type;
|
|
@@ -158,7 +102,7 @@ class OutputPlan {
|
|
|
158
102
|
}
|
|
159
103
|
}
|
|
160
104
|
toString() {
|
|
161
|
-
return `OutputPlan<${this.type.mode}∈${this.layerPlan.id}!${this.rootStep.id}>`;
|
|
105
|
+
return `OutputPlan<${this.type.mode}${this.sideEffectStep ? `^${this.sideEffectStep.id}` : ""}∈${this.layerPlan.id}!${this.rootStep.id}>`;
|
|
162
106
|
}
|
|
163
107
|
addChild(type, key, child) {
|
|
164
108
|
if (this.type.mode === "root" || this.type.mode === "object") {
|
|
@@ -251,7 +195,7 @@ class OutputPlan {
|
|
|
251
195
|
// By just reusing the same path over and over we don't need to allocate
|
|
252
196
|
// more memory for more arrays; but we must be _incredibly_ careful to
|
|
253
197
|
// ensure any changes to it are reversed.
|
|
254
|
-
_mutablePath, _bucket, _bucketIndex) {
|
|
198
|
+
_mutablePath, _bucket, _bucketIndex, _rawBucketRootValue, _bucketRootFlags) {
|
|
255
199
|
throw new Error(`OutputPlan.execute has yet to be built!`);
|
|
256
200
|
}
|
|
257
201
|
// This gets replaced with a mode-specific executor
|
|
@@ -259,12 +203,21 @@ class OutputPlan {
|
|
|
259
203
|
// By just reusing the same path over and over we don't need to allocate
|
|
260
204
|
// more memory for more arrays; but we must be _incredibly_ careful to
|
|
261
205
|
// ensure any changes to it are reversed.
|
|
262
|
-
_mutablePath, _bucket, _bucketIndex) {
|
|
206
|
+
_mutablePath, _bucket, _bucketIndex, _rawBucketRootValue, _bucketRootFlags) {
|
|
263
207
|
throw new Error(`OutputPlan.executeString has yet to be built!`);
|
|
264
208
|
}
|
|
265
209
|
optimize() {
|
|
210
|
+
// This optimization works by ridding us of access steps at the very end of
|
|
211
|
+
// paths and just accessing properties directly. In rare circumstances
|
|
212
|
+
// involving untethered side effects in earlier versions this could lead to
|
|
213
|
+
// errors being skipped and data generated previous to the error being
|
|
214
|
+
// returned; but OutputPlans now check the latestSideEffectStep so this
|
|
215
|
+
// should be safe aga.
|
|
266
216
|
const $root = this.layerPlan.operationPlan.dangerouslyGetStep(this.rootStep.id);
|
|
267
|
-
if ($root instanceof index_js_1.AccessStep &&
|
|
217
|
+
if ($root instanceof index_js_1.AccessStep &&
|
|
218
|
+
$root.fallback === undefined &&
|
|
219
|
+
$root.implicitSideEffectStep === null &&
|
|
220
|
+
(!this.sideEffectStep || !(0, index_js_1.stepADependsOnStepB)($root, this.sideEffectStep))) {
|
|
268
221
|
const expressionDetails = $root.unbatchedExecute[access_js_1.expressionSymbol];
|
|
269
222
|
if (expressionDetails !== undefined) {
|
|
270
223
|
// @ts-ignore
|
|
@@ -278,6 +231,19 @@ class OutputPlan {
|
|
|
278
231
|
}
|
|
279
232
|
}
|
|
280
233
|
finalize() {
|
|
234
|
+
// Clear the sideEffectStep if the rootStep explicitly depends on it.
|
|
235
|
+
// NOTE: this occurs here since more dependencies could have been added to
|
|
236
|
+
// $root after `this` was created.
|
|
237
|
+
const $sideEffect = this.sideEffectStep;
|
|
238
|
+
if ($sideEffect) {
|
|
239
|
+
const $root = this.rootStep;
|
|
240
|
+
if ($root === $sideEffect ||
|
|
241
|
+
$root.implicitSideEffectStep === $sideEffect ||
|
|
242
|
+
(0, index_js_1.stepADependsOnStepB)($root, $sideEffect)) {
|
|
243
|
+
// It's marked readonly, but we override it anyway
|
|
244
|
+
this.sideEffectStep = null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
281
247
|
// Build the executor
|
|
282
248
|
switch (this.type.mode) {
|
|
283
249
|
case "null": {
|
|
@@ -370,12 +336,8 @@ class OutputPlan {
|
|
|
370
336
|
spec.outputPlan.layerPlan.id === this.layerPlan.id,
|
|
371
337
|
};
|
|
372
338
|
}
|
|
373
|
-
makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", false
|
|
374
|
-
|
|
375
|
-
});
|
|
376
|
-
makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", true, (fn) => {
|
|
377
|
-
this.executeString = fn;
|
|
378
|
-
});
|
|
339
|
+
this.execute = makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", false);
|
|
340
|
+
this.executeString = makeObjectExecutor(type.typeName, digestFieldTypes, this.deferredOutputPlans.length > 0, type.mode === "root", true);
|
|
379
341
|
break;
|
|
380
342
|
}
|
|
381
343
|
default: {
|
|
@@ -420,17 +382,20 @@ exports.nonNullError = nonNullError;
|
|
|
420
382
|
*
|
|
421
383
|
* @internal
|
|
422
384
|
*/
|
|
423
|
-
function getChildBucketAndIndex(
|
|
385
|
+
function getChildBucketAndIndex(layerPlan, outputPlan, bucket, bucketIndex, arrayIndex = null) {
|
|
386
|
+
if (bucket.layerPlan === layerPlan) {
|
|
387
|
+
return [bucket, bucketIndex];
|
|
388
|
+
}
|
|
424
389
|
if ((arrayIndex == null) ===
|
|
425
390
|
(outputPlan != null && outputPlan.type.mode === "array")) {
|
|
426
391
|
throw new Error("GrafastInternalError<83d0e3cc-7eec-4185-85b4-846540288162>: arrayIndex must be supplied iff outputPlan is an array");
|
|
427
392
|
}
|
|
428
|
-
if (outputPlan != null &&
|
|
393
|
+
if (outputPlan != null && layerPlan === bucket.layerPlan) {
|
|
429
394
|
// Same layer; straightforward
|
|
430
395
|
return [bucket, bucketIndex];
|
|
431
396
|
}
|
|
432
|
-
const reversePath = [
|
|
433
|
-
let current =
|
|
397
|
+
const reversePath = [layerPlan];
|
|
398
|
+
let current = layerPlan;
|
|
434
399
|
while (!bucket.children[current.id]) {
|
|
435
400
|
current = current.parentLayerPlan;
|
|
436
401
|
if (!current) {
|
|
@@ -484,78 +449,112 @@ function getChildBucketAndIndex(childOutputPlan, outputPlan, bucket, bucketIndex
|
|
|
484
449
|
return [currentBucket, currentIndex];
|
|
485
450
|
}
|
|
486
451
|
exports.getChildBucketAndIndex = getChildBucketAndIndex;
|
|
487
|
-
function
|
|
488
|
-
const {
|
|
489
|
-
|
|
490
|
-
(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
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
|
+
const bucketRootValue = this.processRoot !== null
|
|
471
|
+
? this.processRoot(rawBucketRootValue, bucketRootFlags)
|
|
472
|
+
: rawBucketRootValue;
|
|
473
|
+
const earlyReturn = preamble?.call(this, bucketRootValue);
|
|
474
|
+
if (earlyReturn !== undefined) {
|
|
475
|
+
return earlyReturn;
|
|
476
|
+
}
|
|
477
|
+
if (bucketRootFlags & interfaces_js_1.FLAG_ERROR) {
|
|
478
|
+
throw coerceError(bucketRootValue, this.locationDetails, mutablePath.slice(1));
|
|
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;
|
|
510
488
|
}
|
|
511
|
-
function
|
|
512
|
-
const
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
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
|
+
}
|
|
518
514
|
}
|
|
519
|
-
}
|
|
520
|
-
function makeExecuteChildPlanCode(setTargetOrReturn, locationDetails, childOutputPlan, isNonNull, asString, childBucket = te_childBucket, childBucketIndex = te_childBucketIndex) {
|
|
521
|
-
const te_childOutputPlanExecute = (0, tamedevil_1.default) `${childOutputPlan}.${asString ? te_executeString : te_execute}(
|
|
522
|
-
root,
|
|
523
|
-
mutablePath,
|
|
524
|
-
${childBucket},
|
|
525
|
-
${childBucketIndex},
|
|
526
|
-
${childBucket}.rootStep === this.rootStep ? rawBucketRootValue : undefined,
|
|
527
|
-
${childBucket}.rootStep === this.rootStep ? bucketRootFlags : undefined
|
|
528
|
-
)`;
|
|
529
515
|
// This is the code that changes based on if the field is nullable or not
|
|
530
516
|
if (isNonNull) {
|
|
531
517
|
// No need to catch error
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
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;
|
|
543
535
|
}
|
|
544
536
|
else {
|
|
545
537
|
// Need to catch error and set null
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
+
}
|
|
559
558
|
}
|
|
560
559
|
}
|
|
561
560
|
function commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, root, streamCount, queueCount) {
|
|
@@ -573,97 +572,94 @@ function commonErrorHandler(e, locationDetails, mutablePath, mutablePathIndex, r
|
|
|
573
572
|
}
|
|
574
573
|
root.errors.push(error);
|
|
575
574
|
}
|
|
576
|
-
/*
|
|
577
|
-
* Below here we create the executors that can be shared across many different
|
|
578
|
-
* OutputPlans without having to be recreated (thus saving significant memory,
|
|
579
|
-
* and increasing the probability of optimization).
|
|
580
|
-
*/
|
|
581
575
|
const nullExecutor = makeExecutor({
|
|
582
|
-
inner:
|
|
583
|
-
nameExtra:
|
|
576
|
+
inner: () => null,
|
|
577
|
+
nameExtra: "null",
|
|
584
578
|
asString: false,
|
|
585
579
|
});
|
|
586
580
|
const nullExecutorString = makeExecutor({
|
|
587
|
-
inner:
|
|
588
|
-
nameExtra:
|
|
581
|
+
inner: () => "null",
|
|
582
|
+
nameExtra: `null`,
|
|
589
583
|
asString: true,
|
|
590
584
|
});
|
|
591
585
|
/* This is what leafExecutor should use if insideGraphQL (which isn't currently
|
|
592
|
-
|
|
593
|
-
`\
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
` */
|
|
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
|
+
` */
|
|
601
595
|
const leafExecutor = makeExecutor({
|
|
602
|
-
inner
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
nameExtra:
|
|
596
|
+
inner(bucketRootValue) {
|
|
597
|
+
return this.type.graphqlType.serialize(bucketRootValue);
|
|
598
|
+
},
|
|
599
|
+
nameExtra: `leaf`,
|
|
606
600
|
asString: false,
|
|
607
601
|
});
|
|
608
602
|
const leafExecutorString = makeExecutor({
|
|
609
|
-
inner
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
nameExtra:
|
|
603
|
+
inner(bucketRootValue) {
|
|
604
|
+
return (0, tamedevil_1.stringifyJSON)(this.type.graphqlType.serialize(bucketRootValue));
|
|
605
|
+
},
|
|
606
|
+
nameExtra: `leaf`,
|
|
613
607
|
asString: true,
|
|
614
608
|
});
|
|
615
609
|
const booleanLeafExecutorString = makeExecutor({
|
|
616
|
-
inner
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
nameExtra:
|
|
610
|
+
inner(bucketRootValue) {
|
|
611
|
+
const val = this.type.graphqlType.serialize(bucketRootValue);
|
|
612
|
+
return val === true ? "true" : "false";
|
|
613
|
+
},
|
|
614
|
+
nameExtra: `booleanLeaf`,
|
|
621
615
|
asString: true,
|
|
622
616
|
skipNullHandling: false,
|
|
623
|
-
preamble
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
617
|
+
preamble(bucketRootValue) {
|
|
618
|
+
if (bucketRootValue === true)
|
|
619
|
+
return "true";
|
|
620
|
+
if (bucketRootValue === false)
|
|
621
|
+
return "false";
|
|
622
|
+
},
|
|
627
623
|
});
|
|
628
624
|
const intLeafExecutorString = makeExecutor({
|
|
629
|
-
inner
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
nameExtra:
|
|
625
|
+
inner(bucketRootValue) {
|
|
626
|
+
return "" + this.type.graphqlType.serialize(bucketRootValue);
|
|
627
|
+
},
|
|
628
|
+
nameExtra: `intLeaf`,
|
|
633
629
|
asString: true,
|
|
634
630
|
skipNullHandling: false,
|
|
635
631
|
// Fast check to see if number is 32 bit integer
|
|
636
|
-
preamble
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
632
|
+
preamble(bucketRootValue) {
|
|
633
|
+
if ((bucketRootValue | 0) === bucketRootValue) {
|
|
634
|
+
return "" + bucketRootValue;
|
|
635
|
+
}
|
|
636
|
+
},
|
|
641
637
|
});
|
|
642
638
|
const floatLeafExecutorString = makeExecutor({
|
|
643
|
-
inner
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
nameExtra:
|
|
639
|
+
inner(bucketRootValue) {
|
|
640
|
+
return String(this.type.graphqlType.serialize(bucketRootValue));
|
|
641
|
+
},
|
|
642
|
+
nameExtra: `floatLeaf`,
|
|
647
643
|
asString: true,
|
|
648
644
|
skipNullHandling: false,
|
|
649
|
-
preamble
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
645
|
+
preamble(bucketRootValue) {
|
|
646
|
+
if (Number.isFinite(bucketRootValue)) {
|
|
647
|
+
return "" + bucketRootValue;
|
|
648
|
+
}
|
|
649
|
+
},
|
|
654
650
|
});
|
|
655
651
|
const stringLeafExecutorString = makeExecutor({
|
|
656
|
-
inner
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
nameExtra:
|
|
652
|
+
inner(bucketRootValue) {
|
|
653
|
+
return (0, tamedevil_1.stringifyString)(this.type.graphqlType.serialize(bucketRootValue));
|
|
654
|
+
},
|
|
655
|
+
nameExtra: `stringLeaf`,
|
|
660
656
|
asString: true,
|
|
661
657
|
skipNullHandling: false,
|
|
662
|
-
preamble
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
658
|
+
preamble(bucketRootValue) {
|
|
659
|
+
if (typeof bucketRootValue === "string") {
|
|
660
|
+
return (0, tamedevil_1.stringifyString)(bucketRootValue);
|
|
661
|
+
}
|
|
662
|
+
},
|
|
667
663
|
});
|
|
668
664
|
// NOTE: the reference to $$concreteType here is a (temporary) optimization; it
|
|
669
665
|
// should be `resolveType(bucketRootValue)` but it's not worth the function
|
|
@@ -671,53 +667,32 @@ const stringLeafExecutorString = makeExecutor({
|
|
|
671
667
|
// store.
|
|
672
668
|
function makePolymorphicExecutor(asString) {
|
|
673
669
|
return makeExecutor({
|
|
674
|
-
inner
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
}`
|
|
701
|
-
: tamedevil_1.default.blank}
|
|
702
|
-
|
|
703
|
-
const directChild = bucket.children[childOutputPlan.layerPlan.id];
|
|
704
|
-
if (directChild !== undefined) {
|
|
705
|
-
return childOutputPlan.${asString ? te_executeString : te_execute}(root, mutablePath, directChild.bucket, directChild.map.get(bucketIndex));
|
|
706
|
-
} else {
|
|
707
|
-
const c = ${ref_getChildBucketAndIndex}(
|
|
708
|
-
childOutputPlan,
|
|
709
|
-
this,
|
|
710
|
-
bucket,
|
|
711
|
-
bucketIndex,
|
|
712
|
-
);
|
|
713
|
-
if (!c) {
|
|
714
|
-
throw new Error("GrafastInternalError<691509d8-31fa-4cfe-a6df-dcba21bd521f>: polymorphic executor couldn't determine child bucket");
|
|
715
|
-
}
|
|
716
|
-
const [childBucket, childBucketIndex] = c;
|
|
717
|
-
return childOutputPlan.${asString ? te_executeString : te_execute}(root, mutablePath, childBucket, childBucketIndex);
|
|
718
|
-
}
|
|
719
|
-
`,
|
|
720
|
-
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",
|
|
721
696
|
asString,
|
|
722
697
|
});
|
|
723
698
|
}
|
|
@@ -725,75 +700,91 @@ const polymorphicExecutor = makePolymorphicExecutor(false);
|
|
|
725
700
|
const polymorphicExecutorString = makePolymorphicExecutor(true);
|
|
726
701
|
function makeArrayExecutor(childIsNonNull, canStream, asString) {
|
|
727
702
|
return makeExecutor({
|
|
728
|
-
inner
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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
|
+
root.streams.push({
|
|
774
|
+
root,
|
|
775
|
+
path: mutablePath.slice(1),
|
|
776
|
+
bucket,
|
|
777
|
+
bucketIndex,
|
|
778
|
+
outputPlan: childOutputPlan,
|
|
779
|
+
label: childOutputPlan.layerPlan.reason.stream?.label,
|
|
780
|
+
stream,
|
|
781
|
+
startIndex: bucketRootValue.length,
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return (asString ? string : data);
|
|
786
|
+
},
|
|
787
|
+
nameExtra: `array${childIsNonNull ? "_nonNull" : ""}${canStream ? "_stream" : ""}`,
|
|
797
788
|
asString,
|
|
798
789
|
});
|
|
799
790
|
}
|
|
@@ -813,7 +804,7 @@ const arrayExecutorString_nonNullable_streaming = makeArrayExecutor(true, true,
|
|
|
813
804
|
*
|
|
814
805
|
* ENHANCE: write our own introspection execution!
|
|
815
806
|
*/
|
|
816
|
-
|
|
807
|
+
function introspect(root, outputPlan, mutablePath, asString) {
|
|
817
808
|
const { locationDetails } = outputPlan;
|
|
818
809
|
const { field: rawField, introspectionCacheByVariableValues, variableNames, } = outputPlan.type;
|
|
819
810
|
const field = {
|
|
@@ -846,7 +837,7 @@ const introspect = (root, outputPlan, mutablePath, asString) => {
|
|
|
846
837
|
const canonical = JSON.stringify(variableValues);
|
|
847
838
|
const cached = introspectionCacheByVariableValues.get(canonical);
|
|
848
839
|
if (cached !== undefined) {
|
|
849
|
-
return asString ? JSON.stringify(cached) : cached;
|
|
840
|
+
return (asString ? JSON.stringify(cached) : cached);
|
|
850
841
|
}
|
|
851
842
|
const graphqlResult = executeSync({
|
|
852
843
|
schema: outputPlan.layerPlan.operationPlan.schema,
|
|
@@ -867,167 +858,155 @@ const introspect = (root, outputPlan, mutablePath, asString) => {
|
|
|
867
858
|
}
|
|
868
859
|
const result = graphqlResult.data.a;
|
|
869
860
|
introspectionCacheByVariableValues.set(canonical, result);
|
|
870
|
-
return asString ? JSON.stringify(result) : result;
|
|
871
|
-
}
|
|
872
|
-
const ref_introspect = tamedevil_1.default.ref(introspect, "introspect");
|
|
861
|
+
return (asString ? JSON.stringify(result) : result);
|
|
862
|
+
}
|
|
873
863
|
const introspectionExecutor = makeExecutor({
|
|
874
|
-
inner
|
|
875
|
-
|
|
864
|
+
inner(_bucketRootValue, root, mutablePath) {
|
|
865
|
+
return introspect(root, this, mutablePath, false);
|
|
866
|
+
},
|
|
867
|
+
nameExtra: `introspection`,
|
|
876
868
|
asString: false,
|
|
877
869
|
skipNullHandling: true,
|
|
878
870
|
});
|
|
879
871
|
const introspectionExecutorString = makeExecutor({
|
|
880
|
-
inner
|
|
881
|
-
|
|
872
|
+
inner(_bucketRootValue, root, mutablePath) {
|
|
873
|
+
return introspect(root, this, mutablePath, true);
|
|
874
|
+
},
|
|
875
|
+
nameExtra: `introspection`,
|
|
882
876
|
asString: true,
|
|
883
877
|
skipNullHandling: true,
|
|
884
878
|
});
|
|
885
879
|
const SAFE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
886
880
|
function makeObjectExecutor(typeName, fieldTypes, hasDeferredOutputPlans,
|
|
887
881
|
// this.type.mode === "root",
|
|
888
|
-
isRoot, asString
|
|
882
|
+
isRoot, asString) {
|
|
889
883
|
if (!SAFE_NAME.test(typeName)) {
|
|
890
884
|
throw new Error(`Unsafe type name: ${typeName}; doesn't conform to 'Name' in the GraphQL spec`);
|
|
891
885
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
886
|
+
if (dev_js_1.isDev) {
|
|
887
|
+
if (Object.getPrototypeOf(fieldTypes) !== null) {
|
|
888
|
+
throw new Error(`GrafastInternalError<3d8e3547-d818-44e1-a076-16b828e3a34d>: fieldTypes must have a null prototype`);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const fieldDigests = Object.entries(fieldTypes).map(([responseKey, fieldSpec], i) => {
|
|
892
|
+
// NOTE: this code relies on the fact that fieldName and typeName do
|
|
893
|
+
// not require any quoting in JSON/JS - they must conform to GraphQL
|
|
894
|
+
// `Name`.
|
|
895
|
+
if (!SAFE_NAME.test(responseKey)) {
|
|
900
896
|
// This should not be able to happen if the GraphQL operation is valid
|
|
901
|
-
throw new Error(`Unsafe key: ${
|
|
897
|
+
throw new Error(`Unsafe key: ${responseKey}; doesn't conform to 'Name' in the GraphQL spec`);
|
|
902
898
|
}
|
|
903
|
-
keys.push(key);
|
|
904
|
-
fieldSpecs.push(fieldSpec);
|
|
905
899
|
const { fieldType, sameBucket } = fieldSpec;
|
|
900
|
+
const addComma = asString && i > 0;
|
|
906
901
|
switch (fieldType) {
|
|
907
902
|
case "__typename": {
|
|
908
|
-
|
|
909
|
-
|
|
903
|
+
return {
|
|
904
|
+
isTypeName: true,
|
|
905
|
+
addComma,
|
|
906
|
+
responseKey,
|
|
907
|
+
stringValue: asString ? `"${responseKey}":"${typeName}"` : null,
|
|
908
|
+
};
|
|
910
909
|
}
|
|
910
|
+
case "outputPlan!":
|
|
911
911
|
case "outputPlan?": {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
912
|
+
return {
|
|
913
|
+
isTypeName: false,
|
|
914
|
+
addComma,
|
|
915
|
+
responseKey,
|
|
916
|
+
stringPrefix: asString ? `"${responseKey}":` : null,
|
|
917
|
+
sameBucket,
|
|
918
|
+
isNonNull: fieldType === "outputPlan!",
|
|
919
|
+
};
|
|
918
920
|
}
|
|
919
921
|
default: {
|
|
920
922
|
const never = fieldType;
|
|
921
|
-
throw new Error(`
|
|
923
|
+
throw new Error(`GrafastInternalError<879082f4-fe6f-4112-814f-852b9932ca83>: unsupported key type ${never}`);
|
|
922
924
|
}
|
|
923
925
|
}
|
|
924
|
-
if (!sameBucket) {
|
|
925
|
-
hasChildBucketReference = true;
|
|
926
|
-
signature += "~";
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
withObjectExecutorFactory(signature, fieldSpecs, hasDeferredOutputPlans, isRoot, asString, hasChildBucketReference, (factory) => {
|
|
930
|
-
const fn = factory(typeName, ...keys);
|
|
931
|
-
callback(fn);
|
|
932
926
|
});
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
const mutablePathIndex = mutablePath.push("!") - 1;
|
|
954
|
-
let spec${hasChildBucketReference ? te_childBucketCBIDC : tamedevil_1.default.blank}, fieldResult;
|
|
955
|
-
|
|
956
|
-
${tamedevil_1.default.join(fieldSpecs.map(({ fieldType, sameBucket }, i) => {
|
|
957
|
-
const te_fieldNameI = tamedevil_1.default.identifier(`fieldName_${i}`);
|
|
958
|
-
switch (fieldType) {
|
|
959
|
-
case "__typename": {
|
|
960
|
-
if (asString) {
|
|
961
|
-
// NOTE: this code relies on the fact that fieldName and typeName do
|
|
962
|
-
// not require any quoting in JSON/JS - they must conform to GraphQL
|
|
963
|
-
// `Name`.
|
|
964
|
-
return (0, tamedevil_1.default) ` string += \`${i === 0 ? tamedevil_1.default.blank : te_comma}"\${${te_fieldNameI}}":"\${typeName}"\`;\n`;
|
|
927
|
+
return makeExecutor({
|
|
928
|
+
inner(bucketRootValue, root, mutablePath, bucket, bucketIndex, rawBucketRootValue, bucketRootFlags) {
|
|
929
|
+
let string = asString ? "{" : undefined;
|
|
930
|
+
const obj = asString
|
|
931
|
+
? undefined
|
|
932
|
+
: Object.create(null);
|
|
933
|
+
const keys = this.keys;
|
|
934
|
+
const mutablePathIndex = mutablePath.push("!") - 1;
|
|
935
|
+
for (const digest of fieldDigests) {
|
|
936
|
+
if (digest.addComma) {
|
|
937
|
+
string += ",";
|
|
938
|
+
}
|
|
939
|
+
const responseKey = digest.responseKey;
|
|
940
|
+
if (digest.isTypeName) {
|
|
941
|
+
if (asString) {
|
|
942
|
+
string += digest.stringValue;
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
obj[responseKey] = typeName;
|
|
946
|
+
}
|
|
965
947
|
}
|
|
966
948
|
else {
|
|
967
|
-
|
|
949
|
+
mutablePath[mutablePathIndex] = responseKey;
|
|
950
|
+
const spec = keys[responseKey];
|
|
951
|
+
if (digest.sameBucket) {
|
|
952
|
+
const val = executeChildPlan(this, spec.locationDetails, spec.outputPlan, digest.isNonNull, asString, bucket, bucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags);
|
|
953
|
+
if (asString) {
|
|
954
|
+
string += digest.stringPrefix;
|
|
955
|
+
string += val;
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
obj[responseKey] = val;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
const directChild = bucket.children[spec.outputPlan.layerPlan.id];
|
|
963
|
+
let childBucket, childBucketIndex;
|
|
964
|
+
if (directChild !== undefined) {
|
|
965
|
+
childBucket = directChild.bucket;
|
|
966
|
+
childBucketIndex = directChild.map.get(bucketIndex);
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
const c = getChildBucketAndIndex(spec.outputPlan.layerPlan, this, bucket, bucketIndex);
|
|
970
|
+
if (c !== null) {
|
|
971
|
+
[childBucket, childBucketIndex] = c;
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
childBucket = childBucketIndex = null;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
const val = executeChildPlan(this, spec.locationDetails, spec.outputPlan, digest.isNonNull, asString, childBucket, childBucketIndex, bucket, bucketIndex, mutablePath, mutablePathIndex, root, rawBucketRootValue, bucketRootFlags);
|
|
978
|
+
if (asString) {
|
|
979
|
+
string += digest.stringPrefix;
|
|
980
|
+
string += val;
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
obj[responseKey] = val;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
968
986
|
}
|
|
969
987
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
mutablePath[mutablePathIndex] = ${te_fieldNameI};
|
|
974
|
-
spec = keys[${te_fieldNameI}];
|
|
975
|
-
${asString
|
|
976
|
-
? (0, tamedevil_1.default) ` string += \`${i === 0 ? tamedevil_1.default.blank : te_comma}"\${${te_fieldNameI}}":\`;
|
|
977
|
-
`
|
|
978
|
-
: tamedevil_1.default.blank}\
|
|
979
|
-
${sameBucket
|
|
980
|
-
? (0, tamedevil_1.default) `\
|
|
981
|
-
${makeExecuteChildPlanCode(asString ? te_stringPlusEquals : (0, tamedevil_1.default) `obj[${te_fieldNameI}] =`, te_specDotLocationDetails, te_specDotOutputPlan, fieldType === "outputPlan!", asString, te_bucket, te_bucketIndex)}`
|
|
982
|
-
: (0, tamedevil_1.default) `\
|
|
983
|
-
directChild = bucket.children[spec.outputPlan.layerPlanId];
|
|
984
|
-
if (directChild !== undefined) {
|
|
985
|
-
childBucket = directChild.bucket;
|
|
986
|
-
childBucketIndex = directChild.map.get(bucketIndex);
|
|
987
|
-
} else {
|
|
988
|
-
const c = ${ref_getChildBucketAndIndex}(
|
|
989
|
-
spec.outputPlan,
|
|
990
|
-
this,
|
|
991
|
-
bucket,
|
|
992
|
-
bucketIndex,
|
|
993
|
-
);
|
|
994
|
-
if (c !== null) {
|
|
995
|
-
([childBucket, childBucketIndex] = c);
|
|
996
|
-
} else {
|
|
997
|
-
childBucket = childBucketIndex = null;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
${makeExecuteChildPlanCode(asString ? te_stringPlusEquals : (0, tamedevil_1.default) `obj[${te_fieldNameI}] =`, te_specDotLocationDetails, te_specDotOutputPlan, fieldType === "outputPlan!", asString)}`}
|
|
1001
|
-
`;
|
|
988
|
+
mutablePath.length = mutablePathIndex;
|
|
989
|
+
if (asString) {
|
|
990
|
+
string += "}";
|
|
1002
991
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
992
|
+
if (hasDeferredOutputPlans) {
|
|
993
|
+
// Everything seems okay; queue any deferred payloads
|
|
994
|
+
for (const defer of this.deferredOutputPlans) {
|
|
995
|
+
root.queue.push({
|
|
996
|
+
root,
|
|
997
|
+
path: mutablePath.slice(1),
|
|
998
|
+
bucket,
|
|
999
|
+
bucketIndex,
|
|
1000
|
+
outputPlan: defer,
|
|
1001
|
+
label: defer.type.deferLabel,
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1006
1004
|
}
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
mutablePath.length = mutablePathIndex;
|
|
1011
|
-
${asString ? te_stringPlusEqualsRbrace : tamedevil_1.default.blank}\
|
|
1012
|
-
${hasDeferredOutputPlans ? te_handleDeferred : tamedevil_1.default.blank}
|
|
1013
|
-
return ${asString ? te_string : te_obj};`;
|
|
1014
|
-
const executorExpression = makeExecutorExpression({
|
|
1015
|
-
inner: inner,
|
|
1016
|
-
nameExtra: te_object,
|
|
1005
|
+
return (asString ? string : obj);
|
|
1006
|
+
},
|
|
1007
|
+
nameExtra: "object",
|
|
1017
1008
|
asString,
|
|
1018
1009
|
skipNullHandling: isRoot,
|
|
1019
|
-
preamble: tamedevil_1.default.blank,
|
|
1020
|
-
});
|
|
1021
|
-
const factoryExpression = (0, tamedevil_1.default) `\
|
|
1022
|
-
function objectExecutorFactory(typeName${tamedevil_1.default.join(fieldSpecs.map((_, i) => (0, tamedevil_1.default) `, ${tamedevil_1.default.identifier(`fieldName_${i}`)}`), "")}) {
|
|
1023
|
-
return ${executorExpression};
|
|
1024
|
-
}`;
|
|
1025
|
-
tamedevil_1.default.runInBatch(factoryExpression, (factory) => {
|
|
1026
|
-
makeObjectExecutorCache.set(signature, factory);
|
|
1027
|
-
makingObjectExecutorCallbacks.delete(signature);
|
|
1028
|
-
for (const callback of callbacks) {
|
|
1029
|
-
callback(factory);
|
|
1030
|
-
}
|
|
1031
1010
|
});
|
|
1032
1011
|
}
|
|
1033
1012
|
const makeCache = new lru_1.default({
|