Isomorphism
https://github.com/WordPress/wordpress-playground/pull/214
Description
Generalizes Playground Blueprints from working with just the in-browser Playground API client to working:
- On the web and in Node.js
- With a local Playground object
- With a remote Playground client
With this PR applied, all of the following login()
calls are valid:
// In the browser
const phpInSameThread = await WebPHP.load('7.4');
// unzip WordPress in /wordpress
await login(phpInSameThread);
const phpInWorker = await consumeAPI(playgroundIframe);
await login(phpInWorker);
// In node.js
const phpInSameThread = await NodePHP.load('7.4');
phpInSameThread.mount('/wordpress', '/wordpress');
await login(phpInSameThread);
// ^ @TODO: Still fails unless you provide a DOMParser polyfill
This opens the door to using Blueprints in Node.js tools.
Implementation
Blueprint were initially implemented as a part of the browser API client in @wp-playground/client
. This PR decouples them into an isomorphic @wp-playground/blueprints
package that depends on @php-wasm/universal
which is also isomorphic.
In other words, step handlers such as login(playground)
used to require a PlaygroundClient
instance, but now they can work with a UniversalPHP
instance defined as follows:
type IsomorphicLocalPHP = {
/* ... PHP methods ... */
};
// Remote<T> means every method of T now returns a promise
type IsomorphicRemotePHP = Remote<IsomorphicLocalPHP>;
type UniversalPHP = IsomorphicLocalPHP | IsomorphicRemotePHP;
UniversalPHP
is a type, not a class. It's a common core of all PHP implementations in other packages and provides methods like run()
, request()
, and writeFile()
. @php-wasm/universal
also provides a reference implementation of UniversalPHP
called BasePHP
.
BasePHP
cannot be used directly. Instead, platform-specific packages @php-wasm/web
and @php-wasm/node
provide platform-specific implementations. The former exports WebPHP
, which loads files using fetch()
, and the latter exports NodePHP
, which reads data directly from the host filesystem. Both implement the UniversalPHP
interface and can be used with any Blueprint step.
Other notes
@php-wasm/universal
,@wp-playground/client
, and@wp-playground/blueprints
are published as isomorphic ESM/CJS packages.@php-wasm/node
is published as CJS only for now.
Follow-up work
@wp-playground/blueprints
will need to be smart about providing a Node.js polyfill fornew DOMParser()
andfetch()
.