Skip to content

incremental publisher should handle all response building - #3930

Merged
yaacovCR merged 1 commit into
graphql:mainfrom
yaacovCR:incremental-publisher-should-build
Aug 18, 2023
Merged

incremental publisher should handle all response building#3930
yaacovCR merged 1 commit into
graphql:mainfrom
yaacovCR:incremental-publisher-should-build

Conversation

@yaacovCR

@yaacovCR yaacovCR commented Jul 3, 2023

Copy link
Copy Markdown
Contributor

extracted from #3929

the publisher itself can determine whether to return a single result or the initial result + stream

the only desired change is to replace the following code block with the below:

FROM:

  const incrementalPublisher = exeContext.incrementalPublisher;
  const initialResultRecord = incrementalPublisher.prepareInitialResultRecord();
  try {
    const result = executeOperation(exeContext, initialResultRecord);
    if (isPromise(result)) {
      return result.then(
        (data) => {
          const errors =
            incrementalPublisher.getInitialErrors(initialResultRecord);
          const initialResult = buildResponse(data, errors);
          incrementalPublisher.publishInitial(initialResultRecord);
          if (incrementalPublisher.hasNext()) {
            return {
              initialResult: {
                ...initialResult,
                hasNext: true,
              },
              subsequentResults: incrementalPublisher.subscribe(),
            };
          }
          return initialResult;
        },
        (error) => {
          incrementalPublisher.addFieldError(initialResultRecord, error);
          const errors =
            incrementalPublisher.getInitialErrors(initialResultRecord);
          return buildResponse(null, errors);
        },
      );
    }
    const initialResult = buildResponse(result, initialResultRecord.errors);
    incrementalPublisher.publishInitial(initialResultRecord);
    if (incrementalPublisher.hasNext()) {
      return {
        initialResult: {
          ...initialResult,
          hasNext: true,
        },
        subsequentResults: incrementalPublisher.subscribe(),
      };
    }
    return initialResult;
  } catch (error) {
    incrementalPublisher.addFieldError(initialResultRecord, error);
    const errors = incrementalPublisher.getInitialErrors(initialResultRecord);
    return buildResponse(null, errors);
  }
}

TO::

  const incrementalPublisher = exeContext.incrementalPublisher;
  const initialResultRecord = incrementalPublisher.prepareInitialResultRecord();
  try {
    const data = executeOperation(exeContext, initialResultRecord);
    if (isPromise(data)) {
      return data.then(
        (resolved) =>
          incrementalPublisher.buildDataResponse(initialResultRecord, resolved),
        (error) =>
          incrementalPublisher.buildErrorResponse(initialResultRecord, error),
      );
    }
    return incrementalPublisher.buildDataResponse(initialResultRecord, data);
  } catch (error) {
    return incrementalPublisher.buildErrorResponse(initialResultRecord, error);
  }

Supporting changes are required:

  1. some existing public methods no longer are required to be public and so are made private (or removed entirely!), with lint rules forcing the reordering of existing methods
  2. to prevent cyclic type dependencies (not strictly necessary, but still!), types are moved from execute.ts to IncrementalPublisher.ts

@netlify

netlify Bot commented Jul 3, 2023

Copy link
Copy Markdown

Deploy Preview for compassionate-pike-271cb3 ready!

Name Link
🔨 Latest commit 598608e
🔍 Latest deploy log https://app.netlify.com/sites/compassionate-pike-271cb3/deploys/64a6212e44ace500081baacd
😎 Deploy Preview https://deploy-preview-3930--compassionate-pike-271cb3.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@github-actions

github-actions Bot commented Jul 3, 2023

Copy link
Copy Markdown

Hi @yaacovCR, I'm @github-actions bot happy to help you with this PR 👋

Supported commands

Please post this commands in separate comments and only one per comment:

  • @github-actions run-benchmark - Run benchmark comparing base and merge commits for this PR
  • @github-actions publish-pr-on-npm - Build package from this PR and publish it on NPM

@yaacovCR
yaacovCR force-pushed the incremental-publisher-should-build branch 5 times, most recently from bcb8ac2 to e70b79f Compare July 6, 2023 01:41
@yaacovCR yaacovCR added the PR: polish 💅 PR doesn't change public API or any observed behaviour label Jul 6, 2023
@yaacovCR
yaacovCR requested a review from robrichard July 6, 2023 01:43
@yaacovCR
yaacovCR force-pushed the incremental-publisher-should-build branch 2 times, most recently from a28be91 to 7ef6ee4 Compare July 6, 2023 02:00
@yaacovCR
yaacovCR merged commit 1f30b54 into graphql:main Aug 18, 2023
@yaacovCR
yaacovCR deleted the incremental-publisher-should-build branch August 18, 2023 01:13
yaacovCR added a commit that referenced this pull request Aug 18, 2023
to minimize later diffs, we can watch how the tests change, rather than
simple introducing tons of new tests

depends on #3930
sakesun pushed a commit to sakesun/graphql-js that referenced this pull request Sep 1, 2023
extracted from graphql#3929

the publisher itself can determine whether to return a single result or
the initial result + stream

the only desired change is to replace the following code block with the
below:


[FROM:](https://github.com/graphql/graphql-js/blob/fae5da500bad94c39a7ecd77a4c4361b58d6d2da/src/execution/execute.ts#L293-L340)

```ts
  const incrementalPublisher = exeContext.incrementalPublisher;
  const initialResultRecord = incrementalPublisher.prepareInitialResultRecord();
  try {
    const result = executeOperation(exeContext, initialResultRecord);
    if (isPromise(result)) {
      return result.then(
        (data) => {
          const errors =
            incrementalPublisher.getInitialErrors(initialResultRecord);
          const initialResult = buildResponse(data, errors);
          incrementalPublisher.publishInitial(initialResultRecord);
          if (incrementalPublisher.hasNext()) {
            return {
              initialResult: {
                ...initialResult,
                hasNext: true,
              },
              subsequentResults: incrementalPublisher.subscribe(),
            };
          }
          return initialResult;
        },
        (error) => {
          incrementalPublisher.addFieldError(initialResultRecord, error);
          const errors =
            incrementalPublisher.getInitialErrors(initialResultRecord);
          return buildResponse(null, errors);
        },
      );
    }
    const initialResult = buildResponse(result, initialResultRecord.errors);
    incrementalPublisher.publishInitial(initialResultRecord);
    if (incrementalPublisher.hasNext()) {
      return {
        initialResult: {
          ...initialResult,
          hasNext: true,
        },
        subsequentResults: incrementalPublisher.subscribe(),
      };
    }
    return initialResult;
  } catch (error) {
    incrementalPublisher.addFieldError(initialResultRecord, error);
    const errors = incrementalPublisher.getInitialErrors(initialResultRecord);
    return buildResponse(null, errors);
  }
}
```


[TO:](https://github.com/yaacovCR/graphql-executor/blob/598608e8d8b23bc527dd73283b477997305afd58/src/execution/execute.ts#L234-L250):

```ts
  const incrementalPublisher = exeContext.incrementalPublisher;
  const initialResultRecord = incrementalPublisher.prepareInitialResultRecord();
  try {
    const data = executeOperation(exeContext, initialResultRecord);
    if (isPromise(data)) {
      return data.then(
        (resolved) =>
          incrementalPublisher.buildDataResponse(initialResultRecord, resolved),
        (error) =>
          incrementalPublisher.buildErrorResponse(initialResultRecord, error),
      );
    }
    return incrementalPublisher.buildDataResponse(initialResultRecord, data);
  } catch (error) {
    return incrementalPublisher.buildErrorResponse(initialResultRecord, error);
  }
```

Supporting changes are required:
1. some existing public methods no longer are required to be public and
so are made private (or removed entirely!), with lint rules forcing the
reordering of existing methods
2. to prevent cyclic type dependencies (not strictly necessary, but
still!), types are moved from `execute.ts` to `IncrementalPublisher.ts`
sakesun pushed a commit to sakesun/graphql-js that referenced this pull request Sep 1, 2023
to minimize later diffs, we can watch how the tests change, rather than
simple introducing tons of new tests

depends on graphql#3930
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: polish 💅 PR doesn't change public API or any observed behaviour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants