-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Block Bindings: Allow bindings bootstrap after registration #63797
Block Bindings: Allow bindings bootstrap after registration #63797
Conversation
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.
To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Size Change: +50 B (0%) Total Size: 1.76 MB
ℹ️ View Unchanged
|
packages/blocks/src/store/reducer.js
Outdated
* Keep the exisitng properties in case the source has been registered | ||
* in the client before bootstrapping. | ||
*/ | ||
...state[ action.name ], | ||
label: action.label, | ||
usesContext: action.usesContext, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to reuse the logic from the context PR here to make sure the usesContext
values get merged properly and the server doesn't overwrite the client values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right there will be "conclict changes" once any of the mentioned pull requests gets merged. I don't have a strong opinion of which one should go first, I believe it is irrelevant. I will rebase and resolve the issue once it gets merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So far, these changes make sense to me. I left a comment on the context PR that relates back to this one; as you've mentioned, I think we can try to resolve that PR first to better inform this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will leave the decision about the order of merging PRs to you. Based on the review from @artemiomorales and seeing it addresses the issue I raised earlier, I’m approving this PR. Thank you for a quick follow up.
Co-authored-by: Greg Ziółkowski <[email protected]>
ba4f426
to
d5d070d
Compare
I have merged the other pull request, rebased this one solving the conflicts, and reused the With that, this pull request should be ready. Let's see if the tests pass. |
packages/blocks/src/store/reducer.js
Outdated
@@ -372,19 +372,19 @@ export function collections( state = {}, action ) { | |||
} | |||
|
|||
export function blockBindingsSources( state = {}, action ) { | |||
// Merge usesContext with existing values, potentially defined in the server registration. | |||
let mergedUsesContext = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach. There are a couple of problems though:
- The existing
usesContext
and the newusesContext
can be undefined, so we can't use them directly. - I belive we want to return
undefined
when both of them areundefined
.
I made this change in this commit. I created different variables just for the sake of readability.
Let me know what you think and if that's clearer. For me, it definitely reads better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the reason there should be an undefined
value? Could it default to an empty array otherwise? Would it simplify handling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong reason to have an undefined
value. I was just expecting it to be undefined
if it is not defined in the server or in the client. But maybe we can default to an empty array.
Would it simplify handling?
We could remove this last step where we are checking it the array is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it defaults to null
on the server so maybe keeping it as is would be more consistent. Both work fine as long as the handling on the client is adjusted accordingly. Thank you for providing additional context.
I left a nitpick, which is totally optional as I was curious how to write one-liner to merge two arrays and keep only unique values. The code looks good after merging the latest changes from |
@@ -372,19 +372,17 @@ export function collections( state = {}, action ) { | |||
} | |||
|
|||
export function blockBindingsSources( state = {}, action ) { | |||
// Merge usesContext with existing values, potentially defined in the server registration. | |||
const existingUsesContext = state[ action.name ]?.usesContext || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had one realization afte this PR got merged. Currently, all reducers get executed whenever any action gets dispatched. In effect, the logic added on top of the function will get executed each time. I would recommend turning it into an util that gets called inside the switch
in case it is really needed.
The following could get added as an util:
/**
* Merges usesContext with existing values, potentially defined in the server registration.
*
* @param {string[]} existingUsesContext Existing `usesContext`.
* @param {string[]} newUsesContext Newly added `usesContext`.
* @return {string[]|undefined} Merged `usesContext`.
*/
function getMergedUsesContext( existingUsesContext = [], newUsesContext = [] ) {
const mergedArrays = Array.from(
new Set( existingUsesContext.concat( newUsesContext ) )
);
return mergedArrays.length > 0 ? mergedArrays : undefined;
}
That could be then used when updating reducers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have created a follow-up pull request to discuss it and potentially fix it: link.
What?
As reported here by @gziolo , when plugins start using the editor APIs, there could be a use case where sources are registered in the client before they are bootstrapped from the server. This pull request ensures the properties are not overriden.
Why?
It could break the developer experience once these APIs are public.
How?
Preserving the existing properties in the reducer.
Testing Instructions
I added a unit test to cover this use case. The other registration tests should pass as well.