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.
Files changed (69) hide show
  1. package/LICENSE.md +15 -17
  2. package/README.md +138 -1
  3. package/dist/LICENSES.txt +1 -1
  4. package/dist/args.d.ts +7 -1
  5. package/dist/assert.d.ts +2 -0
  6. package/dist/bucket.d.ts +66 -1
  7. package/dist/constraints.d.ts +31 -0
  8. package/dist/deferred.d.ts +7 -0
  9. package/dist/dev.d.ts +3 -0
  10. package/dist/engine/LayerPlan.d.ts +131 -0
  11. package/dist/engine/OperationPlan.d.ts +151 -0
  12. package/dist/engine/OutputPlan.d.ts +105 -1
  13. package/dist/engine/StepTracker.d.ts +56 -1
  14. package/dist/engine/executeBucket.d.ts +4 -1
  15. package/dist/engine/executeOutputPlan.d.ts +42 -1
  16. package/dist/envelop.d.ts +12 -0
  17. package/dist/envelop.js +2 -51
  18. package/dist/error.d.ts +23 -0
  19. package/dist/establishOperationPlan.d.ts +10 -31
  20. package/dist/execute.d.ts +8 -0
  21. package/dist/exportAs.d.ts +14 -0
  22. package/dist/grafastGraphql.d.ts +8 -3
  23. package/dist/grafastPrint.d.ts +8 -0
  24. package/dist/graphqlCollectFields.d.ts +22 -0
  25. package/dist/graphqlMergeSelectionSets.d.ts +4 -0
  26. package/dist/index.d.ts +9 -4
  27. package/dist/index.js +387 -53
  28. package/dist/input.d.ts +8 -1
  29. package/dist/interfaces.d.ts +356 -59
  30. package/dist/makeGrafastSchema.d.ts +30 -3
  31. package/dist/mermaid.d.ts +28 -0
  32. package/dist/polymorphic.d.ts +8 -0
  33. package/dist/prepare.d.ts +16 -2
  34. package/dist/step.d.ts +183 -0
  35. package/dist/steps/__inputDynamicScalar.d.ts +3 -0
  36. package/dist/steps/__inputList.d.ts +3 -0
  37. package/dist/steps/__inputObject.d.ts +3 -0
  38. package/dist/steps/__inputStaticLeaf.d.ts +5 -0
  39. package/dist/steps/__item.d.ts +8 -0
  40. package/dist/steps/__trackedValue.d.ts +74 -0
  41. package/dist/steps/__value.d.ts +5 -0
  42. package/dist/steps/access.d.ts +20 -0
  43. package/dist/steps/{deepEval.d.ts → applyTransforms.d.ts} +16 -3
  44. package/dist/steps/connection.d.ts +49 -0
  45. package/dist/steps/constant.d.ts +11 -3
  46. package/dist/steps/each.d.ts +3 -0
  47. package/dist/steps/filter.d.ts +4 -0
  48. package/dist/steps/first.d.ts +4 -0
  49. package/dist/steps/graphqlResolver.d.ts +18 -0
  50. package/dist/steps/groupBy.d.ts +6 -0
  51. package/dist/steps/index.d.ts +6 -2
  52. package/dist/steps/lambda.d.ts +8 -0
  53. package/dist/steps/last.d.ts +4 -0
  54. package/dist/steps/list.d.ts +7 -0
  55. package/dist/steps/listTransform.d.ts +21 -0
  56. package/dist/steps/listen.d.ts +16 -0
  57. package/dist/steps/load.d.ts +13 -0
  58. package/dist/steps/node.d.ts +20 -12
  59. package/dist/steps/object.d.ts +15 -0
  60. package/dist/steps/partitionByIndex.d.ts +35 -0
  61. package/dist/steps/proxy.d.ts +11 -0
  62. package/dist/steps/remapKeys.d.ts +8 -0
  63. package/dist/steps/reverse.d.ts +9 -0
  64. package/dist/subscribe.d.ts +4 -0
  65. package/dist/utils.d.ts +113 -5
  66. package/dist/version.d.ts +2 -0
  67. package/fwd/graphql/index.d.ts +1 -0
  68. package/fwd/graphql/index.js +1 -0
  69. 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, rootStep: ExecutableStep, type: TType, locationDetails: LocationDetails);
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
- finalize(): void;
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
- export declare function newBucket(spec: Pick<Bucket, "layerPlan" | "store" | "size" | "hasErrors" | "polymorphicPathList">): Bucket;
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: AsyncIterableIterator<any>;
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
- // Load our decrypted module
54
- eval(decrypted);
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)}])));