Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incremental publisher should handle all response building #3930

Merged
merged 1 commit into from
Aug 18, 2023

Conversation

yaacovCR
Copy link
Contributor

@yaacovCR yaacovCR commented Jul 3, 2023

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
Copy link

netlify bot commented Jul 3, 2023

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
Copy link

github-actions bot commented Jul 3, 2023

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
21 checks passed
@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.

None yet

2 participants