@graphitation/supermassive 3.17.2-canary.0 → 3.18.0
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/.eslintcache +1 -1
- package/CHANGELOG.md +17 -1
- package/README.md +25 -0
- package/lib/executeWithSchema.d.ts +1 -1
- package/lib/executeWithSchema.d.ts.map +1 -1
- package/lib/executeWithSchema.js +8 -2
- package/lib/executeWithSchema.js.map +2 -2
- package/lib/executeWithSchema.mjs +8 -2
- package/lib/executeWithSchema.mjs.map +2 -2
- package/lib/executeWithoutSchema.d.ts +4 -0
- package/lib/executeWithoutSchema.d.ts.map +1 -1
- package/lib/executeWithoutSchema.js +153 -22
- package/lib/executeWithoutSchema.js.map +2 -2
- package/lib/executeWithoutSchema.mjs +153 -22
- package/lib/executeWithoutSchema.mjs.map +2 -2
- package/lib/jsutils/getObjectAtPath.d.ts +8 -0
- package/lib/jsutils/getObjectAtPath.d.ts.map +1 -0
- package/lib/jsutils/getObjectAtPath.js +34 -0
- package/lib/jsutils/getObjectAtPath.js.map +7 -0
- package/lib/jsutils/getObjectAtPath.mjs +15 -0
- package/lib/jsutils/getObjectAtPath.mjs.map +7 -0
- package/lib/types.d.ts +3 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
collectSubfields as _collectSubfields
|
|
10
10
|
} from "./collectFields.mjs";
|
|
11
11
|
import { devAssert } from "./jsutils/devAssert.mjs";
|
|
12
|
+
import { getObjectAtPath } from "./jsutils/getObjectAtPath.mjs";
|
|
12
13
|
import { inspect } from "./jsutils/inspect.mjs";
|
|
13
14
|
import { invariant } from "./jsutils/invariant.mjs";
|
|
14
15
|
import { isIterableObject } from "./jsutils/isIterableObject.mjs";
|
|
@@ -69,7 +70,10 @@ function buildExecutionContext(args) {
|
|
|
69
70
|
typeResolver,
|
|
70
71
|
subscribeFieldResolver,
|
|
71
72
|
fieldExecutionHooks,
|
|
72
|
-
enablePerEventContext
|
|
73
|
+
enablePerEventContext,
|
|
74
|
+
enableEarlyExecution,
|
|
75
|
+
enableDeferredMerge,
|
|
76
|
+
incrementalPayloadBatchingTimeoutMs
|
|
73
77
|
} = args;
|
|
74
78
|
assertValidExecutionArguments(document, variableValues);
|
|
75
79
|
let operation;
|
|
@@ -127,7 +131,10 @@ function buildExecutionContext(args) {
|
|
|
127
131
|
errors: [],
|
|
128
132
|
fieldExecutionHooks,
|
|
129
133
|
subsequentPayloads: /* @__PURE__ */ new Set(),
|
|
130
|
-
enablePerEventContext: enablePerEventContext != null ? enablePerEventContext : true
|
|
134
|
+
enablePerEventContext: enablePerEventContext != null ? enablePerEventContext : true,
|
|
135
|
+
enableEarlyExecution: enableEarlyExecution != null ? enableEarlyExecution : false,
|
|
136
|
+
enableDeferredMerge: enableDeferredMerge != null ? enableDeferredMerge : false,
|
|
137
|
+
incrementalPayloadBatchingTimeoutMs
|
|
131
138
|
};
|
|
132
139
|
}
|
|
133
140
|
function buildPerEventExecutionContext(exeContext, payload) {
|
|
@@ -176,7 +183,8 @@ function executeOperation(exeContext) {
|
|
|
176
183
|
rootValue,
|
|
177
184
|
path,
|
|
178
185
|
groupedFieldSet,
|
|
179
|
-
void 0
|
|
186
|
+
void 0,
|
|
187
|
+
exeContext.enableEarlyExecution ? patches : void 0
|
|
180
188
|
);
|
|
181
189
|
result = buildResponse(exeContext, result);
|
|
182
190
|
break;
|
|
@@ -186,7 +194,8 @@ function executeOperation(exeContext) {
|
|
|
186
194
|
rootTypeName,
|
|
187
195
|
rootValue,
|
|
188
196
|
path,
|
|
189
|
-
groupedFieldSet
|
|
197
|
+
groupedFieldSet,
|
|
198
|
+
exeContext.enableEarlyExecution ? patches : void 0
|
|
190
199
|
);
|
|
191
200
|
result = buildResponse(exeContext, result);
|
|
192
201
|
break;
|
|
@@ -207,16 +216,18 @@ function executeOperation(exeContext) {
|
|
|
207
216
|
`Operation "${operation.operation}" is not a part of GraphQL spec`
|
|
208
217
|
);
|
|
209
218
|
}
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
219
|
+
if (!exeContext.enableEarlyExecution) {
|
|
220
|
+
for (const patch of patches) {
|
|
221
|
+
const { label, groupedFieldSet: patchGroupedFieldSet } = patch;
|
|
222
|
+
executeDeferredFragment(
|
|
223
|
+
exeContext,
|
|
224
|
+
rootTypeName,
|
|
225
|
+
rootValue,
|
|
226
|
+
patchGroupedFieldSet,
|
|
227
|
+
label,
|
|
228
|
+
path
|
|
229
|
+
);
|
|
230
|
+
}
|
|
220
231
|
}
|
|
221
232
|
return result;
|
|
222
233
|
} catch (error) {
|
|
@@ -224,7 +235,7 @@ function executeOperation(exeContext) {
|
|
|
224
235
|
return buildResponse(exeContext, null);
|
|
225
236
|
}
|
|
226
237
|
}
|
|
227
|
-
function buildResponse(exeContext, data) {
|
|
238
|
+
function buildResponse(exeContext, data, deferredMergeAwaited = false) {
|
|
228
239
|
var _a, _b;
|
|
229
240
|
if (isPromise(data)) {
|
|
230
241
|
return data.then(
|
|
@@ -237,6 +248,16 @@ function buildResponse(exeContext, data) {
|
|
|
237
248
|
}
|
|
238
249
|
const hooks = exeContext.fieldExecutionHooks;
|
|
239
250
|
try {
|
|
251
|
+
if (exeContext.enableDeferredMerge && data !== null) {
|
|
252
|
+
const pendingDeferredFragments = includeCompletedDeferredFragmentsInResult(exeContext, data);
|
|
253
|
+
const batchTimeout = exeContext.incrementalPayloadBatchingTimeoutMs;
|
|
254
|
+
if (typeof batchTimeout === "number" && !deferredMergeAwaited && pendingDeferredFragments.length > 0) {
|
|
255
|
+
return raceIncrementalPayloadBatch(
|
|
256
|
+
pendingDeferredFragments,
|
|
257
|
+
batchTimeout
|
|
258
|
+
).then(() => buildResponse(exeContext, data, true));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
240
261
|
const initialResult = exeContext.errors.length === 0 ? { data } : { errors: exeContext.errors, data };
|
|
241
262
|
if (exeContext.subsequentPayloads.size > 0) {
|
|
242
263
|
return {
|
|
@@ -266,7 +287,17 @@ function buildResponse(exeContext, data) {
|
|
|
266
287
|
return buildResponse(exeContext, null);
|
|
267
288
|
}
|
|
268
289
|
}
|
|
269
|
-
function executeFieldsSerially(exeContext, parentTypeName, sourceValue, path, groupedFieldSet) {
|
|
290
|
+
function executeFieldsSerially(exeContext, parentTypeName, sourceValue, path, groupedFieldSet, patches) {
|
|
291
|
+
if (exeContext.enableEarlyExecution) {
|
|
292
|
+
startExecutingPatches(
|
|
293
|
+
exeContext,
|
|
294
|
+
parentTypeName,
|
|
295
|
+
sourceValue,
|
|
296
|
+
path,
|
|
297
|
+
patches,
|
|
298
|
+
void 0
|
|
299
|
+
);
|
|
300
|
+
}
|
|
270
301
|
return promiseReduce(
|
|
271
302
|
groupedFieldSet,
|
|
272
303
|
(results, [responseName, fieldGroup]) => {
|
|
@@ -297,9 +328,19 @@ function executeFieldsSerially(exeContext, parentTypeName, sourceValue, path, gr
|
|
|
297
328
|
/* @__PURE__ */ Object.create(null)
|
|
298
329
|
);
|
|
299
330
|
}
|
|
300
|
-
function executeFields(exeContext, parentTypeName, sourceValue, path, groupedFieldSet, incrementalDataRecord) {
|
|
331
|
+
function executeFields(exeContext, parentTypeName, sourceValue, path, groupedFieldSet, incrementalDataRecord, patches) {
|
|
301
332
|
const results = /* @__PURE__ */ Object.create(null);
|
|
302
333
|
let containsPromise = false;
|
|
334
|
+
if (exeContext.enableEarlyExecution) {
|
|
335
|
+
startExecutingPatches(
|
|
336
|
+
exeContext,
|
|
337
|
+
parentTypeName,
|
|
338
|
+
sourceValue,
|
|
339
|
+
path,
|
|
340
|
+
patches,
|
|
341
|
+
incrementalDataRecord
|
|
342
|
+
);
|
|
343
|
+
}
|
|
303
344
|
try {
|
|
304
345
|
for (const [responseName, fieldGroup] of groupedFieldSet) {
|
|
305
346
|
const fieldPath = addPath(path, responseName, parentTypeName);
|
|
@@ -331,6 +372,46 @@ function executeFields(exeContext, parentTypeName, sourceValue, path, groupedFie
|
|
|
331
372
|
}
|
|
332
373
|
return promiseForObject(results);
|
|
333
374
|
}
|
|
375
|
+
function startExecutingPatches(exeContext, parentTypeName, sourceValue, path, patches, incrementalDataRecord) {
|
|
376
|
+
if (!patches) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
for (const { label, groupedFieldSet: patchGroupedFieldSet } of patches) {
|
|
380
|
+
executeDeferredFragment(
|
|
381
|
+
exeContext,
|
|
382
|
+
parentTypeName,
|
|
383
|
+
sourceValue,
|
|
384
|
+
patchGroupedFieldSet,
|
|
385
|
+
label,
|
|
386
|
+
path,
|
|
387
|
+
incrementalDataRecord
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function includeCompletedDeferredFragmentsInResult(exeContext, result) {
|
|
392
|
+
const pendingDeferredFragments = [];
|
|
393
|
+
for (const incrementalDataRecord of exeContext.subsequentPayloads) {
|
|
394
|
+
if (!isDeferredFragmentRecord(incrementalDataRecord)) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (!incrementalDataRecord.isCompleted) {
|
|
398
|
+
pendingDeferredFragments.push(incrementalDataRecord.promise);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
const target = getObjectAtPath(result, incrementalDataRecord.path);
|
|
402
|
+
if (!target) {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
if (incrementalDataRecord.data != null) {
|
|
406
|
+
Object.assign(target, incrementalDataRecord.data);
|
|
407
|
+
}
|
|
408
|
+
if (incrementalDataRecord.errors.length > 0) {
|
|
409
|
+
exeContext.errors.push(...incrementalDataRecord.errors);
|
|
410
|
+
}
|
|
411
|
+
exeContext.subsequentPayloads.delete(incrementalDataRecord);
|
|
412
|
+
}
|
|
413
|
+
return pendingDeferredFragments;
|
|
414
|
+
}
|
|
334
415
|
function executeField(exeContext, parentTypeName, source, fieldGroup, path, incrementalDataRecord) {
|
|
335
416
|
const schemaFragment = exeContext.schemaFragment;
|
|
336
417
|
const fieldName = fieldGroup[0].name.value;
|
|
@@ -1308,6 +1389,17 @@ function completeObjectValue(exeContext, returnTypeName, fieldGroup, path, resul
|
|
|
1308
1389
|
}
|
|
1309
1390
|
function collectAndExecuteSubfields(exeContext, returnTypeName, fieldGroup, path, result, incrementalDataRecord) {
|
|
1310
1391
|
const { groupedFieldSet: subGroupedFieldSet, patches: subPatches } = collectSubfields(exeContext, { name: returnTypeName }, fieldGroup);
|
|
1392
|
+
if (exeContext.enableEarlyExecution) {
|
|
1393
|
+
return executeFields(
|
|
1394
|
+
exeContext,
|
|
1395
|
+
returnTypeName,
|
|
1396
|
+
result,
|
|
1397
|
+
path,
|
|
1398
|
+
subGroupedFieldSet,
|
|
1399
|
+
incrementalDataRecord,
|
|
1400
|
+
subPatches
|
|
1401
|
+
);
|
|
1402
|
+
}
|
|
1311
1403
|
const subFields = executeFields(
|
|
1312
1404
|
exeContext,
|
|
1313
1405
|
returnTypeName,
|
|
@@ -1926,6 +2018,34 @@ function getCompletedIncrementalResults(exeContext) {
|
|
|
1926
2018
|
}
|
|
1927
2019
|
return incrementalResults;
|
|
1928
2020
|
}
|
|
2021
|
+
async function getCompletedIncrementalResultsWithBatching(exeContext, batchTimeout) {
|
|
2022
|
+
const incremental = getCompletedIncrementalResults(exeContext);
|
|
2023
|
+
if (incremental.length && exeContext.subsequentPayloads.size > 0) {
|
|
2024
|
+
await raceIncrementalPayloadBatch(
|
|
2025
|
+
Array.from(exeContext.subsequentPayloads).map((p) => p.promise),
|
|
2026
|
+
batchTimeout
|
|
2027
|
+
);
|
|
2028
|
+
incremental.push(...getCompletedIncrementalResults(exeContext));
|
|
2029
|
+
}
|
|
2030
|
+
return incremental;
|
|
2031
|
+
}
|
|
2032
|
+
function raceIncrementalPayloadBatch(promises, batchTimeout) {
|
|
2033
|
+
if (!Number.isFinite(batchTimeout) || batchTimeout <= 0) {
|
|
2034
|
+
return Promise.resolve();
|
|
2035
|
+
}
|
|
2036
|
+
let timeoutId;
|
|
2037
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
2038
|
+
timeoutId = setTimeout(resolve, batchTimeout);
|
|
2039
|
+
});
|
|
2040
|
+
return Promise.race([
|
|
2041
|
+
Promise.all(promises).then(() => void 0),
|
|
2042
|
+
timeoutPromise
|
|
2043
|
+
]).finally(() => {
|
|
2044
|
+
if (timeoutId !== void 0) {
|
|
2045
|
+
clearTimeout(timeoutId);
|
|
2046
|
+
}
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
1929
2049
|
function yieldSubsequentPayloads(exeContext) {
|
|
1930
2050
|
let isDone = false;
|
|
1931
2051
|
async function next() {
|
|
@@ -1938,7 +2058,11 @@ function yieldSubsequentPayloads(exeContext) {
|
|
|
1938
2058
|
if (isDone) {
|
|
1939
2059
|
return { value: void 0, done: true };
|
|
1940
2060
|
}
|
|
1941
|
-
const
|
|
2061
|
+
const batchTimeout = exeContext.incrementalPayloadBatchingTimeoutMs;
|
|
2062
|
+
const incremental = typeof batchTimeout === "number" ? await getCompletedIncrementalResultsWithBatching(
|
|
2063
|
+
exeContext,
|
|
2064
|
+
batchTimeout
|
|
2065
|
+
) : getCompletedIncrementalResults(exeContext);
|
|
1942
2066
|
const hasNext = exeContext.subsequentPayloads.size > 0;
|
|
1943
2067
|
if (!incremental.length && hasNext) {
|
|
1944
2068
|
return next();
|
|
@@ -1981,6 +2105,9 @@ function yieldSubsequentPayloads(exeContext) {
|
|
|
1981
2105
|
function isStreamItemsRecord(incrementalDataRecord) {
|
|
1982
2106
|
return incrementalDataRecord.type === "stream";
|
|
1983
2107
|
}
|
|
2108
|
+
function isDeferredFragmentRecord(incrementalDataRecord) {
|
|
2109
|
+
return incrementalDataRecord.type === "defer";
|
|
2110
|
+
}
|
|
1984
2111
|
var DeferredFragmentRecord = class {
|
|
1985
2112
|
constructor(opts) {
|
|
1986
2113
|
this.type = "defer";
|
|
@@ -1996,10 +2123,11 @@ var DeferredFragmentRecord = class {
|
|
|
1996
2123
|
this._resolve = (promiseOrValue) => {
|
|
1997
2124
|
resolve(promiseOrValue);
|
|
1998
2125
|
};
|
|
1999
|
-
}).then((data) =>
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2126
|
+
}).then((data) => this.complete(data));
|
|
2127
|
+
}
|
|
2128
|
+
complete(data) {
|
|
2129
|
+
this.data = data;
|
|
2130
|
+
this.isCompleted = true;
|
|
2003
2131
|
}
|
|
2004
2132
|
addData(data) {
|
|
2005
2133
|
var _a, _b, _c;
|
|
@@ -2008,6 +2136,9 @@ var DeferredFragmentRecord = class {
|
|
|
2008
2136
|
(_b = this._resolve) == null ? void 0 : _b.call(this, parentData.then(() => data));
|
|
2009
2137
|
return;
|
|
2010
2138
|
}
|
|
2139
|
+
if (!isPromise(data)) {
|
|
2140
|
+
this.complete(data);
|
|
2141
|
+
}
|
|
2011
2142
|
(_c = this._resolve) == null ? void 0 : _c.call(this, data);
|
|
2012
2143
|
}
|
|
2013
2144
|
};
|