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.
- package/README.md +2 -3
- package/dist/args.d.ts +4 -7
- package/dist/args.js +53 -38
- package/dist/assert.js +2 -3
- package/dist/bucket.d.ts +1 -89
- package/dist/config.d.ts +0 -17
- package/dist/config.js +1 -95
- package/dist/constraints.d.ts +15 -1
- package/dist/constraints.js +41 -3
- package/dist/deferred.js +1 -2
- package/dist/dev.d.ts +1 -4
- package/dist/dev.js +18 -3
- package/dist/engine/LayerPlan.d.ts +21 -111
- package/dist/engine/LayerPlan.js +196 -78
- package/dist/engine/OperationPlan.d.ts +30 -104
- package/dist/engine/OperationPlan.js +763 -471
- package/dist/engine/OutputPlan.d.ts +9 -20
- package/dist/engine/OutputPlan.js +432 -444
- package/dist/engine/StepTracker.d.ts +1 -95
- package/dist/engine/StepTracker.js +94 -20
- package/dist/engine/executeBucket.d.ts +5 -7
- package/dist/engine/executeBucket.js +646 -244
- package/dist/engine/executeOutputPlan.d.ts +0 -53
- package/dist/engine/executeOutputPlan.js +7 -2
- package/dist/engine/lib/defaultPlanResolver.d.ts +6 -0
- package/dist/engine/lib/defaultPlanResolver.js +11 -0
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +2 -0
- package/dist/engine/lib/withGlobalLayerPlan.js +7 -4
- package/dist/engine/lock.d.ts +4 -0
- package/dist/engine/lock.js +82 -0
- package/dist/envelop.js +5 -4
- package/dist/error.d.ts +18 -49
- package/dist/error.js +50 -39
- package/dist/establishOperationPlan.js +57 -42
- package/dist/execute.d.ts +5 -4
- package/dist/execute.js +31 -15
- package/dist/exportAs.d.ts +1 -18
- package/dist/exportAs.js +2 -3
- package/dist/global.js +2 -3
- package/dist/grafastGraphql.d.ts +6 -1
- package/dist/grafastGraphql.js +35 -16
- package/dist/grafastPrint.d.ts +3 -0
- package/dist/grafastPrint.js +67 -6
- package/dist/graphqlCollectFields.d.ts +7 -34
- package/dist/graphqlCollectFields.js +24 -13
- package/dist/graphqlMergeSelectionSets.js +1 -2
- package/dist/index.d.ts +44 -29
- package/dist/index.js +91 -18
- package/dist/input.d.ts +1 -9
- package/dist/input.js +75 -28
- package/dist/inspect.d.ts +9 -3
- package/dist/inspect.js +3 -3
- package/dist/interfaces.d.ts +238 -93
- package/dist/interfaces.js +20 -3
- package/dist/makeGrafastSchema.d.ts +21 -9
- package/dist/makeGrafastSchema.js +353 -133
- package/dist/mermaid.d.ts +0 -17
- package/dist/mermaid.js +131 -19
- package/dist/middleware.d.ts +7 -0
- package/dist/middleware.js +24 -0
- package/dist/multistep.d.ts +19 -0
- package/dist/multistep.js +54 -0
- package/dist/operationPlan-input.d.ts +5 -4
- package/dist/operationPlan-input.js +140 -368
- package/dist/planJSONInterfaces.d.ts +12 -2
- package/dist/polymorphic.js +4 -5
- package/dist/prepare.d.ts +1 -7
- package/dist/prepare.js +100 -74
- package/dist/step.d.ts +118 -172
- package/dist/step.js +262 -183
- package/dist/steps/__flag.d.ts +65 -0
- package/dist/steps/__flag.js +261 -0
- package/dist/steps/__inputDefault.d.ts +14 -0
- package/dist/steps/__inputDefault.js +48 -0
- package/dist/steps/__inputDynamicScalar.d.ts +4 -6
- package/dist/steps/__inputDynamicScalar.js +4 -2
- package/dist/steps/__inputList.d.ts +5 -9
- package/dist/steps/__inputList.js +4 -1
- package/dist/steps/__inputObject.d.ts +7 -11
- package/dist/steps/__inputObject.js +49 -3
- package/dist/steps/__inputStaticLeaf.d.ts +2 -4
- package/dist/steps/__inputStaticLeaf.js +3 -1
- package/dist/steps/__item.d.ts +10 -12
- package/dist/steps/__item.js +8 -2
- package/dist/steps/__trackedValue.d.ts +7 -55
- package/dist/steps/__trackedValue.js +69 -8
- package/dist/steps/__value.d.ts +5 -4
- package/dist/steps/__value.js +5 -4
- package/dist/steps/access.d.ts +10 -10
- package/dist/steps/access.js +50 -17
- package/dist/steps/applyInput.d.ts +44 -0
- package/dist/steps/applyInput.js +206 -0
- package/dist/steps/applyTransforms.d.ts +2 -25
- package/dist/steps/applyTransforms.js +53 -31
- package/dist/steps/bakedInput.d.ts +23 -0
- package/dist/steps/bakedInput.js +90 -0
- package/dist/steps/condition.d.ts +31 -0
- package/dist/steps/condition.js +94 -0
- package/dist/steps/connection.d.ts +56 -42
- package/dist/steps/connection.js +97 -44
- package/dist/steps/constant.d.ts +7 -7
- package/dist/steps/constant.js +86 -7
- package/dist/steps/each.d.ts +3 -3
- package/dist/steps/each.js +2 -3
- package/dist/steps/error.d.ts +4 -4
- package/dist/steps/error.js +7 -6
- package/dist/steps/filter.d.ts +3 -2
- package/dist/steps/filter.js +1 -2
- package/dist/steps/first.d.ts +10 -9
- package/dist/steps/first.js +9 -13
- package/dist/steps/graphqlResolver.d.ts +3 -76
- package/dist/steps/graphqlResolver.js +89 -72
- package/dist/steps/groupBy.d.ts +3 -2
- package/dist/steps/groupBy.js +1 -2
- package/dist/steps/index.d.ts +12 -3
- package/dist/steps/index.js +48 -6
- package/dist/steps/lambda.d.ts +9 -9
- package/dist/steps/lambda.js +18 -9
- package/dist/steps/last.d.ts +9 -8
- package/dist/steps/last.js +7 -6
- package/dist/steps/list.d.ts +20 -9
- package/dist/steps/list.js +56 -13
- package/dist/steps/listTransform.d.ts +18 -22
- package/dist/steps/listTransform.js +58 -27
- package/dist/steps/listen.d.ts +6 -11
- package/dist/steps/listen.js +14 -16
- package/dist/steps/load.d.ts +42 -33
- package/dist/steps/load.js +60 -27
- package/dist/steps/node.d.ts +17 -10
- package/dist/steps/node.js +18 -6
- package/dist/steps/object.d.ts +33 -27
- package/dist/steps/object.js +53 -32
- package/dist/steps/partitionByIndex.d.ts +3 -2
- package/dist/steps/partitionByIndex.js +1 -2
- package/dist/steps/polymorphicBranch.d.ts +27 -0
- package/dist/steps/polymorphicBranch.js +62 -0
- package/dist/steps/proxy.d.ts +11 -12
- package/dist/steps/proxy.js +8 -5
- package/dist/steps/remapKeys.d.ts +10 -10
- package/dist/steps/remapKeys.js +14 -7
- package/dist/steps/reverse.d.ts +8 -8
- package/dist/steps/reverse.js +10 -7
- package/dist/steps/setter.d.ts +9 -18
- package/dist/steps/setter.js +24 -14
- package/dist/steps/sideEffect.d.ts +28 -0
- package/dist/steps/sideEffect.js +44 -0
- package/dist/stringifyPayload.js +1 -2
- package/dist/stripAnsi.js +2 -2
- package/dist/subscribe.d.ts +7 -1
- package/dist/subscribe.js +24 -9
- package/dist/thereCanBeOnlyOne.js +1 -1
- package/dist/timeSource.d.ts +0 -1
- package/dist/utils.d.ts +56 -55
- package/dist/utils.js +179 -59
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -8
|
@@ -1,80 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
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 &&
|
|
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.
|
|
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
|
|
376
|
-
|
|
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
|
|
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(
|
|
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 &&
|
|
394
|
+
if (outputPlan != null && layerPlan === bucket.layerPlan) {
|
|
431
395
|
// Same layer; straightforward
|
|
432
396
|
return [bucket, bucketIndex];
|
|
433
397
|
}
|
|
434
|
-
const reversePath = [
|
|
435
|
-
let current =
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
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
|
|
513
|
-
const
|
|
514
|
-
if (
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
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:
|
|
577
|
-
nameExtra:
|
|
576
|
+
inner: () => null,
|
|
577
|
+
nameExtra: "null",
|
|
578
578
|
asString: false,
|
|
579
579
|
});
|
|
580
580
|
const nullExecutorString = makeExecutor({
|
|
581
|
-
inner:
|
|
582
|
-
nameExtra:
|
|
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
|
-
|
|
587
|
-
`\
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
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
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
nameExtra:
|
|
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
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
nameExtra:
|
|
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
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
nameExtra:
|
|
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
|
|
618
|
-
|
|
619
|
-
|
|
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
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
nameExtra:
|
|
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
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
632
|
+
preamble(bucketRootValue) {
|
|
633
|
+
if ((bucketRootValue | 0) === bucketRootValue) {
|
|
634
|
+
return "" + bucketRootValue;
|
|
635
|
+
}
|
|
636
|
+
},
|
|
635
637
|
});
|
|
636
638
|
const floatLeafExecutorString = makeExecutor({
|
|
637
|
-
inner
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
nameExtra:
|
|
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
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
645
|
+
preamble(bucketRootValue) {
|
|
646
|
+
if (Number.isFinite(bucketRootValue)) {
|
|
647
|
+
return "" + bucketRootValue;
|
|
648
|
+
}
|
|
649
|
+
},
|
|
648
650
|
});
|
|
649
651
|
const stringLeafExecutorString = makeExecutor({
|
|
650
|
-
inner
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
nameExtra:
|
|
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
|
|
657
|
-
|
|
658
|
-
|
|
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
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
869
|
-
|
|
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
|
|
875
|
-
|
|
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
|
|
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
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
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: ${
|
|
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
|
-
|
|
903
|
-
|
|
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
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
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(`
|
|
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
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
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
|
-
|
|
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
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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
|
-
|
|
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({
|