grafast 0.1.1-beta.5 → 0.1.1-beta.6

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/dist/dev.js CHANGED
@@ -4,7 +4,24 @@ exports.noop = exports.isDev = void 0;
4
4
  /**
5
5
  * @internal
6
6
  */
7
- exports.isDev = typeof process !== "undefined" && process.env.GRAPHILE_ENV === "development";
7
+ const graphileEnv = typeof process !== "undefined" ? process.env.GRAPHILE_ENV : undefined;
8
+ const nodeEnv = typeof process !== "undefined" ? process.env.NODE_ENV : undefined;
9
+ /**
10
+ * @internal
11
+ */
12
+ exports.isDev = graphileEnv !== undefined
13
+ ? graphileEnv === "development" || graphileEnv === "test"
14
+ : nodeEnv === "development" || nodeEnv === "test";
8
15
  function noop() { }
9
16
  exports.noop = noop;
17
+ if (typeof process !== "undefined" &&
18
+ typeof graphileEnv === "undefined" &&
19
+ typeof nodeEnv === "undefined") {
20
+ console.warn(`The GRAPHILE_ENV environmental variable is not set; Grafast will run in production mode. In your development environments, it's recommended that you set \`GRAPHILE_ENV=development\` to opt in to additional checks that will provide guidance and help you to catch issues in your code earlier, and other changes such as formatting to improve your development experience.`);
21
+ }
22
+ else if (exports.isDev) {
23
+ console.warn(`Grafast is running in development mode due to \`${graphileEnv !== undefined
24
+ ? `GRAPHILE_ENV=${graphileEnv}`
25
+ : `NODE_ENV=${nodeEnv}`}\`; this is recommended for development environments (and strongly discouraged in production), but will impact on performance - in particular, planning will be significantly more expensive.`);
26
+ }
10
27
  //# sourceMappingURL=dev.js.map
@@ -21,6 +21,7 @@ const timeSource_js_1 = require("../timeSource.js");
21
21
  const utils_js_1 = require("../utils.js");
22
22
  const LayerPlan_js_1 = require("./LayerPlan.js");
23
23
  const withGlobalLayerPlan_js_1 = require("./lib/withGlobalLayerPlan.js");
24
+ const lock_js_1 = require("./lock.js");
24
25
  const OutputPlan_js_1 = require("./OutputPlan.js");
25
26
  const StepTracker_js_1 = require("./StepTracker.js");
26
27
  const atpe = typeof process !== "undefined" && process.env.ALWAYS_THROW_PLANNING_ERRORS;
@@ -49,9 +50,6 @@ const EMPTY_ARRAY = Object.freeze([]);
49
50
  exports.POLYMORPHIC_ROOT_PATH = null;
50
51
  exports.POLYMORPHIC_ROOT_PATHS = null;
51
52
  Object.freeze(exports.POLYMORPHIC_ROOT_PATHS);
52
- /** In development we might run additional checks */
53
- const isDev = typeof process !== "undefined" &&
54
- (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test");
55
53
  /** How many times will we try re-optimizing before giving up */
56
54
  const MAX_OPTIMIZATION_LOOPS = 10;
57
55
  const REASON_ROOT = Object.freeze({ type: "root" });
@@ -88,7 +86,7 @@ class OperationPlan {
88
86
  /**
89
87
  * Gets updated as we work our way through the plan, useful for making errors more helpful.
90
88
  */
91
- this.loc = isDev
89
+ this.loc = index_js_1.isDev
92
90
  ? []
93
91
  : null /* forbid loc in production */;
94
92
  this.modifierStepCount = 0;
@@ -117,7 +115,7 @@ class OperationPlan {
117
115
  this.laps = [];
118
116
  this.optimizeMeta = new Map();
119
117
  /** @internal Use plan.getStep(id) instead. */
120
- this.getStep = isDev
118
+ this.getStep = index_js_1.isDev
121
119
  ? (id, requestingStep) => {
122
120
  if (!["plan", "validate", "optimize"].includes(this.phase)) {
123
121
  throw new Error(`Getting a step during the '${this.phase}' phase is forbidden - please do so before or during the optimize phase.`);
@@ -191,7 +189,7 @@ class OperationPlan {
191
189
  this.hoistSteps();
192
190
  this.checkTimeout();
193
191
  this.lap("hoistSteps", "planOperation");
194
- if (isDev) {
192
+ if (index_js_1.isDev) {
195
193
  this.phase = "validate";
196
194
  // Helpfully check steps don't do forbidden things.
197
195
  this.validateSteps();
@@ -785,7 +783,7 @@ class OperationPlan {
785
783
  if (this.loc !== null) {
786
784
  this.loc.push(`planSelectionSet(${objectType.name} @ ${outputPlan.layerPlan.id} @ ${path.join(".")} @ ${polymorphicPath ?? ""})`);
787
785
  }
788
- if (isDev) {
786
+ if (index_js_1.isDev) {
789
787
  assertObjectType(objectType);
790
788
  }
791
789
  const groupedFieldSet = (0, withGlobalLayerPlan_js_1.withGlobalLayerPlan)(outputPlan.layerPlan, polymorphicPaths, graphqlCollectFields_js_1.graphqlCollectFields, null, this, parentStep.id, objectType, selections, isMutation);
@@ -847,7 +845,7 @@ class OperationPlan {
847
845
  });
848
846
  }
849
847
  else if (isObjectType(nullableFieldType)) {
850
- if (isDev) {
848
+ if (index_js_1.isDev) {
851
849
  // Check that the plan we're dealing with is the one the user declared
852
850
  /** Either an assertion function or a step class */
853
851
  const stepAssertion = nullableFieldType.extensions?.grafast?.assertStep;
@@ -1159,7 +1157,7 @@ class OperationPlan {
1159
1157
  const trackedArgumentValues = Object.create(null);
1160
1158
  for (const argumentDefinition of argumentDefinitions) {
1161
1159
  const argumentName = argumentDefinition.name;
1162
- if (isDev && trackedArgumentValues[argumentName]) {
1160
+ if (index_js_1.isDev && trackedArgumentValues[argumentName]) {
1163
1161
  throw new index_js_1.SafeError(`Argument name '${argumentName}' seen twice; aborting.`);
1164
1162
  }
1165
1163
  const argumentType = argumentDefinition.type;
@@ -1309,6 +1307,8 @@ class OperationPlan {
1309
1307
  * @internal
1310
1308
  */
1311
1309
  processSteps(actionDescription, order, isReadonly, callback) {
1310
+ if (index_js_1.isDev)
1311
+ this.stepTracker.lockNewSteps();
1312
1312
  const previousStepCount = this.stepTracker.stepCount;
1313
1313
  const processed = new Set();
1314
1314
  for (let i = 0; i < this.stepTracker.stepCount; i++) {
@@ -1317,7 +1317,7 @@ class OperationPlan {
1317
1317
  if (!step || step.id !== i || processed.has(step))
1318
1318
  continue;
1319
1319
  const resultStep = this.processStep(actionDescription, order, isReadonly, callback, processed, step);
1320
- if (isDev) {
1320
+ if (index_js_1.isDev) {
1321
1321
  const plansAdded = this.stepTracker.stepCount - previousStepCount;
1322
1322
  // NOTE: whilst processing steps new steps may be added, thus we must loop
1323
1323
  // ascending and we must re-evaluate this.stepTracker.stepCount on each loop
@@ -1326,8 +1326,13 @@ class OperationPlan {
1326
1326
  throw new Error(`Whilst processing steps as part of ${actionDescription}Plans, ${plansAdded} new steps have been created... That seems like it's likely a bug in the relevant method of one of your steps. The last plan processed was ${resultStep}`);
1327
1327
  }
1328
1328
  }
1329
- if (isReadonly && this.stepTracker.stepCount > previousStepCount) {
1330
- throwNoNewStepsError(this, actionDescription, step, previousStepCount, "Creating steps in isReadonly mode is forbidden");
1329
+ if ((isReadonly || index_js_1.isDev) &&
1330
+ this.stepTracker.stepCount > previousStepCount) {
1331
+ if (isReadonly) {
1332
+ throwNoNewStepsError(this, actionDescription, step, previousStepCount, "Creating steps in isReadonly mode is forbidden");
1333
+ }
1334
+ if (index_js_1.isDev)
1335
+ this.stepTracker.lockNewSteps();
1331
1336
  }
1332
1337
  }
1333
1338
  if (!isReadonly &&
@@ -1803,12 +1808,15 @@ class OperationPlan {
1803
1808
  // planned, which the step class may want to acknowledge by locking certain
1804
1809
  // facets of its functionality (such as adding filters). We'll simplify its
1805
1810
  // work though by giving it an empty array to filter.
1811
+ const wasLocked = index_js_1.isDev && (0, lock_js_1.unlock)(step);
1806
1812
  const equivalentSteps = step.deduplicate(peers);
1813
+ if (wasLocked)
1814
+ (0, lock_js_1.lock)(step);
1807
1815
  if (equivalentSteps.length === 0) {
1808
1816
  // No other equivalents
1809
1817
  return null;
1810
1818
  }
1811
- if (isDev) {
1819
+ if (index_js_1.isDev) {
1812
1820
  if (!equivalentSteps.every((replacementStep) => peers.includes(replacementStep))) {
1813
1821
  throw new Error(`deduplicatePlan error: '${step}.deduplicate' may only return steps from its peers peers (peers = ${peers}), but it returned ${equivalentSteps}. This is currently forbidden because it could cause confusion during the optimization process, instead apply this change in 'optimize', or make sure that any child selections aren't applied until the optimize/finalize phase so that no mapping is required during deduplicate.`);
1814
1822
  }
@@ -1851,12 +1859,18 @@ class OperationPlan {
1851
1859
  }
1852
1860
  // Give the steps a chance to pass their responsibilities to the winner.
1853
1861
  if (winner !== step) {
1862
+ const wasLocked = index_js_1.isDev && (0, lock_js_1.unlock)(step);
1854
1863
  step.deduplicatedWith?.(winner);
1864
+ if (wasLocked)
1865
+ (0, lock_js_1.lock)(step);
1855
1866
  this.stepTracker.replaceStep(step, winner);
1856
1867
  }
1857
1868
  for (const target of equivalentSteps) {
1858
1869
  if (winner !== target) {
1870
+ const wasLocked = index_js_1.isDev && (0, lock_js_1.unlock)(target);
1859
1871
  target.deduplicatedWith?.(winner);
1872
+ if (wasLocked)
1873
+ (0, lock_js_1.lock)(target);
1860
1874
  this.stepTracker.replaceStep(target, winner);
1861
1875
  }
1862
1876
  }
@@ -2000,10 +2014,13 @@ class OperationPlan {
2000
2014
  this.optimizeMeta.set(step.optimizeMetaKey, meta);
2001
2015
  }
2002
2016
  }
2017
+ const wasLocked = index_js_1.isDev && (0, lock_js_1.unlock)(step);
2003
2018
  const replacementStep = step.optimize({
2004
2019
  ...stepOptions,
2005
2020
  meta,
2006
2021
  });
2022
+ if (wasLocked)
2023
+ (0, lock_js_1.lock)(step);
2007
2024
  if (!replacementStep) {
2008
2025
  throw new Error(`Bug in ${step}'s class: the 'optimize' method must return a step. Hint: did you forget 'return this;'?`);
2009
2026
  }
@@ -2054,9 +2071,12 @@ class OperationPlan {
2054
2071
  const initialStepCount = this.stepTracker.stepCount;
2055
2072
  assert.strictEqual(this.modifierSteps.length, 0, "No modifier steps expected when performing finalizeSteps");
2056
2073
  for (const step of this.stepTracker.activeSteps) {
2074
+ const wasLocked = index_js_1.isDev && (0, lock_js_1.unlock)(step);
2057
2075
  step.finalize();
2076
+ if (wasLocked)
2077
+ (0, lock_js_1.lock)(step);
2058
2078
  (0, step_js_1.assertFinalized)(step);
2059
- if (isDev && this.stepTracker.stepCount !== initialStepCount) {
2079
+ if (index_js_1.isDev && this.stepTracker.stepCount !== initialStepCount) {
2060
2080
  throw new Error(`When calling ${step}.finalize() a new plan was created; this is forbidden!`);
2061
2081
  }
2062
2082
  }
@@ -2072,7 +2092,7 @@ class OperationPlan {
2072
2092
  if (currentLayerPlan.copyStepIds.includes(dep.id)) {
2073
2093
  break;
2074
2094
  }
2075
- if (isDev && this.stepTracker.getStepById(dep.id) !== dep) {
2095
+ if (index_js_1.isDev && this.stepTracker.getStepById(dep.id) !== dep) {
2076
2096
  throw new Error(`GrafastInternalError<b291b110-396a-4c9c-814a-5466af3c50e8>: Plan mismatch; are we using a replaced step? Step ID: ${dep.id}; step: ${dep}; stepById: ${this.stepTracker.getStepById(dep.id)}`);
2077
2097
  }
2078
2098
  currentLayerPlan.copyStepIds.push(dep.id);
@@ -4,6 +4,7 @@ exports.StepTracker = void 0;
4
4
  const dev_js_1 = require("../dev.js");
5
5
  const interfaces_js_1 = require("../interfaces.js");
6
6
  const utils_js_1 = require("../utils.js");
7
+ const lock_js_1 = require("./lock.js");
7
8
  /**
8
9
  * We want everything else to treat things like `dependencies` as read only,
9
10
  * however we ourselves want to be able to write to them, so we can use
@@ -29,6 +30,8 @@ class StepTracker {
29
30
  /** @internal */
30
31
  this.stepCount = 0;
31
32
  /** @internal */
33
+ this.lockedStepCount = 0;
34
+ /** @internal */
32
35
  this.activeSteps = new Set();
33
36
  /** @internal */
34
37
  this.stepById = [];
@@ -520,6 +523,17 @@ class StepTracker {
520
523
  removeStepFromItsLayerPlan(step) {
521
524
  step.layerPlan.stepsByConstructor.get(step.constructor).delete(step);
522
525
  }
526
+ lockNewSteps() {
527
+ if (!dev_js_1.isDev)
528
+ return;
529
+ for (let i = this.lockedStepCount; i < this.stepCount; i++) {
530
+ const step = this.getStepById(i, true);
531
+ if (step && step.id === i) {
532
+ (0, lock_js_1.lock)(step);
533
+ }
534
+ }
535
+ this.lockedStepCount = this.stepCount;
536
+ }
523
537
  }
524
538
  exports.StepTracker = StepTracker;
525
539
  //# sourceMappingURL=StepTracker.js.map
@@ -0,0 +1,4 @@
1
+ import type { ExecutableStep } from "..";
2
+ export declare function lock($step: ExecutableStep): void;
3
+ export declare function unlock($step: ExecutableStep): boolean;
4
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unlock = exports.lock = exports.$$unlock = void 0;
4
+ /**
5
+ * Used internally to prevent steps using other steps' optimize/finalize/etc
6
+ * methods.
7
+ *
8
+ * @internal
9
+ */
10
+ exports.$$unlock = Symbol("unlock");
11
+ function isLocked($step) {
12
+ return $step[exports.$$unlock] !== undefined;
13
+ }
14
+ function lock($step) {
15
+ if (!isLocked($step)) {
16
+ const { optimize, finalize, deduplicate, deduplicatedWith } = $step;
17
+ if (optimize) {
18
+ $step.optimize = optimizeLocked;
19
+ }
20
+ if (typeof finalize === "function") {
21
+ $step.finalize = finalizeLocked;
22
+ }
23
+ if (deduplicate) {
24
+ $step.deduplicate = deduplicateLocked;
25
+ }
26
+ if (deduplicatedWith) {
27
+ $step.deduplicatedWith = deduplicatedWithLocked;
28
+ }
29
+ $step[exports.$$unlock] = () => {
30
+ $step[exports.$$unlock] = undefined;
31
+ if (optimize && $step.optimize !== optimizeLocked) {
32
+ console.warn(`Warning: ${$step}'s optimize method changed whilst locked`);
33
+ }
34
+ else {
35
+ $step.optimize = optimize;
36
+ }
37
+ if (typeof finalize === "function" && $step.finalize !== finalizeLocked) {
38
+ console.warn(`Warning: ${$step}'s finalize method changed whilst locked`);
39
+ }
40
+ else {
41
+ $step.finalize = finalize;
42
+ }
43
+ if (deduplicate && $step.deduplicate !== deduplicateLocked) {
44
+ console.warn(`Warning: ${$step}'s deduplicate method changed whilst locked`);
45
+ }
46
+ else {
47
+ $step.deduplicate = deduplicate;
48
+ }
49
+ if (deduplicatedWith &&
50
+ $step.deduplicatedWith !== deduplicatedWithLocked) {
51
+ console.warn(`Warning: ${$step}'s deduplicatedWith method changed whilst locked`);
52
+ }
53
+ else {
54
+ $step.deduplicatedWith = deduplicatedWith;
55
+ }
56
+ };
57
+ }
58
+ }
59
+ exports.lock = lock;
60
+ function unlock($step) {
61
+ if (isLocked($step)) {
62
+ $step[exports.$$unlock]();
63
+ return true;
64
+ }
65
+ else {
66
+ return false;
67
+ }
68
+ }
69
+ exports.unlock = unlock;
70
+ function optimizeLocked() {
71
+ throw new Error(`Only Grafast may call a step's optimize method; rather than calling optimize on the steps your class depends on, consider opting in to multiple optimization passes via \`allowMultipleOptimizations\`.`);
72
+ }
73
+ function finalizeLocked() {
74
+ throw new Error(`Only Grafast may call a step's finalize method; steps should not attempt to interact with other steps during finalize.`);
75
+ }
76
+ function deduplicateLocked() {
77
+ throw new Error(`Only Grafast may call a step's deduplicate method.`);
78
+ }
79
+ function deduplicatedWithLocked() {
80
+ throw new Error(`Only Grafast may call a step's deduplicatedWith method.`);
81
+ }
82
+ //# sourceMappingURL=lock.js.map
package/dist/execute.js CHANGED
@@ -4,18 +4,18 @@ exports.execute = exports.withGrafastArgs = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const eventemitter3_1 = tslib_1.__importDefault(require("eventemitter3"));
6
6
  const config_js_1 = require("./config.js");
7
+ const dev_js_1 = require("./dev.js");
7
8
  const inspect_js_1 = require("./inspect.js");
8
9
  const interfaces_js_1 = require("./interfaces.js");
9
10
  const prepare_js_1 = require("./prepare.js");
10
11
  const utils_js_1 = require("./utils.js");
11
- const isDev = typeof process !== "undefined" && process.env.NODE_ENV === "development";
12
12
  /**
13
13
  * Used by `execute` and `subscribe`.
14
14
  * @internal
15
15
  */
16
16
  function withGrafastArgs(args, resolvedPreset, outputDataAsString) {
17
17
  const options = resolvedPreset?.grafast;
18
- if (isDev) {
18
+ if (dev_js_1.isDev) {
19
19
  if (args.rootValue != null &&
20
20
  (typeof args.rootValue !== "object" ||
21
21
  Object.keys(args.rootValue).length > 0)) {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeGrafastSchema = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const graphql = tslib_1.__importStar(require("graphql"));
6
+ const utils_js_1 = require("./utils.js");
6
7
  const { buildASTSchema, isEnumType, isInputObjectType, isInterfaceType, isObjectType, isScalarType, isUnionType, parse, } = graphql;
7
8
  /**
8
9
  * Takes a GraphQL schema definition in Interface Definition Language (IDL/SDL)
@@ -28,6 +29,7 @@ function makeGrafastSchema(details) {
28
29
  const fields = type.getFields();
29
30
  for (const [fieldName, fieldSpec] of Object.entries(objSpec)) {
30
31
  if (fieldName === "__assertStep") {
32
+ (0, utils_js_1.exportNameHint)(fieldSpec, `${typeName}_assertStep`);
31
33
  type.extensions.grafast = { assertStep: fieldSpec };
32
34
  continue;
33
35
  }
@@ -40,6 +42,7 @@ function makeGrafastSchema(details) {
40
42
  continue;
41
43
  }
42
44
  if (typeof fieldSpec === "function") {
45
+ (0, utils_js_1.exportNameHint)(fieldSpec, `${typeName}_${fieldName}_plan`);
43
46
  // it's a plan
44
47
  field.extensions.grafast = {
45
48
  plan: fieldSpec,
@@ -50,15 +53,19 @@ function makeGrafastSchema(details) {
50
53
  const grafastExtensions = Object.create(null);
51
54
  field.extensions.grafast = grafastExtensions;
52
55
  if (typeof fieldSpec.resolve === "function") {
56
+ (0, utils_js_1.exportNameHint)(fieldSpec.resolve, `${typeName}_${fieldName}_resolve`);
53
57
  field.resolve = fieldSpec.resolve;
54
58
  }
55
59
  if (typeof fieldSpec.subscribe === "function") {
60
+ (0, utils_js_1.exportNameHint)(fieldSpec.subscribe, `${typeName}_${fieldName}_subscribe`);
56
61
  field.subscribe = fieldSpec.subscribe;
57
62
  }
58
63
  if (typeof fieldSpec.plan === "function") {
64
+ (0, utils_js_1.exportNameHint)(fieldSpec.plan, `${typeName}_${fieldName}_plan`);
59
65
  grafastExtensions.plan = fieldSpec.plan;
60
66
  }
61
67
  if (typeof fieldSpec.subscribePlan === "function") {
68
+ (0, utils_js_1.exportNameHint)(fieldSpec.subscribePlan, `${typeName}_${fieldName}_subscribePlan`);
62
69
  grafastExtensions.subscribePlan = fieldSpec.subscribePlan;
63
70
  }
64
71
  if (typeof fieldSpec.args === "object" && fieldSpec.args != null) {
@@ -73,6 +80,10 @@ function makeGrafastSchema(details) {
73
80
  throw new Error(`Invalid configuration for plans.${typeName}.${fieldName}.args.${argName} - saw a function, but expected an object with 'inputPlan' (optional) and 'applyPlan' (optional) plans`);
74
81
  }
75
82
  else {
83
+ if (argSpec) {
84
+ (0, utils_js_1.exportNameHint)(argSpec.applyPlan, `${typeName}_${fieldName}_${argName}_applyPlan`);
85
+ (0, utils_js_1.exportNameHint)(argSpec.inputPlan, `${typeName}_${fieldName}_${argName}_inputPlan`);
86
+ }
76
87
  const grafastExtensions = Object.create(null);
77
88
  arg.extensions.grafast = grafastExtensions;
78
89
  Object.assign(grafastExtensions, argSpec);
@@ -98,6 +109,10 @@ function makeGrafastSchema(details) {
98
109
  throw new Error(`Expected input object type '${typeName}' field '${fieldName}' to be an object, but found a function. We don't know if this should be the 'inputPlan' or 'applyPlan' - please supply an object.`);
99
110
  }
100
111
  else {
112
+ if (fieldSpec) {
113
+ (0, utils_js_1.exportNameHint)(fieldSpec.inputPlan, `${typeName}_${fieldName}_inputPlan`);
114
+ (0, utils_js_1.exportNameHint)(fieldSpec.applyPlan, `${typeName}_${fieldName}_applyPlan`);
115
+ }
101
116
  // it's a spec
102
117
  const grafastExtensions = Object.create(null);
103
118
  field.extensions.grafast = grafastExtensions;
@@ -111,6 +126,7 @@ function makeGrafastSchema(details) {
111
126
  }
112
127
  const polySpec = spec;
113
128
  if (polySpec.__resolveType) {
129
+ (0, utils_js_1.exportNameHint)(polySpec.__resolveType, `${typeName}_resolveType`);
114
130
  type.resolveType = polySpec.__resolveType;
115
131
  }
116
132
  }
@@ -120,15 +136,19 @@ function makeGrafastSchema(details) {
120
136
  }
121
137
  const scalarSpec = spec;
122
138
  if (typeof scalarSpec.serialize === "function") {
139
+ (0, utils_js_1.exportNameHint)(scalarSpec.serialize, `${typeName}_serialize`);
123
140
  type.serialize = scalarSpec.serialize;
124
141
  }
125
142
  if (typeof scalarSpec.parseValue === "function") {
143
+ (0, utils_js_1.exportNameHint)(scalarSpec.parseValue, `${typeName}_parseValue`);
126
144
  type.parseValue = scalarSpec.parseValue;
127
145
  }
128
146
  if (typeof scalarSpec.parseLiteral === "function") {
147
+ (0, utils_js_1.exportNameHint)(scalarSpec.parseLiteral, `${typeName}_parseLiteral`);
129
148
  type.parseLiteral = scalarSpec.parseLiteral;
130
149
  }
131
150
  if (typeof scalarSpec.plan === "function") {
151
+ (0, utils_js_1.exportNameHint)(scalarSpec.plan, `${typeName}_plan`);
132
152
  type.extensions.grafast = { plan: scalarSpec.plan };
133
153
  }
134
154
  }
@@ -144,6 +164,7 @@ function makeGrafastSchema(details) {
144
164
  continue;
145
165
  }
146
166
  if (typeof enumValueSpec === "function") {
167
+ (0, utils_js_1.exportNameHint)(enumValueSpec, `${typeName}_${enumValueName}_applyPlan`);
147
168
  // It's a plan
148
169
  enumValue.extensions.grafast = {
149
170
  applyPlan: enumValueSpec,
@@ -152,6 +173,7 @@ function makeGrafastSchema(details) {
152
173
  else if (typeof enumValueSpec === "object" && enumValueSpec != null) {
153
174
  // It's a full spec
154
175
  if (enumValueSpec.applyPlan) {
176
+ (0, utils_js_1.exportNameHint)(enumValueSpec.applyPlan, `${typeName}_${enumValueName}_applyPlan`);
155
177
  enumValue.extensions.grafast = {
156
178
  applyPlan: enumValueSpec.applyPlan,
157
179
  };
package/dist/step.d.ts CHANGED
@@ -106,7 +106,7 @@ export declare class ExecutableStep<TData = any> extends BaseStep {
106
106
  constructor();
107
107
  protected withMyLayerPlan<T>(callback: () => T): T;
108
108
  protected getStep(id: number): ExecutableStep;
109
- getDep(depId: number): ExecutableStep;
109
+ protected getDep(depId: number): ExecutableStep;
110
110
  /**
111
111
  * Like getDep, except it skips over __ItemStep and similar steps to get to
112
112
  * where the parent really is.
package/dist/step.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- var _a;
2
+ var _a, _b;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.assertListCapableStep = exports.isListCapableStep = exports.assertModifierStep = exports.isModifierStep = exports.ModifierStep = exports.isPolymorphicStep = exports.isStreamableStep = exports.isListLikeStep = exports.isObjectLikeStep = exports.isUnbatchedExecutableStep = exports.assertExecutableStep = exports.isExecutableStep = exports.UnbatchedExecutableStep = exports.ExecutableStep = exports.BaseStep = exports.assertFinalized = exports.$$noExec = exports.$$deepDepSkip = void 0;
5
5
  const tslib_1 = require("tslib");
@@ -7,6 +7,7 @@ const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
7
  const tamedevil_1 = tslib_1.__importDefault(require("tamedevil"));
8
8
  const dev_js_1 = require("./dev.js");
9
9
  const withGlobalLayerPlan_js_1 = require("./engine/lib/withGlobalLayerPlan.js");
10
+ const lock_js_1 = require("./engine/lock.js");
10
11
  const global_js_1 = require("./global.js");
11
12
  const inspect_js_1 = require("./inspect.js");
12
13
  const interfaces_js_1 = require("./interfaces.js");
@@ -97,8 +98,11 @@ exports.BaseStep = BaseStep;
97
98
  * they must be able to execute to return values.
98
99
  */
99
100
  class ExecutableStep extends BaseStep {
101
+ static { _b = lock_js_1.$$unlock; }
100
102
  constructor() {
101
103
  super();
104
+ /** @internal */
105
+ this[_b] = undefined;
102
106
  this.dependencies = [];
103
107
  this.dependents = [];
104
108
  this.isOptimized = false;
@@ -17,6 +17,7 @@ export declare class __ItemStep<TData> extends UnbatchedExecutableStep<TData> {
17
17
  constructor(parentPlan: ExecutableStep<TData> | ExecutableStep<TData[]>, depth?: number);
18
18
  toStringMeta(): string;
19
19
  planJSONExtra(): Record<string, JSONValue | undefined> | undefined;
20
+ getParentStep(): ExecutableStep;
20
21
  [$$deepDepSkip](): ExecutableStep;
21
22
  execute(): never;
22
23
  unbatchedExecute(): never;
@@ -30,6 +30,9 @@ class __ItemStep extends step_js_1.UnbatchedExecutableStep {
30
30
  transformStepId: this.transformStepId,
31
31
  };
32
32
  }
33
+ getParentStep() {
34
+ return this.getDep(0);
35
+ }
33
36
  [(_a = step_js_1.$$noExec, step_js_1.$$deepDepSkip)]() {
34
37
  return this.getDep(0);
35
38
  }
@@ -93,7 +93,7 @@ export declare class ConnectionStep<TItemStep extends ExecutableStep, TCursorSte
93
93
  */
94
94
  addValidation(callback: () => ExecutableStep): void;
95
95
  edges(): ExecutableStep;
96
- nodes(): TStep | import("./listTransform.js").__ListTransformStep<any, any, any, any>;
96
+ nodes(): import("./listTransform.js").__ListTransformStep<any, any, any, any> | TStep;
97
97
  wrapEdge($edge: TItemStep): EdgeStep<TItemStep, TCursorStep, TStep, TNodeStep>;
98
98
  pageInfo(): PageInfoCapableStep;
99
99
  execute(count: number): GrafastResultsList<Record<string, never>>;
@@ -43,7 +43,7 @@ function each(listStep, mapper) {
43
43
  const layerPlan = this.subroutineLayer;
44
44
  const rootStep = layerPlan.rootStep;
45
45
  if (rootStep instanceof __item_js_1.__ItemStep &&
46
- rootStep.getDep(0).layerPlan !== layerPlan) {
46
+ rootStep.getParentStep().layerPlan !== layerPlan) {
47
47
  // We don't do anything; replace ourself with our parent
48
48
  return this.getListStep();
49
49
  }
@@ -179,6 +179,7 @@ class LoadStep extends step_js_1.ExecutableStep {
179
179
  idByLoad.set(this.load, loadId);
180
180
  }
181
181
  this.metaKey = `LoadStep|${loadId}|${this.loadOptionsKey}`;
182
+ super.finalize();
182
183
  }
183
184
  execute(count, [specs], extra) {
184
185
  const meta = extra.meta;
@@ -50,7 +50,7 @@ export declare class ObjectStep<TPlans extends {
50
50
  execute(count: number, values: Array<Array<DataFromPlans<TPlans>[keyof TPlans]>>, extra: ExecutionExtra): Array<DataFromPlans<TPlans>>;
51
51
  unbatchedExecute(_extra: ExecutionExtra, ..._values: any[]): any;
52
52
  deduplicate(peers: ObjectStep<any>[]): ObjectStep<TPlans>[];
53
- optimize(opts: StepOptimizeOptions): this | ConstantStep<any>;
53
+ optimize(opts: StepOptimizeOptions): ConstantStep<any> | this;
54
54
  /**
55
55
  * Get the original plan with the given key back again.
56
56
  */
package/dist/utils.d.ts CHANGED
@@ -144,5 +144,6 @@ export declare function hasItemPlan(step: ExecutableStep & {
144
144
  }): step is ExecutableStep & {
145
145
  itemPlan: ($item: ExecutableStep) => ExecutableStep;
146
146
  };
147
+ export declare function exportNameHint(obj: any, nameHint: string): void;
147
148
  export {};
148
149
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasItemPlan = exports.assertNotAsync = exports.canonicalJSONStringify = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.sudo = exports.isTypePlanned = exports.findVariableNamesUsed = exports.arrayOfLengthCb = exports.arrayOfLength = exports.stack = exports.sharedNull = exports.getEnumValueConfig = exports.inputObjectFieldSpec = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.objectFieldSpec = exports.newObjectTypeBuilder = exports.objectSpec = exports.arraysMatch = exports.isDeferred = exports.isPromiseLike = exports.isPromise = exports.defaultValueToValueNode = exports.assertNullPrototype = exports.ROOT_VALUE_OBJECT = void 0;
3
+ exports.exportNameHint = exports.hasItemPlan = exports.assertNotAsync = exports.canonicalJSONStringify = exports.stepsAreInSamePhase = exports.stepAMayDependOnStepB = exports.stepADependsOnStepB = exports.sudo = exports.isTypePlanned = exports.findVariableNamesUsed = exports.arrayOfLengthCb = exports.arrayOfLength = exports.stack = exports.sharedNull = exports.getEnumValueConfig = exports.inputObjectFieldSpec = exports.newInputObjectTypeBuilder = exports.newGrafastFieldConfigBuilder = exports.objectFieldSpec = exports.newObjectTypeBuilder = exports.objectSpec = exports.arraysMatch = exports.isDeferred = exports.isPromiseLike = exports.isPromise = exports.defaultValueToValueNode = exports.assertNullPrototype = exports.ROOT_VALUE_OBJECT = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const graphql = tslib_1.__importStar(require("graphql"));
6
6
  const assert = tslib_1.__importStar(require("./assert.js"));
@@ -702,4 +702,18 @@ function hasItemPlan(step) {
702
702
  return "itemPlan" in step && typeof step.itemPlan === "function";
703
703
  }
704
704
  exports.hasItemPlan = hasItemPlan;
705
+ function exportNameHint(obj, nameHint) {
706
+ if ((typeof obj === "object" && obj != null) || typeof obj === "function") {
707
+ if (!("$exporter$name" in obj)) {
708
+ Object.defineProperty(obj, "$exporter$name", {
709
+ writable: true,
710
+ value: nameHint,
711
+ });
712
+ }
713
+ else if (!obj.$exporter$name) {
714
+ obj.$exporter$name = nameHint;
715
+ }
716
+ }
717
+ }
718
+ exports.exportNameHint = exportNameHint;
705
719
  //# sourceMappingURL=utils.js.map
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.1.1-beta.5";
1
+ export declare const version = "0.1.1-beta.6";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // This file is autogenerated by /scripts/postversion.mjs
5
- exports.version = "0.1.1-beta.5";
5
+ exports.version = "0.1.1-beta.6";
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grafast",
3
- "version": "0.1.1-beta.5",
3
+ "version": "0.1.1-beta.6",
4
4
  "description": "Cutting edge GraphQL planning and execution engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -61,14 +61,14 @@
61
61
  "eventemitter3": "^5.0.1",
62
62
  "graphql": "^16.1.0-experimental-stream-defer.6",
63
63
  "iterall": "^1.3.0",
64
- "tamedevil": "^0.0.0-beta.5",
64
+ "tamedevil": "^0.0.0-beta.6",
65
65
  "tslib": "^2.6.2"
66
66
  },
67
67
  "peerDependencies": {
68
68
  "@envelop/core": "^3.0.4",
69
69
  "graphile-config": "^0.0.1-beta.7",
70
70
  "graphql": "^16.1.0-experimental-stream-defer.6",
71
- "tamedevil": "^0.0.0-beta.5"
71
+ "tamedevil": "^0.0.0-beta.6"
72
72
  },
73
73
  "peerDependenciesMeta": {
74
74
  "@envelop/core": {