From fbba6ae0490353789f5d632d5af079b643ba49f2 Mon Sep 17 00:00:00 2001 From: Ella Date: Thu, 31 Oct 2024 19:08:40 +0100 Subject: [PATCH 1/5] Safari: try to figure out race condition issue --- lib/compat/wordpress-6.8/preload.php | 5 +--- packages/core-data/src/resolvers.js | 36 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/lib/compat/wordpress-6.8/preload.php b/lib/compat/wordpress-6.8/preload.php index 16aeb4a50619f3..aabe0d4fb574cc 100644 --- a/lib/compat/wordpress-6.8/preload.php +++ b/lib/compat/wordpress-6.8/preload.php @@ -17,10 +17,7 @@ function gutenberg_block_editor_preload_paths_6_8( $paths, $context ) { } } - // Core already preloads both of these for `core/edit-post`. - // To do: investigate why adding this preload path breaks the site - // editor in Safari ("template not found"). Perhaps a race condition? - // $paths[] = '/wp/v2/settings'; + $paths[] = '/wp/v2/settings'; $paths[] = array( '/wp/v2/settings', 'OPTIONS' ); $paths[] = '/?_fields=' . implode( ',', diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index a3bbd37f2d7c20..9c0758d66dcc78 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -750,26 +750,26 @@ export const getNavigationFallbackId = export const getDefaultTemplateId = ( query ) => async ( { dispatch, registry } ) => { - const response = await apiFetch( { + const template = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), - parse: false, } ); - const template = await response.json(); - // Endpoint may return an empty object if no template is found. - if ( template?.id ) { - registry.batch( () => { - dispatch.receiveDefaultTemplateId( query, template.id ); - dispatch.receiveEntityRecords( 'postType', 'wp_template', [ - template, - ] ); - // Avoid further network requests. - dispatch.finishResolution( 'getEntityRecord', [ - 'postType', - 'wp_template', - template.id, - ] ); - } ); - } + setTimeout( () => { + // Endpoint may return an empty object if no template is found. + if ( template?.id ) { + registry.batch( () => { + dispatch.receiveDefaultTemplateId( query, template.id ); + dispatch.receiveEntityRecords( 'postType', 'wp_template', [ + template, + ] ); + // Avoid further network requests. + dispatch.finishResolution( 'getEntityRecord', [ + 'postType', + 'wp_template', + template.id, + ] ); + } ); + } + }, 100 ); }; /** From 6863aa67f22f507910621fc28857c84304f38318 Mon Sep 17 00:00:00 2001 From: Ella Date: Thu, 31 Oct 2024 19:33:00 +0100 Subject: [PATCH 2/5] Ensure entity config is loaded --- packages/core-data/src/resolvers.js | 76 +++++++++++++---------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 9c0758d66dcc78..005be9154d76c6 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -25,6 +25,13 @@ import { import { getSyncProvider } from './sync'; import { fetchBlockPatterns } from './fetch'; +async function getConfig( resolveSelect, kind, name ) { + const configs = await resolveSelect.getEntitiesConfig( kind ); + return configs.find( + ( config ) => config.name === name && config.kind === kind + ); +} + /** * Requests authors from the REST API. * @@ -65,10 +72,7 @@ export const getCurrentUser = export const getEntityRecord = ( kind, name, key = '', query ) => async ( { select, dispatch, registry, resolveSelect } ) => { - const configs = await resolveSelect.getEntitiesConfig( kind ); - const entityConfig = configs.find( - ( config ) => config.name === name && config.kind === kind - ); + const entityConfig = await getConfig( resolveSelect, kind, name ); if ( ! entityConfig ) { return; } @@ -231,10 +235,7 @@ export const getEditedEntityRecord = forwardResolver( 'getEntityRecord' ); export const getEntityRecords = ( kind, name, query = {} ) => async ( { dispatch, registry, resolveSelect } ) => { - const configs = await resolveSelect.getEntitiesConfig( kind ); - const entityConfig = configs.find( - ( config ) => config.name === name && config.kind === kind - ); + const entityConfig = await getConfig( resolveSelect, kind, name ); if ( ! entityConfig ) { return; } @@ -459,13 +460,10 @@ export const canUser = throw new Error( 'The entity resource object is not valid.' ); } - const configs = await resolveSelect.getEntitiesConfig( - resource.kind - ); - const entityConfig = configs.find( - ( config ) => - config.name === resource.name && - config.kind === resource.kind + const entityConfig = await getConfig( + resolveSelect, + resource.kind, + resource.name ); if ( ! entityConfig ) { return; @@ -749,27 +747,28 @@ export const getNavigationFallbackId = export const getDefaultTemplateId = ( query ) => - async ( { dispatch, registry } ) => { + async ( { dispatch, registry, resolveSelect } ) => { + const kind = 'postType'; + const name = 'wp_template'; + if ( ! ( await getConfig( resolveSelect, kind, name ) ) ) { + return; + } const template = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), } ); - setTimeout( () => { - // Endpoint may return an empty object if no template is found. - if ( template?.id ) { - registry.batch( () => { - dispatch.receiveDefaultTemplateId( query, template.id ); - dispatch.receiveEntityRecords( 'postType', 'wp_template', [ - template, - ] ); - // Avoid further network requests. - dispatch.finishResolution( 'getEntityRecord', [ - 'postType', - 'wp_template', - template.id, - ] ); - } ); - } - }, 100 ); + // Endpoint may return an empty object if no template is found. + if ( template?.id ) { + registry.batch( () => { + dispatch.receiveDefaultTemplateId( query, template.id ); + dispatch.receiveEntityRecords( kind, name, [ template ] ); + // Avoid further network requests. + dispatch.finishResolution( 'getEntityRecord', [ + kind, + name, + template.id, + ] ); + } ); + } }; /** @@ -785,11 +784,7 @@ export const getDefaultTemplateId = export const getRevisions = ( kind, name, recordKey, query = {} ) => async ( { dispatch, registry, resolveSelect } ) => { - const configs = await resolveSelect.getEntitiesConfig( kind ); - const entityConfig = configs.find( - ( config ) => config.name === name && config.kind === kind - ); - + const entityConfig = await getConfig( resolveSelect, kind, name ); if ( ! entityConfig ) { return; } @@ -906,10 +901,7 @@ getRevisions.shouldInvalidate = ( action, kind, name, recordKey ) => export const getRevision = ( kind, name, recordKey, revisionKey, query ) => async ( { dispatch, resolveSelect } ) => { - const configs = await resolveSelect.getEntitiesConfig( kind ); - const entityConfig = configs.find( - ( config ) => config.name === name && config.kind === kind - ); + const entityConfig = await getConfig( resolveSelect, kind, name ); if ( ! entityConfig ) { return; From 472451d382315434cd26fbd04bf613322e4ebb83 Mon Sep 17 00:00:00 2001 From: Ella Date: Thu, 31 Oct 2024 19:43:20 +0100 Subject: [PATCH 3/5] Revert "Ensure entity config is loaded" This reverts commit 89469892dcff27c08cd2519295f329af140fea6d. --- packages/core-data/src/resolvers.js | 76 ++++++++++++++++------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 005be9154d76c6..9c0758d66dcc78 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -25,13 +25,6 @@ import { import { getSyncProvider } from './sync'; import { fetchBlockPatterns } from './fetch'; -async function getConfig( resolveSelect, kind, name ) { - const configs = await resolveSelect.getEntitiesConfig( kind ); - return configs.find( - ( config ) => config.name === name && config.kind === kind - ); -} - /** * Requests authors from the REST API. * @@ -72,7 +65,10 @@ export const getCurrentUser = export const getEntityRecord = ( kind, name, key = '', query ) => async ( { select, dispatch, registry, resolveSelect } ) => { - const entityConfig = await getConfig( resolveSelect, kind, name ); + const configs = await resolveSelect.getEntitiesConfig( kind ); + const entityConfig = configs.find( + ( config ) => config.name === name && config.kind === kind + ); if ( ! entityConfig ) { return; } @@ -235,7 +231,10 @@ export const getEditedEntityRecord = forwardResolver( 'getEntityRecord' ); export const getEntityRecords = ( kind, name, query = {} ) => async ( { dispatch, registry, resolveSelect } ) => { - const entityConfig = await getConfig( resolveSelect, kind, name ); + const configs = await resolveSelect.getEntitiesConfig( kind ); + const entityConfig = configs.find( + ( config ) => config.name === name && config.kind === kind + ); if ( ! entityConfig ) { return; } @@ -460,10 +459,13 @@ export const canUser = throw new Error( 'The entity resource object is not valid.' ); } - const entityConfig = await getConfig( - resolveSelect, - resource.kind, - resource.name + const configs = await resolveSelect.getEntitiesConfig( + resource.kind + ); + const entityConfig = configs.find( + ( config ) => + config.name === resource.name && + config.kind === resource.kind ); if ( ! entityConfig ) { return; @@ -747,28 +749,27 @@ export const getNavigationFallbackId = export const getDefaultTemplateId = ( query ) => - async ( { dispatch, registry, resolveSelect } ) => { - const kind = 'postType'; - const name = 'wp_template'; - if ( ! ( await getConfig( resolveSelect, kind, name ) ) ) { - return; - } + async ( { dispatch, registry } ) => { const template = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), } ); - // Endpoint may return an empty object if no template is found. - if ( template?.id ) { - registry.batch( () => { - dispatch.receiveDefaultTemplateId( query, template.id ); - dispatch.receiveEntityRecords( kind, name, [ template ] ); - // Avoid further network requests. - dispatch.finishResolution( 'getEntityRecord', [ - kind, - name, - template.id, - ] ); - } ); - } + setTimeout( () => { + // Endpoint may return an empty object if no template is found. + if ( template?.id ) { + registry.batch( () => { + dispatch.receiveDefaultTemplateId( query, template.id ); + dispatch.receiveEntityRecords( 'postType', 'wp_template', [ + template, + ] ); + // Avoid further network requests. + dispatch.finishResolution( 'getEntityRecord', [ + 'postType', + 'wp_template', + template.id, + ] ); + } ); + } + }, 100 ); }; /** @@ -784,7 +785,11 @@ export const getDefaultTemplateId = export const getRevisions = ( kind, name, recordKey, query = {} ) => async ( { dispatch, registry, resolveSelect } ) => { - const entityConfig = await getConfig( resolveSelect, kind, name ); + const configs = await resolveSelect.getEntitiesConfig( kind ); + const entityConfig = configs.find( + ( config ) => config.name === name && config.kind === kind + ); + if ( ! entityConfig ) { return; } @@ -901,7 +906,10 @@ getRevisions.shouldInvalidate = ( action, kind, name, recordKey ) => export const getRevision = ( kind, name, recordKey, revisionKey, query ) => async ( { dispatch, resolveSelect } ) => { - const entityConfig = await getConfig( resolveSelect, kind, name ); + const configs = await resolveSelect.getEntitiesConfig( kind ); + const entityConfig = configs.find( + ( config ) => config.name === name && config.kind === kind + ); if ( ! entityConfig ) { return; From f504feaef0931c4fa0d41840f24680463fc941f9 Mon Sep 17 00:00:00 2001 From: Ella Date: Thu, 31 Oct 2024 19:45:11 +0100 Subject: [PATCH 4/5] Wait for entities config after fetch --- packages/core-data/src/resolvers.js | 35 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 9c0758d66dcc78..623e68ae6afe4d 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -749,27 +749,26 @@ export const getNavigationFallbackId = export const getDefaultTemplateId = ( query ) => - async ( { dispatch, registry } ) => { + async ( { dispatch, registry, resolveSelect } ) => { const template = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), } ); - setTimeout( () => { - // Endpoint may return an empty object if no template is found. - if ( template?.id ) { - registry.batch( () => { - dispatch.receiveDefaultTemplateId( query, template.id ); - dispatch.receiveEntityRecords( 'postType', 'wp_template', [ - template, - ] ); - // Avoid further network requests. - dispatch.finishResolution( 'getEntityRecord', [ - 'postType', - 'wp_template', - template.id, - ] ); - } ); - } - }, 100 ); + await resolveSelect.getEntitiesConfig( 'postType' ); + // Endpoint may return an empty object if no template is found. + if ( template?.id ) { + registry.batch( () => { + dispatch.receiveDefaultTemplateId( query, template.id ); + dispatch.receiveEntityRecords( 'postType', 'wp_template', [ + template, + ] ); + // Avoid further network requests. + dispatch.finishResolution( 'getEntityRecord', [ + 'postType', + 'wp_template', + template.id, + ] ); + } ); + } }; /** From 62b329b84a913503dba221a030bf3719a09e9238 Mon Sep 17 00:00:00 2001 From: Ella Date: Fri, 1 Nov 2024 09:45:35 +0100 Subject: [PATCH 5/5] Add comment --- packages/core-data/src/resolvers.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index 623e68ae6afe4d..ae0c7f456e533d 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -753,6 +753,8 @@ export const getDefaultTemplateId = const template = await apiFetch( { path: addQueryArgs( '/wp/v2/templates/lookup', query ), } ); + // Wait for the the entities config to be loaded, otherwise receiving + // the template as an entity will not work. await resolveSelect.getEntitiesConfig( 'postType' ); // Endpoint may return an empty object if no template is found. if ( template?.id ) {