grafast 0.1.1-beta.21 → 0.1.1-beta.22
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 -4
- package/dist/args.js +3 -3
- package/dist/constants.d.ts +79 -0
- package/dist/constants.js +79 -0
- package/dist/engine/LayerPlan.d.ts +71 -8
- package/dist/engine/LayerPlan.js +375 -265
- package/dist/engine/OperationPlan.d.ts +77 -14
- package/dist/engine/OperationPlan.js +1508 -382
- package/dist/engine/OperationPlanTypes.d.ts +66 -0
- package/dist/engine/OperationPlanTypes.js +3 -0
- package/dist/engine/OutputPlan.d.ts +6 -0
- package/dist/engine/OutputPlan.js +138 -82
- package/dist/engine/StepTracker.js +76 -17
- package/dist/engine/executeBucket.js +327 -166
- package/dist/engine/lib/defaultPlanResolver.d.ts +1 -4
- package/dist/engine/lib/defaultPlanResolver.js +1 -5
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +3 -1
- package/dist/engine/lib/withGlobalLayerPlan.js +19 -1
- package/dist/envelop.js +14 -3
- package/dist/error.d.ts +1 -1
- package/dist/error.js +9 -9
- package/dist/establishOperationPlan.d.ts +2 -1
- package/dist/establishOperationPlan.js +10 -10
- package/dist/execute.js +7 -5
- package/dist/global.d.ts +10 -0
- package/dist/global.js +25 -0
- package/dist/grafastGraphql.js +4 -3
- package/dist/grafastPrint.js +36 -4
- package/dist/index.d.ts +76 -8
- package/dist/index.js +37 -33
- package/dist/input.js +20 -1
- package/dist/inspect.js +1 -0
- package/dist/interfaces.d.ts +80 -122
- package/dist/interfaces.js +0 -77
- package/dist/makeGrafastSchema.d.ts +118 -35
- package/dist/makeGrafastSchema.js +197 -29
- package/dist/mermaid.js +198 -97
- package/dist/operationPlan-input.d.ts +1 -1
- package/dist/operationPlan-input.js +15 -5
- package/dist/planJSONInterfaces.d.ts +24 -5
- package/dist/prepare.d.ts +16 -9
- package/dist/prepare.js +54 -51
- package/dist/step.d.ts +45 -9
- package/dist/step.js +139 -22
- package/dist/steps/__flag.d.ts +3 -2
- package/dist/steps/__flag.js +31 -29
- package/dist/steps/__inputObject.d.ts +1 -1
- package/dist/steps/__inputStaticLeaf.d.ts +3 -2
- package/dist/steps/__inputStaticLeaf.js +13 -7
- package/dist/steps/__item.d.ts +1 -1
- package/dist/steps/__item.js +3 -3
- package/dist/steps/__trackedValue.d.ts +6 -3
- package/dist/steps/__trackedValue.js +25 -9
- package/dist/steps/__value.d.ts +2 -1
- package/dist/steps/__value.js +5 -0
- package/dist/steps/access.d.ts +17 -1
- package/dist/steps/access.js +14 -1
- package/dist/steps/applyInput.d.ts +1 -1
- package/dist/steps/applyInput.js +7 -6
- package/dist/steps/applyTransforms.js +9 -7
- package/dist/steps/bakedInput.js +2 -2
- package/dist/steps/coalesce.d.ts +15 -0
- package/dist/steps/coalesce.js +36 -0
- package/dist/steps/constant.js +16 -14
- package/dist/steps/each.d.ts +2 -2
- package/dist/steps/first.d.ts +2 -0
- package/dist/steps/first.js +5 -1
- package/dist/steps/graphqlResolver.d.ts +2 -2
- package/dist/steps/graphqlResolver.js +63 -161
- package/dist/steps/index.d.ts +3 -15
- package/dist/steps/index.js +6 -41
- package/dist/steps/lambda.js +1 -1
- package/dist/steps/last.d.ts +2 -0
- package/dist/steps/last.js +4 -0
- package/dist/steps/listTransform.d.ts +2 -2
- package/dist/steps/listTransform.js +11 -13
- package/dist/steps/load.d.ts +28 -22
- package/dist/steps/load.js +47 -1
- package/dist/steps/node.d.ts +10 -7
- package/dist/steps/node.js +5 -19
- package/dist/steps/object.js +6 -1
- package/dist/steps/proxy.d.ts +0 -6
- package/dist/steps/proxy.js +3 -3
- package/dist/steps/remapKeys.d.ts +1 -1
- package/dist/steps/remapKeys.js +0 -1
- package/dist/utils.d.ts +27 -5
- package/dist/utils.js +235 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -6
- package/dist/polymorphic.d.ts +0 -14
- package/dist/polymorphic.js +0 -72
- package/dist/steps/polymorphicBranch.d.ts +0 -27
- package/dist/steps/polymorphicBranch.js +0 -62
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { FieldNode, GraphQLFieldMap, GraphQLInterfaceType, GraphQLList, GraphQLObjectType, GraphQLOutputType, GraphQLUnionType, SelectionNode } from "graphql";
|
|
2
|
+
import type { SelectionSetDigest } from "../graphqlCollectFields";
|
|
3
|
+
import type { LocationDetails, Maybe } from "../interfaces";
|
|
4
|
+
import type { Step } from "../step";
|
|
5
|
+
import type { LayerPlan, LayerPlanReasonListItemStream } from "./LayerPlan";
|
|
6
|
+
import type { OutputPlan } from "./OutputPlan";
|
|
7
|
+
export type StreamDetails = {
|
|
8
|
+
if: Step<boolean>;
|
|
9
|
+
initialCount: Step<number>;
|
|
10
|
+
label: Step<Maybe<string>>;
|
|
11
|
+
};
|
|
12
|
+
export interface CommonPlanningDetails<TType extends GraphQLOutputType | GraphQLInterfaceType | GraphQLUnionType = GraphQLOutputType> {
|
|
13
|
+
outputPlan: OutputPlan;
|
|
14
|
+
path: readonly string[];
|
|
15
|
+
planningPath: string;
|
|
16
|
+
polymorphicPaths: ReadonlySet<string> | null;
|
|
17
|
+
parentStep: Step;
|
|
18
|
+
positionType: TType;
|
|
19
|
+
layerPlan: LayerPlan;
|
|
20
|
+
}
|
|
21
|
+
export interface PlanIntoOutputPlanDetails extends CommonPlanningDetails<GraphQLOutputType> {
|
|
22
|
+
resolverEmulation: boolean;
|
|
23
|
+
selections: readonly SelectionNode[] | undefined;
|
|
24
|
+
parentObjectType: GraphQLObjectType | null;
|
|
25
|
+
responseKey: string | null;
|
|
26
|
+
locationDetails: LocationDetails;
|
|
27
|
+
listDepth: number;
|
|
28
|
+
streamDetails: StreamDetails | null;
|
|
29
|
+
}
|
|
30
|
+
export interface PlanFieldReturnTypeDetails extends Omit<PlanIntoOutputPlanDetails, "listDepth"> {
|
|
31
|
+
parentObjectType: GraphQLObjectType;
|
|
32
|
+
}
|
|
33
|
+
export interface ProcessGroupedFieldSetDetails extends CommonPlanningDetails<GraphQLObjectType> {
|
|
34
|
+
objectTypeFields: GraphQLFieldMap<any, any>;
|
|
35
|
+
isMutation: boolean;
|
|
36
|
+
groupedFieldSet: SelectionSetDigest;
|
|
37
|
+
}
|
|
38
|
+
export interface PlanSelectionSetDetails extends CommonPlanningDetails<GraphQLObjectType> {
|
|
39
|
+
resolverEmulation: boolean;
|
|
40
|
+
selections: readonly SelectionNode[];
|
|
41
|
+
isMutation?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface PlanListItemDetails extends CommonPlanningDetails<GraphQLList<GraphQLOutputType>> {
|
|
44
|
+
resolverEmulation: boolean;
|
|
45
|
+
selections: readonly SelectionNode[] | undefined;
|
|
46
|
+
listDepth: number;
|
|
47
|
+
stream: LayerPlanReasonListItemStream | undefined;
|
|
48
|
+
locationDetails: LocationDetails;
|
|
49
|
+
}
|
|
50
|
+
export interface PolymorphicResolveTypeDetails extends CommonPlanningDetails<GraphQLInterfaceType | GraphQLUnionType> {
|
|
51
|
+
resolverEmulation: boolean;
|
|
52
|
+
selections: readonly SelectionNode[];
|
|
53
|
+
allPossibleObjectTypes: readonly GraphQLObjectType<any, any>[];
|
|
54
|
+
locationDetails: LocationDetails;
|
|
55
|
+
parentObjectType: GraphQLObjectType | null;
|
|
56
|
+
responseKey: string | null;
|
|
57
|
+
isNonNull: boolean;
|
|
58
|
+
stepForType?: ReadonlyMap<GraphQLObjectType, Step | Error>;
|
|
59
|
+
}
|
|
60
|
+
export interface PolymorphicPlanObjectTypeDetails extends CommonPlanningDetails<GraphQLObjectType> {
|
|
61
|
+
resolverEmulation: boolean;
|
|
62
|
+
fieldNodes: readonly FieldNode[];
|
|
63
|
+
locationDetails: LocationDetails;
|
|
64
|
+
isNonNull: boolean;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=OperationPlanTypes.d.ts.map
|
|
@@ -163,6 +163,7 @@ export declare class OutputPlan<TType extends OutputPlanType = OutputPlanType> {
|
|
|
163
163
|
rootStep: Step, type: TType, locationDetails: LocationDetails);
|
|
164
164
|
print(): string;
|
|
165
165
|
toString(): string;
|
|
166
|
+
expectChild(type: GraphQLObjectType | null, key: string | null): void;
|
|
166
167
|
addChild(type: GraphQLObjectType | null, key: string | null, child: OutputPlanKeyValue): void;
|
|
167
168
|
getLayerPlans(layerPlans?: Set<LayerPlan<import("./LayerPlan.js").LayerPlanReason>>): Set<LayerPlan>;
|
|
168
169
|
makeNextStepByLayerPlan(): Record<number, any[]>;
|
|
@@ -173,4 +174,9 @@ export declare class OutputPlan<TType extends OutputPlanType = OutputPlanType> {
|
|
|
173
174
|
}
|
|
174
175
|
export declare function coerceError(error: Error, locationDetails: LocationDetails, path: ReadonlyArray<string | number>): graphql.GraphQLError;
|
|
175
176
|
export declare function nonNullError(locationDetails: LocationDetails, path: readonly (string | number)[]): graphql.GraphQLError;
|
|
177
|
+
/**
|
|
178
|
+
* Finds the child of `targetParent` that has a path towards `descendent` (by
|
|
179
|
+
* walking backwards from descendent to targetParent).
|
|
180
|
+
*/
|
|
181
|
+
export declare function getDirectLayerPlanChild(targetParent: LayerPlan, descendent: LayerPlan): LayerPlan;
|
|
176
182
|
//# sourceMappingURL=OutputPlan.d.ts.map
|
|
@@ -4,17 +4,22 @@ exports.OutputPlan = void 0;
|
|
|
4
4
|
exports.coerceError = coerceError;
|
|
5
5
|
exports.nonNullError = nonNullError;
|
|
6
6
|
exports.getChildBucketAndIndex = getChildBucketAndIndex;
|
|
7
|
+
exports.getDirectLayerPlanChild = getDirectLayerPlanChild;
|
|
7
8
|
const tslib_1 = require("tslib");
|
|
8
9
|
const lru_1 = tslib_1.__importDefault(require("@graphile/lru"));
|
|
10
|
+
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
9
11
|
const graphql = tslib_1.__importStar(require("graphql"));
|
|
10
12
|
const tamedevil_1 = tslib_1.__importStar(require("tamedevil"));
|
|
11
13
|
const assert = tslib_1.__importStar(require("../assert.js"));
|
|
14
|
+
const constants_js_1 = require("../constants.js");
|
|
12
15
|
const dev_js_1 = require("../dev.js");
|
|
13
16
|
const index_js_1 = require("../index.js");
|
|
14
17
|
const inspect_js_1 = require("../inspect.js");
|
|
15
|
-
const interfaces_js_1 = require("../interfaces.js");
|
|
16
|
-
const polymorphic_js_1 = require("../polymorphic.js");
|
|
17
18
|
const access_js_1 = require("../steps/access.js");
|
|
19
|
+
const utils_js_1 = require("../utils.js");
|
|
20
|
+
const LayerPlan_js_1 = require("./LayerPlan.js");
|
|
21
|
+
const debug = (0, debug_1.default)("grafast:OutputPlan");
|
|
22
|
+
const debugVerbose = debug.extend("verbose");
|
|
18
23
|
const { executeSync, GraphQLBoolean, GraphQLError, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLString, isObjectType, Kind, OperationTypeNode, } = graphql;
|
|
19
24
|
/**
|
|
20
25
|
* Defines a way of taking a layerPlan and converting it into an output value.
|
|
@@ -105,7 +110,32 @@ class OutputPlan {
|
|
|
105
110
|
}
|
|
106
111
|
}
|
|
107
112
|
toString() {
|
|
108
|
-
|
|
113
|
+
let processRootString = "";
|
|
114
|
+
if (this.processRoot != null) {
|
|
115
|
+
const fnBody = this.processRoot.toString();
|
|
116
|
+
const VALUE_ARROW = "value => ";
|
|
117
|
+
if (fnBody.startsWith(VALUE_ARROW)) {
|
|
118
|
+
const sliced = fnBody.slice(VALUE_ARROW.length);
|
|
119
|
+
if (sliced.startsWith("(value") &&
|
|
120
|
+
sliced.endsWith(")") &&
|
|
121
|
+
sliced.replace(/[()]/g, "").length === sliced.length - 2) {
|
|
122
|
+
processRootString = sliced.slice(6, -1);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
processRootString = `:value=>${sliced}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
processRootString = `:${fnBody}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return `OutputPlan<${this.type.mode}${this.sideEffectStep ? `^${this.sideEffectStep.id}` : ""}∈${this.layerPlan.id}!${this.rootStep.id}${processRootString}>`;
|
|
133
|
+
}
|
|
134
|
+
// HACK: ensure output objects are ordered correctly
|
|
135
|
+
expectChild(type, key) {
|
|
136
|
+
if (this.type.mode === "root" || this.type.mode === "object") {
|
|
137
|
+
this.keys[key] = undefined; // placeholder
|
|
138
|
+
}
|
|
109
139
|
}
|
|
110
140
|
addChild(type, key, child) {
|
|
111
141
|
if (this.type.mode === "root" || this.type.mode === "object") {
|
|
@@ -155,7 +185,8 @@ class OutputPlan {
|
|
|
155
185
|
assert.ok(type && this.type.typeNames.includes(type.name), "GrafastInternalError<566a34ac-1138-4dbf-943e-f704819431dd>: polymorphic output plan can only addChild for a matching type");
|
|
156
186
|
assert.strictEqual(key, null, "GrafastInternalError<4346ebda-a02d-4489-b767-7a6d621a73c7>: addChild for polymorphic OutputPlan should not specify a key");
|
|
157
187
|
assert.ok(child.type === "outputPlan", "GrafastInternalError<b29285da-fb07-4943-9038-708edc785041>: polymorphic OutputPlan child must be an outputPlan");
|
|
158
|
-
assert.ok(child.outputPlan.type.mode === "object"
|
|
188
|
+
assert.ok(child.outputPlan.type.mode === "object" ||
|
|
189
|
+
child.outputPlan.type.mode === "null", "GrafastInternalError<203469c6-4bfa-4cd1-ae82-cc5d0132ca16>: polymorphic OutputPlan child must be an object outputPlan");
|
|
159
190
|
}
|
|
160
191
|
this.childByTypeName[type.name] = child.outputPlan;
|
|
161
192
|
}
|
|
@@ -218,13 +249,16 @@ class OutputPlan {
|
|
|
218
249
|
// should be safe aga.
|
|
219
250
|
const $root = this.layerPlan.operationPlan.dangerouslyGetStep(this.rootStep.id);
|
|
220
251
|
if ($root instanceof index_js_1.AccessStep &&
|
|
252
|
+
$root.isSyncAndSafe && // Make sure we're not using it for streaming!
|
|
221
253
|
$root.fallback === undefined &&
|
|
222
254
|
$root.implicitSideEffectStep === null &&
|
|
223
255
|
(!this.sideEffectStep || !(0, index_js_1.stepADependsOnStepB)($root, this.sideEffectStep))) {
|
|
224
256
|
const expressionDetails = $root.unbatchedExecute[access_js_1.expressionSymbol];
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
257
|
+
// @ts-ignore
|
|
258
|
+
const { step: $parent, onReject, acceptFlags } = $root._getDepOptions(0);
|
|
259
|
+
if (expressionDetails !== undefined &&
|
|
260
|
+
onReject == null &&
|
|
261
|
+
acceptFlags === constants_js_1.DEFAULT_ACCEPT_FLAGS) {
|
|
228
262
|
this.layerPlan.operationPlan.stepTracker.setOutputPlanRootStep(this, $parent);
|
|
229
263
|
const [path, fallback] = expressionDetails;
|
|
230
264
|
withFastExpression(path, fallback, (fn) => {
|
|
@@ -292,14 +326,7 @@ class OutputPlan {
|
|
|
292
326
|
throw new Error("GrafastInternalError<48fabdc8-ce84-45ec-ac20-35a2af9098e0>: No child output plan for list bucket?");
|
|
293
327
|
}
|
|
294
328
|
const childIsNonNull = this.childIsNonNull;
|
|
295
|
-
|
|
296
|
-
while (directLayerPlanChild.parentLayerPlan !== this.layerPlan) {
|
|
297
|
-
const parent = directLayerPlanChild.parentLayerPlan;
|
|
298
|
-
if (!parent) {
|
|
299
|
-
throw new Error(`GrafastInternalError<d43e06d8-c533-4e7b-b3e7-af399f19c83f>: Invalid heirarchy - could not find direct layerPlan child of ${this}`);
|
|
300
|
-
}
|
|
301
|
-
directLayerPlanChild = parent;
|
|
302
|
-
}
|
|
329
|
+
const directLayerPlanChild = getDirectLayerPlanChild(this.layerPlan, this.child.layerPlan);
|
|
303
330
|
const canStream = directLayerPlanChild.reason.type === "listItem" &&
|
|
304
331
|
!!directLayerPlanChild.reason.stream;
|
|
305
332
|
if (childIsNonNull) {
|
|
@@ -391,63 +418,57 @@ function getChildBucketAndIndex(layerPlan, outputPlan, bucket, bucketIndex, arra
|
|
|
391
418
|
(outputPlan != null && outputPlan.type.mode === "array")) {
|
|
392
419
|
throw new Error("GrafastInternalError<83d0e3cc-7eec-4185-85b4-846540288162>: arrayIndex must be supplied iff outputPlan is an array");
|
|
393
420
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return
|
|
397
|
-
}
|
|
398
|
-
const reversePath = [layerPlan];
|
|
399
|
-
let current = layerPlan;
|
|
400
|
-
while (!bucket.children[current.id]) {
|
|
401
|
-
current = current.parentLayerPlan;
|
|
402
|
-
if (!current) {
|
|
403
|
-
return null;
|
|
404
|
-
}
|
|
405
|
-
reversePath.push(current);
|
|
421
|
+
const paths = (0, utils_js_1.pathsFromAncestorToTargetLayerPlan)(bucket.layerPlan, layerPlan);
|
|
422
|
+
if (paths.length === 0) {
|
|
423
|
+
return null;
|
|
406
424
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const out = child.map.get(currentIndex);
|
|
416
|
-
if (out == null) {
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
/*
|
|
420
|
-
* TEST: I think this '|| i !== l - 1' check is saying that an array can
|
|
421
|
-
* only occur at the furthest ancestor and everything since then must be
|
|
422
|
-
* non-array. Presumably in the case of nested arrays there would be an
|
|
423
|
-
* intermediary bucket, hence why this check is allowed, but that should be
|
|
424
|
-
* tested. Also, are there any confounding factors when it comes to steps
|
|
425
|
-
* themselves using arrays for object values - for example pgSelectSingle is
|
|
426
|
-
* represented by an array (tuple), but that doesn't make it a list so it should
|
|
427
|
-
* be fine. Use tests to validate this is all fine.
|
|
428
|
-
*/
|
|
429
|
-
if (arrayIndex == null || i !== l - 1) {
|
|
430
|
-
if (Array.isArray(out)) {
|
|
431
|
-
throw new Error("GrafastInternalError<db189d32-bf8f-4e58-b55f-5c5ac3bb2381>: Was expecting an arrayIndex, but none was provided");
|
|
425
|
+
toNextPath: for (const path of paths) {
|
|
426
|
+
let currentBucket = bucket;
|
|
427
|
+
let currentIndex = bucketIndex;
|
|
428
|
+
for (let i = 0, l = path.length; i < l; i++) {
|
|
429
|
+
const layerPlan = path[i];
|
|
430
|
+
const child = currentBucket.children[layerPlan.id];
|
|
431
|
+
if (!child) {
|
|
432
|
+
continue toNextPath;
|
|
432
433
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
else {
|
|
437
|
-
if (!Array.isArray(out)) {
|
|
438
|
-
throw new Error(`GrafastInternalError<8190d09f-dc75-46ec-8162-b20ad516de41>: Cannot access array index in non-array ${(0, inspect_js_1.inspect)(out)}`);
|
|
434
|
+
const out = child.map.get(currentIndex);
|
|
435
|
+
if (out == null) {
|
|
436
|
+
continue toNextPath;
|
|
439
437
|
}
|
|
440
|
-
|
|
441
|
-
|
|
438
|
+
/*
|
|
439
|
+
* TEST: I think this '|| i !== l - 1' check is saying that an array can
|
|
440
|
+
* only occur at the furthest ancestor and everything since then must be
|
|
441
|
+
* non-array. Presumably in the case of nested arrays there would be an
|
|
442
|
+
* intermediary bucket, hence why this check is allowed, but that should be
|
|
443
|
+
* tested. Also, are there any confounding factors when it comes to steps
|
|
444
|
+
* themselves using arrays for object values - for example pgSelectSingle is
|
|
445
|
+
* represented by an array (tuple), but that doesn't make it a list so it should
|
|
446
|
+
* be fine. Use tests to validate this is all fine.
|
|
447
|
+
*/
|
|
448
|
+
if (arrayIndex == null || i !== 0) {
|
|
449
|
+
if (Array.isArray(out)) {
|
|
450
|
+
throw new Error("GrafastInternalError<db189d32-bf8f-4e58-b55f-5c5ac3bb2381>: Was expecting an arrayIndex, but none was provided");
|
|
451
|
+
}
|
|
452
|
+
currentBucket = child.bucket;
|
|
453
|
+
currentIndex = out;
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
if (!Array.isArray(out)) {
|
|
457
|
+
throw new Error(`GrafastInternalError<8190d09f-dc75-46ec-8162-b20ad516de41>: Cannot access array index in non-array ${(0, inspect_js_1.inspect)(out)}`);
|
|
458
|
+
}
|
|
459
|
+
if (!(out.length > arrayIndex)) {
|
|
460
|
+
throw new Error(`GrafastInternalError<1f596c22-368b-4d0d-94df-fb3df632b064>: Attempted to retrieve array index '${arrayIndex}' which is out of bounds of array with length '${out.length}'`);
|
|
461
|
+
}
|
|
462
|
+
currentBucket = child.bucket;
|
|
463
|
+
currentIndex = out[arrayIndex];
|
|
442
464
|
}
|
|
443
|
-
currentBucket = child.bucket;
|
|
444
|
-
currentIndex = out[arrayIndex];
|
|
445
465
|
}
|
|
466
|
+
if (currentIndex == null) {
|
|
467
|
+
continue toNextPath;
|
|
468
|
+
}
|
|
469
|
+
return [currentBucket, currentIndex];
|
|
446
470
|
}
|
|
447
|
-
|
|
448
|
-
return null;
|
|
449
|
-
}
|
|
450
|
-
return [currentBucket, currentIndex];
|
|
471
|
+
return null;
|
|
451
472
|
}
|
|
452
473
|
function makeExecutor(config) {
|
|
453
474
|
const { preamble = null, inner, asString, nameExtra, skipNullHandling = false, } = config;
|
|
@@ -461,13 +482,13 @@ function makeExecutor(config) {
|
|
|
461
482
|
throw new Error(`GrafastInternalError<da9cc5a0-23bf-4af8-a103-92f995795398>: ${(0, index_js_1.stripAnsi)(String(this.sideEffectStep))} has no entry in ${bucket}`);
|
|
462
483
|
}
|
|
463
484
|
const seFlags = ev._flagsAt(sideEffectBucketIndex);
|
|
464
|
-
if (seFlags &
|
|
485
|
+
if (seFlags & constants_js_1.FLAG_ERROR) {
|
|
465
486
|
const seVal = ev.at(sideEffectBucketIndex);
|
|
466
487
|
throw coerceError(seVal, this.locationDetails, mutablePath.slice(1));
|
|
467
488
|
}
|
|
468
489
|
}
|
|
469
490
|
}
|
|
470
|
-
if (bucketRootFlags &
|
|
491
|
+
if (bucketRootFlags & constants_js_1.FLAG_ERROR) {
|
|
471
492
|
throw coerceError(rawBucketRootValue, this.locationDetails, mutablePath.slice(1));
|
|
472
493
|
}
|
|
473
494
|
const bucketRootValue = this.processRoot !== null
|
|
@@ -498,7 +519,7 @@ function executeChildPlan(that, locationDetails, childOutputPlan, isNonNull, asS
|
|
|
498
519
|
throw new Error(`GrafastInternalError<d18d52b5-f5bf-42df-a2dd-80e522310b8e>: ${(0, index_js_1.stripAnsi)(String($sideEffect))} has no entry in ${bucket}`);
|
|
499
520
|
}
|
|
500
521
|
const flags = ev._flagsAt(sideEffectBucketIndex);
|
|
501
|
-
if (flags &
|
|
522
|
+
if (flags & constants_js_1.FLAG_ERROR) {
|
|
502
523
|
const e = coerceError(ev.at(sideEffectBucketIndex), locationDetails, mutablePath.slice(1));
|
|
503
524
|
if (isNonNull) {
|
|
504
525
|
throw e;
|
|
@@ -661,23 +682,19 @@ const stringLeafExecutorString = makeExecutor({
|
|
|
661
682
|
}
|
|
662
683
|
},
|
|
663
684
|
});
|
|
664
|
-
//
|
|
665
|
-
// should be `resolveType(bucketRootValue)` but it's not worth the function
|
|
666
|
-
// call overhead. Longer term it should just be read directly from a different
|
|
667
|
-
// store.
|
|
685
|
+
// TODO: do we need this or can we skip it?
|
|
668
686
|
function makePolymorphicExecutor(asString) {
|
|
669
687
|
return makeExecutor({
|
|
670
688
|
inner(bucketRootValue, root, mutablePath, bucket, bucketIndex) {
|
|
689
|
+
const typeName = bucketRootValue;
|
|
671
690
|
if (dev_js_1.isDev) {
|
|
672
|
-
|
|
673
|
-
throw coerceError(new Error("GrafastInternalError<db7fcda5-dc39-4568-a7ce-ee8acb88806b>: Expected polymorphic data"), this.locationDetails, mutablePath.slice(1));
|
|
674
|
-
}
|
|
691
|
+
assert.ok(typeName, "GrafastInternalError<fd3f3cf0-0789-4c74-a6cd-839c808896ed>: Could not determine concreteType for object");
|
|
675
692
|
}
|
|
676
|
-
const typeName = bucketRootValue[interfaces_js_1.$$concreteType];
|
|
677
693
|
const childOutputPlan = this.childByTypeName[typeName];
|
|
678
|
-
if (
|
|
679
|
-
|
|
680
|
-
|
|
694
|
+
if (!childOutputPlan) {
|
|
695
|
+
// Search: InvalidConcreteTypeName
|
|
696
|
+
console.warn(`Invalid object type name for this abstract position${this.locationDetails.parentTypeName && this.locationDetails.fieldName ? ` at ${this.locationDetails.parentTypeName}.${this.locationDetails.fieldName}` : ""}; saw %o, but expected one of ${this.type.typeNames.join(", ")}`, typeName);
|
|
697
|
+
return (asString ? "null" : null);
|
|
681
698
|
}
|
|
682
699
|
const directChild = bucket.children[childOutputPlan.layerPlan.id];
|
|
683
700
|
if (directChild !== undefined) {
|
|
@@ -686,7 +703,13 @@ function makePolymorphicExecutor(asString) {
|
|
|
686
703
|
else {
|
|
687
704
|
const c = getChildBucketAndIndex(childOutputPlan.layerPlan, this, bucket, bucketIndex);
|
|
688
705
|
if (!c) {
|
|
689
|
-
|
|
706
|
+
// TODO: Implies that the bucket didn't run; is this a normal
|
|
707
|
+
// situation? We should be able to detect it and handle it more
|
|
708
|
+
// cleanly.
|
|
709
|
+
if (dev_js_1.isDev) {
|
|
710
|
+
debugVerbose(`GrafastInternalWarning<691509d8-31fa-4cfe-a6df-dcba21bd521f>: polymorphic executor couldn't determine child bucket. childOutputPlan=%c, childOutputPlan.layerPlan=%c, bucket=%c`, childOutputPlan, childOutputPlan.layerPlan, bucket);
|
|
711
|
+
}
|
|
712
|
+
return (asString ? "null" : null);
|
|
690
713
|
}
|
|
691
714
|
const [childBucket, childBucketIndex] = c;
|
|
692
715
|
return childOutputPlan[asString ? "executeString" : "execute"](root, mutablePath, childBucket, childBucketIndex);
|
|
@@ -768,7 +791,7 @@ function makeArrayExecutor(childIsNonNull, canStream, asString) {
|
|
|
768
791
|
}
|
|
769
792
|
}
|
|
770
793
|
if (canStream) {
|
|
771
|
-
const stream = bucketRootValue[
|
|
794
|
+
const stream = bucketRootValue[constants_js_1.$$streamMore];
|
|
772
795
|
if (stream !== undefined) {
|
|
773
796
|
const labelStepId = childOutputPlan.layerPlan.reason.stream?.labelStepId;
|
|
774
797
|
root.streams.push({
|
|
@@ -1044,4 +1067,37 @@ function withFastExpression(path, fallback, callback) {
|
|
|
1044
1067
|
}
|
|
1045
1068
|
});
|
|
1046
1069
|
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Finds the child of `targetParent` that has a path towards `descendent` (by
|
|
1072
|
+
* walking backwards from descendent to targetParent).
|
|
1073
|
+
*/
|
|
1074
|
+
function getDirectLayerPlanChild(targetParent, descendent) {
|
|
1075
|
+
const child = _getDirectLayerPlanChild(targetParent, descendent);
|
|
1076
|
+
if (child == null) {
|
|
1077
|
+
throw new Error(`GrafastInternalError<d43e06d8-c533-4e7b-b3e7-af399f19c83f>: Invalid hierarchy - could not find direct layerPlan child of ${targetParent} that leads to ${descendent}`);
|
|
1078
|
+
}
|
|
1079
|
+
return child;
|
|
1080
|
+
}
|
|
1081
|
+
function _getDirectLayerPlanChild(targetParent, descendent) {
|
|
1082
|
+
let directLayerPlanChild = descendent;
|
|
1083
|
+
let parent;
|
|
1084
|
+
while ((0, LayerPlan_js_1.hasParentLayerPlan)(directLayerPlanChild.reason) &&
|
|
1085
|
+
(parent = directLayerPlanChild.reason.parentLayerPlan) !== targetParent) {
|
|
1086
|
+
directLayerPlanChild = parent;
|
|
1087
|
+
}
|
|
1088
|
+
if (directLayerPlanChild.reason.type === "combined") {
|
|
1089
|
+
for (const plp of directLayerPlanChild.reason.parentLayerPlans) {
|
|
1090
|
+
const dlpc = _getDirectLayerPlanChild(targetParent, plp);
|
|
1091
|
+
if (dlpc)
|
|
1092
|
+
return dlpc;
|
|
1093
|
+
}
|
|
1094
|
+
return null;
|
|
1095
|
+
}
|
|
1096
|
+
else if (directLayerPlanChild.reason.type === "root") {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
else {
|
|
1100
|
+
return directLayerPlanChild;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1047
1103
|
//# sourceMappingURL=OutputPlan.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StepTracker = void 0;
|
|
4
|
+
const constants_js_1 = require("../constants.js");
|
|
4
5
|
const dev_js_1 = require("../dev.js");
|
|
5
6
|
const inspect_js_1 = require("../inspect.js");
|
|
6
|
-
const interfaces_js_1 = require("../interfaces.js");
|
|
7
7
|
const step_js_1 = require("../step.js");
|
|
8
8
|
const utils_js_1 = require("../utils.js");
|
|
9
9
|
const lock_js_1 = require("./lock.js");
|
|
@@ -40,6 +40,8 @@ class StepTracker {
|
|
|
40
40
|
/** @internal */
|
|
41
41
|
this.layerPlansByParentStep = new Map();
|
|
42
42
|
/** @internal */
|
|
43
|
+
this.layerPlansByDependentStep = new Map();
|
|
44
|
+
/** @internal */
|
|
43
45
|
this.layerPlans = [];
|
|
44
46
|
/**
|
|
45
47
|
* All the OutputPlans that were created to allow a more efficient
|
|
@@ -96,6 +98,7 @@ class StepTracker {
|
|
|
96
98
|
case "root":
|
|
97
99
|
case "subscription":
|
|
98
100
|
case "mutationField":
|
|
101
|
+
case "polymorphicPartition":
|
|
99
102
|
case "defer": {
|
|
100
103
|
break;
|
|
101
104
|
}
|
|
@@ -115,13 +118,16 @@ class StepTracker {
|
|
|
115
118
|
}
|
|
116
119
|
case "subroutine": {
|
|
117
120
|
const parent = layerPlan.reason.parentStep;
|
|
118
|
-
if (parent[
|
|
121
|
+
if (parent[constants_js_1.$$subroutine] !== null) {
|
|
119
122
|
throw new Error(`Steps may currently only have one subroutine. If you have need for a step with multiple subroutines, please get in touch.`);
|
|
120
123
|
}
|
|
121
|
-
parent[
|
|
124
|
+
parent[constants_js_1.$$subroutine] =
|
|
122
125
|
layerPlan;
|
|
123
126
|
break;
|
|
124
127
|
}
|
|
128
|
+
case "combined": {
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
125
131
|
default: {
|
|
126
132
|
const never = layerPlan.reason;
|
|
127
133
|
throw new Error(`Unexpected layerPlan reason ${never.type}`);
|
|
@@ -165,10 +171,22 @@ class StepTracker {
|
|
|
165
171
|
}
|
|
166
172
|
this.layerPlans[layerPlan.id] = null;
|
|
167
173
|
// Remove layerPlan from its parent
|
|
168
|
-
if (layerPlan.
|
|
169
|
-
|
|
174
|
+
if (layerPlan.reason.type === "root") {
|
|
175
|
+
// no action
|
|
176
|
+
}
|
|
177
|
+
else if (layerPlan.reason.type === "combined") {
|
|
178
|
+
for (const parentLayerPlan of layerPlan.reason.parentLayerPlans) {
|
|
179
|
+
const idx = parentLayerPlan.children.indexOf(layerPlan);
|
|
180
|
+
if (idx >= 0) {
|
|
181
|
+
parentLayerPlan.children.splice(idx, 1);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const parentLayerPlan = layerPlan.reason.parentLayerPlan;
|
|
187
|
+
const idx = parentLayerPlan.children.indexOf(layerPlan);
|
|
170
188
|
if (idx >= 0) {
|
|
171
|
-
|
|
189
|
+
parentLayerPlan.children.splice(idx, 1);
|
|
172
190
|
}
|
|
173
191
|
}
|
|
174
192
|
// Remove references
|
|
@@ -184,6 +202,16 @@ class StepTracker {
|
|
|
184
202
|
.delete(layerPlan);
|
|
185
203
|
}
|
|
186
204
|
}
|
|
205
|
+
if (layerPlan.reason.type === "combined") {
|
|
206
|
+
for (const combo of layerPlan.combinations) {
|
|
207
|
+
for (const source of combo.sources) {
|
|
208
|
+
const step = this.getStepById(source.stepId);
|
|
209
|
+
this.layerPlansByDependentStep
|
|
210
|
+
.get(step)
|
|
211
|
+
.delete(layerPlan);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
187
215
|
// Remove all plans in this layer
|
|
188
216
|
const handled = new Set();
|
|
189
217
|
const handle = (step) => {
|
|
@@ -220,16 +248,16 @@ class StepTracker {
|
|
|
220
248
|
const $dependent = (0, utils_js_1.sudo)(raw$dependent);
|
|
221
249
|
const $dependency = (0, utils_js_1.sudo)(options.step);
|
|
222
250
|
if (!this.activeSteps.has($dependent)) {
|
|
223
|
-
throw new Error(`Cannot add ${$dependency} as a dependency of ${$dependent}; the latter is deleted
|
|
251
|
+
throw new Error(`Cannot add ${$dependency} as a dependency of ${$dependent}; the latter is deleted! Explanation: https://err.red/gasdd#phase=${this.operationPlan.phase}&dependency=${encodeURIComponent(String($dependency))}&dependent=${encodeURIComponent(String($dependent))}&deleted=dependent`);
|
|
224
252
|
}
|
|
225
253
|
if (!this.activeSteps.has($dependency)) {
|
|
226
|
-
throw new Error(`Cannot add ${$dependency} as a dependency of ${$dependent}; the former is deleted
|
|
254
|
+
throw new Error(`Cannot add ${$dependency} as a dependency of ${$dependent}; the former is deleted! Explanation: https://err.red/gasdd#phase=${this.operationPlan.phase}&dependency=${encodeURIComponent(String($dependency))}&dependent=${encodeURIComponent(String($dependent))}&deleted=dependency`);
|
|
227
255
|
}
|
|
228
256
|
if ($dependent.isFinalized) {
|
|
229
257
|
throw new Error("You cannot add a dependency after the step is finalized.");
|
|
230
258
|
}
|
|
231
259
|
if (!($dependency instanceof step_js_1.Step)) {
|
|
232
|
-
throw new Error(`Error occurred when adding dependency for '${$dependent}', value passed was not a step, it was '${(0, inspect_js_1.inspect)($dependency)}'`);
|
|
260
|
+
throw new Error(`Error occurred when adding dependency for '${$dependent}', value passed was not a step, it was '${(0, inspect_js_1.inspect)($dependency)}' (phase = ${this.operationPlan.phase})`);
|
|
233
261
|
}
|
|
234
262
|
if (dev_js_1.isDev) {
|
|
235
263
|
// Check that we can actually add this as a dependency
|
|
@@ -237,19 +265,21 @@ class StepTracker {
|
|
|
237
265
|
throw new Error(
|
|
238
266
|
//console.error(
|
|
239
267
|
// This is not a GrafastInternalError
|
|
240
|
-
`Attempted to add '${$dependency}' (${$dependency.layerPlan}) as a dependency of '${$dependent}' (${$dependent.layerPlan}), but we cannot because that LayerPlan isn't an ancestor`);
|
|
268
|
+
`Attempted to add '${$dependency}' (${$dependency.layerPlan}) as a dependency of '${$dependent}' (${$dependent.layerPlan}), but we cannot because that LayerPlan isn't an ancestor. (phase = ${this.operationPlan.phase})`);
|
|
241
269
|
}
|
|
242
270
|
}
|
|
243
271
|
const dependentDependencies = (0, utils_js_1.writeableArray)($dependent.dependencies);
|
|
244
272
|
const dependentDependencyForbiddenFlags = (0, utils_js_1.writeableArray)($dependent.dependencyForbiddenFlags);
|
|
245
273
|
const dependentDependencyOnReject = (0, utils_js_1.writeableArray)($dependent.dependencyOnReject);
|
|
246
|
-
const
|
|
274
|
+
const dependentDependencyDataOnly = (0, utils_js_1.writeableArray)($dependent.dependencyDataOnly);
|
|
275
|
+
const { skipDeduplication, acceptFlags = constants_js_1.ALL_FLAGS & ~$dependent.defaultForbiddenFlags, onReject, dataOnly = false, } = options;
|
|
247
276
|
// When copying dependencies between classes, we might not want to
|
|
248
277
|
// deduplicate because we might refer to the dependency by its index. As
|
|
249
278
|
// such, we should only dedupe by default but allow opting out.
|
|
250
279
|
// TODO: change this to `!skipDeduplication`
|
|
251
280
|
if (skipDeduplication === false) {
|
|
252
|
-
const
|
|
281
|
+
const $searchForMe = options.step;
|
|
282
|
+
const existingIndex = dependentDependencies.indexOf($searchForMe);
|
|
253
283
|
if (existingIndex >= 0) {
|
|
254
284
|
return existingIndex;
|
|
255
285
|
}
|
|
@@ -260,13 +290,14 @@ class StepTracker {
|
|
|
260
290
|
}
|
|
261
291
|
$dependent._isUnary = false;
|
|
262
292
|
}
|
|
263
|
-
const forbiddenFlags =
|
|
293
|
+
const forbiddenFlags = constants_js_1.ALL_FLAGS & ~(acceptFlags & $dependent.__trappableFlags);
|
|
264
294
|
this.stepsWithNoDependenciesByConstructor
|
|
265
295
|
.get($dependent.constructor)
|
|
266
296
|
?.delete($dependent);
|
|
267
297
|
const dependencyIndex = dependentDependencies.push($dependency) - 1;
|
|
268
298
|
dependentDependencyForbiddenFlags[dependencyIndex] = forbiddenFlags;
|
|
269
299
|
dependentDependencyOnReject[dependencyIndex] = onReject;
|
|
300
|
+
dependentDependencyDataOnly[dependencyIndex] = dataOnly;
|
|
270
301
|
(0, utils_js_1.writeableArray)($dependency.dependents).push({
|
|
271
302
|
step: $dependent,
|
|
272
303
|
dependencyIndex,
|
|
@@ -274,13 +305,16 @@ class StepTracker {
|
|
|
274
305
|
return dependencyIndex;
|
|
275
306
|
}
|
|
276
307
|
addStepUnaryDependency($dependent, options) {
|
|
308
|
+
if (options.dataOnly) {
|
|
309
|
+
throw new Error(`${$dependent} attempted to add dataOnly unary dependency; this is not permitted.`);
|
|
310
|
+
}
|
|
277
311
|
const $dependency = options.step;
|
|
312
|
+
const { nonUnaryMessage = defaultNonUnaryMessage, ...rest } = options;
|
|
278
313
|
if (!$dependency._isUnary) {
|
|
279
|
-
const { nonUnaryMessage = defaultNonUnaryMessage } = options;
|
|
280
314
|
throw new Error(nonUnaryMessage($dependent, $dependency));
|
|
281
315
|
}
|
|
282
316
|
$dependency._isUnaryLocked = true;
|
|
283
|
-
return this.addStepDependency($dependent,
|
|
317
|
+
return this.addStepDependency($dependent, { ...rest, dataOnly: false });
|
|
284
318
|
}
|
|
285
319
|
setOutputPlanRootStep(outputPlan, $dependency) {
|
|
286
320
|
if (!this.activeSteps.has($dependency)) {
|
|
@@ -402,6 +436,28 @@ class StepTracker {
|
|
|
402
436
|
layerPlans.clear();
|
|
403
437
|
}
|
|
404
438
|
}
|
|
439
|
+
// Update combos
|
|
440
|
+
{
|
|
441
|
+
const layerPlans = this.layerPlansByDependentStep.get($original);
|
|
442
|
+
if (layerPlans?.size) {
|
|
443
|
+
let layerPlansByReplacementDependentStep = this.layerPlansByDependentStep.get($replacement);
|
|
444
|
+
if (!layerPlansByReplacementDependentStep) {
|
|
445
|
+
layerPlansByReplacementDependentStep = new Set();
|
|
446
|
+
this.layerPlansByDependentStep.set($replacement, layerPlansByReplacementDependentStep);
|
|
447
|
+
}
|
|
448
|
+
for (const layerPlan of layerPlans) {
|
|
449
|
+
for (const combo of layerPlan.combinations) {
|
|
450
|
+
for (const source of combo.sources) {
|
|
451
|
+
if (source.stepId === $original.id) {
|
|
452
|
+
source.stepId = $replacement.id;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
layerPlansByReplacementDependentStep.add(layerPlan);
|
|
457
|
+
}
|
|
458
|
+
layerPlans.clear();
|
|
459
|
+
}
|
|
460
|
+
}
|
|
405
461
|
// NOTE: had to add the code ensuring all the layer plan parentStepId's
|
|
406
462
|
// existed to fix polymorphism, but it feels wrong. Should we be doing
|
|
407
463
|
// something different?
|
|
@@ -456,6 +512,9 @@ class StepTracker {
|
|
|
456
512
|
const s3 = this.layerPlansByParentStep.get($step);
|
|
457
513
|
if (s3 && s3.size !== 0)
|
|
458
514
|
return false;
|
|
515
|
+
const s4 = this.layerPlansByDependentStep.get($step);
|
|
516
|
+
if (s4 && s4.size !== 0)
|
|
517
|
+
return false;
|
|
459
518
|
return true;
|
|
460
519
|
}
|
|
461
520
|
/**
|
|
@@ -498,8 +557,8 @@ class StepTracker {
|
|
|
498
557
|
* then they can also be eradicated _except_ during the 'plan' phase.
|
|
499
558
|
*/
|
|
500
559
|
eradicate($original) {
|
|
501
|
-
if ($original[
|
|
502
|
-
this.deleteLayerPlan($original[
|
|
560
|
+
if ($original[constants_js_1.$$subroutine] !== null) {
|
|
561
|
+
this.deleteLayerPlan($original[constants_js_1.$$subroutine]);
|
|
503
562
|
}
|
|
504
563
|
this.removeStepFromItsLayerPlan($original);
|
|
505
564
|
const oldAliases = this.aliasesById[$original.id];
|