grafast 0.0.1-alpha.9 → 0.0.1-beta.2
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/LICENSE.md +15 -17
- package/README.md +138 -1
- package/dist/LICENSES.txt +1 -1
- package/dist/args.d.ts +7 -1
- package/dist/assert.d.ts +2 -0
- package/dist/bucket.d.ts +66 -1
- package/dist/constraints.d.ts +31 -0
- package/dist/deferred.d.ts +7 -0
- package/dist/dev.d.ts +3 -0
- package/dist/engine/LayerPlan.d.ts +131 -0
- package/dist/engine/OperationPlan.d.ts +151 -0
- package/dist/engine/OutputPlan.d.ts +105 -1
- package/dist/engine/StepTracker.d.ts +56 -1
- package/dist/engine/executeBucket.d.ts +4 -1
- package/dist/engine/executeOutputPlan.d.ts +42 -1
- package/dist/envelop.d.ts +12 -0
- package/dist/envelop.js +2 -51
- package/dist/error.d.ts +23 -0
- package/dist/establishOperationPlan.d.ts +10 -31
- package/dist/execute.d.ts +8 -0
- package/dist/exportAs.d.ts +14 -0
- package/dist/grafastGraphql.d.ts +8 -3
- package/dist/grafastPrint.d.ts +8 -0
- package/dist/graphqlCollectFields.d.ts +22 -0
- package/dist/graphqlMergeSelectionSets.d.ts +4 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +387 -53
- package/dist/input.d.ts +8 -1
- package/dist/interfaces.d.ts +356 -59
- package/dist/makeGrafastSchema.d.ts +30 -3
- package/dist/mermaid.d.ts +28 -0
- package/dist/polymorphic.d.ts +8 -0
- package/dist/prepare.d.ts +16 -2
- package/dist/step.d.ts +183 -0
- package/dist/steps/__inputDynamicScalar.d.ts +3 -0
- package/dist/steps/__inputList.d.ts +3 -0
- package/dist/steps/__inputObject.d.ts +3 -0
- package/dist/steps/__inputStaticLeaf.d.ts +5 -0
- package/dist/steps/__item.d.ts +8 -0
- package/dist/steps/__trackedValue.d.ts +74 -0
- package/dist/steps/__value.d.ts +5 -0
- package/dist/steps/access.d.ts +20 -0
- package/dist/steps/{deepEval.d.ts → applyTransforms.d.ts} +16 -3
- package/dist/steps/connection.d.ts +49 -0
- package/dist/steps/constant.d.ts +11 -3
- package/dist/steps/each.d.ts +3 -0
- package/dist/steps/filter.d.ts +4 -0
- package/dist/steps/first.d.ts +4 -0
- package/dist/steps/graphqlResolver.d.ts +18 -0
- package/dist/steps/groupBy.d.ts +6 -0
- package/dist/steps/index.d.ts +6 -2
- package/dist/steps/lambda.d.ts +8 -0
- package/dist/steps/last.d.ts +4 -0
- package/dist/steps/list.d.ts +7 -0
- package/dist/steps/listTransform.d.ts +21 -0
- package/dist/steps/listen.d.ts +16 -0
- package/dist/steps/load.d.ts +13 -0
- package/dist/steps/node.d.ts +20 -12
- package/dist/steps/object.d.ts +15 -0
- package/dist/steps/partitionByIndex.d.ts +35 -0
- package/dist/steps/proxy.d.ts +11 -0
- package/dist/steps/remapKeys.d.ts +8 -0
- package/dist/steps/reverse.d.ts +9 -0
- package/dist/subscribe.d.ts +4 -0
- package/dist/utils.d.ts +113 -5
- package/dist/version.d.ts +2 -0
- package/fwd/graphql/index.d.ts +1 -0
- package/fwd/graphql/index.js +1 -0
- package/package.json +14 -6
|
@@ -11,6 +11,7 @@ import { OutputPlan } from "./OutputPlan.js";
|
|
|
11
11
|
import { StepTracker } from "./StepTracker.js";
|
|
12
12
|
export declare const POLYMORPHIC_ROOT_PATH: null;
|
|
13
13
|
export declare const POLYMORPHIC_ROOT_PATHS: ReadonlySet<string> | null;
|
|
14
|
+
/** @internal */
|
|
14
15
|
export type OperationPlanPhase = "init" | "plan" | "validate" | "optimize" | "finalize" | "ready";
|
|
15
16
|
export interface MetaByMetaKey {
|
|
16
17
|
[metaKey: string | number | symbol]: Record<string, any>;
|
|
@@ -38,35 +39,76 @@ export declare class OperationPlan {
|
|
|
38
39
|
[objectTypeName: string]: ReadonlyArray<GraphQLUnionType>;
|
|
39
40
|
};
|
|
40
41
|
private operationType;
|
|
42
|
+
/**
|
|
43
|
+
* What state is the OpPlan in?
|
|
44
|
+
*
|
|
45
|
+
* 1. init
|
|
46
|
+
* 2. plan
|
|
47
|
+
* 3. validate
|
|
48
|
+
* 5. optimize
|
|
49
|
+
* 6. finalize
|
|
50
|
+
* 7. ready
|
|
51
|
+
*
|
|
52
|
+
* Once in 'ready' state we can execute the plan.
|
|
53
|
+
*
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
41
56
|
phase: OperationPlanPhase;
|
|
57
|
+
/**
|
|
58
|
+
* Gets updated as we work our way through the plan, useful for making errors more helpful.
|
|
59
|
+
*/
|
|
42
60
|
loc: string[] | null;
|
|
61
|
+
/** @internal */
|
|
43
62
|
rootLayerPlan: LayerPlan;
|
|
63
|
+
/**
|
|
64
|
+
* Assigned during OperationPlan.planOperation(), guaranteed to exist after
|
|
65
|
+
* initialization.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
44
69
|
rootOutputPlan: OutputPlan;
|
|
45
70
|
private modifierStepCount;
|
|
46
71
|
private modifierDepthCount;
|
|
47
72
|
private modifierSteps;
|
|
73
|
+
/** @internal */
|
|
48
74
|
readonly stepTracker: StepTracker;
|
|
49
75
|
private maxDeduplicatedStepId;
|
|
50
76
|
private maxValidatedStepId;
|
|
77
|
+
/** Constraints based on evaluating variables. @internal */
|
|
51
78
|
readonly variableValuesConstraints: Constraint[];
|
|
79
|
+
/** Stores the actual variableValues. @internal */
|
|
52
80
|
readonly variableValuesStep: __ValueStep<{
|
|
53
81
|
[key: string]: any;
|
|
54
82
|
}>;
|
|
83
|
+
/** A step for accessing variableValues in a tracked manner (allowing eval). @internal */
|
|
55
84
|
readonly trackedVariableValuesStep: __TrackedValueStep<{
|
|
56
85
|
[key: string]: any;
|
|
57
86
|
}>;
|
|
87
|
+
/** Constraints based on evaluating context. @internal */
|
|
58
88
|
readonly contextConstraints: Constraint[];
|
|
89
|
+
/** Stores the actual value of the context. @internal */
|
|
59
90
|
readonly contextStep: __ValueStep<Grafast.Context>;
|
|
91
|
+
/** Allows accessing context in a tracked manner (allowing eval). @internal */
|
|
60
92
|
readonly trackedContextStep: __TrackedValueStep<{
|
|
61
93
|
[key: string]: any;
|
|
62
94
|
}>;
|
|
95
|
+
/** Constraints based on evaluating rootValue. @internal */
|
|
63
96
|
readonly rootValueConstraints: Constraint[];
|
|
97
|
+
/** Stores the actual value of rootValue. @internal */
|
|
64
98
|
readonly rootValueStep: __ValueStep<any>;
|
|
99
|
+
/** Allows accessing rootValue in a tracked manner (allowing eval). @internal */
|
|
65
100
|
readonly trackedRootValueStep: __TrackedValueStep<any>;
|
|
101
|
+
/** @internal */
|
|
66
102
|
makeMetaByMetaKey: () => MetaByMetaKey;
|
|
103
|
+
/**
|
|
104
|
+
* @internal
|
|
105
|
+
*/
|
|
67
106
|
readonly itemStepIdByListStepId: {
|
|
68
107
|
[listStepId: number]: number | undefined;
|
|
69
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* If true, then this operation doesn't use (custom) resolvers.
|
|
111
|
+
*/
|
|
70
112
|
pure: boolean;
|
|
71
113
|
private startTime;
|
|
72
114
|
private previousLap;
|
|
@@ -82,50 +124,159 @@ export declare class OperationPlan {
|
|
|
82
124
|
}, rootValue: any, planningTimeout: number | null);
|
|
83
125
|
private lap;
|
|
84
126
|
private checkTimeout;
|
|
127
|
+
/**
|
|
128
|
+
* Called by the LayerPlan's constructor when it wants to get a new id to use.
|
|
129
|
+
*
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
85
132
|
addLayerPlan(layerPlan: LayerPlan): number;
|
|
133
|
+
/**
|
|
134
|
+
* Adds a plan to the known steps and returns the number to use as the plan
|
|
135
|
+
* id. ONLY to be used from Step, user code should never call this directly.
|
|
136
|
+
*
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
86
139
|
_addStep(plan: ExecutableStep): number;
|
|
140
|
+
/**
|
|
141
|
+
* Adds a plan to the known steps and returns the number to use as the plan
|
|
142
|
+
* id. ONLY to be used from Step, user code should never call this directly.
|
|
143
|
+
*
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
87
146
|
_addModifierStep(step: ModifierStep<any>): string;
|
|
147
|
+
/** @internal Use plan.getStep(id) instead. */
|
|
88
148
|
getStep: (id: number, requestingStep: ExecutableStep) => ExecutableStep;
|
|
149
|
+
/**
|
|
150
|
+
* Get a plan without specifying who requested it; this disables all the
|
|
151
|
+
* caller checks. Only intended to be called from internal code.
|
|
152
|
+
*
|
|
153
|
+
* @internal
|
|
154
|
+
*/
|
|
89
155
|
dangerouslyGetStep(id: number): ExecutableStep;
|
|
90
156
|
private planOperation;
|
|
157
|
+
/**
|
|
158
|
+
* Plans a GraphQL query operation.
|
|
159
|
+
*/
|
|
91
160
|
private planQuery;
|
|
161
|
+
/**
|
|
162
|
+
* Implements the `PlanOpPlanMutation` algorithm.
|
|
163
|
+
*/
|
|
92
164
|
private planMutation;
|
|
165
|
+
/**
|
|
166
|
+
* Implements the `PlanOpPlanSubscription` algorithm.
|
|
167
|
+
*/
|
|
93
168
|
private planSubscription;
|
|
169
|
+
/**
|
|
170
|
+
* Gets the item plan for a given parent list plan - this ensures we only
|
|
171
|
+
* create one item plan per parent plan.
|
|
172
|
+
*/
|
|
94
173
|
private itemStepForListStep;
|
|
95
174
|
processGroupedFieldSet(outputPlan: OutputPlan, path: readonly string[], polymorphicPath: string | null, polymorphicPaths: ReadonlySet<string> | null, parentStep: ExecutableStep, objectType: GraphQLObjectType, objectTypeFields: GraphQLFieldMap<any, any>, isMutation: boolean, groupedFieldSet: SelectionSetDigest): void;
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @param outputPlan - The output plan that this selection set is being added to
|
|
178
|
+
* @param path - The path within the outputPlan that we're adding stuff (only for root/object OutputPlans)
|
|
179
|
+
* @param parentStep - The step that represents the selection set root
|
|
180
|
+
* @param objectType - The object type that this selection set is being evaluated for (note polymorphic selection should already have been handled by this point)
|
|
181
|
+
* @param selections - The GraphQL selections (fields, fragment spreads, inline fragments) to evaluate
|
|
182
|
+
* @param isMutation - If true this selection set should be executed serially rather than in parallel (each field gets its own LayerPlan)
|
|
183
|
+
*/
|
|
96
184
|
private planSelectionSet;
|
|
97
185
|
private planIntoOutputPlan;
|
|
98
186
|
private polymorphicLayerPlanByPathByLayerPlan;
|
|
99
187
|
private getPolymorphicLayerPlan;
|
|
100
188
|
private planField;
|
|
189
|
+
/**
|
|
190
|
+
* A replacement for GraphQL's
|
|
191
|
+
* `CoerceArgumentValues` that factors in tracked variables.
|
|
192
|
+
*
|
|
193
|
+
* @see https://spec.graphql.org/draft/#CoerceArgumentValues()
|
|
194
|
+
*/
|
|
101
195
|
private getTrackedArguments;
|
|
102
196
|
withModifiers<T>(cb: () => T): T;
|
|
197
|
+
/**
|
|
198
|
+
* Sets up tracking for the given value (variableValues, context, rootValue).
|
|
199
|
+
*/
|
|
103
200
|
private track;
|
|
201
|
+
/**
|
|
202
|
+
* Checks that no step has a property on it whose value is another step. It
|
|
203
|
+
* should addDependency instead.
|
|
204
|
+
*/
|
|
104
205
|
private validateSteps;
|
|
105
206
|
private replaceStep;
|
|
106
207
|
private processStep;
|
|
208
|
+
/**
|
|
209
|
+
* Process the given steps, either dependencies first (root to leaf) or
|
|
210
|
+
* dependents first (leaves to root).
|
|
211
|
+
*
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
107
214
|
processSteps(actionDescription: string, order: "dependents-first" | "dependencies-first", isReadonly: boolean, callback: (plan: ExecutableStep) => ExecutableStep): void;
|
|
215
|
+
/**
|
|
216
|
+
* Peers are steps of the same type (but not the same step!) that are in
|
|
217
|
+
* compatible layers and have the same dependencies. Peers must not have side
|
|
218
|
+
* effects. A step is not its own peer.
|
|
219
|
+
*/
|
|
108
220
|
private getPeers;
|
|
109
221
|
private isImmoveable;
|
|
222
|
+
/**
|
|
223
|
+
* Attempts to hoist the step into a higher layerPlan to maximize
|
|
224
|
+
* deduplication.
|
|
225
|
+
*/
|
|
110
226
|
private hoistStep;
|
|
227
|
+
/**
|
|
228
|
+
* Attempts to push the step into the lowest layerPlan to minimize the need
|
|
229
|
+
* for copying between layer plans.
|
|
230
|
+
*/
|
|
111
231
|
private pushDown;
|
|
112
232
|
private _deduplicateInnerLogic;
|
|
113
233
|
private deduplicateStep;
|
|
114
234
|
private deduplicateStepsProcess;
|
|
235
|
+
/**
|
|
236
|
+
* Gives us a chance to replace nearly-duplicate plans with other existing
|
|
237
|
+
* plans (and adding the necessary transforms); this means that by the time
|
|
238
|
+
* we come to optimize the plan tree should already be simpler. For example
|
|
239
|
+
* if you have two plans at the same level that both request row data from
|
|
240
|
+
* the same database table with the same identifiers, `WHERE`, `LIMIT`,
|
|
241
|
+
* `OFFSET` and `ORDER BY`, but different `SELECT`s we could merge the two
|
|
242
|
+
* plans together by replacing the latter with the former and having the
|
|
243
|
+
* former SELECT additional fields, then transform the results back to what
|
|
244
|
+
* our child plans would be expecting.
|
|
245
|
+
*/
|
|
115
246
|
private deduplicateSteps;
|
|
116
247
|
private hoistAndDeduplicate;
|
|
117
248
|
private hoistSteps;
|
|
118
249
|
private pushDownSteps;
|
|
119
250
|
private getStepOptionsForStep;
|
|
251
|
+
/**
|
|
252
|
+
* Calls the 'optimize' method on a plan, which may cause the plan to
|
|
253
|
+
* communicate with its (deep) dependencies, and even to replace itself with
|
|
254
|
+
* a different plan.
|
|
255
|
+
*/
|
|
120
256
|
private optimizeStep;
|
|
257
|
+
/**
|
|
258
|
+
* Note that we work through dependents first so we can make sure that we
|
|
259
|
+
* know all our dependent's needs before we optimise ourself.
|
|
260
|
+
*/
|
|
121
261
|
private optimizeSteps;
|
|
262
|
+
/** Finalizes each step */
|
|
122
263
|
private finalizeSteps;
|
|
123
264
|
private finalizeLayerPlans;
|
|
265
|
+
/** Optimizes each output plan */
|
|
124
266
|
private optimizeOutputPlans;
|
|
267
|
+
/** Finalizes each output plan */
|
|
125
268
|
private finalizeOutputPlans;
|
|
126
269
|
private walkOutputPlans;
|
|
270
|
+
/**
|
|
271
|
+
* Convert an OpPlan into a plan graph in mermaid-js format.
|
|
272
|
+
*/
|
|
127
273
|
printPlanGraph(options?: PrintPlanGraphOptions): string;
|
|
128
274
|
finishSubroutine(subroutineStep: ExecutableStep, layerPlan: LayerPlan<LayerPlanReasonSubroutine>): void;
|
|
275
|
+
/**
|
|
276
|
+
* HIGHLY EXPERIMENTAL!
|
|
277
|
+
*
|
|
278
|
+
* @internal
|
|
279
|
+
*/
|
|
129
280
|
deleteLayerPlan(layerPlan: LayerPlan): void;
|
|
130
281
|
getStepsByMetaKey(metaKey: string | number | symbol): ExecutableStep[];
|
|
131
282
|
getStepsByStepClass<TClass extends ExecutableStep>(klass: {
|
|
@@ -8,34 +8,80 @@ import type { PayloadRoot } from "./executeOutputPlan.js";
|
|
|
8
8
|
import type { LayerPlan } from "./LayerPlan.js";
|
|
9
9
|
export type OutputPlanTypeIntrospection = {
|
|
10
10
|
mode: "introspection";
|
|
11
|
+
/**
|
|
12
|
+
* The GraphQL introspection field selection (may include arguments/etc). We
|
|
13
|
+
* can build a GraphQL document from this and issue it to graphql-js rather
|
|
14
|
+
* than replicating that effort.
|
|
15
|
+
*/
|
|
11
16
|
field: FieldNode;
|
|
17
|
+
/**
|
|
18
|
+
* The names of the variables used in this document.
|
|
19
|
+
*/
|
|
12
20
|
variableNames: string[];
|
|
21
|
+
/**
|
|
22
|
+
* No need to re-run the introspection each time, may as well cache it,
|
|
23
|
+
* right?
|
|
24
|
+
*
|
|
25
|
+
* Key: canonical JSON stringify of the variables used.
|
|
26
|
+
* Value: the GraphQL result (`{data, errors}`) for this.
|
|
27
|
+
*/
|
|
13
28
|
introspectionCacheByVariableValues: LRU<string, JSONValue>;
|
|
14
29
|
};
|
|
15
30
|
export type OutputPlanTypeRoot = {
|
|
31
|
+
/**
|
|
32
|
+
* Always return `{}`
|
|
33
|
+
*/
|
|
16
34
|
mode: "root";
|
|
17
35
|
typeName: string;
|
|
18
36
|
};
|
|
19
37
|
export type OutputPlanTypeObject = {
|
|
38
|
+
/**
|
|
39
|
+
* Return `{}` if non-null
|
|
40
|
+
*/
|
|
20
41
|
mode: "object";
|
|
21
42
|
typeName: string;
|
|
22
43
|
deferLabel: string | undefined;
|
|
23
44
|
};
|
|
24
45
|
export type OutputPlanTypePolymorphicObject = {
|
|
46
|
+
/**
|
|
47
|
+
* Return `{}` if non-null
|
|
48
|
+
*/
|
|
25
49
|
mode: "polymorphic";
|
|
26
50
|
typeNames: string[];
|
|
27
51
|
deferLabel: string | undefined;
|
|
28
52
|
};
|
|
29
53
|
export type OutputPlanTypeArray = {
|
|
54
|
+
/**
|
|
55
|
+
* Return a list of the same length if an array
|
|
56
|
+
*/
|
|
30
57
|
mode: "array";
|
|
31
58
|
};
|
|
32
59
|
export type OutputPlanTypeLeaf = {
|
|
60
|
+
/**
|
|
61
|
+
* Return the value.
|
|
62
|
+
*/
|
|
33
63
|
mode: "leaf";
|
|
34
64
|
graphqlType: GraphQLScalarType | GraphQLEnumType;
|
|
35
65
|
};
|
|
36
66
|
export type OutputPlanTypeNull = {
|
|
37
67
|
mode: "null";
|
|
38
68
|
};
|
|
69
|
+
/**
|
|
70
|
+
* Thanks to `@stream`, output plans must handle their own nullability concerns
|
|
71
|
+
* and we might need an output plan for any of these:
|
|
72
|
+
*
|
|
73
|
+
* - A concrete object
|
|
74
|
+
* - A polymorphic object
|
|
75
|
+
* - A leaf (enum/scalar)
|
|
76
|
+
* - Something we know will always be null
|
|
77
|
+
* - A list of any of the above
|
|
78
|
+
* - A list of lists
|
|
79
|
+
*
|
|
80
|
+
* In addition to the above, we also need to cover
|
|
81
|
+
*
|
|
82
|
+
* - The root object (which is like a concrete object, except it's never null)
|
|
83
|
+
* - Introspection
|
|
84
|
+
*/
|
|
39
85
|
export type OutputPlanType = OutputPlanTypeRoot | OutputPlanTypeObject | OutputPlanTypePolymorphicObject | OutputPlanTypeLeaf | OutputPlanTypeNull | OutputPlanTypeArray | OutputPlanTypeIntrospection;
|
|
40
86
|
export type OutputPlanKeyValueOutputPlan = {
|
|
41
87
|
type: "outputPlan";
|
|
@@ -51,22 +97,69 @@ export type OutputPlanKeyValue = OutputPlanKeyValueOutputPlan | OutputPlanKeyVal
|
|
|
51
97
|
export type OutputPlanKeyValueOutputPlanWithCachedBits = OutputPlanKeyValueOutputPlan & {
|
|
52
98
|
layerPlanId: number;
|
|
53
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* Defines a way of taking a layerPlan and converting it into an output value.
|
|
102
|
+
*
|
|
103
|
+
* The result of executing an output plan will be the following:
|
|
104
|
+
*
|
|
105
|
+
* - data?: the data for this layer, could be object, array or leaf (see OutputPlanMode)
|
|
106
|
+
* - errors: a list of errors that occurred (if any), including path details _within the output plan_
|
|
107
|
+
* - streams: a list of streams that were created
|
|
108
|
+
*/
|
|
54
109
|
export declare class OutputPlan<TType extends OutputPlanType = OutputPlanType> {
|
|
55
110
|
layerPlan: LayerPlan;
|
|
56
111
|
readonly type: TType;
|
|
112
|
+
/** For errors */
|
|
57
113
|
readonly locationDetails: LocationDetails;
|
|
114
|
+
/**
|
|
115
|
+
* The step that represents the root value. How this is used depends on the
|
|
116
|
+
* OutputPlanMode.
|
|
117
|
+
*/
|
|
58
118
|
readonly rootStep: ExecutableStep;
|
|
119
|
+
/**
|
|
120
|
+
* Appended to the root step when accessed to avoid the need for AccessSteps
|
|
121
|
+
*/
|
|
59
122
|
private processRoot;
|
|
123
|
+
/**
|
|
124
|
+
* For root/object output plans, the keys to set on the resulting object
|
|
125
|
+
* grouped by the concrete object type name.
|
|
126
|
+
*
|
|
127
|
+
* IMPORTANT: the order of these keys is significant, they MUST match the
|
|
128
|
+
* order in the request otherwise we break GraphQL spec compliance!
|
|
129
|
+
*/
|
|
60
130
|
keys: {
|
|
61
131
|
[key: string]: OutputPlanKeyValueTypeName | OutputPlanKeyValueOutputPlanWithCachedBits;
|
|
62
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* For list output plans, the output plan that describes the list children.
|
|
135
|
+
*/
|
|
63
136
|
child: OutputPlan | null;
|
|
64
137
|
childIsNonNull: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* For polymorphic output plans, the Object output plan for each specific type.
|
|
140
|
+
*/
|
|
65
141
|
childByTypeName: {
|
|
66
142
|
[typeName: string]: OutputPlan<OutputPlanTypeObject>;
|
|
67
143
|
} | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* For object output plan types only.
|
|
146
|
+
*/
|
|
68
147
|
deferredOutputPlans: OutputPlan<OutputPlanTypeObject | OutputPlanTypePolymorphicObject>[];
|
|
69
|
-
constructor(layerPlan: LayerPlan,
|
|
148
|
+
constructor(layerPlan: LayerPlan,
|
|
149
|
+
/**
|
|
150
|
+
* For root, this should always be an object.
|
|
151
|
+
*
|
|
152
|
+
* For object this could represent an object or null.
|
|
153
|
+
*
|
|
154
|
+
* For polymorphic this could represent a polymorphic object or null.
|
|
155
|
+
*
|
|
156
|
+
* For array it's the list itself (or null) and dictates the length of the result.
|
|
157
|
+
*
|
|
158
|
+
* For leaf, it's the leaf plan itself.
|
|
159
|
+
*
|
|
160
|
+
* For `introspection`, `null` it's irrelevant. Use `constant(null)` or whatever.
|
|
161
|
+
*/
|
|
162
|
+
rootStep: ExecutableStep, type: TType, locationDetails: LocationDetails);
|
|
70
163
|
print(): string;
|
|
71
164
|
toString(): string;
|
|
72
165
|
addChild(type: GraphQLObjectType | null, key: string | null, child: OutputPlanKeyValue): void;
|
|
@@ -79,5 +172,16 @@ export declare class OutputPlan<TType extends OutputPlanType = OutputPlanType> {
|
|
|
79
172
|
}
|
|
80
173
|
export declare function coerceError(error: Error, locationDetails: LocationDetails, path: ReadonlyArray<string | number>): graphql.GraphQLError;
|
|
81
174
|
export declare function nonNullError(locationDetails: LocationDetails, path: readonly (string | number)[]): graphql.GraphQLError;
|
|
175
|
+
/**
|
|
176
|
+
* We're currently running OutputPlan `outputPlan` in bucket `bucket` at index
|
|
177
|
+
* `bucketIndex`. If this is an array OutputPlan then we're looping over the
|
|
178
|
+
* entries in our list and we're currently at index `inArrayIndex` (otherwise
|
|
179
|
+
* this is null).
|
|
180
|
+
*
|
|
181
|
+
* Now we want to run `childOutputPlan`, but to do so we need to find the
|
|
182
|
+
* related `childBucket` and `childBucketIndex`.
|
|
183
|
+
*
|
|
184
|
+
* @internal
|
|
185
|
+
*/
|
|
82
186
|
export declare function getChildBucketAndIndex(childOutputPlan: OutputPlan, outputPlan: OutputPlan | null, bucket: Bucket, bucketIndex: number, arrayIndex?: number | null): [Bucket, number] | null;
|
|
83
187
|
//# sourceMappingURL=OutputPlan.d.ts.map
|
|
@@ -2,37 +2,92 @@ import type { OperationPlan } from "../index.js";
|
|
|
2
2
|
import type { ExecutableStep } from "../step";
|
|
3
3
|
import type { LayerPlan, LayerPlanReasonsWithParentStep } from "./LayerPlan";
|
|
4
4
|
import type { OutputPlan } from "./OutputPlan";
|
|
5
|
+
/**
|
|
6
|
+
* This class keeps track of all of our steps, and the dependencies between
|
|
7
|
+
* steps and other steps, layer plans and steps, and output plans and steps.
|
|
8
|
+
*
|
|
9
|
+
* When a step is replaced by another step, all the dependencies are updated
|
|
10
|
+
* such that the replaced step simply evaporates.
|
|
11
|
+
*
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
5
14
|
export declare class StepTracker {
|
|
6
15
|
private readonly operationPlan;
|
|
16
|
+
/** @internal */
|
|
7
17
|
stepCount: number;
|
|
18
|
+
/** @internal */
|
|
8
19
|
activeSteps: Set<ExecutableStep<any>>;
|
|
20
|
+
/** @internal */
|
|
9
21
|
stepById: {
|
|
10
22
|
[stepId: number]: ExecutableStep | null;
|
|
11
23
|
};
|
|
24
|
+
/** @internal */
|
|
12
25
|
private aliasesById;
|
|
26
|
+
/** @internal */
|
|
13
27
|
stepsWithNoDependencies: Set<ExecutableStep<any>>;
|
|
28
|
+
/** @internal */
|
|
14
29
|
outputPlansByRootStep: Map<ExecutableStep<any>, Set<OutputPlan<import("./OutputPlan").OutputPlanType>>>;
|
|
30
|
+
/** @internal */
|
|
15
31
|
layerPlansByRootStep: Map<ExecutableStep<any>, Set<LayerPlan<import("./LayerPlan").LayerPlanReason>>>;
|
|
32
|
+
/** @internal */
|
|
16
33
|
layerPlansByParentStep: Map<ExecutableStep<any>, Set<LayerPlan<LayerPlanReasonsWithParentStep>>>;
|
|
34
|
+
/** @internal */
|
|
17
35
|
layerPlans: Array<LayerPlan | null>;
|
|
36
|
+
/**
|
|
37
|
+
* All the OutputPlans that were created to allow a more efficient
|
|
38
|
+
* walkOutputPlans implementation.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
18
42
|
allOutputPlans: OutputPlan[];
|
|
19
43
|
nextStepIdToDeduplicate: number;
|
|
20
44
|
constructor(operationPlan: OperationPlan);
|
|
21
45
|
newStepsSince(oldStepCount: number): ExecutableStep<any>[];
|
|
22
|
-
|
|
46
|
+
private forbid;
|
|
47
|
+
/** Called when OperationPlan enters finalize phase. */
|
|
48
|
+
finalizeSteps(): void;
|
|
49
|
+
/** Called when OperationPlan is about to finalize the output plans. */
|
|
50
|
+
finalizeOutputPlans(): void;
|
|
23
51
|
addStep($step: ExecutableStep): number;
|
|
52
|
+
/**
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
24
55
|
addLayerPlan(layerPlan: LayerPlan): number;
|
|
56
|
+
/**
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
25
59
|
addOutputPlan(outputPlan: OutputPlan): void;
|
|
60
|
+
/**
|
|
61
|
+
* HIGHLY EXPERIMENTAL!
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
26
65
|
deleteLayerPlan(layerPlan: LayerPlan): void;
|
|
27
66
|
getStepById(id: number): ExecutableStep;
|
|
28
67
|
getStepById(id: number, allowUnset: true): ExecutableStep | null;
|
|
29
68
|
addStepDependency($dependent: ExecutableStep, $dependency: ExecutableStep): number;
|
|
30
69
|
setOutputPlanRootStep(outputPlan: OutputPlan, $dependency: ExecutableStep): void;
|
|
31
70
|
setLayerPlanRootStep(layerPlan: LayerPlan, $dependency: ExecutableStep): void;
|
|
71
|
+
/** @internal */
|
|
32
72
|
replaceStep($original: ExecutableStep, $replacement: ExecutableStep): void;
|
|
33
73
|
treeShakeSteps(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Return true if this step can be tree-shaken.
|
|
76
|
+
*/
|
|
34
77
|
private isNotNeeded;
|
|
78
|
+
/**
|
|
79
|
+
* Only for use during planField.
|
|
80
|
+
*/
|
|
35
81
|
purgeBackTo(count: number): void;
|
|
82
|
+
/**
|
|
83
|
+
* ONLY CALL THIS IF NOTHING DEPENDS ON $original! It's intended to be called
|
|
84
|
+
* from `replaceStep` or from itself.
|
|
85
|
+
*
|
|
86
|
+
* This method removes $original from the various maps/sets/lists, and also
|
|
87
|
+
* removes the fact that it was dependent on other steps. If these other
|
|
88
|
+
* steps no longer have any dependents (steps, layer plans or output plans)
|
|
89
|
+
* then they can also be eradicated _except_ during the 'plan' phase.
|
|
90
|
+
*/
|
|
36
91
|
private eradicate;
|
|
37
92
|
moveStepToLayerPlan(step: ExecutableStep, targetLayerPlan: LayerPlan): void;
|
|
38
93
|
addStepToItsLayerPlan(step: ExecutableStep): void;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { Bucket, RequestTools } from "../bucket.js";
|
|
2
2
|
import type { PromiseOrDirect } from "../interfaces.js";
|
|
3
|
+
import type { MetaByMetaKey } from "./OperationPlan.js";
|
|
4
|
+
/** @internal */
|
|
3
5
|
export declare function executeBucket(bucket: Bucket, requestContext: RequestTools): PromiseOrDirect<void>;
|
|
4
|
-
|
|
6
|
+
/** @internal */
|
|
7
|
+
export declare function newBucket(spec: Pick<Bucket, "layerPlan" | "store" | "size" | "hasErrors" | "polymorphicPathList" | "iterators">, parentMetaByMetaKey: MetaByMetaKey | null): Bucket;
|
|
5
8
|
//# sourceMappingURL=executeBucket.d.ts.map
|
|
@@ -6,11 +6,49 @@ export type OutputPath = Array<string | number>;
|
|
|
6
6
|
export interface OutputStream {
|
|
7
7
|
asyncIterable: AsyncIterableIterator<any>;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* PayloadRoot handles the root-level of a payload, it's ultimately responsible
|
|
11
|
+
* for sharing the `data`/`errors` with the user. But it also handles the
|
|
12
|
+
* intermediate payloads for stream/defer.
|
|
13
|
+
*
|
|
14
|
+
* A standard GraphQL query/mutation request (one that doesn't use
|
|
15
|
+
* `@stream`/`@defer`) will have just one payload. A standard GraphQL
|
|
16
|
+
* subscription request gets one payload per subscription event.
|
|
17
|
+
*
|
|
18
|
+
* When we mix `@stream` and `@defer` into this, we will require (often quite a
|
|
19
|
+
* lot) more payloads.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
9
23
|
export interface PayloadRoot {
|
|
24
|
+
/**
|
|
25
|
+
* Serialization works differently if we're running inside GraphQL. (Namely:
|
|
26
|
+
* we don't serialize - that's GraphQL's job.)
|
|
27
|
+
*/
|
|
10
28
|
insideGraphQL: false;
|
|
29
|
+
/**
|
|
30
|
+
* The errors that have occurred; these are proper GraphQLErrors and will be
|
|
31
|
+
* returned directly to clients so they must be complete.
|
|
32
|
+
*/
|
|
11
33
|
errors: GraphQLError[];
|
|
34
|
+
/**
|
|
35
|
+
* Defer queue - we don't start executing these until after the main
|
|
36
|
+
* payload is completed (to allow for a non-null boundary to abort
|
|
37
|
+
* execution).
|
|
38
|
+
*/
|
|
12
39
|
queue: Array<SubsequentPayloadSpec>;
|
|
40
|
+
/**
|
|
41
|
+
* Stream queue - we don't start executing these until after the main
|
|
42
|
+
* payload is completed (to allow for a non-null boundary to abort
|
|
43
|
+
* execution).
|
|
44
|
+
*/
|
|
13
45
|
streams: Array<SubsequentStreamSpec>;
|
|
46
|
+
/**
|
|
47
|
+
* VERY DANGEROUS. This is _only_ to pass variables through to introspection
|
|
48
|
+
* selections, it shouldn't be used for anything else.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
* */
|
|
14
52
|
variables: {
|
|
15
53
|
[key: string]: any;
|
|
16
54
|
};
|
|
@@ -35,8 +73,11 @@ export interface SubsequentStreamSpec {
|
|
|
35
73
|
bucketIndex: number;
|
|
36
74
|
outputPlan: OutputPlan;
|
|
37
75
|
label: string | undefined;
|
|
38
|
-
stream:
|
|
76
|
+
stream: AsyncIterator<any> | Iterator<any>;
|
|
39
77
|
startIndex: number;
|
|
40
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
41
82
|
export declare function executeOutputPlan(ctx: OutputPlanContext, outputPlan: OutputPlan, bucket: Bucket, bucketIndex: number, outputDataAsString: boolean): JSONValue;
|
|
42
83
|
//# sourceMappingURL=executeOutputPlan.d.ts.map
|
package/dist/envelop.d.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import type { Plugin as EnvelopPlugin } from "@envelop/core";
|
|
2
2
|
export interface UseGrafastOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Set this to 'true' to allow all explains; set it to a list of the allowed
|
|
5
|
+
* explains to allow only those, set it to false to disable explains.
|
|
6
|
+
*/
|
|
3
7
|
explainAllowed?: boolean | string[];
|
|
4
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* An Envelop plugin that uses Grafast to prepare and execute the GraphQL
|
|
11
|
+
* query.
|
|
12
|
+
*/
|
|
5
13
|
export declare const useGrafast: (options?: UseGrafastOptions) => EnvelopPlugin;
|
|
14
|
+
/**
|
|
15
|
+
* An Envelop plugin that will make any GraphQL errors easier to read from
|
|
16
|
+
* inside of GraphiQL.
|
|
17
|
+
*/
|
|
6
18
|
export declare const useMoreDetailedErrors: () => EnvelopPlugin;
|
|
7
19
|
//# sourceMappingURL=envelop.d.ts.map
|
package/dist/envelop.js
CHANGED
|
@@ -1,54 +1,5 @@
|
|
|
1
|
-
const { Buffer } = require('node:buffer');
|
|
2
|
-
const { scryptSync, createDecipheriv } = require('node:crypto');
|
|
3
|
-
const pkgName = "grafast";
|
|
4
|
-
const pkgVersion = "0.0.1-alpha.9";
|
|
5
|
-
|
|
6
|
-
const RESET = '\x1b[0m';
|
|
7
|
-
const BOLD_BLACK_ON_RED = '\x1b[40;31;1;7m';
|
|
8
|
-
const RED = '\x1b[31m';
|
|
9
|
-
const BOLD = '\x1b[1m';
|
|
10
|
-
const BOLD_BLUE = '\x1b[34;1m';
|
|
11
|
-
const BOLD_BLUE_UNDERLINED = '\x1b[34;1;4m';
|
|
12
|
-
|
|
13
|
-
const iSponsorGraphile = `${RESET}${BOLD_BLUE}I_SPONSOR_GRAPHILE${RESET}${RED}`;
|
|
14
|
-
const website = `${RESET}${BOLD_BLUE_UNDERLINED}https://grafast.org${RESET}`;
|
|
15
|
-
const errorPrefix = `${BOLD_BLACK_ON_RED}[ ERROR ]${RESET} ${RED}`;
|
|
16
|
-
const errorSuffix = `${RESET}
|
|
17
|
-
${BOLD_BLACK_ON_RED}[ CONTEXT ]${RESET} ${RED}You are attempting to run pre-release software that is only available to Graphile sponsors.${RESET}
|
|
18
|
-
|
|
19
|
-
Please refer to the ${website} documentation for the right code to use with this version '${BOLD}${pkgName}@${pkgVersion}${RESET}'.${RESET}
|
|
20
|
-
`;
|
|
21
|
-
|
|
22
|
-
const password = process.env.I_SPONSOR_GRAPHILE;
|
|
23
|
-
if (typeof password !== 'string') {
|
|
24
|
-
console.error(
|
|
25
|
-
`${errorPrefix}You must set the ${iSponsorGraphile} environmental variable to the shared secret to use this pre-release software.${errorSuffix}`,
|
|
26
|
-
);
|
|
27
|
-
process.exit(42);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const algorithm = "aes-192-cbc";
|
|
31
|
-
const salt = "We wouldn't be able to do so much OSS without sponsorship. 8585103646644423";
|
|
32
|
-
const key = scryptSync(password, salt, 24);
|
|
33
|
-
const ivBuffer = Buffer.from("iqQBrlQhhzLygmT7ks2rJQ==", "base64");
|
|
34
|
-
const iv = new Uint8Array(ivBuffer.buffer, ivBuffer.byteOffset, ivBuffer.length);
|
|
35
|
-
const decipher = createDecipheriv(algorithm, key, iv);
|
|
36
|
-
const encrypted = "AmT/IOgDt1FGoVOYzAKMlZupq/MPvSJrqBAW/mdLvRna1yQ6KzmfFYwF9hObAuhFTPr5QH8bQEvB1MLD7WBfCLpYAR6Txzi5DIuIAnHNMpFIR6Umv7heJsn4w/UmO38gKoXsDvJgAhBARl1DiKDa8lPOQntQVZbFSGKjIZ9gzhnbx8ACpFGKci/1kgmNxuko76gTdEWrvLV5Bdhbbx8JG5qpwluJC1ya4AExLxwThsgLUaAu5s91hjLiW74Wd+0qxoL1EvO5kHrGZyCtbut0CWtzSm9X+tOjM5qLG2xXTgzEzX8JEspbr82i6jorHy9S7yRtd3jfKx/2OnKxDAZ1RLu1EP459599sLSzZZJt0wcgrVxokMHRdwtXtbPVAWIoehfjI12djGxkTKgPn6n1JlGD5CRLvuush6maBuKZkibiZvgvVyvcVcNAAXxGc2T2owlKf/QPWa4MI+/KH7OWT/qEeMLdgjwCoQVEFeXMxIhjEWeJU1omvZbrgUkWrq2oG3VsPcSm+wjjdxxekHNYy3UP6m+iM012jtUkZBWv1aqEWSroklOyiXMwWl8YSrt9Q35ZUlvh7pv3g4Xyqf6MBj5+RnHfIv/mDIhmwpe3zDSQVqB3okVdtCWNhTeQX/dU40NoYMDkNahRxF23IcCkYUdHbKDjiqKFymsr7E5+PX97ffpehPW2lgjR6CQcjZfQyfy0tHI4FkU3SjHwMYKPq1RRQ6w69sCyrhZHph84fKY+CuXTd36JzuN8wRYe5sGUk6r7rZ2Cs8q3gDJp5sw9mudU1WyADzjcXYzwXW78+XJbvTl5W8pHicg7RBWPBRlU39qb2VMDPlhTVVynPToK/sM2uI1YmVyKykZkIlnULf3577ejJ38U2L0JqPOtC9RHV59uyUG6FubdGxpZkbkVD84kWFt06ClChbYsxJo9PQ3VhRoA3/gBdV02PY7kExFcHK8hrvVcP4bF2Au/AllBZqMamQuU2aK2zMcAucbRphNp8FyKXxJxIxTKTaACMAMsGA8h4tZyuhnBovYDFaHyOJWh/dLwJLWMY/sPAssAeWQrNK6Hy9oIZkX3sq2q2+OaF/1YcMVaG44JacyINuqU1bi+AgYCg0sY73nRMjBO3sXP3DO/BPtkLAMGD4SjqwfWgF02uWd/EVIhQ+QVKGtrTAzPCJBVkPZYLXpZiEnHdedJ4Cc0a85nSZBQ3gMf4fHiTes7AHLKW1jnmRN4+JQDFgJoMTE5+b7aO9xyqKYWFXDH9M4FbuS/ty/doZx2ejvU6LjXgLQ+ubzIxB/nJzhg7dQ3NbuJ0eTghimMtuzrbg8nraTZXRwTgR5sglbcu/ZoxKDWdMV2Nms8X2c80RYOpbGtKz4rWmLJng3TJyb6jHXXAjcQ/fEMEsaBbO2X0a+6Q3lKTOG5xZkrwvEWOXH75zZ7qfxQZ78Jaq4V50PH2n6M1gIWI6ULCrDW2jvxePC1Ei4zLHeys/6IDYvBbIh5GzHf1aCVQswvPI754E/6QPAb1FVofpkSET/vGb6B1jTzbTeOuFm7Luiw+QIvkaBi3PPhBOEMFmje5BUpb5kUfdF1xeQraAY5PWbuUBDTMtij2D1zeDYVRPGVIlEXlPw8xXUxzYhtFGpCxTFdwes+oj9WbLQowr+mfZoh9kbyVAVrzVfiUcfA71alYRbgz6CQeK8JNzepN4U4ntdJQGphpiDViZnPHkAfEp/PCWekxRt09VqsafxyskQlvqPgVcGNG/EvtJmZ+lZCa9+jgPdT9KqFaeVXBfH9TtuxUoKskIjf/qLckjLodsij6gowMm45laF4BZxuK1FJozOHaJmmeeA="
|
|
37
|
-
let decrypted;
|
|
38
|
-
try {
|
|
39
|
-
decrypted = decipher.update(encrypted, 'base64', 'utf8') + decipher.final('utf8');
|
|
40
|
-
} catch (e) {
|
|
41
|
-
console.error(
|
|
42
|
-
`${errorPrefix}The value for the ${iSponsorGraphile} environmental variable (value: '${password.slice(
|
|
43
|
-
0,
|
|
44
|
-
2,
|
|
45
|
-
)}...${password.slice(-2)}') is incorrect.${errorSuffix}`,
|
|
46
|
-
);
|
|
47
|
-
process.exit(42);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
1
|
// Convince Node to allow ESM named imports
|
|
51
2
|
|
|
52
3
|
|
|
53
|
-
//
|
|
54
|
-
|
|
4
|
+
// Bundled module
|
|
5
|
+
"use strict";!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.grafast=r():e.grafast=r()}(this,(()=>(this.webpackChunkgrafast=this.webpackChunkgrafast||[]).push([[764],{3837:(e,r,s)=>{Object.defineProperty(r,"__esModule",{value:!0}),r.useMoreDetailedErrors=r.useGrafast=void 0;const t=s(6587),n=s(6522),a=s(680);function o(e,r){if(!1===e||Array.isArray(e)&&0===e.length)return;const s=Array.isArray(r)?r.join(","):r;if(!s)return;const t=s.split(",");return!0===e||void 0===e?t:e.filter((e=>t.includes(e)))}r.useGrafast=(e={})=>{const{explainAllowed:r=!0}=e;return{async onExecute(e){const s=e.args.contextValue?.req?.headers["x-graphql-explain"],n=o(r,s);e.setExecuteFn((e=>(0,t.execute)(e,{grafast:{explain:n}})))},async onSubscribe(e){const s=e.args.contextValue,t=(s?.req?.headers||s?.request?.headers||s?.connectionParams)?.["x-graphql-explain"],n=o(r,t);e.setSubscribeFn((async e=>(0,a.subscribe)(e,{grafast:{explain:n}})))}}};r.useMoreDetailedErrors=()=>({onExecute:()=>({onExecuteDone({result:e}){"errors"in e&&e.errors&&(e.errors=e.errors.map((e=>{const r=e.toJSON();return Object.assign(r,{message:(0,n.stripAnsi)(r.message),extensions:{stack:(0,n.stripAnsi)(e.stack??"").split("\n")}})})))}})})}},e=>{var r;return r=3837,e(e.s=r)}])));
|