grafast 0.1.1-beta.26 → 0.1.1-beta.27

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.
@@ -4,7 +4,6 @@ exports.OperationPlan = exports.POLYMORPHIC_ROOT_PATHS = exports.POLYMORPHIC_ROO
4
4
  const tslib_1 = require("tslib");
5
5
  const lru_1 = tslib_1.__importDefault(require("@graphile/lru"));
6
6
  const graphql = tslib_1.__importStar(require("graphql"));
7
- const tamedevil_1 = tslib_1.__importDefault(require("tamedevil"));
8
7
  const assert = tslib_1.__importStar(require("../assert.js"));
9
8
  const constants_js_1 = require("../constants.js");
10
9
  const graphqlCollectFields_js_1 = require("../graphqlCollectFields.js");
@@ -217,9 +216,7 @@ class OperationPlan {
217
216
  this.checkTimeout();
218
217
  this.lap("treeShakeSteps", "optimize");
219
218
  // Replace/inline/optimise steps
220
- tamedevil_1.default.batch(() => {
221
- this.optimizeSteps();
222
- });
219
+ this.optimizeSteps();
223
220
  this.checkTimeout();
224
221
  this.lap("optimizeSteps");
225
222
  this.inlineSteps();
@@ -239,14 +236,10 @@ class OperationPlan {
239
236
  this.lap("pushDownSteps");
240
237
  // Plans are expected to execute later; they may take steps here to prepare
241
238
  // themselves (e.g. compiling SQL queries ahead of time).
242
- tamedevil_1.default.batch(() => {
243
- this.finalizeSteps();
244
- });
239
+ this.finalizeSteps();
245
240
  this.lap("finalizeSteps");
246
241
  // Replace access plans with direct access, etc (must come after finalizeSteps)
247
- tamedevil_1.default.batch(() => {
248
- this.optimizeOutputPlans();
249
- });
242
+ this.optimizeOutputPlans();
250
243
  this.checkTimeout();
251
244
  this.lap("optimizeOutputPlans");
252
245
  // AccessSteps may have been removed
@@ -254,13 +247,9 @@ class OperationPlan {
254
247
  this.checkTimeout();
255
248
  this.lap("treeShakeSteps", "optimizeOutputPlans");
256
249
  this.stepTracker.finalizeOutputPlans();
257
- tamedevil_1.default.batch(() => {
258
- this.finalizeLayerPlans();
259
- });
250
+ this.finalizeLayerPlans();
260
251
  this.lap("finalizeLayerPlans");
261
- tamedevil_1.default.batch(() => {
262
- this.finalizeOutputPlans();
263
- });
252
+ this.finalizeOutputPlans();
264
253
  this.lap("finalizeOutputPlans");
265
254
  this.finalize();
266
255
  this.lap("finalizeOperationPlan");
@@ -466,7 +455,7 @@ class OperationPlan {
466
455
  }
467
456
  const planningPath = rootType.name + ".";
468
457
  const selectionSet = this.operation.selectionSet;
469
- const stepStreamOptions = {};
458
+ const stepStreamOptions = true;
470
459
  const groupedFieldSet = (0, withGlobalLayerPlan_js_1.withGlobalLayerPlan)(this.rootLayerPlan, exports.POLYMORPHIC_ROOT_PATHS, planningPath, stepStreamOptions, graphqlCollectFields_js_1.graphqlCollectFields, null, this, this.trackedRootValueStep.id, rootType, selectionSet.selections, (0, graphqlCollectFields_js_1.newSelectionSetDigest)(false));
471
460
  if (groupedFieldSet.deferred !== undefined) {
472
461
  throw new index_js_1.SafeError("@defer forbidden on subscription root selection set");
@@ -1932,7 +1921,7 @@ class OperationPlan {
1932
1921
  let stepStreamOptions = undefined;
1933
1922
  if (streamDetails === true) {
1934
1923
  // subscription
1935
- stepStreamOptions = {};
1924
+ stepStreamOptions = true;
1936
1925
  }
1937
1926
  else if (streamDetails === false) {
1938
1927
  // Simple list, no action necessary
@@ -3653,6 +3642,7 @@ But ${p} is not in ${winner.layerPlan}'s expected polymorphic paths:
3653
3642
  function printStep(step) {
3654
3643
  const metaString = step.toStringMeta();
3655
3644
  const sstep = (0, utils_js_1.sudo)(step);
3645
+ const { stream } = step._stepOptions;
3656
3646
  return {
3657
3647
  id: step.id,
3658
3648
  stepClass: step.constructor.name,
@@ -3670,9 +3660,11 @@ But ${p} is not in ${winner.layerPlan}'s expected polymorphic paths:
3670
3660
  isSyncAndSafe: step.isSyncAndSafe || undefined,
3671
3661
  supportsUnbatched: typeof step.unbatchedExecute === "function" || undefined,
3672
3662
  hasSideEffects: step.hasSideEffects || undefined,
3673
- stream: step._stepOptions.stream
3674
- ? { initialCountStepId: step._stepOptions.stream.initialCountStepId }
3675
- : undefined,
3663
+ stream: stream === true
3664
+ ? {}
3665
+ : stream
3666
+ ? { initialCountStepId: stream.initialCountStepId }
3667
+ : undefined,
3676
3668
  extra: step.planJSONExtra(),
3677
3669
  };
3678
3670
  }
@@ -1,4 +1,4 @@
1
- import LRU from "@graphile/lru";
1
+ import type LRU from "@graphile/lru";
2
2
  import type { FieldNode, GraphQLEnumType, GraphQLObjectType, GraphQLScalarType } from "graphql";
3
3
  import * as graphql from "graphql";
4
4
  import type { Bucket } from "../bucket.js";
@@ -6,16 +6,14 @@ exports.nonNullError = nonNullError;
6
6
  exports.getChildBucketAndIndex = getChildBucketAndIndex;
7
7
  exports.getDirectLayerPlanChild = getDirectLayerPlanChild;
8
8
  const tslib_1 = require("tslib");
9
- const lru_1 = tslib_1.__importDefault(require("@graphile/lru"));
10
9
  const debug_1 = tslib_1.__importDefault(require("debug"));
11
10
  const graphql = tslib_1.__importStar(require("graphql"));
12
- const tamedevil_1 = tslib_1.__importStar(require("tamedevil"));
13
11
  const assert = tslib_1.__importStar(require("../assert.js"));
14
12
  const constants_js_1 = require("../constants.js");
15
13
  const dev_js_1 = require("../dev.js");
16
14
  const index_js_1 = require("../index.js");
17
15
  const inspect_js_1 = require("../inspect.js");
18
- const access_js_1 = require("../steps/access.js");
16
+ const tamedevilUtils_1 = require("../tamedevilUtils");
19
17
  const utils_js_1 = require("../utils.js");
20
18
  const LayerPlan_js_1 = require("./LayerPlan.js");
21
19
  const debug = (0, debug_1.default)("grafast:OutputPlan");
@@ -240,33 +238,7 @@ class OutputPlan {
240
238
  _mutablePath, _bucket, _bucketIndex, _rawBucketRootValue, _bucketRootFlags) {
241
239
  throw new Error(`OutputPlan.executeString has yet to be built!`);
242
240
  }
243
- optimize() {
244
- // This optimization works by ridding us of access steps at the very end of
245
- // paths and just accessing properties directly. In rare circumstances
246
- // involving untethered side effects in earlier versions this could lead to
247
- // errors being skipped and data generated previous to the error being
248
- // returned; but OutputPlans now check the latestSideEffectStep so this
249
- // should be safe aga.
250
- const $root = this.layerPlan.operationPlan.dangerouslyGetStep(this.rootStep.id);
251
- if ($root instanceof index_js_1.AccessStep &&
252
- $root.isSyncAndSafe && // Make sure we're not using it for streaming!
253
- $root.fallback === undefined &&
254
- $root.implicitSideEffectStep === null &&
255
- (!this.sideEffectStep || !(0, index_js_1.stepADependsOnStepB)($root, this.sideEffectStep))) {
256
- const expressionDetails = $root.unbatchedExecute[access_js_1.expressionSymbol];
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) {
262
- this.layerPlan.operationPlan.stepTracker.setOutputPlanRootStep(this, $parent);
263
- const [path, fallback] = expressionDetails;
264
- withFastExpression(path, fallback, (fn) => {
265
- this.processRoot = fn;
266
- });
267
- }
268
- }
269
- }
241
+ optimize() { }
270
242
  finalize() {
271
243
  // Clear the sideEffectStep if the rootStep explicitly depends on it.
272
244
  // NOTE: this occurs here since more dependencies could have been added to
@@ -597,7 +569,7 @@ const leafExecutor = makeExecutor({
597
569
  });
598
570
  const leafExecutorString = makeExecutor({
599
571
  inner(bucketRootValue) {
600
- return (0, tamedevil_1.stringifyJSON)(this.type.graphqlType.serialize(bucketRootValue));
572
+ return (0, tamedevilUtils_1.stringifyJSON)(this.type.graphqlType.serialize(bucketRootValue));
601
573
  },
602
574
  nameExtra: `leaf`,
603
575
  asString: true,
@@ -646,14 +618,14 @@ const floatLeafExecutorString = makeExecutor({
646
618
  });
647
619
  const stringLeafExecutorString = makeExecutor({
648
620
  inner(bucketRootValue) {
649
- return (0, tamedevil_1.stringifyString)(this.type.graphqlType.serialize(bucketRootValue));
621
+ return (0, tamedevilUtils_1.stringifyString)(this.type.graphqlType.serialize(bucketRootValue));
650
622
  },
651
623
  nameExtra: `stringLeaf`,
652
624
  asString: true,
653
625
  skipNullHandling: false,
654
626
  preamble(bucketRootValue) {
655
627
  if (typeof bucketRootValue === "string") {
656
- return (0, tamedevil_1.stringifyString)(bucketRootValue);
628
+ return (0, tamedevilUtils_1.stringifyString)(bucketRootValue);
657
629
  }
658
630
  },
659
631
  });
@@ -1010,38 +982,6 @@ isRoot, asString) {
1010
982
  skipNullHandling: isRoot,
1011
983
  });
1012
984
  }
1013
- const makeCache = new lru_1.default({
1014
- maxLength: 1000,
1015
- });
1016
- const makingCache = new Map();
1017
- function withFastExpression(path, fallback, callback) {
1018
- const signature = (fallback === undefined ? "d" : "f") + "_" + path.join("|");
1019
- const existing = makeCache.get(signature);
1020
- if (existing !== undefined) {
1021
- callback(existing);
1022
- return;
1023
- }
1024
- const existingCallbacks = makingCache.get(signature);
1025
- if (existingCallbacks !== undefined) {
1026
- existingCallbacks.push(callback);
1027
- return;
1028
- }
1029
- const callbacks = [callback];
1030
- makingCache.set(signature, callbacks);
1031
- const jitParts = [];
1032
- for (let i = 0, l = path.length; i < l; i++) {
1033
- const part = path[i];
1034
- jitParts.push(tamedevil_1.default.optionalGet(part));
1035
- }
1036
- const expression = tamedevil_1.default.join(jitParts, "");
1037
- tamedevil_1.default.runInBatch((0, tamedevil_1.default) `(value => (value${expression})${fallback !== undefined ? (0, tamedevil_1.default) ` ?? ${tamedevil_1.default.lit(fallback)}` : tamedevil_1.default.blank})`, (fn) => {
1038
- makeCache.set(signature, fn);
1039
- makingCache.delete(signature);
1040
- for (const callback of callbacks) {
1041
- callback(fn);
1042
- }
1043
- });
1044
- }
1045
985
  /**
1046
986
  * Finds the child of `targetParent` that has a path towards `descendent` (by
1047
987
  * walking backwards from descendent to targetParent).
@@ -741,7 +741,7 @@ function executeBucket(bucket, requestContext) {
741
741
  indexFlags |= constants_js_1.FLAG_POLY_SKIPPED;
742
742
  forceIndexValue = null;
743
743
  }
744
- else if (extra._bucket.flagUnion !== 0) {
744
+ else if (extra._bucket.flagUnion !== constants_js_1.NO_FLAGS) {
745
745
  for (let i = 0; i < dependenciesIncludingSideEffectsCount; i++) {
746
746
  const depExecutionVal = dependenciesIncludingSideEffects[i];
747
747
  const forbiddenFlags = dependencyForbiddenFlags[i];
@@ -1174,7 +1174,7 @@ function newBucket(parent, spec) {
1174
1174
  if (index >= size) {
1175
1175
  throw new Error(`GrafastInternalError<9465db89-cc9d-415c-97e7-57bb19ddebe0>: attempt to write to out of bounds index ${index} for bucket of size ${size} for step ${step}`);
1176
1176
  }
1177
- if (flags !== 0) {
1177
+ if (flags !== constants_js_1.NO_FLAGS) {
1178
1178
  this.flagUnion |= flags;
1179
1179
  }
1180
1180
  if (step._isUnary) {
@@ -1337,14 +1337,14 @@ function executeStepFromEvent(event) {
1337
1337
  }
1338
1338
  function evaluateStream(bucket, step, distributorOptions) {
1339
1339
  const stream = step._stepOptions.stream;
1340
- if (!stream)
1340
+ if (stream === null)
1341
1341
  return null;
1342
- const shouldStream = stream.ifStepId == null
1342
+ const shouldStream = stream === true || stream.ifStepId == null
1343
1343
  ? true
1344
1344
  : (bucket.store.get(stream.ifStepId)?.unaryValue() ?? true);
1345
1345
  if (!shouldStream)
1346
1346
  return null;
1347
- const initialCount = stream.initialCountStepId == null
1347
+ const initialCount = stream === true || stream.initialCountStepId == null
1348
1348
  ? 0
1349
1349
  : (bucket.store.get(stream.initialCountStepId)?.unaryValue() ?? 0);
1350
1350
  if (initialCount >= distributorOptions.distributorTargetBufferSize) {
@@ -1,14 +1,18 @@
1
1
  import type { ExecutionDetailsStream, StepStreamOptions } from "../../interfaces";
2
2
  import type { Step } from "../../step";
3
3
  import type { LayerPlan } from "../LayerPlan";
4
- export declare function withGlobalLayerPlan<T, TThis = any, TArgs extends [...args: any[]] = [...args: any[]]>(layerPlan: LayerPlan, polymorphicPaths: ReadonlySet<string> | null, planningPath: string | null, stepStreamOptions: StepStreamOptions | null, callback: (this: TThis, ...args: TArgs) => T, callbackThis?: TThis, ...callbackArgs: TArgs): T;
4
+ export declare function withGlobalLayerPlan<T, TThis = any, TArgs extends [...args: any[]] = [...args: any[]]>(layerPlan: LayerPlan, polymorphicPaths: ReadonlySet<string> | null, planningPath: string | null, stepStreamOptions: StepStreamOptions | true | null, callback: (this: TThis, ...args: TArgs) => T, callbackThis?: TThis, ...callbackArgs: TArgs): T;
5
5
  export declare function currentLayerPlan(): LayerPlan;
6
6
  export declare function currentPolymorphicPaths(): ReadonlySet<string> | null;
7
7
  /** UNUSED */
8
8
  export declare function currentPlanningPath(): string | undefined;
9
9
  /**
10
+ * Step - stream details.
11
+ * true - Not a stream, but it is a subscription.
12
+ * null - neither stream nor subscription
13
+ *
10
14
  * @experimental
11
15
  */
12
- export declare function currentFieldStreamDetails(): Step<ExecutionDetailsStream | null> | null;
16
+ export declare function currentFieldStreamDetails(): Step<ExecutionDetailsStream | null> | true | null;
13
17
  export declare function isUnaryStep($step: Step): boolean;
14
18
  //# sourceMappingURL=withGlobalLayerPlan.d.ts.map
@@ -60,12 +60,19 @@ function currentPlanningPath() {
60
60
  return globalData_planningPath;
61
61
  }
62
62
  /**
63
+ * Step - stream details.
64
+ * true - Not a stream, but it is a subscription.
65
+ * null - neither stream nor subscription
66
+ *
63
67
  * @experimental
64
68
  */
65
69
  function currentFieldStreamDetails() {
66
70
  if (globalData_stepStreamOptions == null) {
67
71
  return null;
68
72
  }
73
+ if (globalData_stepStreamOptions === true) {
74
+ return true;
75
+ }
69
76
  const { ifStepId, initialCountStepId } = globalData_stepStreamOptions;
70
77
  return (0, global_js_1.operationPlan)().withRootLayerPlan(() => {
71
78
  const $obj = (0, object_js_1.object)({
@@ -0,0 +1,13 @@
1
+ import type { DefinitionNode, GraphQLDirective } from "graphql";
2
+ export declare const graphqlHasStreamDefer: any;
3
+ /**
4
+ * Used to conditionally defer fragments.
5
+ */
6
+ export declare const GraphQLDeferDirective: GraphQLDirective;
7
+ export declare const deferDefinition: DefinitionNode;
8
+ /**
9
+ * Used to conditionally stream list fields.
10
+ */
11
+ export declare const GraphQLStreamDirective: GraphQLDirective;
12
+ export declare const streamDefinition: DefinitionNode;
13
+ //# sourceMappingURL=incremental.d.ts.map
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.streamDefinition = exports.GraphQLStreamDirective = exports.deferDefinition = exports.GraphQLDeferDirective = exports.graphqlHasStreamDefer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const graphql = tslib_1.__importStar(require("graphql"));
6
+ const { DirectiveLocation, GraphQLBoolean, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLString, Kind, } = graphql;
7
+ exports.graphqlHasStreamDefer = graphql.GraphQLStreamDirective &&
8
+ graphql.GraphQLDeferDirective;
9
+ // This file contains the Stream/Defer directives, to be used when GraphQL itself doesn't provide them.
10
+ // Taken from https://github.com/graphql/graphql-js/blob/bc6b2e47512ee11c01eb5185d184990e743df736/src/type/directives.ts
11
+ /*
12
+ MIT License
13
+
14
+ Copyright (c) GraphQL Contributors
15
+
16
+ Permission is hereby granted, free of charge, to any person obtaining a copy
17
+ of this software and associated documentation files (the "Software"), to deal
18
+ in the Software without restriction, including without limitation the rights
19
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20
+ copies of the Software, and to permit persons to whom the Software is
21
+ furnished to do so, subject to the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be included in all
24
+ copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ SOFTWARE.
33
+ */
34
+ /**
35
+ * Used to conditionally defer fragments.
36
+ */
37
+ exports.GraphQLDeferDirective = graphql.GraphQLDeferDirective ||
38
+ new graphql.GraphQLDirective({
39
+ name: "defer",
40
+ description: "Directs the executor to defer this fragment when the `if` argument is true or undefined.",
41
+ locations: [
42
+ DirectiveLocation.FRAGMENT_SPREAD,
43
+ DirectiveLocation.INLINE_FRAGMENT,
44
+ ],
45
+ args: {
46
+ if: {
47
+ type: GraphQLBoolean,
48
+ description: "Deferred when true or undefined.",
49
+ },
50
+ label: {
51
+ type: GraphQLString,
52
+ description: "Unique name",
53
+ },
54
+ },
55
+ });
56
+ exports.deferDefinition = toDirectiveDef(exports.GraphQLDeferDirective);
57
+ /**
58
+ * Used to conditionally stream list fields.
59
+ */
60
+ exports.GraphQLStreamDirective = graphql.GraphQLStreamDirective ||
61
+ new graphql.GraphQLDirective({
62
+ name: "stream",
63
+ description: "Directs the executor to stream plural fields when the `if` argument is true or undefined.",
64
+ locations: [DirectiveLocation.FIELD],
65
+ args: {
66
+ if: {
67
+ type: GraphQLBoolean,
68
+ description: "Stream when true or undefined.",
69
+ },
70
+ label: {
71
+ type: GraphQLString,
72
+ description: "Unique name",
73
+ },
74
+ initialCount: {
75
+ defaultValue: 0,
76
+ type: GraphQLInt,
77
+ description: "Number of items to return immediately",
78
+ },
79
+ },
80
+ });
81
+ exports.streamDefinition = toDirectiveDef(exports.GraphQLStreamDirective);
82
+ function toDirectiveDef(directive) {
83
+ return {
84
+ kind: Kind.DIRECTIVE_DEFINITION,
85
+ description: toDescription(directive.description),
86
+ name: { kind: Kind.NAME, value: directive.name },
87
+ arguments: directive.args.map(toDirectiveArgDef),
88
+ repeatable: directive.isRepeatable,
89
+ locations: directive.locations.map((n) => ({ kind: Kind.NAME, value: n })),
90
+ };
91
+ }
92
+ function toDirectiveArgDef(arg) {
93
+ return {
94
+ kind: Kind.INPUT_VALUE_DEFINITION,
95
+ description: toDescription(arg.description),
96
+ name: { kind: Kind.NAME, value: arg.name },
97
+ type: toTypeDef(arg.type),
98
+ defaultValue: toValue(arg.defaultValue),
99
+ };
100
+ }
101
+ function toTypeDef(type) {
102
+ if (type instanceof GraphQLNonNull) {
103
+ return {
104
+ kind: Kind.NON_NULL_TYPE,
105
+ type: toTypeDef(type.ofType),
106
+ };
107
+ }
108
+ else if (type instanceof GraphQLList) {
109
+ return {
110
+ kind: Kind.LIST_TYPE,
111
+ type: toTypeDef(type.ofType),
112
+ };
113
+ }
114
+ else {
115
+ return {
116
+ kind: Kind.NAMED_TYPE,
117
+ name: { kind: Kind.NAME, value: type.name },
118
+ };
119
+ }
120
+ }
121
+ function toDescription(value) {
122
+ return value != null ? { kind: Kind.STRING, value } : undefined;
123
+ }
124
+ function toValue(value) {
125
+ if (value === undefined) {
126
+ return undefined;
127
+ }
128
+ else if (typeof value === "boolean") {
129
+ return { kind: Kind.BOOLEAN, value };
130
+ }
131
+ else if (typeof value === "number") {
132
+ if (parseInt(String(value), 10) === value) {
133
+ return { kind: Kind.INT, value: String(value) };
134
+ }
135
+ else {
136
+ return { kind: Kind.FLOAT, value: String(value) };
137
+ }
138
+ }
139
+ else {
140
+ console.dir(value);
141
+ throw new Error(`Not yet supported`);
142
+ }
143
+ }
144
+ //# sourceMappingURL=incremental.js.map
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import "./thereCanBeOnlyOne.js";
2
2
  import type LRU from "@graphile/lru";
3
3
  import type { MiddlewareHandlers } from "graphile-config";
4
- import type { DocumentNode, GraphQLError, OperationDefinitionNode } from "graphql";
4
+ import type { DocumentNode, ExecutionResult, GraphQLError, OperationDefinitionNode } from "graphql";
5
+ import type { ObjMap } from "graphql/jsutils/ObjMap";
5
6
  import type { DataFromObjectSteps } from "./steps/object.js";
6
7
  type PromiseOrValue<T> = T | Promise<T>;
7
8
  import { exportAs, exportAsMany } from "./exportAs.js";
@@ -30,6 +31,7 @@ import { stringifyPayload } from "./stringifyPayload.js";
30
31
  import { stripAnsi } from "./stripAnsi.js";
31
32
  import { subscribe } from "./subscribe.js";
32
33
  import { arrayOfLength, arraysMatch, asyncIteratorWithCleanup, getEnumValueConfig, getEnumValueConfigs, GrafastInputFieldConfigMap, GrafastInputObjectType, GrafastObjectType, GraphQLSpecifiedErrorBehaviors, inputObjectFieldSpec, InputObjectTypeSpec, isPromiseLike, mapsMatch, maybeArraysMatch, newGrafastFieldConfigBuilder, newInputObjectTypeBuilder, newObjectTypeBuilder, objectFieldSpec, objectSpec, ObjectTypeFields, ObjectTypeSpec, recordsMatch, setsMatch, stepADependsOnStepB, stepAMayDependOnStepB, stepAShouldTryAndInlineIntoStepB, stepsAreInSamePhase } from "./utils.js";
34
+ export { GraphQLDeferDirective, graphqlHasStreamDefer, GraphQLStreamDirective, } from "./incremental.js";
33
35
  export { isAsyncIterable } from "iterall";
34
36
  export { __FlagStep, __InputListStep, __InputObjectStep, __InputObjectStepWithDollars, __InputStaticLeafStep, __ItemStep, __ListTransformStep, __TrackedValueStep, __TrackedValueStepWithDollars, __ValueStep, $$bypassGraphQL, $$eventEmitter, $$extensions, $$idempotent, $$inhibit, $$verbatim, AbstractTypePlan, AbstractTypePlanner, access, AccessStep, ActualKeyByDesiredKey, applyInput, ApplyInputStep, applyTransforms, ApplyTransformsStep, arrayOfLength, arraysMatch, assertExecutableStep, assertListCapableStep, assertModifier, assertNotNull, assertStep, asyncIteratorWithCleanup, bakedInput, bakedInputRuntime, BakedInputStep, BaseEventMap, BaseGraphQLArguments, BaseGraphQLRootValue, BaseGraphQLVariables, BatchExecutionValue, coalesce, CoalesceStep, condition, ConditionStep, connection, ConnectionHandlingResult, ConnectionHandlingStep, ConnectionOptimizedStep, ConnectionStep, constant, ConstantStep, context, createObjectAndApplyChildren, currentFieldStreamDetails, DataFromObjectSteps, DataFromStep, debugPlans, DEFAULT_ACCEPT_FLAGS, defaultPlanResolver, defer, Deferred, DeprecatedInputObjectPlan, DeprecatedObjectPlan, each, EdgeStep, EnumPlan, EnumValueConfig, EnumValueInput, error, ErrorBehavior, ErrorStep, EventCallback, EventMapKey, Step as ExecutableStep, execute, ExecutionDetails, ExecutionDetailsStream, ExecutionEventEmitter, ExecutionEventMap, ExecutionExtra, ExecutionResults, ExecutionResultValue, ExecutionValue, exportAs, exportAsMany, FieldArg, FieldArgs, FieldInfo, FieldPlan, FieldPlanResolver, filter, FilterPlanMemo, first, FirstStep, flagError, get, getEnumValueConfig, getEnumValueConfigs, getGrafastMiddleware, getNullableInputTypeAtPath, grafast, GrafastArgumentConfig, GrafastExecutionArgs, GrafastFieldConfig, GrafastFieldConfigArgumentMap, grafast as grafastGraphql, grafastSync as grafastGraphqlSync, GrafastInputFieldConfig, GrafastInputFieldConfigMap, GrafastInputObjectType, GrafastObjectType, GrafastPlanJSON, grafastPrint, GrafastResultsList, GrafastResultStreamList, GrafastSchemaConfig, GrafastSubscriber, grafastSync, GrafastValuesList, graphqlResolver, GraphQLResolverStep, GraphQLSpecifiedErrorBehaviors, groupBy, GroupByPlanMemo, inhibitOnNull, InputFieldPlan, InputObjectFieldApplyResolver, InputObjectFieldConfig, inputObjectFieldSpec, InputObjectPlan, InputObjectTypeBakedInfo, InputObjectTypeBakedResolver, InputObjectTypeSpec, inspect, AbstractTypePlan as InterfaceOrUnionPlans, InterfacePlan, isDev, isExecutableStep, isListCapableStep, isListLikeStep, isModifier, isObjectLikeStep, isPromiseLike, isSafeError, isStep, isUnaryStep, JSONArray, JSONObject, JSONValue, lambda, LambdaStep, last, LastStep, list, ListCapableStep, listen, ListenStep, ListLikeStep, ListStep, listTransform, ListTransformItemPlanCallback, ListTransformOptions, ListTransformReduce, LoadedRecordStep, loadMany, LoadManyCallback, loadManyCallback, LoadManyInfo, LoadManyLoader, loadManyLoader, LoadManyStep, loadOne, LoadOneCallback, loadOneCallback, LoadOneInfo, LoadOneLoader, loadOneLoader, LoadOneStep, makeDecodeNodeId, makeDecodeNodeIdRuntime, makeGrafastSchema, mapsMatch, Maybe, maybeArraysMatch, Modifier, Multistep, multistep, newGrafastFieldConfigBuilder, newInputObjectTypeBuilder, newObjectTypeBuilder, node, NodeIdCodec, nodeIdFromNode, NodeIdHandler, NodeStep, noop, object, ObjectFieldConfig, objectFieldSpec, ObjectLikeStep, ObjectPlan, ObjectPlanMeta, objectSpec, ObjectStep, ObjectTypeFields, ObjectTypeSpec, OperationPlan, operationPlan, PaginationFeatures, PaginationParams, partitionByIndex, PlanTypeInfo, PromiseOrDirect, proxy, ProxyStep, recordsMatch, remapKeys, RemapKeysStep, reverse, reverseArray, ReverseStep, rootValue, SafeError, ScalarPlan, ScalarPlanResolver, setsMatch, Setter, setter, SetterCapable, sideEffect, SideEffectStep, specFromNodeId, Step, stepADependsOnStepB, stepAMayDependOnStepB, stepAShouldTryAndInlineIntoStepB, StepOptimizeOptions, StepRepresentingList, stepsAreInSamePhase, StepStreamOptions, stringifyPayload, stripAnsi, subscribe, Thunk, trap, TRAP_ERROR, TRAP_ERROR_OR_INHIBITED, TRAP_INHIBITED, TypedEventEmitter, UnaryExecutionValue, UnbatchedStep as UnbatchedExecutableStep, UnbatchedExecutionExtra, UnbatchedStep, UnionPlan, UnwrapMultistep, };
35
37
  export { hookArgs } from "./args.js";
@@ -342,4 +344,29 @@ declare module "graphql" {
342
344
  grafast?: Grafast.SchemaExtensions;
343
345
  }
344
346
  }
347
+ declare module "graphql/execution/execute" {
348
+ interface ExecutionResult<TData = ObjMap<unknown>, TExtensions = ObjMap<unknown>> {
349
+ hasNext?: never;
350
+ }
351
+ interface ExecutionPatchResult<TData = ObjMap<unknown> | unknown, TExtensions = ObjMap<unknown>> {
352
+ errors?: ReadonlyArray<GraphQLError>;
353
+ data?: TData | null;
354
+ path?: ReadonlyArray<string | number>;
355
+ label?: string;
356
+ hasNext: boolean;
357
+ extensions?: TExtensions;
358
+ }
359
+ type AsyncExecutionResult = ExecutionResult | ExecutionPatchResult;
360
+ }
361
+ declare module "graphql" {
362
+ interface ExecutionPatchResult<TData = ObjMap<unknown> | unknown, TExtensions = ObjMap<unknown>> {
363
+ errors?: ReadonlyArray<GraphQLError>;
364
+ data?: TData | null;
365
+ path?: ReadonlyArray<string | number>;
366
+ label?: string;
367
+ hasNext: boolean;
368
+ extensions?: TExtensions;
369
+ }
370
+ type AsyncExecutionResult = ExecutionResult | ExecutionPatchResult;
371
+ }
345
372
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.error = exports.EdgeStep = exports.each = exports.defer = exports.defaultPlanResolver = exports.DEFAULT_ACCEPT_FLAGS = exports.debugPlans = exports.currentFieldStreamDetails = exports.createObjectAndApplyChildren = exports.context = exports.ConstantStep = exports.constant = exports.ConnectionStep = exports.connection = exports.ConditionStep = exports.condition = exports.CoalesceStep = exports.coalesce = exports.BakedInputStep = exports.bakedInputRuntime = exports.bakedInput = exports.asyncIteratorWithCleanup = exports.assertStep = exports.assertNotNull = exports.assertModifier = exports.assertListCapableStep = exports.assertExecutableStep = exports.arraysMatch = exports.arrayOfLength = exports.ApplyTransformsStep = exports.applyTransforms = exports.ApplyInputStep = exports.applyInput = exports.AccessStep = exports.access = exports.$$verbatim = exports.$$inhibit = exports.$$idempotent = exports.$$extensions = exports.$$eventEmitter = exports.$$bypassGraphQL = exports.__ValueStep = exports.__TrackedValueStep = exports.__ListTransformStep = exports.__ItemStep = exports.__InputStaticLeafStep = exports.__InputObjectStep = exports.__InputListStep = exports.__FlagStep = exports.isAsyncIterable = void 0;
4
- exports.LoadManyStep = exports.loadManyLoader = exports.loadManyCallback = exports.loadMany = exports.LoadedRecordStep = exports.listTransform = exports.ListStep = exports.ListenStep = exports.listen = exports.list = exports.LastStep = exports.last = exports.LambdaStep = exports.lambda = exports.isUnaryStep = exports.isStep = exports.isSafeError = exports.isPromiseLike = exports.isObjectLikeStep = exports.isModifier = exports.isListLikeStep = exports.isListCapableStep = exports.isExecutableStep = exports.isDev = exports.inspect = exports.inputObjectFieldSpec = exports.inhibitOnNull = exports.groupBy = exports.GraphQLSpecifiedErrorBehaviors = exports.GraphQLResolverStep = exports.graphqlResolver = exports.grafastSync = exports.grafastPrint = exports.grafastGraphqlSync = exports.grafastGraphql = exports.grafast = exports.getNullableInputTypeAtPath = exports.getGrafastMiddleware = exports.getEnumValueConfigs = exports.getEnumValueConfig = exports.get = exports.flagError = exports.FirstStep = exports.first = exports.filter = exports.exportAsMany = exports.exportAs = exports.execute = exports.ExecutableStep = exports.ErrorStep = void 0;
5
- exports.trap = exports.subscribe = exports.stripAnsi = exports.stringifyPayload = exports.stepsAreInSamePhase = exports.stepAShouldTryAndInlineIntoStepB = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.Step = exports.specFromNodeId = exports.SideEffectStep = exports.sideEffect = exports.setter = exports.Setter = exports.setsMatch = exports.SafeError = exports.rootValue = exports.ReverseStep = exports.reverseArray = exports.reverse = exports.RemapKeysStep = exports.remapKeys = exports.recordsMatch = exports.ProxyStep = exports.proxy = exports.partitionByIndex = exports.operationPlan = exports.OperationPlan = exports.ObjectStep = exports.objectSpec = exports.objectFieldSpec = exports.object = exports.noop = exports.NodeStep = exports.nodeIdFromNode = exports.node = exports.newObjectTypeBuilder = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.multistep = exports.Modifier = exports.maybeArraysMatch = exports.mapsMatch = exports.makeGrafastSchema = exports.makeDecodeNodeIdRuntime = exports.makeDecodeNodeId = exports.LoadOneStep = exports.loadOneLoader = exports.loadOneCallback = exports.loadOne = void 0;
6
- exports.DeepEvalStep = exports.deepEval = exports.version = exports.hookArgs = exports.UnbatchedStep = exports.UnbatchedExecutableStep = exports.TRAP_INHIBITED = exports.TRAP_ERROR_OR_INHIBITED = exports.TRAP_ERROR = void 0;
3
+ exports.defer = exports.defaultPlanResolver = exports.DEFAULT_ACCEPT_FLAGS = exports.debugPlans = exports.currentFieldStreamDetails = exports.createObjectAndApplyChildren = exports.context = exports.ConstantStep = exports.constant = exports.ConnectionStep = exports.connection = exports.ConditionStep = exports.condition = exports.CoalesceStep = exports.coalesce = exports.BakedInputStep = exports.bakedInputRuntime = exports.bakedInput = exports.asyncIteratorWithCleanup = exports.assertStep = exports.assertNotNull = exports.assertModifier = exports.assertListCapableStep = exports.assertExecutableStep = exports.arraysMatch = exports.arrayOfLength = exports.ApplyTransformsStep = exports.applyTransforms = exports.ApplyInputStep = exports.applyInput = exports.AccessStep = exports.access = exports.$$verbatim = exports.$$inhibit = exports.$$idempotent = exports.$$extensions = exports.$$eventEmitter = exports.$$bypassGraphQL = exports.__ValueStep = exports.__TrackedValueStep = exports.__ListTransformStep = exports.__ItemStep = exports.__InputStaticLeafStep = exports.__InputObjectStep = exports.__InputListStep = exports.__FlagStep = exports.isAsyncIterable = exports.GraphQLStreamDirective = exports.graphqlHasStreamDefer = exports.GraphQLDeferDirective = void 0;
4
+ exports.loadMany = exports.LoadedRecordStep = exports.listTransform = exports.ListStep = exports.ListenStep = exports.listen = exports.list = exports.LastStep = exports.last = exports.LambdaStep = exports.lambda = exports.isUnaryStep = exports.isStep = exports.isSafeError = exports.isPromiseLike = exports.isObjectLikeStep = exports.isModifier = exports.isListLikeStep = exports.isListCapableStep = exports.isExecutableStep = exports.isDev = exports.inspect = exports.inputObjectFieldSpec = exports.inhibitOnNull = exports.groupBy = exports.GraphQLSpecifiedErrorBehaviors = exports.GraphQLResolverStep = exports.graphqlResolver = exports.grafastSync = exports.grafastPrint = exports.grafastGraphqlSync = exports.grafastGraphql = exports.grafast = exports.getNullableInputTypeAtPath = exports.getGrafastMiddleware = exports.getEnumValueConfigs = exports.getEnumValueConfig = exports.get = exports.flagError = exports.FirstStep = exports.first = exports.filter = exports.exportAsMany = exports.exportAs = exports.execute = exports.ExecutableStep = exports.ErrorStep = exports.error = exports.EdgeStep = exports.each = void 0;
5
+ exports.stringifyPayload = exports.stepsAreInSamePhase = exports.stepAShouldTryAndInlineIntoStepB = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.Step = exports.specFromNodeId = exports.SideEffectStep = exports.sideEffect = exports.setter = exports.Setter = exports.setsMatch = exports.SafeError = exports.rootValue = exports.ReverseStep = exports.reverseArray = exports.reverse = exports.RemapKeysStep = exports.remapKeys = exports.recordsMatch = exports.ProxyStep = exports.proxy = exports.partitionByIndex = exports.operationPlan = exports.OperationPlan = exports.ObjectStep = exports.objectSpec = exports.objectFieldSpec = exports.object = exports.noop = exports.NodeStep = exports.nodeIdFromNode = exports.node = exports.newObjectTypeBuilder = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.multistep = exports.Modifier = exports.maybeArraysMatch = exports.mapsMatch = exports.makeGrafastSchema = exports.makeDecodeNodeIdRuntime = exports.makeDecodeNodeId = exports.LoadOneStep = exports.loadOneLoader = exports.loadOneCallback = exports.loadOne = exports.LoadManyStep = exports.loadManyLoader = exports.loadManyCallback = void 0;
6
+ exports.DeepEvalStep = exports.deepEval = exports.version = exports.hookArgs = exports.UnbatchedStep = exports.UnbatchedExecutableStep = exports.TRAP_INHIBITED = exports.TRAP_ERROR_OR_INHIBITED = exports.TRAP_ERROR = exports.trap = exports.subscribe = exports.stripAnsi = void 0;
7
7
  const tslib_1 = require("tslib");
8
8
  require("./thereCanBeOnlyOne.js");
9
9
  const debug_1 = tslib_1.__importDefault(require("debug"));
@@ -187,6 +187,10 @@ Object.defineProperty(exports, "stepADependsOnStepB", { enumerable: true, get: f
187
187
  Object.defineProperty(exports, "stepAMayDependOnStepB", { enumerable: true, get: function () { return utils_js_1.stepAMayDependOnStepB; } });
188
188
  Object.defineProperty(exports, "stepAShouldTryAndInlineIntoStepB", { enumerable: true, get: function () { return utils_js_1.stepAShouldTryAndInlineIntoStepB; } });
189
189
  Object.defineProperty(exports, "stepsAreInSamePhase", { enumerable: true, get: function () { return utils_js_1.stepsAreInSamePhase; } });
190
+ var incremental_js_1 = require("./incremental.js");
191
+ Object.defineProperty(exports, "GraphQLDeferDirective", { enumerable: true, get: function () { return incremental_js_1.GraphQLDeferDirective; } });
192
+ Object.defineProperty(exports, "graphqlHasStreamDefer", { enumerable: true, get: function () { return incremental_js_1.graphqlHasStreamDefer; } });
193
+ Object.defineProperty(exports, "GraphQLStreamDirective", { enumerable: true, get: function () { return incremental_js_1.GraphQLStreamDirective; } });
190
194
  var iterall_1 = require("iterall");
191
195
  Object.defineProperty(exports, "isAsyncIterable", { enumerable: true, get: function () { return iterall_1.isAsyncIterable; } });
192
196
  (0, exportAs_js_1.exportAsMany)("grafast", {
@@ -260,8 +260,14 @@ export interface StepStreamOptions extends LayerPlanReasonListItemStream {
260
260
  export interface StepOptions {
261
261
  /**
262
262
  * Details for the `@stream` directive.
263
+ *
264
+ * object - `@stream` details
265
+ *
266
+ * true - no stream directive, but is inside a subscription field
267
+ *
268
+ * null - no stream directive
263
269
  */
264
- stream: StepStreamOptions | null;
270
+ stream: StepStreamOptions | true | null;
265
271
  /**
266
272
  * Should we walk an iterable if presented. This is important because we
267
273
  * don't want to walk things like Map/Set except if we're doing it as part of
@@ -4,6 +4,7 @@ exports.makeGrafastSchema = makeGrafastSchema;
4
4
  const tslib_1 = require("tslib");
5
5
  const graphql_1 = require("graphql");
6
6
  const graphql = tslib_1.__importStar(require("graphql"));
7
+ const incremental_js_1 = require("./incremental.js");
7
8
  const utils_js_1 = require("./utils.js");
8
9
  const { buildASTSchema, isEnumType, isInputObjectType, isInterfaceType, isObjectType, isScalarType, isUnionType, parse, } = graphql;
9
10
  /**
@@ -12,7 +13,7 @@ const { buildASTSchema, isEnumType, isInputObjectType, isInterfaceType, isObject
12
13
  */
13
14
  function makeGrafastSchema(details) {
14
15
  const { typeDefs, plans: rawPlans, objects, unions, interfaces, inputObjects, scalars, enums, enableDeferStream = false, } = details;
15
- const document = typeof typeDefs === "string"
16
+ const baseDocument = typeof typeDefs === "string"
16
17
  ? parse(typeDefs)
17
18
  : Array.isArray(typeDefs)
18
19
  ? {
@@ -20,11 +21,22 @@ function makeGrafastSchema(details) {
20
21
  definitions: typeDefs.flatMap((t) => t.definitions),
21
22
  }
22
23
  : typeDefs;
24
+ const document = incremental_js_1.graphqlHasStreamDefer || !enableDeferStream
25
+ ? baseDocument
26
+ : {
27
+ ...baseDocument,
28
+ definitions: [
29
+ ...baseDocument.definitions,
30
+ incremental_js_1.deferDefinition,
31
+ incremental_js_1.streamDefinition,
32
+ ],
33
+ };
23
34
  if (!document || document.kind !== "Document") {
24
35
  throw new Error("The first argument to makeGrafastSchema must be an object containing a `typeDefs` field; the value for this field should be a parsed GraphQL document, array of these, or a string.");
25
36
  }
26
37
  const astSchema = buildASTSchema(document, {
27
- enableDeferStream,
38
+ // @ts-ignore
39
+ enableDeferStream: enableDeferStream && incremental_js_1.graphqlHasStreamDefer,
28
40
  });
29
41
  let plans;
30
42
  if (rawPlans) {
package/dist/mermaid.d.ts CHANGED
@@ -11,7 +11,12 @@ export interface PrintPlanGraphOptions {
11
11
  includePaths?: boolean;
12
12
  concise?: boolean;
13
13
  skipBuckets?: boolean;
14
+ /**
15
+ * Should the leaves render as a vertical chain to save horizontal space?
16
+ * Set false to disable
17
+ */
18
+ collapseLeaves?: boolean;
14
19
  }
15
- export declare function planToMermaid(planJSON: GrafastPlanJSON, { concise, skipBuckets, }?: PrintPlanGraphOptions): string;
20
+ export declare function planToMermaid(planJSON: GrafastPlanJSON, { concise, collapseLeaves, skipBuckets, }?: PrintPlanGraphOptions): string;
16
21
  export * from "./planJSONInterfaces.js";
17
22
  //# sourceMappingURL=mermaid.d.ts.map
package/dist/mermaid.js CHANGED
@@ -67,7 +67,7 @@ function isGrafastPlanJSONv1(json) {
67
67
  }
68
68
  function planToMermaid(planJSON, {
69
69
  // printPathRelations = false,
70
- concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false, } = {}) {
70
+ concise = false, collapseLeaves = true, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false, } = {}) {
71
71
  if (!isGrafastPlanJSONv1(planJSON)) {
72
72
  throw new Error("planToMermaid only supports v1 plan JSON");
73
73
  }
@@ -107,7 +107,7 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
107
107
  }
108
108
  if (step.bucketId === 0 &&
109
109
  step.isSyncAndSafe &&
110
- (dependentsByStepId[step.id]?.length ?? 0) === 0) {
110
+ !dependentsByStepId[step.id]) {
111
111
  return true;
112
112
  }
113
113
  return false;
@@ -294,6 +294,7 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
294
294
  if (shouldHideStep(plan))
295
295
  return;
296
296
  const planNode = planId(plan);
297
+ /** `plan`'s dependencies as rendered step ids */
297
298
  const depNodes = plan.dependencyIds.map((depId) => {
298
299
  const step = stepById[depId];
299
300
  if (shouldHideStep(step) || isExcessivelyReferenced(depId)) {
@@ -334,7 +335,7 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
334
335
  }
335
336
  }
336
337
  else {
337
- if (concise &&
338
+ if (collapseLeaves !== false &&
338
339
  !dependentsByStepId[plan.id] &&
339
340
  depNodes.length === 1) {
340
341
  // Try alternating the nodes so they render closer together