-
Notifications
You must be signed in to change notification settings - Fork 272
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 npm package #147
Comments
1000% yes to this! |
Just a thought.. I wonder if it'd be useful (or practical) to export lower-level primitives of the Playground, without dependency on React or the UI layer in general. The reason I ask is, when I was experimenting with the "dual pane" idea, I had to create a new entry point for Rollup in In pseudo-code, I picture something like: import { bootWordPress } from '@wordpress/playground/boot'
import { login } from '@wordpress/playground/wp-macros'
const workerThread = await bootWordPress(config)
await login(workerThread, 'admin', 'password') That might make it easier for people to build their own playground interfaces, for example using Web Components. |
## Description With this PR, Playground exposes a consistent communication layer for its consumers: ```ts const playground = connect( iframe.contentWindow ); playground.writeFile( '/wordpress/test.php', 'Hello, world!' ); playground.goTo( '/test.php' ); ``` It means **your app can have the same powers as the official demo**. Just note this PR does not expose any public packages yet. That will be the next step. ## Under the hood Technically, this PR: 1. Formalizes `php-wasm` public API 2. Formalizes Playground public API as an extension of the above 3. Uses the [comlink](https://github.com/GoogleChromeLabs/comlink) library to expose Playground's public API There are a few layers to this: * Playground worker initializes the PHP and WordPress and exposes an internal API using comlink * Playground "connector" HTML page consumes the worker API, extends it, and re-exposes it publicly using comlink * Playground UI is now a separate app that connects to the "connector" page and consumes its API using comlink All the public-facing features, like plugin pre-installation or import/export, are now implemented by consuming the public API. Once I [publish these features in npm](#147), consuming Playground will be as simple as importing a package. This PR also refactors the Playground website to use React – this process was indispensable in shaping the public API. ## Public API Here's the raw interface – the documentation will be shipped with the npm package and provided in this repo. ```ts interface PlaygroundAPI { absoluteUrl: string; goTo(requestedPath: string): Promise<void>; getCurrentURL(): Promise<void>; setIframeSandboxFlags(flags: string[]): Promise<void>; onNavigation(callback: (newURL: string) => void): Promise<void>; onDownloadProgress( callback: (progress: CustomEvent<ProgressEvent>) => void ): Promise<void>; getWordPressModuleDetails(): Promise<{ staticAssetsDirectory: string; defaultTheme: string; }>; pathToInternalUrl(path: string): Promise<string>; internalUrlToPath(internalUrl: string): Promise<string>; request( request: PHPServerRequest, redirects?: number ): Promise<PHPResponse>; run(request?: PHPRequest | undefined): Promise<PHPResponse>; setPhpIniPath(path: string): Promise<void>; setPhpIniEntry(key: string, value: string): Promise<void>; mkdirTree(path: string): Promise<void>; readFileAsText(path: string): Promise<string>; readFileAsBuffer(path: string): Promise<Uint8Array>; writeFile(path: string, data: string | Uint8Array): Promise<void>; unlink(path: string): Promise<void>; listFiles(path: string): Promise<string[]>; isDir(path: string): Promise<boolean>; fileExists(path: string): Promise<boolean>; } ```
## Description Sets up the correct build pipeline for all parts of Playground and PHP.wasm. This enables a public release of the [Playground API](#149) npm package! I've been [struggling](#146) with [this](#70) for [a while](#150) and couldn't understand what's so hard. NX made it apparent – look at this dependency graph! <img width="1291" alt="CleanShot 2023-03-16 at 23 16 26@2x" src="https://user-images.githubusercontent.com/205419/225764795-7fa8e972-09f8-41ef-aac2-1c96bd100ea0.png"> No wonder it's been almost impossible to set everything up by hand! ## Usage Start with `yarn install` ### Shortcuts To start a copy of `wasm.wordpress.net` locally, run `yarn run dev`. To build it, run `yarn run build`. ### Fully qualified commands In reality, these `yarn run` commands are just triggering the underlying project's nx `dev` and `build` commands: ```bash nx dev playground-website nx build playground-website ``` Here's a few more interesting commands: ```bash # Build and run PHP.wasm CLI nx start php-wasm-cli # Build latest WordPress releases nx recompile-wordpress:all playground-remote # Recompile PHP 5.6 - 8.2 releases to .wasm for web nx recompile-php:all php-wasm-web # Recompile PHP 5.6 - 8.2 releases to .wasm for node nx recompile-php:all php-wasm-node # Builds markdown files for readthedocs site nx build docs-site # Builds the Playground Client npm package nx build playground-client ``` ## NX is the tool Playground needed from the outset It's ridiculous how many problems this solves: * The build pipeline is explicitly defined and easy to modify * Tasks only run once their dependencies are ready * The dev mode works and is fast * The build works and is fast * We get CI checks to confirm the entire build process still works (which solves #150) * Cross-package TypeScript just works * There are linters and formatters (which solves #14) * Documentation is correctly generated from the latest built artifacts * There are nice generators for bootstraping new packages and moving the existing ones around * There are checks to ensure the private `php-wasm-common` package is not imported by anything else than `php-wasm-web` and `php-wasm-node` ## Next steps * Add Lerna to harness package publishing * Additional developer documentation for the nx-based flow Related to #148 and #147
@eliot-akira a generic Playground client package is now available! import { connectPlayground } from '@wp-playground/client';
const client = await connectPlayground(
document.getElementById('wp')! as HTMLIFrameElement,
`https://wasm.wordpress.net/remote.html`
);
await client.isReady();
await client.goTo('/wp-admin/');
const result = await client.run({
code: '<?php echo "Hi!"; ',
});
console.log(new TextDecoder().decode(result.body)); Boarding a plane now, I’ll write another comment here later on. Edit: I forgot to follow-up and what I had to say :D |
Wonderful! I saw the pull request for Playground Public API, separating the functional layers of PHP WASM, the API with convenient wrapper for WebWorker interaction, and the UI as its own module that uses the API. It really clarified the separation of concerns, and defined the building blocks that the public can use to create their own playgrounds. And the related code refactoring to use NX for package build orchestration, it makes a lot of sense. Looked like a huge overhaul to bring all the work so far into a new level of logical organization. It's been so educational to watch the evolution of this project. |
I'm glad you like it! Does it help with the dual-pane use-case you've mentioned? |
## Description With this PR, Playground exposes a consistent communication layer for its consumers: ```ts const playground = connect( iframe.contentWindow ); playground.writeFile( '/wordpress/test.php', 'Hello, world!' ); playground.goTo( '/test.php' ); ``` It means **your app can have the same powers as the official demo**. Just note this PR does not expose any public packages yet. That will be the next step. ## Under the hood Technically, this PR: 1. Formalizes `php-wasm` public API 2. Formalizes Playground public API as an extension of the above 3. Uses the [comlink](https://github.com/GoogleChromeLabs/comlink) library to expose Playground's public API There are a few layers to this: * Playground worker initializes the PHP and WordPress and exposes an internal API using comlink * Playground "connector" HTML page consumes the worker API, extends it, and re-exposes it publicly using comlink * Playground UI is now a separate app that connects to the "connector" page and consumes its API using comlink All the public-facing features, like plugin pre-installation or import/export, are now implemented by consuming the public API. Once I [publish these features in npm](WordPress/wordpress-playground#147), consuming Playground will be as simple as importing a package. This PR also refactors the Playground website to use React – this process was indispensable in shaping the public API. ## Public API Here's the raw interface – the documentation will be shipped with the npm package and provided in this repo. ```ts interface PlaygroundAPI { absoluteUrl: string; goTo(requestedPath: string): Promise<void>; getCurrentURL(): Promise<void>; setIframeSandboxFlags(flags: string[]): Promise<void>; onNavigation(callback: (newURL: string) => void): Promise<void>; onDownloadProgress( callback: (progress: CustomEvent<ProgressEvent>) => void ): Promise<void>; getWordPressModuleDetails(): Promise<{ staticAssetsDirectory: string; defaultTheme: string; }>; pathToInternalUrl(path: string): Promise<string>; internalUrlToPath(internalUrl: string): Promise<string>; request( request: PHPServerRequest, redirects?: number ): Promise<PHPResponse>; run(request?: PHPRequest | undefined): Promise<PHPResponse>; setPhpIniPath(path: string): Promise<void>; setPhpIniEntry(key: string, value: string): Promise<void>; mkdirTree(path: string): Promise<void>; readFileAsText(path: string): Promise<string>; readFileAsBuffer(path: string): Promise<Uint8Array>; writeFile(path: string, data: string | Uint8Array): Promise<void>; unlink(path: string): Promise<void>; listFiles(path: string): Promise<string[]>; isDir(path: string): Promise<boolean>; fileExists(path: string): Promise<boolean>; } ```
## Description Sets up the correct build pipeline for all parts of Playground and PHP.wasm. This enables a public release of the [Playground API](WordPress/wordpress-playground#149) npm package! I've been [struggling](WordPress/wordpress-playground#146) with [this](WordPress/wordpress-playground#70) for [a while](WordPress/wordpress-playground#150) and couldn't understand what's so hard. NX made it apparent – look at this dependency graph! <img width="1291" alt="CleanShot 2023-03-16 at 23 16 26@2x" src="https://user-images.githubusercontent.com/205419/225764795-7fa8e972-09f8-41ef-aac2-1c96bd100ea0.png"> No wonder it's been almost impossible to set everything up by hand! ## Usage Start with `yarn install` ### Shortcuts To start a copy of `wasm.wordpress.net` locally, run `yarn run dev`. To build it, run `yarn run build`. ### Fully qualified commands In reality, these `yarn run` commands are just triggering the underlying project's nx `dev` and `build` commands: ```bash nx dev playground-website nx build playground-website ``` Here's a few more interesting commands: ```bash # Build and run PHP.wasm CLI nx start php-wasm-cli # Build latest WordPress releases nx recompile-wordpress:all playground-remote # Recompile PHP 5.6 - 8.2 releases to .wasm for web nx recompile-php:all php-wasm-web # Recompile PHP 5.6 - 8.2 releases to .wasm for node nx recompile-php:all php-wasm-node # Builds markdown files for readthedocs site nx build docs-site # Builds the Playground Client npm package nx build playground-client ``` ## NX is the tool Playground needed from the outset It's ridiculous how many problems this solves: * The build pipeline is explicitly defined and easy to modify * Tasks only run once their dependencies are ready * The dev mode works and is fast * The build works and is fast * We get CI checks to confirm the entire build process still works (which solves #150) * Cross-package TypeScript just works * There are linters and formatters (which solves #14) * Documentation is correctly generated from the latest built artifacts * There are nice generators for bootstraping new packages and moving the existing ones around * There are checks to ensure the private `php-wasm-common` package is not imported by anything else than `php-wasm-web` and `php-wasm-node` ## Next steps * Add Lerna to harness package publishing * Additional developer documentation for the nx-based flow Related to WordPress/wordpress-playground#148 and WordPress/wordpress-playground#147
Description
It would be great to build custom apps with WordPress Playground like this:
Technically, all these features are already implemented. There's just no package with neat API to import.
The text was updated successfully, but these errors were encountered: