fix(core): Fix OperationContext._identity not allowing operation contexts to be deeply cloned #2732
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolve #2726
Summary
While we don't imply or implicitly disallow cloning
OperationContext
, and it's definitely not expected and encouraged, if it's done, it can have some unexpected consequences.Specifically, if an
OperationContext
is deeply cloned rather than spread, thenOperationContext._identity
is destroyed. This leads to theClient
not being able to find the right mutation result for a given operation with an unknown_identity
.Previously, we assigned identities with an empty array (
[]
). There are alternatives, of course, like{}
, symbols, functions, etc. But all may be instances that will be swapped out by users.Instead, we now assign a numeric ID to the field, which is marked as an opaque type in TypeScript. This is a rolling-over 32-bit counter, which is sufficient to prevent mutation results from being confused.
More importantly, this change makes
OperationContext
serializable in all cases again.Set of changes
OperationContext._identity
with anumber
ID based on a 32-bit roll-over