Description
The documentation for @wordpress/core-abilities says:
|
Simply import the package to initialize the WordPress abilities: |
|
|
|
```js |
|
import '@wordpress/core-abilities'; |
|
``` |
But this is not accurate because you actually have to wait for two REST API requests to finish:
/wp-json/wp-abilities/v1/categories?per_page=100&context=edit&_locale=user
/wp-json/wp-abilities/v1/abilities?per_page=100&context=edit&_locale=user
Once they finish, then calling getAbilities() will return the list of abilities and calls to executeAbility() will work. Otherwise, I have to add a setTimeout() to introduce a delay:
add_action( 'admin_enqueue_scripts', static function () {
wp_register_script(
'abilities-test',
false,
array(),
false,
array(
'module_dependencies' => array(
'@wordpress/core-abilities',
'@wordpress/abilities'
),
)
);
wp_enqueue_script( 'abilities-test' );
add_action( 'admin_print_footer_scripts', function () {
wp_print_inline_script_tag(
<<<'JS'
import '@wordpress/core-abilities';
import { getAbilities, executeAbility } from '@wordpress/abilities';
setTimeout(
async () => {
console.log( getAbilities() );
console.info( await executeAbility( "core/get-site-info" ) );
},
1000 // 👈 👈 👈 Fails if zero. Timeout is not reliable.
);
JS,
array( 'type' => 'module' )
);
} );
} );
It seems that the current @wordpress/core-abilities package is assuming all usage will be done via React and the data store. But it should be usable independently. For example, a Promise should be exported by @wordpress/core-abilities which can be awaited for before attempting to access abilities.
Claude's analysis:
Look at the last two lines of core-abilities/src/index.ts:
// Auto-initialize on import
initialize();
initialize() is called fire-and-forget — it's not awaited and the returned promise is discarded. So when your inline script imports @wordpress/abilities and calls getAbilities(), the two REST API fetches (/wp-abilities/v1/categories and /wp-abilities/v1/abilities) are still in-flight. The 1000ms setTimeout just happens to be long enough for those network calls to complete.
The proper fix would be for @wordpress/core-abilities to export its initialization promise so consumers can await it:
// In core-abilities/src/index.ts
export const ready: Promise< void > = initialize();
Then your inline script can do:
const { getAbilities, executeAbility } = await import( '@wordpress/abilities' );
const { ready } = await import( '@wordpress/core-abilities' );
await ready; // wait for REST API fetches to complete
console.log( getAbilities() ); // now populated
No setTimeout needed at all. The await import() resolves once the module is loaded, but that doesn't mean its async side-effects (the REST API calls) are done. Exporting ready gives callers a proper hook into that async initialization.
Additionally, it seems like the core abilities should actually be exported with PHP via the script_module_data_@wordpress/core-abilities filter. The abilities data would then be available in a SCRIPT[type=application/json] script which would eliminate the need to do two additional REST API calls every time you load a page which uses @wordpress/core-abilities.
Step-by-step reproduction instructions
See plugin code in description.
Screenshots, screen recording, code snippet
No response
Environment info
WordPress 7.1-alpha-62161-src (latest trunk) on wordpress-develop
Please confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Please confirm which theme type you used for testing.
Description
The documentation for
@wordpress/core-abilitiessays:gutenberg/packages/core-abilities/README.md
Lines 26 to 30 in da35702
But this is not accurate because you actually have to wait for two REST API requests to finish:
/wp-json/wp-abilities/v1/categories?per_page=100&context=edit&_locale=user/wp-json/wp-abilities/v1/abilities?per_page=100&context=edit&_locale=userOnce they finish, then calling
getAbilities()will return the list of abilities and calls toexecuteAbility()will work. Otherwise, I have to add asetTimeout()to introduce a delay:It seems that the current
@wordpress/core-abilitiespackage is assuming all usage will be done via React and the data store. But it should be usable independently. For example, aPromiseshould be exported by@wordpress/core-abilitieswhich can be awaited for before attempting to access abilities.Claude's analysis:
Additionally, it seems like the core abilities should actually be exported with PHP via the
script_module_data_@wordpress/core-abilitiesfilter. The abilities data would then be available in aSCRIPT[type=application/json]script which would eliminate the need to do two additional REST API calls every time you load a page which uses@wordpress/core-abilities.Step-by-step reproduction instructions
See plugin code in description.
Screenshots, screen recording, code snippet
No response
Environment info
WordPress 7.1-alpha-62161-src (latest
trunk) onwordpress-developPlease confirm that you have searched existing issues in the repo.
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Please confirm which theme type you used for testing.