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

fix(graphql): add custom logic for reference unions #8350

Merged
merged 3 commits into from
Jan 24, 2025

Conversation

cngonzalez
Copy link
Member

@cngonzalez cngonzalez commented Jan 21, 2025

Description

We discovered a bug where a union-style reference definition that referenced itself (e.g.:

defineType({
  type: 'document',
  name: 'union',
  fields: [
    defineField({
      name: 'body',
      type: 'array',
      of: [
        {
          type: 'reference',
          to: [{type: 'a'}, {type: 'b'}, {type: 'union'}],
        },
        {type: 'a'},
      ],
    }),
  ],
})

would not correctly bail out of the getUnionDefinition recursion and cause a maximum calls exceeded error. This PR better aligns our reference definition logic to what we do with type generation by adding a few lines to code to the getReferenceDefinition function and avoiding the union definition logic altogether.

What to review

  1. The changed code -- any gotchas?
  2. Should we include a references array? I've commented it out for now just because it would make our new snapshots a bit noisy. We've done without this array for quite a while, but it seems nice to have.

Testing

Please review the updated snapshots and make sure all is well.

Notes for release

Fixes an issue where referencing a type of the same kind of document within a document would cause a Maximum call stack size exceeded error during GraphQL schema generation.

@cngonzalez cngonzalez requested a review from a team as a code owner January 21, 2025 17:17
@cngonzalez cngonzalez requested review from juice49 and removed request for a team January 21, 2025 17:17
Copy link

vercel bot commented Jan 21, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
page-building-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 2:55pm
performance-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 2:55pm
test-studio ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 23, 2025 2:55pm
2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
studio-workshop ⬜️ Ignored (Inspect) Visit Preview Jan 23, 2025 2:55pm
test-next-studio ⬜️ Ignored (Inspect) Jan 23, 2025 2:55pm


return {
type: name,
// references: targetTypes,
Copy link
Member Author

@cngonzalez cngonzalez Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to have this comment 😅
Would we like to have this? It seems like what we would like to do, based on the usage in getUnionDefinition, but this implementation adds quite a bit of content to our testing snapshots.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make it "optional"?

const def = {type: name, ...base}
if (targetTypes !== undefined) {
  def.references = targetTypes
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, added now! I realize my previous hesitation wasn't clear -- it seems like we weren't effectively adding this array in getUnionDefinition (although it seems we intended to), so I was worried about adding the 7k extra lines in our snapshots that you see now. I don't know the code well enough to know if this is duplicative, if there are side effects, etc.

Copy link
Contributor

No changes to documentation

Copy link
Contributor

github-actions bot commented Jan 21, 2025

Component Testing Report Updated Jan 23, 2025 2:58 PM (UTC)

❌ Failed Tests (2) -- expand for details
File Status Duration Passed Skipped Failed
comments/CommentInput.spec.tsx ✅ Passed (Inspect) 1m 5s 15 0 0
formBuilder/ArrayInput.spec.tsx ✅ Passed (Inspect) 12s 3 0 0
formBuilder/inputs/PortableText/Annotations.spec.tsx ❌ Failed (Inspect) 1m 20s 5 0 1
formBuilder/inputs/PortableText/copyPaste/CopyPaste.spec.tsx ✅ Passed (Inspect) 51s 11 7 0
formBuilder/inputs/PortableText/copyPaste/CopyPasteFields.spec.tsx ✅ Passed (Inspect) 0s 0 12 0
formBuilder/inputs/PortableText/Decorators.spec.tsx ✅ Passed (Inspect) 25s 6 0 0
formBuilder/inputs/PortableText/DisableFocusAndUnset.spec.tsx ✅ Passed (Inspect) 14s 3 0 0
formBuilder/inputs/PortableText/DragAndDrop.spec.tsx ✅ Passed (Inspect) 26s 6 0 0
formBuilder/inputs/PortableText/FocusTracking.spec.tsx ✅ Passed (Inspect) 1m 6s 15 0 0
formBuilder/inputs/PortableText/Input.spec.tsx ✅ Passed (Inspect) 1m 32s 21 0 0
formBuilder/inputs/PortableText/ObjectBlock.spec.tsx ✅ Passed (Inspect) 2m 2s 21 0 0
formBuilder/inputs/PortableText/PresenceCursors.spec.tsx ✅ Passed (Inspect) 13s 3 9 0
formBuilder/inputs/PortableText/Styles.spec.tsx ✅ Passed (Inspect) 26s 6 0 0
formBuilder/inputs/PortableText/Toolbar.spec.tsx ❌ Failed (Inspect) 2m 23s 20 0 1
formBuilder/tree-editing/TreeEditing.spec.tsx ✅ Passed (Inspect) 0s 0 3 0
formBuilder/tree-editing/TreeEditingNestedObjects.spec.tsx ✅ Passed (Inspect) 0s 0 3 0

Copy link
Contributor

github-actions bot commented Jan 21, 2025

⚡️ Editor Performance Report

Updated Thu, 23 Jan 2025 15:00:21 GMT

Benchmark reference
latency of sanity@latest
experiment
latency of this branch
Δ (%)
latency difference
article (title) 21.3 efps (47ms) 25.6 efps (39ms) -8ms (-17.0%)
article (body) 78.1 efps (13ms) 72.7 efps (14ms) +1ms (-/-%)
article (string inside object) 26.3 efps (38ms) 27.0 efps (37ms) -1ms (-2.6%)
article (string inside array) 22.7 efps (44ms) 23.3 efps (43ms) -1ms (-2.3%)
recipe (name) 50.0 efps (20ms) 47.6 efps (21ms) +1ms (+5.0%)
recipe (description) 55.6 efps (18ms) 52.6 efps (19ms) +1ms (+5.6%)
recipe (instructions) 99.9+ efps (6ms) 99.9+ efps (6ms) +0ms (-/-%)
synthetic (title) 18.5 efps (54ms) 18.9 efps (53ms) -1ms (-1.9%)
synthetic (string inside object) 18.2 efps (55ms) 19.2 efps (52ms) -3ms (-5.5%)

efps — editor "frames per second". The number of updates assumed to be possible within a second.

Derived from input latency. efps = 1000 / input_latency

Detailed information

🏠 Reference result

The performance result of sanity@latest

Benchmark latency p75 p90 p99 blocking time test duration
article (title) 47ms 63ms 75ms 437ms 906ms 11.7s
article (body) 13ms 14ms 19ms 92ms 84ms 5.2s
article (string inside object) 38ms 40ms 45ms 167ms 170ms 6.7s
article (string inside array) 44ms 45ms 54ms 79ms 189ms 7.0s
recipe (name) 20ms 22ms 25ms 40ms 0ms 7.6s
recipe (description) 18ms 20ms 22ms 37ms 0ms 4.5s
recipe (instructions) 6ms 8ms 9ms 10ms 0ms 3.2s
synthetic (title) 54ms 58ms 68ms 495ms 1320ms 15.7s
synthetic (string inside object) 55ms 58ms 70ms 378ms 894ms 8.3s

🧪 Experiment result

The performance result of this branch

Benchmark latency p75 p90 p99 blocking time test duration
article (title) 39ms 46ms 68ms 402ms 647ms 11.1s
article (body) 14ms 15ms 18ms 134ms 184ms 5.0s
article (string inside object) 37ms 39ms 47ms 54ms 134ms 6.5s
article (string inside array) 43ms 44ms 51ms 59ms 195ms 6.9s
recipe (name) 21ms 22ms 25ms 55ms 18ms 7.7s
recipe (description) 19ms 20ms 23ms 42ms 0ms 4.5s
recipe (instructions) 6ms 8ms 9ms 12ms 0ms 3.2s
synthetic (title) 53ms 56ms 59ms 268ms 810ms 13.1s
synthetic (string inside object) 52ms 54ms 59ms 87ms 623ms 7.8s

📚 Glossary

column definitions

  • benchmark — the name of the test, e.g. "article", followed by the label of the field being measured, e.g. "(title)".
  • latency — the time between when a key was pressed and when it was rendered. derived from a set of samples. the median (p50) is shown to show the most common latency.
  • p75 — the 75th percentile of the input latency in the test run. 75% of the sampled inputs in this benchmark were processed faster than this value. this provides insight into the upper range of typical performance.
  • p90 — the 90th percentile of the input latency in the test run. 90% of the sampled inputs were faster than this. this metric helps identify slower interactions that occurred less frequently during the benchmark.
  • p99 — the 99th percentile of the input latency in the test run. only 1% of sampled inputs were slower than this. this represents the worst-case scenarios encountered during the benchmark, useful for identifying potential performance outliers.
  • blocking time — the total time during which the main thread was blocked, preventing user input and UI updates. this metric helps identify performance bottlenecks that may cause the interface to feel unresponsive.
  • test duration — how long the test run took to complete.

@cngonzalez cngonzalez changed the title fix(graphql): do not send references to union type function fix(graphql): add custom logic for reference unions Jan 21, 2025
Copy link
Contributor

@rneatherway rneatherway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable based on what I learned while doing that recent PR that this improves upon. However, I'm not an expert in this code and haven't looked at the typegen code so I think it's best if I defer to Sindre on this one.

sgulseth
sgulseth previously approved these changes Jan 22, 2025

return {
type: name,
// references: targetTypes,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make it "optional"?

const def = {type: name, ...base}
if (targetTypes !== undefined) {
  def.references = targetTypes
}

sgulseth
sgulseth previously approved these changes Jan 23, 2025
@juice49 juice49 dismissed sgulseth’s stale review January 23, 2025 13:56

The merge-base changed after approval.

@juice49 juice49 requested a review from a team as a code owner January 23, 2025 13:56
@cngonzalez cngonzalez requested a review from sgulseth January 23, 2025 14:34
renovate bot and others added 2 commits January 23, 2025 09:42
@cngonzalez cngonzalez added this pull request to the merge queue Jan 24, 2025
Merged via the queue into next with commit cdeeae6 Jan 24, 2025
56 checks passed
@cngonzalez cngonzalez deleted the fix/use-custom-logic-for-graphql-reference-types branch January 24, 2025 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants