-
Notifications
You must be signed in to change notification settings - Fork 268
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
Playground Blueprints #211
Conversation
a9cb891
to
3f48eb7
Compare
I simplified the JSON structure to remove "resources" and started on automatic progress management, applying a blueprint will now provide progress % and a human-readable caption. Some more changes incoming. |
I'm noodling on setting up GlotPress playground using blueprints, here's what I have so far: |
OK I think this is ready! See the updated example in the PR description. I'm planning to split this into smaller changesets and start merging them. If you were holding back with any feedback, now is a good time to share it. |
f897c6e
to
ecf1180
Compare
ecf1180
to
62bcdb2
Compare
We're down to 27 updated files from 85 in the beginning. I'd say that's good enough. Let's merge! |
## Description Generalizes [Playground Blueprints](#211) 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: ```ts // In the browser const phpInSameThread = await WebPHP.load( '7.4', { dataModules: [ 'wp.data' ] } ); await login( phpInSameThread ); const phpInWorker = await consumeAPI( playgroundIframe ); await login( phpInWorker ); ``` ```ts // 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 the VS Code extension, wp-now, and other 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: ```ts 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 for `new DOMParser()` and `fetch()`.
## Description Generalizes [Playground Blueprints](WordPress/wordpress-playground#211) 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: ```ts // In the browser const phpInSameThread = await WebPHP.load( '7.4', { dataModules: [ 'wp.data' ] } ); await login( phpInSameThread ); const phpInWorker = await consumeAPI( playgroundIframe ); await login( phpInWorker ); ``` ```ts // 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 the VS Code extension, wp-now, and other 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: ```ts 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 for `new DOMParser()` and `fetch()`.
Description
Adds Blueprints – a declarative data format for setting up new Playground instances. The big idea is:
@wp-playground/client
has python-like batteries, e.g. installPlugin, login, importFile etcphp.writeFile
fetch()
-ed in parallelBecause Blueprints merely invoke the existing Playground client functions, an advanced user may choose to not use them at all and setup their Playground using a bootstrap script that would invoke the same publicly exported functions.
Blueprints have three advantages over using a custom JavaScript file like
setup.js
:mergeBlueprints()
function to turn a list of Blueprints into a single Blueprint. Technically, it will concatenate the steps, parallelize resource fetching, and resolve any PHP and WP version constraints from all the merged Blueprints.Example
The new
loadPlayground
helper makes setting up a Playground instance as easy as:Here's a longer example. The following blueprint logs you in as admin, installs the twentytwentytwo theme, installs the gutenberg plugin, and redirects the user to
/wp-admin
.Steps
For the first version, Blueprints support the following steps:
Other notes
This PR also moves the progress bar UI component from Playground Website to
remote.html
to make reusable in other apps. Virtually every Playground consumer will want to display a progress bar, there's no need to ask everyone to reimplement it when Playground can provide a convenient API.Solves #201
Related to #115
cc @bengreeley @akirk @dmsnell @StevenDufresne