diff --git a/src/execution/IncrementalPublisher.ts b/src/execution/IncrementalPublisher.ts index b7ba6adb94..4b19718152 100644 --- a/src/execution/IncrementalPublisher.ts +++ b/src/execution/IncrementalPublisher.ts @@ -566,7 +566,8 @@ export class IncrementalPublisher { } const incrementalResult: IncrementalStreamResult = { items: subsequentResultRecord.items, - path: subsequentResultRecord.streamRecord.path, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + id: subsequentResultRecord.streamRecord.id!, }; if (subsequentResultRecord.errors.length > 0) { incrementalResult.errors = subsequentResultRecord.errors; @@ -583,11 +584,8 @@ export class IncrementalPublisher { for (const deferredGroupedFieldSetRecord of subsequentResultRecord.deferredGroupedFieldSetRecords) { if (!deferredGroupedFieldSetRecord.sent) { deferredGroupedFieldSetRecord.sent = true; - const incrementalResult: IncrementalDeferResult = { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - data: deferredGroupedFieldSetRecord.data!, - path: deferredGroupedFieldSetRecord.path, - }; + const incrementalResult: IncrementalDeferResult = + this._getIncrementalDeferResult(deferredGroupedFieldSetRecord); if (deferredGroupedFieldSetRecord.errors.length > 0) { incrementalResult.errors = deferredGroupedFieldSetRecord.errors; } @@ -604,6 +602,40 @@ export class IncrementalPublisher { }; } + private _getIncrementalDeferResult( + deferredGroupedFieldSetRecord: DeferredGroupedFieldSetRecord, + ): IncrementalDeferResult { + const { data, deferredFragmentRecords } = deferredGroupedFieldSetRecord; + let maxLength = deferredFragmentRecords[0].path.length; + let maxIndex = 0; + for (let i = 1; i < deferredFragmentRecords.length; i++) { + const deferredFragmentRecord = deferredFragmentRecords[i]; + const length = deferredFragmentRecord.path.length; + if (length > maxLength) { + maxLength = length; + maxIndex = i; + } + } + const recordWithLongestPath = deferredFragmentRecords[maxIndex]; + const longestPath = recordWithLongestPath.path; + const subPath = deferredGroupedFieldSetRecord.path.slice( + longestPath.length, + ); + const id = recordWithLongestPath.id; + const incrementalDeferResult: IncrementalDeferResult = { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + data: data!, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + id: id!, + }; + + if (subPath.length > 0) { + incrementalDeferResult.subPath = subPath; + } + + return incrementalDeferResult; + } + private _completedRecordToResult( completedRecord: DeferredFragmentRecord | StreamRecord, ): CompletedResult { diff --git a/src/execution/__tests__/defer-test.ts b/src/execution/__tests__/defer-test.ts index 158b379335..19a2e1c77f 100644 --- a/src/execution/__tests__/defer-test.ts +++ b/src/execution/__tests__/defer-test.ts @@ -185,7 +185,7 @@ describe('Execute: defer directive', () => { data: { name: 'Luke', }, - path: ['hero'], + id: '0', }, ], completed: [{ id: '0' }], @@ -239,7 +239,7 @@ describe('Execute: defer directive', () => { incremental: [ { data: { name: 'Luke' }, - path: ['hero'], + id: '0', }, ], completed: [{ id: '0' }], @@ -274,7 +274,7 @@ describe('Execute: defer directive', () => { id: '1', }, }, - path: [], + id: '0', }, ], completed: [{ id: '0' }], @@ -323,7 +323,7 @@ describe('Execute: defer directive', () => { path: ['hero', 'name'], }, ], - path: [], + id: '0', }, ], completed: [{ id: '0' }], @@ -367,13 +367,13 @@ describe('Execute: defer directive', () => { data: { id: '1', }, - path: ['hero'], + id: '0', }, { data: { friends: [{ name: 'Han' }, { name: 'Leia' }, { name: 'C-3PO' }], }, - path: ['hero'], + id: '1', }, ], completed: [{ id: '0' }, { id: '1' }], @@ -460,7 +460,7 @@ describe('Execute: defer directive', () => { hasNext: true, }, { - incremental: [{ data: { name: 'Luke' }, path: ['hero'] }], + incremental: [{ data: { name: 'Luke' }, id: '0' }], completed: [{ id: '0' }], hasNext: false, }, @@ -527,13 +527,13 @@ describe('Execute: defer directive', () => { data: { id: '1', }, - path: ['hero'], + id: '0', }, { data: { name: 'Luke', }, - path: ['hero'], + id: '1', }, ], completed: [{ id: '0' }, { id: '1' }], @@ -571,15 +571,17 @@ describe('Execute: defer directive', () => { incremental: [ { data: { hero: {} }, - path: [], + id: '0', }, { data: { id: '1' }, - path: ['hero'], + id: '0', + subPath: ['hero'], }, { data: { name: 'Luke' }, - path: ['hero'], + id: '1', + subPath: ['hero'], }, ], completed: [{ id: '0' }, { id: '1' }], @@ -622,15 +624,17 @@ describe('Execute: defer directive', () => { incremental: [ { data: { hero: {} }, - path: [], + id: '0', }, { data: { id: '1' }, - path: ['hero'], + id: '0', + subPath: ['hero'], }, { data: { name: 'Luke' }, - path: ['hero'], + id: '1', + subPath: ['hero'], }, ], completed: [{ id: '0' }, { id: '1' }], @@ -672,13 +676,14 @@ describe('Execute: defer directive', () => { data: { id: '1', }, - path: ['hero'], + id: '1', }, { data: { name: 'Luke', }, - path: ['hero'], + id: '0', + subPath: ['hero'], }, ], completed: [{ id: '1' }, { id: '0' }], @@ -716,7 +721,7 @@ describe('Execute: defer directive', () => { name: 'Luke', }, }, - path: [], + id: '0', }, ], completed: [{ id: '0' }], @@ -728,7 +733,7 @@ describe('Execute: defer directive', () => { data: { id: '1', }, - path: ['hero'], + id: '1', }, ], completed: [{ id: '1' }], @@ -786,9 +791,9 @@ describe('Execute: defer directive', () => { }, { incremental: [ - { data: { id: '2', name: 'Han' }, path: ['hero', 'friends', 0] }, - { data: { id: '3', name: 'Leia' }, path: ['hero', 'friends', 1] }, - { data: { id: '4', name: 'C-3PO' }, path: ['hero', 'friends', 2] }, + { data: { id: '2', name: 'Han' }, id: '0' }, + { data: { id: '3', name: 'Leia' }, id: '4' }, + { data: { id: '4', name: 'C-3PO' }, id: '8' }, ], completed: [ { id: '1' }, @@ -867,7 +872,8 @@ describe('Execute: defer directive', () => { incremental: [ { data: { bar: 'bar' }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '0', + subPath: ['nestedObject', 'deeperObject'], }, ], completed: [{ id: '0' }], @@ -914,7 +920,7 @@ describe('Execute: defer directive', () => { deeperObject: { foo: 'foo' }, }, }, - path: ['hero'], + id: '0', }, ], completed: [{ id: '0' }], @@ -926,7 +932,7 @@ describe('Execute: defer directive', () => { data: { bar: 'bar', }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '1', }, ], completed: [{ id: '1' }], @@ -994,7 +1000,8 @@ describe('Execute: defer directive', () => { incremental: [ { data: { bar: 'bar' }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '0', + subPath: ['nestedObject', 'deeperObject'], }, ], completed: [{ id: '0' }], @@ -1005,7 +1012,8 @@ describe('Execute: defer directive', () => { incremental: [ { data: { baz: 'baz' }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '1', + subPath: ['deeperObject'], }, ], hasNext: true, @@ -1015,7 +1023,7 @@ describe('Execute: defer directive', () => { incremental: [ { data: { bak: 'bak' }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '2', }, ], completed: [{ id: '2' }], @@ -1073,7 +1081,7 @@ describe('Execute: defer directive', () => { data: { foo: 'foo', }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '1', }, ], completed: [{ id: '0' }, { id: '1' }], @@ -1085,7 +1093,7 @@ describe('Execute: defer directive', () => { data: { bar: 'bar', }, - path: ['hero', 'nestedObject', 'deeperObject'], + id: '2', }, ], completed: [{ id: '2' }], @@ -1153,11 +1161,11 @@ describe('Execute: defer directive', () => { incremental: [ { data: { e: { f: 'f' } }, - path: ['a', 'b'], + id: '1', }, { data: { g: { h: 'h' } }, - path: [], + id: '0', }, ], completed: [{ id: '1' }, { id: '0' }], @@ -1208,11 +1216,12 @@ describe('Execute: defer directive', () => { incremental: [ { data: { b: { c: {} } }, - path: ['a'], + id: '1', }, { data: { d: 'd' }, - path: ['a', 'b', 'c'], + id: '1', + subPath: ['b', 'c'], }, ], completed: [ @@ -1279,11 +1288,12 @@ describe('Execute: defer directive', () => { incremental: [ { data: { b: { c: {} } }, - path: ['a'], + id: '1', }, { data: { d: 'd' }, - path: ['a', 'b', 'c'], + id: '0', + subPath: ['a', 'b', 'c'], }, ], completed: [ @@ -1358,11 +1368,12 @@ describe('Execute: defer directive', () => { incremental: [ { data: { b: { c: {} } }, - path: ['a'], + id: '1', }, { data: { d: 'd' }, - path: ['a', 'b', 'c'], + id: '1', + subPath: ['b', 'c'], }, ], completed: [{ id: '1' }], @@ -1458,7 +1469,7 @@ describe('Execute: defer directive', () => { path: ['hero', 'nonNullName'], }, ], - path: [], + id: '0', }, ], completed: [{ id: '0' }], @@ -1603,15 +1614,18 @@ describe('Execute: defer directive', () => { incremental: [ { data: { id: '2' }, - path: ['hero', 'friends', 0], + id: '0', + subPath: ['friends', 0], }, { data: { id: '3' }, - path: ['hero', 'friends', 1], + id: '0', + subPath: ['friends', 1], }, { data: { id: '4' }, - path: ['hero', 'friends', 2], + id: '0', + subPath: ['friends', 2], }, ], completed: [{ id: '0' }], @@ -1751,7 +1765,7 @@ describe('Execute: defer directive', () => { incremental: [ { data: { name: null }, - path: ['hero'], + id: '0', errors: [ { message: 'bad', @@ -1931,7 +1945,7 @@ describe('Execute: defer directive', () => { incremental: [ { data: { name: 'slow', friends: [{}, {}, {}] }, - path: ['hero'], + id: '0', }, ], completed: [{ id: '0' }], @@ -1939,9 +1953,9 @@ describe('Execute: defer directive', () => { }, { incremental: [ - { data: { name: 'Han' }, path: ['hero', 'friends', 0] }, - { data: { name: 'Leia' }, path: ['hero', 'friends', 1] }, - { data: { name: 'C-3PO' }, path: ['hero', 'friends', 2] }, + { data: { name: 'Han' }, id: '1' }, + { data: { name: 'Leia' }, id: '2' }, + { data: { name: 'C-3PO' }, id: '3' }, ], completed: [{ id: '1' }, { id: '2' }, { id: '3' }], hasNext: false, @@ -1987,7 +2001,7 @@ describe('Execute: defer directive', () => { name: 'Luke', friends: [{}, {}, {}], }, - path: ['hero'], + id: '0', }, ], completed: [{ id: '0' }], @@ -1995,9 +2009,9 @@ describe('Execute: defer directive', () => { }, { incremental: [ - { data: { name: 'Han' }, path: ['hero', 'friends', 0] }, - { data: { name: 'Leia' }, path: ['hero', 'friends', 1] }, - { data: { name: 'C-3PO' }, path: ['hero', 'friends', 2] }, + { data: { name: 'Han' }, id: '1' }, + { data: { name: 'Leia' }, id: '2' }, + { data: { name: 'C-3PO' }, id: '3' }, ], completed: [{ id: '1' }, { id: '2' }, { id: '3' }], hasNext: false, diff --git a/src/execution/__tests__/mutations-test.ts b/src/execution/__tests__/mutations-test.ts index 8589ef29f3..5697bf5250 100644 --- a/src/execution/__tests__/mutations-test.ts +++ b/src/execution/__tests__/mutations-test.ts @@ -243,7 +243,7 @@ describe('Execute: Handles mutation execution ordering', () => { { incremental: [ { - path: ['first'], + id: '0', data: { promiseToGetTheNumber: 2, }, @@ -319,7 +319,7 @@ describe('Execute: Handles mutation execution ordering', () => { { incremental: [ { - path: [], + id: '0', data: { first: { theNumber: 1, diff --git a/src/execution/__tests__/stream-test.ts b/src/execution/__tests__/stream-test.ts index 3691ce38f1..77fd5ce9e9 100644 --- a/src/execution/__tests__/stream-test.ts +++ b/src/execution/__tests__/stream-test.ts @@ -146,11 +146,11 @@ describe('Execute: stream directive', () => { hasNext: true, }, { - incremental: [{ items: ['banana'], path: ['scalarList'] }], + incremental: [{ items: ['banana'], id: '0' }], hasNext: true, }, { - incremental: [{ items: ['coconut'], path: ['scalarList'] }], + incremental: [{ items: ['coconut'], id: '0' }], completed: [{ id: '0' }], hasNext: false, }, @@ -170,15 +170,15 @@ describe('Execute: stream directive', () => { hasNext: true, }, { - incremental: [{ items: ['apple'], path: ['scalarList'] }], + incremental: [{ items: ['apple'], id: '0' }], hasNext: true, }, { - incremental: [{ items: ['banana'], path: ['scalarList'] }], + incremental: [{ items: ['banana'], id: '0' }], hasNext: true, }, { - incremental: [{ items: ['coconut'], path: ['scalarList'] }], + incremental: [{ items: ['coconut'], id: '0' }], completed: [{ id: '0' }], hasNext: false, }, @@ -226,7 +226,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: ['banana'], - path: ['scalarList'], + id: '0', }, ], hasNext: true, @@ -235,7 +235,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: ['coconut'], - path: ['scalarList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -268,7 +268,7 @@ describe('Execute: stream directive', () => { hasNext: true, }, { - incremental: [{ items: ['coconut'], path: ['scalarList'] }], + incremental: [{ items: ['coconut'], id: '0' }], completed: [{ id: '0' }], hasNext: false, }, @@ -295,7 +295,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [['banana', 'banana', 'banana']], - path: ['scalarListList'], + id: '0', }, ], hasNext: true, @@ -304,7 +304,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [['coconut', 'coconut', 'coconut']], - path: ['scalarListList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -350,7 +350,7 @@ describe('Execute: stream directive', () => { id: '3', }, ], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -382,7 +382,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Luke', id: '1' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -391,7 +391,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Han', id: '2' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -400,7 +400,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -450,7 +450,7 @@ describe('Execute: stream directive', () => { id: '3', }, ], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -495,7 +495,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -533,7 +533,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['friendList'], + id: '0', errors: [ { message: 'bad', @@ -549,7 +549,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -585,7 +585,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Luke', id: '1' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -594,7 +594,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Han', id: '2' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -603,7 +603,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -645,7 +645,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -718,7 +718,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Leia', id: '3' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -908,7 +908,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['scalarList'], + id: '0', errors: [ { message: 'String cannot represent value: {}', @@ -952,7 +952,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['friendList'], + id: '0', errors: [ { message: 'Oops', @@ -968,7 +968,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ nonNullName: 'Han' }], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -1003,7 +1003,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['friendList'], + id: '0', errors: [ { message: 'Oops', @@ -1019,7 +1019,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ nonNullName: 'Han' }], - path: ['friendList'], + id: '0', }, ], completed: [{ id: '0' }], @@ -1138,7 +1138,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['friendList'], + id: '0', errors: [ { message: 'Oops', @@ -1154,7 +1154,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ nonNullName: 'Han' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -1461,7 +1461,7 @@ describe('Execute: stream directive', () => { incremental: [ { data: { scalarField: null }, - path: ['otherNestedObject'], + id: '0', errors: [ { message: 'Oops', @@ -1472,7 +1472,7 @@ describe('Execute: stream directive', () => { }, { items: [{ name: 'Luke' }], - path: ['nestedObject', 'nestedFriendList'], + id: '1', }, ], completed: [{ id: '0' }], @@ -1523,7 +1523,7 @@ describe('Execute: stream directive', () => { data: { deeperNestedObject: null, }, - path: ['nestedObject'], + id: '0', errors: [ { message: @@ -1574,7 +1574,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [null], - path: ['friendList'], + id: '0', errors: [ { message: @@ -1671,7 +1671,7 @@ describe('Execute: stream directive', () => { data: { deeperNestedObject: null, }, - path: ['nestedObject'], + id: '0', errors: [ { message: @@ -1727,7 +1727,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ id: '2', name: 'Han' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -1736,7 +1736,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ id: '3', name: 'Leia' }], - path: ['friendList'], + id: '0', }, ], hasNext: true, @@ -1790,7 +1790,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ id: '1', name: 'Luke' }], - path: ['nestedObject', 'nestedFriendList'], + id: '1', }, ], completed: [{ id: '0' }], @@ -1800,7 +1800,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ id: '2', name: 'Han' }], - path: ['nestedObject', 'nestedFriendList'], + id: '1', }, ], hasNext: true, @@ -1861,7 +1861,7 @@ describe('Execute: stream directive', () => { incremental: [ { data: { scalarField: 'slow', nestedFriendList: [] }, - path: ['nestedObject'], + id: '0', }, ], completed: [{ id: '0' }], @@ -1875,7 +1875,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Luke' }], - path: ['nestedObject', 'nestedFriendList'], + id: '1', }, ], hasNext: true, @@ -1888,7 +1888,7 @@ describe('Execute: stream directive', () => { incremental: [ { items: [{ name: 'Han' }], - path: ['nestedObject', 'nestedFriendList'], + id: '1', }, ], hasNext: true, @@ -1967,11 +1967,11 @@ describe('Execute: stream directive', () => { incremental: [ { data: { name: 'Luke' }, - path: ['friendList', 0], + id: '0', }, { items: [{ id: '2' }], - path: ['friendList'], + id: '1', }, ], completed: [{ id: '0' }], @@ -1996,7 +1996,7 @@ describe('Execute: stream directive', () => { incremental: [ { data: { name: 'Han' }, - path: ['friendList', 1], + id: '2', }, ], completed: [{ id: '2' }], @@ -2068,11 +2068,11 @@ describe('Execute: stream directive', () => { incremental: [ { data: { name: 'Luke' }, - path: ['friendList', 0], + id: '0', }, { items: [{ id: '2' }], - path: ['friendList'], + id: '1', }, ], completed: [{ id: '0' }], @@ -2087,7 +2087,7 @@ describe('Execute: stream directive', () => { incremental: [ { data: { name: 'Han' }, - path: ['friendList', 1], + id: '2', }, ], completed: [{ id: '2' }],