* @param executionResult The complete execution result object which will be * mutated by merging the contents of the incremental result. * @param incrementalResult The incremental result that will be merged into the * complete execution result.
( executionResult: IncrementalResult, incrementalResult: IncrementalResult, )
| 347 | * complete execution result. |
| 348 | */ |
| 349 | function mergeIncrementalResult( |
| 350 | executionResult: IncrementalResult, |
| 351 | incrementalResult: IncrementalResult, |
| 352 | ): void { |
| 353 | let path: ReadonlyArray<string | number> | undefined = [ |
| 354 | 'data', |
| 355 | ...(incrementalResult.path ?? []), |
| 356 | ]; |
| 357 | |
| 358 | for (const result of [executionResult, incrementalResult]) { |
| 359 | if (result.pending) { |
| 360 | let paths = pathsMap.get(executionResult); |
| 361 | if (paths === undefined) { |
| 362 | paths = new Map(); |
| 363 | pathsMap.set(executionResult, paths); |
| 364 | } |
| 365 | |
| 366 | for (const { id, path: pendingPath } of result.pending) { |
| 367 | paths.set(id, ['data', ...pendingPath]); |
| 368 | } |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | const { items } = incrementalResult; |
| 373 | if (items) { |
| 374 | const { id } = incrementalResult; |
| 375 | if (id) { |
| 376 | path = pathsMap.get(executionResult)?.get(id); |
| 377 | if (path === undefined) { |
| 378 | throw new Error('Invalid incremental delivery format.'); |
| 379 | } |
| 380 | |
| 381 | const list = getValue(executionResult, path.join('.')); |
| 382 | list.push(...items); |
| 383 | } else { |
| 384 | path = ['data', ...(incrementalResult.path ?? [])]; |
| 385 | for (const item of items) { |
| 386 | setValue(executionResult, path.join('.'), item); |
| 387 | // Increment the last path segment (the array index) to merge the next item at the next index |
| 388 | // @ts-expect-error -- (path[path.length - 1] as number)++ breaks react compiler |
| 389 | path[path.length - 1]++; |
| 390 | } |
| 391 | } |
| 392 | } |
| 393 | |
| 394 | const { data } = incrementalResult; |
| 395 | if (data) { |
| 396 | const { id } = incrementalResult; |
| 397 | if (id) { |
| 398 | path = pathsMap.get(executionResult)?.get(id); |
| 399 | if (path === undefined) { |
| 400 | throw new Error('Invalid incremental delivery format.'); |
| 401 | } |
| 402 | const { subPath } = incrementalResult; |
| 403 | if (subPath !== undefined) { |
| 404 | path = [...path, ...subPath]; |
| 405 | } |
| 406 | } |