grafast 0.1.1-beta.21 → 0.1.1-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -4
- package/dist/args.js +3 -3
- package/dist/constants.d.ts +79 -0
- package/dist/constants.js +79 -0
- package/dist/engine/LayerPlan.d.ts +71 -8
- package/dist/engine/LayerPlan.js +375 -265
- package/dist/engine/OperationPlan.d.ts +77 -14
- package/dist/engine/OperationPlan.js +1508 -382
- package/dist/engine/OperationPlanTypes.d.ts +66 -0
- package/dist/engine/OperationPlanTypes.js +3 -0
- package/dist/engine/OutputPlan.d.ts +6 -0
- package/dist/engine/OutputPlan.js +138 -82
- package/dist/engine/StepTracker.js +76 -17
- package/dist/engine/executeBucket.js +327 -166
- package/dist/engine/lib/defaultPlanResolver.d.ts +1 -4
- package/dist/engine/lib/defaultPlanResolver.js +1 -5
- package/dist/engine/lib/withGlobalLayerPlan.d.ts +3 -1
- package/dist/engine/lib/withGlobalLayerPlan.js +19 -1
- package/dist/envelop.js +14 -3
- package/dist/error.d.ts +1 -1
- package/dist/error.js +9 -9
- package/dist/establishOperationPlan.d.ts +2 -1
- package/dist/establishOperationPlan.js +10 -10
- package/dist/execute.js +7 -5
- package/dist/global.d.ts +10 -0
- package/dist/global.js +25 -0
- package/dist/grafastGraphql.js +4 -3
- package/dist/grafastPrint.js +36 -4
- package/dist/index.d.ts +76 -8
- package/dist/index.js +37 -33
- package/dist/input.js +20 -1
- package/dist/inspect.js +1 -0
- package/dist/interfaces.d.ts +80 -122
- package/dist/interfaces.js +0 -77
- package/dist/makeGrafastSchema.d.ts +118 -35
- package/dist/makeGrafastSchema.js +197 -29
- package/dist/mermaid.js +198 -97
- package/dist/operationPlan-input.d.ts +1 -1
- package/dist/operationPlan-input.js +15 -5
- package/dist/planJSONInterfaces.d.ts +24 -5
- package/dist/prepare.d.ts +16 -9
- package/dist/prepare.js +54 -51
- package/dist/step.d.ts +45 -9
- package/dist/step.js +139 -22
- package/dist/steps/__flag.d.ts +3 -2
- package/dist/steps/__flag.js +31 -29
- package/dist/steps/__inputObject.d.ts +1 -1
- package/dist/steps/__inputStaticLeaf.d.ts +3 -2
- package/dist/steps/__inputStaticLeaf.js +13 -7
- package/dist/steps/__item.d.ts +1 -1
- package/dist/steps/__item.js +3 -3
- package/dist/steps/__trackedValue.d.ts +6 -3
- package/dist/steps/__trackedValue.js +25 -9
- package/dist/steps/__value.d.ts +2 -1
- package/dist/steps/__value.js +5 -0
- package/dist/steps/access.d.ts +17 -1
- package/dist/steps/access.js +14 -1
- package/dist/steps/applyInput.d.ts +1 -1
- package/dist/steps/applyInput.js +7 -6
- package/dist/steps/applyTransforms.js +9 -7
- package/dist/steps/bakedInput.js +2 -2
- package/dist/steps/coalesce.d.ts +15 -0
- package/dist/steps/coalesce.js +36 -0
- package/dist/steps/constant.js +16 -14
- package/dist/steps/each.d.ts +2 -2
- package/dist/steps/first.d.ts +2 -0
- package/dist/steps/first.js +5 -1
- package/dist/steps/graphqlResolver.d.ts +2 -2
- package/dist/steps/graphqlResolver.js +63 -161
- package/dist/steps/index.d.ts +3 -15
- package/dist/steps/index.js +6 -41
- package/dist/steps/lambda.js +1 -1
- package/dist/steps/last.d.ts +2 -0
- package/dist/steps/last.js +4 -0
- package/dist/steps/listTransform.d.ts +2 -2
- package/dist/steps/listTransform.js +11 -13
- package/dist/steps/load.d.ts +28 -22
- package/dist/steps/load.js +47 -1
- package/dist/steps/node.d.ts +10 -7
- package/dist/steps/node.js +5 -19
- package/dist/steps/object.js +6 -1
- package/dist/steps/proxy.d.ts +0 -6
- package/dist/steps/proxy.js +3 -3
- package/dist/steps/remapKeys.d.ts +1 -1
- package/dist/steps/remapKeys.js +0 -1
- package/dist/utils.d.ts +27 -5
- package/dist/utils.js +235 -15
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -6
- package/dist/polymorphic.d.ts +0 -14
- package/dist/polymorphic.js +0 -72
- package/dist/steps/polymorphicBranch.d.ts +0 -27
- package/dist/steps/polymorphicBranch.js +0 -62
package/dist/mermaid.js
CHANGED
|
@@ -65,9 +65,6 @@ exports.mermaidEscape = mermaidEscape;
|
|
|
65
65
|
function isGrafastPlanJSONv1(json) {
|
|
66
66
|
return json.version === "v1";
|
|
67
67
|
}
|
|
68
|
-
function shouldHideStep(step) {
|
|
69
|
-
return step.extra?.constant?.type === "undefined";
|
|
70
|
-
}
|
|
71
68
|
function planToMermaid(planJSON, {
|
|
72
69
|
// printPathRelations = false,
|
|
73
70
|
concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false, } = {}) {
|
|
@@ -79,6 +76,9 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
79
76
|
const dependentsByStepId = Object.create(null);
|
|
80
77
|
const sortedSteps = [];
|
|
81
78
|
const extractSteps = (bucket) => {
|
|
79
|
+
if (layerPlanById[bucket.id]) {
|
|
80
|
+
throw new Error(`Two buckets with the same ID ${bucket.id}?`);
|
|
81
|
+
}
|
|
82
82
|
layerPlanById[bucket.id] = bucket;
|
|
83
83
|
// Shallowest bucket first, then most dependencies
|
|
84
84
|
const sorted = [...bucket.steps].sort((a, z) => z.dependencyIds.length - a.dependencyIds.length);
|
|
@@ -97,11 +97,46 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
};
|
|
101
|
+
planJSON.buckets.forEach(extractSteps);
|
|
102
|
+
const shouldHideStep = (step) => {
|
|
103
|
+
if (step.stepClass === "ConstantStep")
|
|
104
|
+
return true;
|
|
105
|
+
if (step.extra?.constant?.type === "undefined") {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
if (step.bucketId === 0 &&
|
|
109
|
+
step.isSyncAndSafe &&
|
|
110
|
+
(dependentsByStepId[step.id]?.length ?? 0) === 0) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
const partitionToPoly = (bucketId) => {
|
|
116
|
+
const lp = layerPlanById[bucketId];
|
|
117
|
+
if (lp.reason.type === "polymorphicPartition") {
|
|
118
|
+
return layerPlans.find((lp) => lp.childIds.includes(bucketId));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
return bucketId;
|
|
102
122
|
}
|
|
103
123
|
};
|
|
104
|
-
|
|
124
|
+
const isExcessivelyReferenced = (stepId) => {
|
|
125
|
+
const step = stepById[stepId];
|
|
126
|
+
if (!step)
|
|
127
|
+
return true;
|
|
128
|
+
if (step.stepClass === "ConstantStep")
|
|
129
|
+
return true;
|
|
130
|
+
if (step.bucketId !== 0)
|
|
131
|
+
return false;
|
|
132
|
+
const dependents = dependentsByStepId[stepId];
|
|
133
|
+
if (!dependents || dependents.length === 0)
|
|
134
|
+
return false;
|
|
135
|
+
const firstDependent = dependents[0];
|
|
136
|
+
// If it's referenced by more than one layer plan, it's excessive
|
|
137
|
+
return dependents.some((d) => partitionToPoly(d.bucketId) !==
|
|
138
|
+
partitionToPoly(firstDependent.bucketId));
|
|
139
|
+
};
|
|
105
140
|
const color = (i) => {
|
|
106
141
|
return exports.COLORS[i % exports.COLORS.length];
|
|
107
142
|
};
|
|
@@ -126,6 +161,45 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
126
161
|
}
|
|
127
162
|
return str;
|
|
128
163
|
};
|
|
164
|
+
const stepToString = (step) => {
|
|
165
|
+
return `${step.stepClass.replace(/Step$/, "")}${step.bucketId === 0 ? "" : `{${step.bucketId}}`}${step.metaString ? `<${step.metaString}>` : ""}[${step.id}]`;
|
|
166
|
+
};
|
|
167
|
+
const layerPlans = Object.values(layerPlanById);
|
|
168
|
+
if (!skipBuckets) {
|
|
169
|
+
if (!concise)
|
|
170
|
+
graph.push(" subgraph Buckets");
|
|
171
|
+
for (let i = 0, l = layerPlans.length; i < l; i++) {
|
|
172
|
+
const layerPlan = layerPlans[i];
|
|
173
|
+
const raisonDEtre = ` (${layerPlan.reason.type})` +
|
|
174
|
+
(layerPlan.reason.type === "polymorphicPartition"
|
|
175
|
+
? `\n|${layerPlan.reason.typeNames.join("\n|")}`
|
|
176
|
+
: layerPlan.reason.type === "polymorphic"
|
|
177
|
+
? `\n__typename: ${shortStep(stepById[layerPlan.reason.parentStepId])}`
|
|
178
|
+
: ``);
|
|
179
|
+
graph.push(` Bucket${layerPlan.id}(${(0, exports.mermaidEscape)(`Bucket ${layerPlan.id}${raisonDEtre}${layerPlan.parentSideEffectStepId != null
|
|
180
|
+
? `\nParent side effect step: ${stepById[layerPlan.parentSideEffectStepId].id}`
|
|
181
|
+
: ""}${layerPlan.copyStepIds.length > 0
|
|
182
|
+
? `\nDeps: ${layerPlan.copyStepIds
|
|
183
|
+
.map((pId) => stepById[pId].id)
|
|
184
|
+
.join(", ")}`
|
|
185
|
+
: ""}${layerPlan.reason.type === "polymorphicPartition"
|
|
186
|
+
? "\n" + pp(layerPlan.reason.polymorphicPaths)
|
|
187
|
+
: ""}\n${layerPlan.rootStepId != null && layerPlan.reason.type !== "root"
|
|
188
|
+
? `\nROOT ${stepToString(stepById[layerPlan.rootStepId])}`
|
|
189
|
+
: ""}${startSteps(layerPlan)}`)}):::bucket`);
|
|
190
|
+
}
|
|
191
|
+
if (!concise)
|
|
192
|
+
graph.push(" end");
|
|
193
|
+
}
|
|
194
|
+
if (!skipBuckets) {
|
|
195
|
+
for (let i = 0, l = layerPlans.length; i < l; i++) {
|
|
196
|
+
const layerPlan = layerPlans[i];
|
|
197
|
+
const childNodes = layerPlan.childIds.map((cId) => `Bucket${cId}`);
|
|
198
|
+
if (childNodes.length > 0) {
|
|
199
|
+
graph.push(` Bucket${layerPlan.id} --> ${childNodes.join(" & ")}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
129
203
|
const planIdMap = Object.create(null);
|
|
130
204
|
const planId = (plan) => {
|
|
131
205
|
if (!planIdMap[plan.id]) {
|
|
@@ -140,18 +214,32 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
140
214
|
const meta = concise && strippedMeta ? squish(strippedMeta) : strippedMeta;
|
|
141
215
|
const isUnbatched = plan.supportsUnbatched;
|
|
142
216
|
const polyPaths = pp(plan.polymorphicPaths);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
const [lBrace, rBrace] = plan.stepClass === "__ItemStep"
|
|
217
|
+
const depIdsInSameBucket = plan.dependencyIds.filter((id) => stepById[id].bucketId === plan.bucketId);
|
|
218
|
+
const polyPathsAreSame = depIdsInSameBucket.length >= 1 &&
|
|
219
|
+
depIdsInSameBucket.every((id) => pp(stepById[id].polymorphicPaths) === polyPaths);
|
|
220
|
+
const polyPathsIfDifferent = polyPathsAreSame || polyPaths === "" ? "" : `\n${polyPaths}`;
|
|
221
|
+
const [lBrace, rBrace, shape = "", planNameText = planName] = plan.stepClass === "__ItemStep"
|
|
149
222
|
? ["[/", "\\]"]
|
|
150
|
-
: plan.
|
|
151
|
-
?
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
223
|
+
: plan.stepClass === "__ValueStep" && plan.extra?.combined
|
|
224
|
+
? [null, null, "docs", "__Combined"]
|
|
225
|
+
: plan.isSyncAndSafe
|
|
226
|
+
? isUnbatched
|
|
227
|
+
? ["{{", "}}"]
|
|
228
|
+
: ["[", "]"]
|
|
229
|
+
: ["[[", "]]"];
|
|
230
|
+
const depCount = isExcessivelyReferenced(plan.id)
|
|
231
|
+
? `\nDependents: ${dependentsByStepId[plan.id]?.length}`
|
|
232
|
+
: ``;
|
|
233
|
+
const extraDeps = plan.dependencyIds.filter(isExcessivelyReferenced);
|
|
234
|
+
const extraDependencies = extraDeps.length > 0
|
|
235
|
+
? `\nMore deps:\n${extraDeps
|
|
236
|
+
.map((depId) => {
|
|
237
|
+
const step = stepById[depId];
|
|
238
|
+
return `- ${shortStep(step)}`;
|
|
239
|
+
})
|
|
240
|
+
.join("\n")}`
|
|
241
|
+
: ``;
|
|
242
|
+
const planString = `${planNameText}[${plan.id}${`∈${plan.bucketId}`}${plan.stream ? "@s" : ""}]${plan.isUnary ? " ➊" : ""}${polyPathsAreSame && polyPaths !== "" ? "^" : ""}${meta ? `\n<${meta}>` : ""}${polyPathsIfDifferent}${depCount}${extraDependencies}`;
|
|
155
243
|
const planClass = plan.hasSideEffects
|
|
156
244
|
? "sideeffectplan"
|
|
157
245
|
: plan.stepClass === "__ItemStep"
|
|
@@ -159,7 +247,12 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
159
247
|
: isUnbatched && !plan.isSyncAndSafe
|
|
160
248
|
? "unbatchedplan"
|
|
161
249
|
: "plan";
|
|
162
|
-
|
|
250
|
+
if (lBrace === null) {
|
|
251
|
+
graph.push(` ${planNode}:::${planClass}@{shape: ${shape}, label: ${(0, exports.mermaidEscape)(planString)}}`);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
graph.push(` ${planNode}${lBrace}${(0, exports.mermaidEscape)(planString)}${rBrace}:::${planClass}`);
|
|
255
|
+
}
|
|
163
256
|
}
|
|
164
257
|
return planIdMap[plan.id];
|
|
165
258
|
};
|
|
@@ -169,6 +262,9 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
169
262
|
const depDeets = (step, idx) => {
|
|
170
263
|
const forbiddenFlags = step.dependencyForbiddenFlags[idx];
|
|
171
264
|
const onReject = step.dependencyOnReject[idx];
|
|
265
|
+
// TODO: factor 'data only' into the diagrams
|
|
266
|
+
//
|
|
267
|
+
// const dataOnly = step.dependencyDataOnly[idx];
|
|
172
268
|
const info = [];
|
|
173
269
|
if (forbiddenFlags) {
|
|
174
270
|
if ((forbiddenFlags & 2) === 2) {
|
|
@@ -198,17 +294,15 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
198
294
|
if (shouldHideStep(plan))
|
|
199
295
|
return;
|
|
200
296
|
const planNode = planId(plan);
|
|
201
|
-
const depNodes = plan.dependencyIds
|
|
202
|
-
.map((depId) => {
|
|
297
|
+
const depNodes = plan.dependencyIds.map((depId) => {
|
|
203
298
|
const step = stepById[depId];
|
|
204
|
-
if (shouldHideStep(step)) {
|
|
299
|
+
if (shouldHideStep(step) || isExcessivelyReferenced(depId)) {
|
|
205
300
|
return null;
|
|
206
301
|
}
|
|
207
302
|
else {
|
|
208
303
|
return planId(step);
|
|
209
304
|
}
|
|
210
|
-
})
|
|
211
|
-
.filter((n) => n !== null);
|
|
305
|
+
});
|
|
212
306
|
const transformItemPlanNode = null;
|
|
213
307
|
/*
|
|
214
308
|
plan.stepClass === '__ListTransformStep'
|
|
@@ -217,23 +311,25 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
217
311
|
)
|
|
218
312
|
: null;
|
|
219
313
|
*/
|
|
220
|
-
|
|
314
|
+
const firstDep = depNodes.find((n) => n != null);
|
|
315
|
+
if (depNodes.length > 0 && firstDep) {
|
|
221
316
|
if (plan.stepClass === "__ItemStep") {
|
|
222
|
-
const [firstDep, ...rest] = depNodes;
|
|
223
317
|
const arrow = plan.extra?.transformStepId == null ? "==>" : "-.->";
|
|
224
318
|
graph.push(` ${firstDep} ${arrow}${depDeets(plan, 0)} ${planNode}`);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
319
|
+
const normal = [];
|
|
320
|
+
for (let i = 0; i < depNodes.length; i++) {
|
|
321
|
+
const r = depNodes[i];
|
|
322
|
+
if (r == null || r === firstDep)
|
|
323
|
+
continue;
|
|
324
|
+
const deets = depDeets(plan, i);
|
|
325
|
+
if (deets) {
|
|
326
|
+
graph.push(` ${r} -->${deets} ${planNode}`);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
normal.push(r);
|
|
236
330
|
}
|
|
331
|
+
}
|
|
332
|
+
if (normal.length > 0) {
|
|
237
333
|
outputGroupedNormalLinks(graph, planNode, normal);
|
|
238
334
|
}
|
|
239
335
|
}
|
|
@@ -242,20 +338,21 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
242
338
|
!dependentsByStepId[plan.id] &&
|
|
243
339
|
depNodes.length === 1) {
|
|
244
340
|
// Try alternating the nodes so they render closer together
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
graph.push(` ${depNode} -->${depDeets(plan, 0)} ${planNode}`);
|
|
341
|
+
if (chainByDep[firstDep] === undefined) {
|
|
342
|
+
graph.push(` ${firstDep} -->${depDeets(plan, 0)} ${planNode}`);
|
|
248
343
|
}
|
|
249
344
|
else {
|
|
250
|
-
graph.push(` ${chainByDep[
|
|
345
|
+
graph.push(` ${chainByDep[firstDep]} o--o${depDeets(plan, 0)} ${planNode}`);
|
|
251
346
|
}
|
|
252
|
-
chainByDep[
|
|
347
|
+
chainByDep[firstDep] = planNode;
|
|
253
348
|
}
|
|
254
349
|
else {
|
|
255
350
|
const normal = [];
|
|
256
351
|
for (let i = 0; i < depNodes.length; i++) {
|
|
257
352
|
const r = depNodes[i];
|
|
258
|
-
|
|
353
|
+
if (r == null)
|
|
354
|
+
continue;
|
|
355
|
+
const deets = depDeets(plan, i);
|
|
259
356
|
if (deets) {
|
|
260
357
|
graph.push(` ${r} -->${deets} ${planNode}`);
|
|
261
358
|
}
|
|
@@ -279,9 +376,15 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
279
376
|
planId(step);
|
|
280
377
|
}
|
|
281
378
|
});
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
379
|
+
for (let i = 0, l = layerPlans.length; i < l; i++) {
|
|
380
|
+
const layerPlan = layerPlans[i];
|
|
381
|
+
const steps = layerPlan.steps;
|
|
382
|
+
graph.push(` classDef bucket${layerPlan.id} stroke:${color(typeof layerPlan.id === "number" ? layerPlan.id : Object.values(layerPlanById).indexOf(layerPlan))}`);
|
|
383
|
+
graph.push(` class ${[
|
|
384
|
+
`Bucket${layerPlan.id}`,
|
|
385
|
+
...steps.filter((s) => !shouldHideStep(s)).map(planId),
|
|
386
|
+
].join(",")} bucket${layerPlan.id}`);
|
|
387
|
+
}
|
|
285
388
|
let firstSideEffect = true;
|
|
286
389
|
sortedSteps.forEach((step) => {
|
|
287
390
|
if (step.implicitSideEffectStepId) {
|
|
@@ -295,64 +398,22 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
295
398
|
}
|
|
296
399
|
});
|
|
297
400
|
graph.push("");
|
|
298
|
-
|
|
299
|
-
graph.push(" subgraph Buckets");
|
|
300
|
-
const layerPlans = Object.values(layerPlanById);
|
|
401
|
+
// Handle concat for any "combination" layer plans
|
|
301
402
|
for (let i = 0, l = layerPlans.length; i < l; i++) {
|
|
302
403
|
const layerPlan = layerPlans[i];
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
? `\nParent side effect step: ${stepById[layerPlan.parentSideEffectStepId].id}`
|
|
311
|
-
: ""}${layerPlan.copyStepIds.length > 0
|
|
312
|
-
? `\nDeps: ${layerPlan.copyStepIds
|
|
313
|
-
.map((pId) => stepById[pId].id)
|
|
314
|
-
.join(", ")}`
|
|
315
|
-
: ""}${layerPlan.reason.type === "polymorphic"
|
|
316
|
-
? "\n" + pp(layerPlan.reason.polymorphicPaths)
|
|
317
|
-
: ""}\n${layerPlan.rootStepId != null && layerPlan.reason.type !== "root"
|
|
318
|
-
? `\nROOT ${stepToString(stepById[layerPlan.rootStepId])}`
|
|
319
|
-
: ""}${startSteps(layerPlan)}`)}):::bucket`);
|
|
320
|
-
}
|
|
321
|
-
graph.push(` classDef bucket${layerPlan.id} stroke:${color(layerPlan.id)}`);
|
|
322
|
-
graph.push(` class ${[
|
|
323
|
-
`Bucket${layerPlan.id}`,
|
|
324
|
-
...steps.filter((s) => !shouldHideStep(s)).map(planId),
|
|
325
|
-
].join(",")} bucket${layerPlan.id}`);
|
|
326
|
-
}
|
|
327
|
-
if (!skipBuckets) {
|
|
328
|
-
for (let i = 0, l = layerPlans.length; i < l; i++) {
|
|
329
|
-
const layerPlan = layerPlans[i];
|
|
330
|
-
const childNodes = layerPlan.children.map((c) => `Bucket${c.id}`);
|
|
331
|
-
if (childNodes.length > 0) {
|
|
332
|
-
graph.push(` Bucket${layerPlan.id} --> ${childNodes.join(" & ")}`);
|
|
404
|
+
if (layerPlan.reason.type === "combined") {
|
|
405
|
+
for (const { targetStepId, sources } of layerPlan.reason.combinations) {
|
|
406
|
+
const targetStep = stepById[targetStepId];
|
|
407
|
+
for (const { stepId } of sources) {
|
|
408
|
+
const step = stepById[stepId];
|
|
409
|
+
graph.push(` ${planId(step)} -.-x ${planId(targetStep)}`);
|
|
410
|
+
}
|
|
333
411
|
}
|
|
334
412
|
}
|
|
335
413
|
}
|
|
336
|
-
if (!concise && !skipBuckets)
|
|
337
|
-
graph.push(" end");
|
|
338
414
|
const graphString = graph.join("\n");
|
|
339
415
|
return graphString;
|
|
340
416
|
function startSteps(layerPlan) {
|
|
341
|
-
function shortStep(step) {
|
|
342
|
-
return `${step.stepClass.replace(/Step$/, "") ?? ""}[${step.id}]`;
|
|
343
|
-
}
|
|
344
|
-
function shortSteps(steps) {
|
|
345
|
-
if (!steps) {
|
|
346
|
-
return "";
|
|
347
|
-
}
|
|
348
|
-
const str = steps.map(shortStep).join(", ");
|
|
349
|
-
if (str.length < 40) {
|
|
350
|
-
return str;
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
return steps.map((s) => s.id).join(", ");
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
417
|
return layerPlan.phases.length === 1
|
|
357
418
|
? ``
|
|
358
419
|
: `\n${layerPlan.phases
|
|
@@ -362,11 +423,51 @@ concise = false, skipBuckets = global.grafastExplainMermaidSkipBuckets ?? false,
|
|
|
362
423
|
.join("\n")}`;
|
|
363
424
|
}
|
|
364
425
|
}
|
|
426
|
+
function shortStep(step) {
|
|
427
|
+
if (step.stepClass === "ConstantStep") {
|
|
428
|
+
return `Constant${step.metaString ? `<${step.metaString}>` : ""}[${step.id}]`;
|
|
429
|
+
}
|
|
430
|
+
return `${step.stepClass.replace(/Step$/, "") ?? ""}[${step.id}]`;
|
|
431
|
+
}
|
|
432
|
+
function shortSteps(steps) {
|
|
433
|
+
if (!steps) {
|
|
434
|
+
return "";
|
|
435
|
+
}
|
|
436
|
+
const str = steps.map(shortStep).join(", ");
|
|
437
|
+
if (str.length < 40) {
|
|
438
|
+
return str;
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
return steps.map((s) => s.id).join(", ");
|
|
442
|
+
}
|
|
443
|
+
}
|
|
365
444
|
function pp(polymorphicPaths) {
|
|
366
|
-
if (
|
|
445
|
+
if (polymorphicPaths == null) {
|
|
367
446
|
return "";
|
|
368
447
|
}
|
|
369
|
-
|
|
448
|
+
const counts = Object.create(null);
|
|
449
|
+
const out = [];
|
|
450
|
+
const last = Object.create(null);
|
|
451
|
+
for (const p of polymorphicPaths) {
|
|
452
|
+
const i = p.lastIndexOf(">");
|
|
453
|
+
if (i <= 0) {
|
|
454
|
+
out.push(p);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
const end = p.slice(i);
|
|
458
|
+
last[end] = p;
|
|
459
|
+
if (counts[end]) {
|
|
460
|
+
counts[end]++;
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
counts[end] = 1;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
for (const [end, count] of Object.entries(counts)) {
|
|
468
|
+
out.push(count === 1 ? last[end] : `(${count}) ...${end}`);
|
|
469
|
+
}
|
|
470
|
+
return out.join("\n");
|
|
370
471
|
}
|
|
371
472
|
tslib_1.__exportStar(require("./planJSONInterfaces.js"), exports);
|
|
372
473
|
function trim(string, length = 15) {
|
|
@@ -3,6 +3,6 @@ import type { OperationPlan } from "./engine/OperationPlan.js";
|
|
|
3
3
|
import type { FieldArgs, TrackedArguments } from "./interfaces.js";
|
|
4
4
|
import type { Step } from "./step.js";
|
|
5
5
|
export type ApplyAfterModeArg = "plan" | "subscribePlan";
|
|
6
|
-
export declare function withFieldArgsForArguments<T extends Step>(operationPlan: OperationPlan,
|
|
6
|
+
export declare function withFieldArgsForArguments<T extends Step>(operationPlan: OperationPlan, trackedArguments: TrackedArguments, field: GraphQLField<any, any, any>, $parent: Step, applyAfterMode: ApplyAfterModeArg, coordinate: string, callback: (fieldArgs: FieldArgs) => T | null | undefined): T | null;
|
|
7
7
|
export declare function getNullableInputTypeAtPath(startType: GraphQLInputType, path: ReadonlyArray<string | number>): GraphQLInputType & GraphQLNullableType;
|
|
8
8
|
//# sourceMappingURL=operationPlan-input.d.ts.map
|
|
@@ -13,7 +13,7 @@ function assertNotRuntime(operationPlan, description) {
|
|
|
13
13
|
throw new Error(`${description} may only be called at planning time; however you have code that has attempted to call it during execution time. Please revisit your plan resolvers to locate the issue.`);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
function withFieldArgsForArguments(operationPlan,
|
|
16
|
+
function withFieldArgsForArguments(operationPlan, trackedArguments, field, $parent, applyAfterMode, coordinate, callback) {
|
|
17
17
|
if (operationPlan.loc !== null)
|
|
18
18
|
operationPlan.loc.push(`withFieldArgsForArguments(${field.name})`);
|
|
19
19
|
const args = Object.create(null);
|
|
@@ -62,17 +62,17 @@ function withFieldArgsForArguments(operationPlan, $all, field, $parent, applyAft
|
|
|
62
62
|
getRaw(path) {
|
|
63
63
|
assertNotRuntime(operationPlan, `fieldArgs.getRaw()`);
|
|
64
64
|
if (path === undefined) {
|
|
65
|
-
return (0, index_js_1.object)(
|
|
65
|
+
return (0, index_js_1.object)(trackedArguments);
|
|
66
66
|
}
|
|
67
67
|
else if (typeof path === "string") {
|
|
68
|
-
return
|
|
68
|
+
return trackedArguments[path];
|
|
69
69
|
}
|
|
70
70
|
else if (Array.isArray(path)) {
|
|
71
71
|
const [first, ...rest] = path;
|
|
72
72
|
if (!first) {
|
|
73
73
|
throw new Error(`getRaw() must be called with a non-empty path`);
|
|
74
74
|
}
|
|
75
|
-
let $entry =
|
|
75
|
+
let $entry = trackedArguments[first];
|
|
76
76
|
for (const pathSegment of rest) {
|
|
77
77
|
if (typeof pathSegment === "number" && "at" in $entry) {
|
|
78
78
|
$entry = $entry.at(pathSegment);
|
|
@@ -141,13 +141,16 @@ function withFieldArgsForArguments(operationPlan, $all, field, $parent, applyAft
|
|
|
141
141
|
});
|
|
142
142
|
}
|
|
143
143
|
const result = callback(fieldArgs);
|
|
144
|
+
if (result === undefined) {
|
|
145
|
+
throw new Error(`Field ${coordinate} returned 'undefined'; perhaps you forgot the 'return' statement?`);
|
|
146
|
+
}
|
|
144
147
|
(0, utils_js_1.assertNotPromise)(result, callback, operationPlan.loc?.join(">") ?? "???");
|
|
145
148
|
if (!explicitlyApplied && result != null) {
|
|
146
149
|
processAfter($parent, fieldArgs, result, args, applyAfterMode, coordinate);
|
|
147
150
|
}
|
|
148
151
|
if (operationPlan.loc !== null)
|
|
149
152
|
operationPlan.loc.pop();
|
|
150
|
-
return
|
|
153
|
+
return result;
|
|
151
154
|
}
|
|
152
155
|
function processAfter($parent, rootFieldArgs, $result, args, applyAfterMode, coordinate) {
|
|
153
156
|
const schema = $parent.operationPlan.schema;
|
|
@@ -158,6 +161,13 @@ function processAfter($parent, rootFieldArgs, $result, args, applyAfterMode, coo
|
|
|
158
161
|
? arg.extensions.grafast?.applySubscribePlan
|
|
159
162
|
: null;
|
|
160
163
|
if (autoApply) {
|
|
164
|
+
if (arg.defaultValue === undefined) {
|
|
165
|
+
const $argVal = rootFieldArgs.getRaw(argName);
|
|
166
|
+
if ($argVal instanceof index_js_1.ConstantStep && $argVal.data === undefined) {
|
|
167
|
+
// no action necessary
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
161
171
|
// TODO: should this have dollars on it for accessing subkeys?
|
|
162
172
|
const input = {
|
|
163
173
|
typeAt(path) {
|
|
@@ -12,6 +12,7 @@ export interface GrafastPlanStepJSONv1 {
|
|
|
12
12
|
dependencyIds: ReadonlyArray<string | number>;
|
|
13
13
|
dependencyForbiddenFlags: ReadonlyArray<ExecutionEntryFlags>;
|
|
14
14
|
dependencyOnReject: ReadonlyArray<string | null | undefined>;
|
|
15
|
+
dependencyDataOnly: ReadonlyArray<boolean>;
|
|
15
16
|
polymorphicPaths: readonly string[] | undefined;
|
|
16
17
|
isSyncAndSafe: boolean | undefined;
|
|
17
18
|
supportsUnbatched: boolean | undefined;
|
|
@@ -25,7 +26,7 @@ export interface GrafastPlanBucketPhaseJSONv1 {
|
|
|
25
26
|
normalStepIds?: ReadonlyArray<string | number>;
|
|
26
27
|
unbatchedStepIds?: ReadonlyArray<string | number>;
|
|
27
28
|
}
|
|
28
|
-
export type GrafastPlanBucketReasonJSONv1 = GrafastPlanBucketReasonRootJSONv1 | GrafastPlanBucketReasonNullableFieldJSONv1 | GrafastPlanBucketReasonListItemJSONv1 | GrafastPlanBucketReasonSubscriptionJSONv1 | GrafastPlanBucketReasonMutationFieldJSONv1 | GrafastPlanBucketReasonDeferJSONv1 | GrafastPlanBucketReasonPolymorphicJSONv1 | GrafastPlanBucketReasonSubroutineJSONv1;
|
|
29
|
+
export type GrafastPlanBucketReasonJSONv1 = GrafastPlanBucketReasonRootJSONv1 | GrafastPlanBucketReasonNullableFieldJSONv1 | GrafastPlanBucketReasonListItemJSONv1 | GrafastPlanBucketReasonSubscriptionJSONv1 | GrafastPlanBucketReasonMutationFieldJSONv1 | GrafastPlanBucketReasonDeferJSONv1 | GrafastPlanBucketReasonPolymorphicJSONv1 | GrafastPlanBucketReasonPolymorphicPartitionJSONv1 | GrafastPlanBucketReasonCombinedJSONv1 | GrafastPlanBucketReasonSubroutineJSONv1;
|
|
29
30
|
export interface GrafastPlanBucketReasonRootJSONv1 {
|
|
30
31
|
type: "root";
|
|
31
32
|
}
|
|
@@ -59,31 +60,49 @@ export interface GrafastPlanBucketReasonDeferJSONv1 {
|
|
|
59
60
|
type: "defer";
|
|
60
61
|
label?: string;
|
|
61
62
|
}
|
|
62
|
-
/**
|
|
63
|
+
/** Non-branching, non-deferred */
|
|
63
64
|
export interface GrafastPlanBucketReasonPolymorphicJSONv1 {
|
|
64
65
|
type: "polymorphic";
|
|
65
66
|
typeNames: readonly string[];
|
|
66
67
|
parentStepId: string | number;
|
|
67
68
|
polymorphicPaths: ReadonlyArray<string>;
|
|
68
69
|
}
|
|
70
|
+
/** Branching, non-deferred */
|
|
71
|
+
export interface GrafastPlanBucketReasonPolymorphicPartitionJSONv1 {
|
|
72
|
+
type: "polymorphicPartition";
|
|
73
|
+
typeNames: readonly string[];
|
|
74
|
+
polymorphicPaths: ReadonlyArray<string>;
|
|
75
|
+
}
|
|
69
76
|
/** Non-branching, non-deferred */
|
|
70
77
|
export interface GrafastPlanBucketReasonSubroutineJSONv1 {
|
|
71
78
|
type: "subroutine";
|
|
72
79
|
parentStepId: string | number;
|
|
73
80
|
}
|
|
81
|
+
/** Anti-branching, non-deferred */
|
|
82
|
+
export interface GrafastPlanBucketReasonCombinedJSONv1 {
|
|
83
|
+
type: "combined";
|
|
84
|
+
parentLayerPlanIds: ReadonlyArray<string | number>;
|
|
85
|
+
combinations: ReadonlyArray<{
|
|
86
|
+
sources: readonly {
|
|
87
|
+
layerPlanId: string | number;
|
|
88
|
+
stepId: string | number;
|
|
89
|
+
}[];
|
|
90
|
+
targetStepId: number;
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
74
93
|
export interface GrafastPlanBucketJSONv1 {
|
|
75
|
-
id: number;
|
|
94
|
+
id: number | string;
|
|
76
95
|
reason: GrafastPlanBucketReasonJSONv1;
|
|
77
96
|
parentSideEffectStepId: string | number | null;
|
|
78
97
|
copyStepIds: ReadonlyArray<string | number>;
|
|
79
98
|
steps: ReadonlyArray<GrafastPlanStepJSONv1>;
|
|
80
99
|
rootStepId: string | number | null;
|
|
81
100
|
phases: ReadonlyArray<GrafastPlanBucketPhaseJSONv1>;
|
|
82
|
-
|
|
101
|
+
childIds: ReadonlyArray<number | string>;
|
|
83
102
|
}
|
|
84
103
|
export interface GrafastPlanJSONv1 extends GrafastPlanJSON {
|
|
85
104
|
version: "v1";
|
|
86
|
-
|
|
105
|
+
buckets: ReadonlyArray<GrafastPlanBucketJSONv1>;
|
|
87
106
|
}
|
|
88
107
|
export type JSONValue = boolean | number | string | null | JSONObject | JSONArray;
|
|
89
108
|
export interface JSONObject {
|
package/dist/prepare.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import type { GrafastPlanJSON } from "./index.js";
|
|
2
1
|
import type { GrafastTimeouts } from "./interfaces.js";
|
|
3
|
-
|
|
4
|
-
export interface GrafastPrepareOptions {
|
|
2
|
+
export interface GrafastOperationOptions {
|
|
5
3
|
/**
|
|
6
4
|
* A list of 'explain' types that should be included in `extensions.explain`.
|
|
7
5
|
*
|
|
@@ -18,11 +16,20 @@ export interface GrafastPrepareOptions {
|
|
|
18
16
|
*/
|
|
19
17
|
outputDataAsString?: boolean;
|
|
20
18
|
timeouts?: GrafastTimeouts;
|
|
19
|
+
/**
|
|
20
|
+
* How many planning layers deep do we allow? Should be handled by validation.
|
|
21
|
+
*
|
|
22
|
+
* A planning layer can happen due to:
|
|
23
|
+
*
|
|
24
|
+
* - A nested selection set
|
|
25
|
+
* - Planning a field return type
|
|
26
|
+
* - A list position
|
|
27
|
+
* - A polymorphic type
|
|
28
|
+
* - A deferred/streamed response
|
|
29
|
+
*
|
|
30
|
+
* These reasons may each cause 1, 2 or 3 planning layers to be added, so this
|
|
31
|
+
* limit should be set quite high - e.g. 6x the selection set depth.
|
|
32
|
+
*/
|
|
33
|
+
maxPlanningDepth?: number;
|
|
21
34
|
}
|
|
22
|
-
declare module "./engine/OperationPlan.js" {
|
|
23
|
-
interface OperationPlan {
|
|
24
|
-
[$$contextPlanCache]?: GrafastPlanJSON;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export {};
|
|
28
35
|
//# sourceMappingURL=prepare.d.ts.map
|