@wp-playground/cli 3.0.4 → 3.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-playground/cli",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "WordPress Playground CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,7 +34,7 @@
34
34
  "bin": {
35
35
  "wp-playground-cli": "wp-playground.js"
36
36
  },
37
- "gitHead": "878b2c84eea28790c7e8fc8651cc53d5d829072a",
37
+ "gitHead": "76ac040706918e24e56aa96a89e266887d323691",
38
38
  "dependencies": {
39
39
  "@zip.js/zip.js": "2.7.57",
40
40
  "ajv": "8.12.0",
@@ -59,16 +59,16 @@
59
59
  "ws": "8.18.1",
60
60
  "xml2js": "0.6.2",
61
61
  "yargs": "17.7.2",
62
- "@php-wasm/logger": "3.0.4",
63
- "@php-wasm/progress": "3.0.4",
64
- "@php-wasm/universal": "3.0.4",
65
- "@wp-playground/blueprints": "3.0.4",
66
- "@wp-playground/common": "3.0.4",
67
- "@wp-playground/wordpress": "3.0.4",
68
- "@php-wasm/node": "3.0.4",
69
- "@php-wasm/util": "3.0.4",
70
- "@wp-playground/storage": "3.0.4",
71
- "@php-wasm/xdebug-bridge": "3.0.4"
62
+ "@php-wasm/logger": "3.0.6",
63
+ "@php-wasm/progress": "3.0.6",
64
+ "@php-wasm/universal": "3.0.6",
65
+ "@wp-playground/blueprints": "3.0.6",
66
+ "@wp-playground/common": "3.0.6",
67
+ "@wp-playground/wordpress": "3.0.6",
68
+ "@php-wasm/node": "3.0.6",
69
+ "@php-wasm/util": "3.0.6",
70
+ "@wp-playground/storage": "3.0.6",
71
+ "@php-wasm/xdebug-bridge": "3.0.6"
72
72
  },
73
73
  "overrides": {
74
74
  "rollup": "^4.34.6",
@@ -1,3 +1,3 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("@php-wasm/node"),E=require("@php-wasm/progress"),s=require("@php-wasm/universal"),O=require("@php-wasm/util"),A=require("@wp-playground/common"),_=require("@wp-playground/wordpress"),C=require("tls"),D=require("wasm-feature-detect"),I=require("worker_threads"),c=require("./mounts-BJFrPHGW.cjs");function S(b,e,...a){console.log(performance.now().toFixed(6).padStart(15,"0"),b.toString().padStart(16,"0"),O.sprintf(e,...a))}class M extends s.PHPWorker{constructor(e){super(void 0,e),this.booted=!1}async useFileLockManager(e){await D.jspi()?this.fileLockManager=s.consumeAPI(e):this.fileLockManager=await s.consumeAPISync(e)}async bootAsPrimaryWorker({siteUrl:e,mountsBeforeWpInstall:a,mountsAfterWpInstall:l,phpVersion:n=A.RecommendedPHPVersion,wordPressZip:d,sqliteIntegrationPluginZip:u,firstProcessId:i,processIdSpaceLength:m,dataSqlPath:h,followSymlinks:o,trace:y,internalCookieStore:t,withXdebug:g,nativeInternalDirPath:r}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let p=i;const L=i+m-1;try{const w={WP_DEBUG:!0,WP_DEBUG_LOG:!0,WP_DEBUG_DISPLAY:!1};let k=!1;const q=await _.bootWordPressAndRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const P=p;return p<L?p++:p=i,await R.loadNodeRuntime(n,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:P,trace:y?S:void 0,phpWasmInitOptions:{nativeInternalDirPath:r}},followSymlinks:o,withXdebug:g})},wordPressZip:d!==void 0?new File([d],"wordpress.zip"):void 0,sqliteIntegrationPluginZip:u!==void 0?new File([u],"sqlite-integration-plugin.zip"):void 0,sapiName:"cli",createFiles:{"/internal/shared/ca-bundle.crt":C.rootCertificates.join(`
2
- `)},constants:w,phpIniEntries:{"openssl.cafile":"/internal/shared/ca-bundle.crt",allow_url_fopen:"1",disable_functions:""},cookieStore:t?void 0:!1,dataSqlPath:h,spawnHandler:s.sandboxedSpawnHandlerFactory,async onPHPInstanceCreated(P){await c.mountResources(P,a),k&&await c.mountResources(P,l)}});this.__internal_setRequestHandler(q),k=!0;const H=await q.getPrimaryPhp();await this.setPrimaryPHP(H),await c.mountResources(H,l),W()}catch(w){throw v(w),w}}async bootAsSecondaryWorker(e){await this.bootRequestHandler(e)}async bootRequestHandler({siteUrl:e,allow:a,phpVersion:l,firstProcessId:n,processIdSpaceLength:d,trace:u,nativeInternalDirPath:i,mountsBeforeWpInstall:m,mountsAfterWpInstall:h}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let o=n;const y=n+d-1;try{const t=await _.bootRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const r=o;return o<y?o++:o=n,await R.loadNodeRuntime(l,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:r,trace:u?S:void 0,ENV:{DOCROOT:"/wordpress"},phpWasmInitOptions:{nativeInternalDirPath:i}},followSymlinks:a?.includes("follow-symlinks")})},onPHPInstanceCreated:async r=>{this.registerWorkerListeners(r),await c.mountResources(r,m),await c.mountResources(r,h)},sapiName:"cli",cookieStore:!1,spawnHandler:s.sandboxedSpawnHandlerFactory});this.__internal_setRequestHandler(t);const g=await t.getPrimaryPhp();await this.setPrimaryPHP(g),W()}catch(t){throw v(t),t}}async dispose(){await this[Symbol.asyncDispose]()}}const f=new I.MessageChannel,[W,v]=s.exposeAPI(new M(new E.EmscriptenDownloadMonitor),void 0,f.port1);I.parentPort?.postMessage({command:"worker-script-initialized",phpPort:f.port2},[f.port2]);exports.PlaygroundCliBlueprintV1Worker=M;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@php-wasm/node"),E=require("@php-wasm/progress"),s=require("@php-wasm/universal"),O=require("@php-wasm/util"),A=require("@wp-playground/common"),_=require("@wp-playground/wordpress"),C=require("tls"),D=require("wasm-feature-detect"),I=require("worker_threads"),c=require("./mounts-BJFrPHGW.cjs"),F=require("@php-wasm/logger");function S(l,e,...n){console.log(performance.now().toFixed(6).padStart(15,"0"),l.toString().padStart(16,"0"),O.sprintf(e,...n))}class M extends s.PHPWorker{constructor(e){super(void 0,e),this.booted=!1}async useFileLockManager(e){await D.jspi()?this.fileLockManager=s.consumeAPI(e):this.fileLockManager=await s.consumeAPISync(e)}async bootAsPrimaryWorker({siteUrl:e,mountsBeforeWpInstall:n,mountsAfterWpInstall:d,phpVersion:a=A.RecommendedPHPVersion,wordPressZip:u,sqliteIntegrationPluginZip:p,firstProcessId:i,processIdSpaceLength:m,dataSqlPath:y,followSymlinks:o,trace:g,internalCookieStore:t,withXdebug:f,nativeInternalDirPath:r}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let w=i;const L=i+m-1;try{const P={WP_DEBUG:!0,WP_DEBUG_LOG:!0,WP_DEBUG_DISPLAY:!1};let q=!1;const k=await _.bootWordPressAndRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const h=w;return w<L?w++:w=i,await H.loadNodeRuntime(a,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:h,trace:g?S:void 0,phpWasmInitOptions:{nativeInternalDirPath:r}},followSymlinks:o,withXdebug:f})},wordPressZip:u!==void 0?new File([u],"wordpress.zip"):void 0,sqliteIntegrationPluginZip:p!==void 0?new File([p],"sqlite-integration-plugin.zip"):void 0,sapiName:"cli",createFiles:{"/internal/shared/ca-bundle.crt":C.rootCertificates.join(`
2
+ `)},constants:P,phpIniEntries:{"openssl.cafile":"/internal/shared/ca-bundle.crt",allow_url_fopen:"1",disable_functions:""},cookieStore:t?void 0:!1,dataSqlPath:y,spawnHandler:s.sandboxedSpawnHandlerFactory,async onPHPInstanceCreated(h){await c.mountResources(h,n),q&&await c.mountResources(h,d)}});this.__internal_setRequestHandler(k),q=!0;const R=await k.getPrimaryPhp();await this.setPrimaryPHP(R),await c.mountResources(R,d),W()}catch(P){throw v(P),P}}async bootAsSecondaryWorker(e){await this.bootRequestHandler(e)}async bootRequestHandler({siteUrl:e,allow:n,phpVersion:d,firstProcessId:a,processIdSpaceLength:u,trace:p,nativeInternalDirPath:i,mountsBeforeWpInstall:m,mountsAfterWpInstall:y}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let o=a;const g=a+u-1;try{const t=await _.bootRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const r=o;return o<g?o++:o=a,await H.loadNodeRuntime(d,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:r,trace:p?S:void 0,ENV:{DOCROOT:"/wordpress"},phpWasmInitOptions:{nativeInternalDirPath:i}},followSymlinks:n?.includes("follow-symlinks")})},onPHPInstanceCreated:async r=>{this.registerWorkerListeners(r),await c.mountResources(r,m),await c.mountResources(r,y)},sapiName:"cli",cookieStore:!1,spawnHandler:s.sandboxedSpawnHandlerFactory});this.__internal_setRequestHandler(t);const f=await t.getPrimaryPhp();await this.setPrimaryPHP(f),W()}catch(t){throw v(t),t}}async dispose(){await this[Symbol.asyncDispose]()}}process.on("unhandledRejection",l=>{F.logger.error("Unhandled rejection:",l)});const b=new I.MessageChannel,[W,v]=s.exposeAPI(new M(new E.EmscriptenDownloadMonitor),void 0,b.port1);I.parentPort?.postMessage({command:"worker-script-initialized",phpPort:b.port2},[b.port2]);exports.PlaygroundCliBlueprintV1Worker=M;
3
3
  //# sourceMappingURL=worker-thread-v1.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-thread-v1.cjs","sources":["../../../../packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts"],"sourcesContent":["import type { FileLockManager } from '@php-wasm/node';\nimport { loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { RemoteAPI, SupportedPHPVersion } from '@php-wasm/universal';\nimport {\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport { RecommendedPHPVersion } from '@wp-playground/common';\nimport {\n\tbootRequestHandler,\n\tbootWordPressAndRequestHandler,\n} from '@wp-playground/wordpress';\nimport { rootCertificates } from 'tls';\nimport { jspi } from 'wasm-feature-detect';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport { mountResources } from '../mounts';\n\nexport interface Mount {\n\thostPath: string;\n\tvfsPath: string;\n}\n\nexport type WorkerBootOptions = {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\tfollowSymlinks: boolean;\n\ttrace: boolean;\n\t/**\n\t * When true, Playground will not send cookies to the client but will manage\n\t * them internally. This can be useful in environments that can't store cookies,\n\t * e.g. VS Code WebView.\n\t *\n\t * Default: false.\n\t */\n\tinternalCookieStore?: boolean;\n\twithXdebug?: boolean;\n\tnativeInternalDirPath: string;\n};\n\nexport type PrimaryWorkerBootOptions = WorkerBootOptions & {\n\twpVersion?: string;\n\twordPressZip?: ArrayBuffer;\n\tsqliteIntegrationPluginZip?: ArrayBuffer;\n\tdataSqlPath?: string;\n};\n\ninterface WorkerBootRequestHandlerOptions {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\nexport class PlaygroundCliBlueprintV1Worker extends PHPWorker {\n\tbooted = false;\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker({\n\t\tsiteUrl,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t\tphpVersion: php = RecommendedPHPVersion,\n\t\twordPressZip,\n\t\tsqliteIntegrationPluginZip,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\tdataSqlPath,\n\t\tfollowSymlinks,\n\t\ttrace,\n\t\tinternalCookieStore,\n\t\twithXdebug,\n\t\tnativeInternalDirPath,\n\t}: PrimaryWorkerBootOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst constants: Record<string, string | number | boolean | null> =\n\t\t\t\t{\n\t\t\t\t\tWP_DEBUG: true,\n\t\t\t\t\tWP_DEBUG_LOG: true,\n\t\t\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t\t\t};\n\t\t\tlet wordpressBooted = false;\n\t\t\tconst requestHandler = await bootWordPressAndRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(php, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks,\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\twordPressZip:\n\t\t\t\t\twordPressZip !== undefined\n\t\t\t\t\t\t? new File([wordPressZip], 'wordpress.zip')\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsqliteIntegrationPluginZip:\n\t\t\t\t\tsqliteIntegrationPluginZip !== undefined\n\t\t\t\t\t\t? new File(\n\t\t\t\t\t\t\t\t[sqliteIntegrationPluginZip],\n\t\t\t\t\t\t\t\t'sqlite-integration-plugin.zip'\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles: {\n\t\t\t\t\t'/internal/shared/ca-bundle.crt':\n\t\t\t\t\t\trootCertificates.join('\\n'),\n\t\t\t\t},\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries: {\n\t\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t\t\tallow_url_fopen: '1',\n\t\t\t\t\tdisable_functions: '',\n\t\t\t\t},\n\t\t\t\tcookieStore: internalCookieStore ? undefined : false,\n\t\t\t\tdataSqlPath,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t\tasync onPHPInstanceCreated(php) {\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tif (wordpressBooted) {\n\t\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t\twordpressBooted = true;\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\t// The primary PHP instance is persistent, so we need to apply\n\t\t\t// post-install mounts now that WordPress has been booted.\n\t\t\t// All secondary PHP instances created after WP boot will get\n\t\t\t// these mounts automatically.\n\t\t\tawait mountResources(primaryPhp, mountsAfterWpInstall);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync bootAsSecondaryWorker(args: WorkerBootOptions) {\n\t\tawait this.bootRequestHandler(args);\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated: async (php) => {\n\t\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t},\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV1Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["tracePhpWasm","processId","format","args","sprintf","PlaygroundCliBlueprintV1Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","siteUrl","mountsBeforeWpInstall","mountsAfterWpInstall","php","RecommendedPHPVersion","wordPressZip","sqliteIntegrationPluginZip","firstProcessId","processIdSpaceLength","dataSqlPath","followSymlinks","trace","internalCookieStore","withXdebug","nativeInternalDirPath","nextProcessId","lastProcessId","constants","wordpressBooted","requestHandler","bootWordPressAndRequestHandler","loadNodeRuntime","rootCertificates","sandboxedSpawnHandlerFactory","mountResources","primaryPhp","setApiReady","e","setAPIError","allow","phpVersion","bootRequestHandler","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
1
+ {"version":3,"file":"worker-thread-v1.cjs","sources":["../../../../packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts"],"sourcesContent":["import type { FileLockManager } from '@php-wasm/node';\nimport { loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { RemoteAPI, SupportedPHPVersion } from '@php-wasm/universal';\nimport {\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport { RecommendedPHPVersion } from '@wp-playground/common';\nimport {\n\tbootRequestHandler,\n\tbootWordPressAndRequestHandler,\n} from '@wp-playground/wordpress';\nimport { rootCertificates } from 'tls';\nimport { jspi } from 'wasm-feature-detect';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport { mountResources } from '../mounts';\nimport { logger } from '@php-wasm/logger';\n\nexport interface Mount {\n\thostPath: string;\n\tvfsPath: string;\n}\n\nexport type WorkerBootOptions = {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\tfollowSymlinks: boolean;\n\ttrace: boolean;\n\t/**\n\t * When true, Playground will not send cookies to the client but will manage\n\t * them internally. This can be useful in environments that can't store cookies,\n\t * e.g. VS Code WebView.\n\t *\n\t * Default: false.\n\t */\n\tinternalCookieStore?: boolean;\n\twithXdebug?: boolean;\n\tnativeInternalDirPath: string;\n};\n\nexport type PrimaryWorkerBootOptions = WorkerBootOptions & {\n\twpVersion?: string;\n\twordPressZip?: ArrayBuffer;\n\tsqliteIntegrationPluginZip?: ArrayBuffer;\n\tdataSqlPath?: string;\n};\n\ninterface WorkerBootRequestHandlerOptions {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\nexport class PlaygroundCliBlueprintV1Worker extends PHPWorker {\n\tbooted = false;\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker({\n\t\tsiteUrl,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t\tphpVersion: php = RecommendedPHPVersion,\n\t\twordPressZip,\n\t\tsqliteIntegrationPluginZip,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\tdataSqlPath,\n\t\tfollowSymlinks,\n\t\ttrace,\n\t\tinternalCookieStore,\n\t\twithXdebug,\n\t\tnativeInternalDirPath,\n\t}: PrimaryWorkerBootOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst constants: Record<string, string | number | boolean | null> =\n\t\t\t\t{\n\t\t\t\t\tWP_DEBUG: true,\n\t\t\t\t\tWP_DEBUG_LOG: true,\n\t\t\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t\t\t};\n\t\t\tlet wordpressBooted = false;\n\t\t\tconst requestHandler = await bootWordPressAndRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(php, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks,\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\twordPressZip:\n\t\t\t\t\twordPressZip !== undefined\n\t\t\t\t\t\t? new File([wordPressZip], 'wordpress.zip')\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsqliteIntegrationPluginZip:\n\t\t\t\t\tsqliteIntegrationPluginZip !== undefined\n\t\t\t\t\t\t? new File(\n\t\t\t\t\t\t\t\t[sqliteIntegrationPluginZip],\n\t\t\t\t\t\t\t\t'sqlite-integration-plugin.zip'\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles: {\n\t\t\t\t\t'/internal/shared/ca-bundle.crt':\n\t\t\t\t\t\trootCertificates.join('\\n'),\n\t\t\t\t},\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries: {\n\t\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t\t\tallow_url_fopen: '1',\n\t\t\t\t\tdisable_functions: '',\n\t\t\t\t},\n\t\t\t\tcookieStore: internalCookieStore ? undefined : false,\n\t\t\t\tdataSqlPath,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t\tasync onPHPInstanceCreated(php) {\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tif (wordpressBooted) {\n\t\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t\twordpressBooted = true;\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\t// The primary PHP instance is persistent, so we need to apply\n\t\t\t// post-install mounts now that WordPress has been booted.\n\t\t\t// All secondary PHP instances created after WP boot will get\n\t\t\t// these mounts automatically.\n\t\t\tawait mountResources(primaryPhp, mountsAfterWpInstall);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync bootAsSecondaryWorker(args: WorkerBootOptions) {\n\t\tawait this.bootRequestHandler(args);\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated: async (php) => {\n\t\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t},\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nprocess.on('unhandledRejection', (e: any) => {\n\tlogger.error('Unhandled rejection:', e);\n});\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV1Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["tracePhpWasm","processId","format","args","sprintf","PlaygroundCliBlueprintV1Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","siteUrl","mountsBeforeWpInstall","mountsAfterWpInstall","php","RecommendedPHPVersion","wordPressZip","sqliteIntegrationPluginZip","firstProcessId","processIdSpaceLength","dataSqlPath","followSymlinks","trace","internalCookieStore","withXdebug","nativeInternalDirPath","nextProcessId","lastProcessId","constants","wordpressBooted","requestHandler","bootWordPressAndRequestHandler","loadNodeRuntime","rootCertificates","sandboxedSpawnHandlerFactory","mountResources","primaryPhp","setApiReady","e","setAPIError","allow","phpVersion","bootRequestHandler","logger","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
@@ -1,21 +1,22 @@
1
- import { loadNodeRuntime as _ } from "@php-wasm/node";
1
+ import { loadNodeRuntime as R } from "@php-wasm/node";
2
2
  import { EmscriptenDownloadMonitor as M } from "@php-wasm/progress";
3
- import { exposeAPI as q, PHPWorker as v, consumeAPI as E, consumeAPISync as A, sandboxedSpawnHandlerFactory as R } from "@php-wasm/universal";
3
+ import { exposeAPI as q, PHPWorker as v, consumeAPI as E, consumeAPISync as A, sandboxedSpawnHandlerFactory as _ } from "@php-wasm/universal";
4
4
  import { sprintf as O } from "@php-wasm/util";
5
5
  import { RecommendedPHPVersion as x } from "@wp-playground/common";
6
6
  import { bootWordPressAndRequestHandler as C, bootRequestHandler as D } from "@wp-playground/wordpress";
7
7
  import { rootCertificates as F } from "tls";
8
8
  import { jspi as B } from "wasm-feature-detect";
9
- import { MessageChannel as G, parentPort as N } from "worker_threads";
10
- import { m as n } from "./mounts-D1_eXSTw.js";
11
- function I(g, e, ...a) {
9
+ import { MessageChannel as j, parentPort as G } from "worker_threads";
10
+ import { m as i } from "./mounts-D1_eXSTw.js";
11
+ import { logger as N } from "@php-wasm/logger";
12
+ function I(c, e, ...a) {
12
13
  console.log(
13
14
  performance.now().toFixed(6).padStart(15, "0"),
14
- g.toString().padStart(16, "0"),
15
+ c.toString().padStart(16, "0"),
15
16
  O(e, ...a)
16
17
  );
17
18
  }
18
- class V extends v {
19
+ class U extends v {
19
20
  constructor(e) {
20
21
  super(void 0, e), this.booted = !1;
21
22
  }
@@ -34,26 +35,26 @@ class V extends v {
34
35
  async bootAsPrimaryWorker({
35
36
  siteUrl: e,
36
37
  mountsBeforeWpInstall: a,
37
- mountsAfterWpInstall: c,
38
- phpVersion: s = x,
39
- wordPressZip: l,
40
- sqliteIntegrationPluginZip: d,
41
- firstProcessId: i,
38
+ mountsAfterWpInstall: l,
39
+ phpVersion: n = x,
40
+ wordPressZip: d,
41
+ sqliteIntegrationPluginZip: p,
42
+ firstProcessId: s,
42
43
  processIdSpaceLength: P,
43
- dataSqlPath: h,
44
+ dataSqlPath: u,
44
45
  followSymlinks: r,
45
- trace: u,
46
+ trace: f,
46
47
  internalCookieStore: t,
47
- withXdebug: f,
48
+ withXdebug: y,
48
49
  nativeInternalDirPath: o
49
50
  }) {
50
51
  if (this.booted)
51
52
  throw new Error("Playground already booted");
52
53
  this.booted = !0;
53
- let p = i;
54
- const L = i + P - 1;
54
+ let m = s;
55
+ const L = s + P - 1;
55
56
  try {
56
- const m = {
57
+ const w = {
57
58
  WP_DEBUG: !0,
58
59
  WP_DEBUG_LOG: !0,
59
60
  WP_DEBUG_DISPLAY: !1
@@ -62,21 +63,21 @@ class V extends v {
62
63
  const k = await C({
63
64
  siteUrl: e,
64
65
  createPhpRuntime: async () => {
65
- const w = p;
66
- return p < L ? p++ : p = i, await _(s, {
66
+ const h = m;
67
+ return m < L ? m++ : m = s, await R(n, {
67
68
  emscriptenOptions: {
68
69
  fileLockManager: this.fileLockManager,
69
- processId: w,
70
- trace: u ? I : void 0,
70
+ processId: h,
71
+ trace: f ? I : void 0,
71
72
  phpWasmInitOptions: { nativeInternalDirPath: o }
72
73
  },
73
74
  followSymlinks: r,
74
- withXdebug: f
75
+ withXdebug: y
75
76
  });
76
77
  },
77
- wordPressZip: l !== void 0 ? new File([l], "wordpress.zip") : void 0,
78
- sqliteIntegrationPluginZip: d !== void 0 ? new File(
79
- [d],
78
+ wordPressZip: d !== void 0 ? new File([d], "wordpress.zip") : void 0,
79
+ sqliteIntegrationPluginZip: p !== void 0 ? new File(
80
+ [p],
80
81
  "sqlite-integration-plugin.zip"
81
82
  ) : void 0,
82
83
  sapiName: "cli",
@@ -84,24 +85,24 @@ class V extends v {
84
85
  "/internal/shared/ca-bundle.crt": F.join(`
85
86
  `)
86
87
  },
87
- constants: m,
88
+ constants: w,
88
89
  phpIniEntries: {
89
90
  "openssl.cafile": "/internal/shared/ca-bundle.crt",
90
91
  allow_url_fopen: "1",
91
92
  disable_functions: ""
92
93
  },
93
94
  cookieStore: t ? void 0 : !1,
94
- dataSqlPath: h,
95
- spawnHandler: R,
96
- async onPHPInstanceCreated(w) {
97
- await n(w, a), b && await n(w, c);
95
+ dataSqlPath: u,
96
+ spawnHandler: _,
97
+ async onPHPInstanceCreated(h) {
98
+ await i(h, a), b && await i(h, l);
98
99
  }
99
100
  });
100
101
  this.__internal_setRequestHandler(k), b = !0;
101
102
  const H = await k.getPrimaryPhp();
102
- await this.setPrimaryPHP(H), await n(H, c), S();
103
- } catch (m) {
104
- throw W(m), m;
103
+ await this.setPrimaryPHP(H), await i(H, l), S();
104
+ } catch (w) {
105
+ throw W(w), w;
105
106
  }
106
107
  }
107
108
  async bootAsSecondaryWorker(e) {
@@ -110,47 +111,47 @@ class V extends v {
110
111
  async bootRequestHandler({
111
112
  siteUrl: e,
112
113
  allow: a,
113
- phpVersion: c,
114
- firstProcessId: s,
115
- processIdSpaceLength: l,
116
- trace: d,
117
- nativeInternalDirPath: i,
114
+ phpVersion: l,
115
+ firstProcessId: n,
116
+ processIdSpaceLength: d,
117
+ trace: p,
118
+ nativeInternalDirPath: s,
118
119
  mountsBeforeWpInstall: P,
119
- mountsAfterWpInstall: h
120
+ mountsAfterWpInstall: u
120
121
  }) {
121
122
  if (this.booted)
122
123
  throw new Error("Playground already booted");
123
124
  this.booted = !0;
124
- let r = s;
125
- const u = s + l - 1;
125
+ let r = n;
126
+ const f = n + d - 1;
126
127
  try {
127
128
  const t = await D({
128
129
  siteUrl: e,
129
130
  createPhpRuntime: async () => {
130
131
  const o = r;
131
- return r < u ? r++ : r = s, await _(c, {
132
+ return r < f ? r++ : r = n, await R(l, {
132
133
  emscriptenOptions: {
133
134
  fileLockManager: this.fileLockManager,
134
135
  processId: o,
135
- trace: d ? I : void 0,
136
+ trace: p ? I : void 0,
136
137
  ENV: {
137
138
  DOCROOT: "/wordpress"
138
139
  },
139
- phpWasmInitOptions: { nativeInternalDirPath: i }
140
+ phpWasmInitOptions: { nativeInternalDirPath: s }
140
141
  },
141
142
  followSymlinks: a?.includes("follow-symlinks")
142
143
  });
143
144
  },
144
145
  onPHPInstanceCreated: async (o) => {
145
- this.registerWorkerListeners(o), await n(o, P), await n(o, h);
146
+ this.registerWorkerListeners(o), await i(o, P), await i(o, u);
146
147
  },
147
148
  sapiName: "cli",
148
149
  cookieStore: !1,
149
- spawnHandler: R
150
+ spawnHandler: _
150
151
  });
151
152
  this.__internal_setRequestHandler(t);
152
- const f = await t.getPrimaryPhp();
153
- await this.setPrimaryPHP(f), S();
153
+ const y = await t.getPrimaryPhp();
154
+ await this.setPrimaryPHP(y), S();
154
155
  } catch (t) {
155
156
  throw W(t), t;
156
157
  }
@@ -160,19 +161,22 @@ class V extends v {
160
161
  await this[Symbol.asyncDispose]();
161
162
  }
162
163
  }
163
- const y = new G(), [S, W] = q(
164
- new V(new M()),
164
+ process.on("unhandledRejection", (c) => {
165
+ N.error("Unhandled rejection:", c);
166
+ });
167
+ const g = new j(), [S, W] = q(
168
+ new U(new M()),
165
169
  void 0,
166
- y.port1
170
+ g.port1
167
171
  );
168
- N?.postMessage(
172
+ G?.postMessage(
169
173
  {
170
174
  command: "worker-script-initialized",
171
- phpPort: y.port2
175
+ phpPort: g.port2
172
176
  },
173
- [y.port2]
177
+ [g.port2]
174
178
  );
175
179
  export {
176
- V as PlaygroundCliBlueprintV1Worker
180
+ U as PlaygroundCliBlueprintV1Worker
177
181
  };
178
182
  //# sourceMappingURL=worker-thread-v1.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-thread-v1.js","sources":["../../../../packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts"],"sourcesContent":["import type { FileLockManager } from '@php-wasm/node';\nimport { loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { RemoteAPI, SupportedPHPVersion } from '@php-wasm/universal';\nimport {\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport { RecommendedPHPVersion } from '@wp-playground/common';\nimport {\n\tbootRequestHandler,\n\tbootWordPressAndRequestHandler,\n} from '@wp-playground/wordpress';\nimport { rootCertificates } from 'tls';\nimport { jspi } from 'wasm-feature-detect';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport { mountResources } from '../mounts';\n\nexport interface Mount {\n\thostPath: string;\n\tvfsPath: string;\n}\n\nexport type WorkerBootOptions = {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\tfollowSymlinks: boolean;\n\ttrace: boolean;\n\t/**\n\t * When true, Playground will not send cookies to the client but will manage\n\t * them internally. This can be useful in environments that can't store cookies,\n\t * e.g. VS Code WebView.\n\t *\n\t * Default: false.\n\t */\n\tinternalCookieStore?: boolean;\n\twithXdebug?: boolean;\n\tnativeInternalDirPath: string;\n};\n\nexport type PrimaryWorkerBootOptions = WorkerBootOptions & {\n\twpVersion?: string;\n\twordPressZip?: ArrayBuffer;\n\tsqliteIntegrationPluginZip?: ArrayBuffer;\n\tdataSqlPath?: string;\n};\n\ninterface WorkerBootRequestHandlerOptions {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\nexport class PlaygroundCliBlueprintV1Worker extends PHPWorker {\n\tbooted = false;\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker({\n\t\tsiteUrl,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t\tphpVersion: php = RecommendedPHPVersion,\n\t\twordPressZip,\n\t\tsqliteIntegrationPluginZip,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\tdataSqlPath,\n\t\tfollowSymlinks,\n\t\ttrace,\n\t\tinternalCookieStore,\n\t\twithXdebug,\n\t\tnativeInternalDirPath,\n\t}: PrimaryWorkerBootOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst constants: Record<string, string | number | boolean | null> =\n\t\t\t\t{\n\t\t\t\t\tWP_DEBUG: true,\n\t\t\t\t\tWP_DEBUG_LOG: true,\n\t\t\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t\t\t};\n\t\t\tlet wordpressBooted = false;\n\t\t\tconst requestHandler = await bootWordPressAndRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(php, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks,\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\twordPressZip:\n\t\t\t\t\twordPressZip !== undefined\n\t\t\t\t\t\t? new File([wordPressZip], 'wordpress.zip')\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsqliteIntegrationPluginZip:\n\t\t\t\t\tsqliteIntegrationPluginZip !== undefined\n\t\t\t\t\t\t? new File(\n\t\t\t\t\t\t\t\t[sqliteIntegrationPluginZip],\n\t\t\t\t\t\t\t\t'sqlite-integration-plugin.zip'\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles: {\n\t\t\t\t\t'/internal/shared/ca-bundle.crt':\n\t\t\t\t\t\trootCertificates.join('\\n'),\n\t\t\t\t},\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries: {\n\t\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t\t\tallow_url_fopen: '1',\n\t\t\t\t\tdisable_functions: '',\n\t\t\t\t},\n\t\t\t\tcookieStore: internalCookieStore ? undefined : false,\n\t\t\t\tdataSqlPath,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t\tasync onPHPInstanceCreated(php) {\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tif (wordpressBooted) {\n\t\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t\twordpressBooted = true;\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\t// The primary PHP instance is persistent, so we need to apply\n\t\t\t// post-install mounts now that WordPress has been booted.\n\t\t\t// All secondary PHP instances created after WP boot will get\n\t\t\t// these mounts automatically.\n\t\t\tawait mountResources(primaryPhp, mountsAfterWpInstall);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync bootAsSecondaryWorker(args: WorkerBootOptions) {\n\t\tawait this.bootRequestHandler(args);\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated: async (php) => {\n\t\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t},\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV1Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["tracePhpWasm","processId","format","args","sprintf","PlaygroundCliBlueprintV1Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","siteUrl","mountsBeforeWpInstall","mountsAfterWpInstall","php","RecommendedPHPVersion","wordPressZip","sqliteIntegrationPluginZip","firstProcessId","processIdSpaceLength","dataSqlPath","followSymlinks","trace","internalCookieStore","withXdebug","nativeInternalDirPath","nextProcessId","lastProcessId","constants","wordpressBooted","requestHandler","bootWordPressAndRequestHandler","loadNodeRuntime","rootCertificates","sandboxedSpawnHandlerFactory","mountResources","primaryPhp","setApiReady","e","setAPIError","allow","phpVersion","bootRequestHandler","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":";;;;;;;;;;AA0EA,SAASA,EAAaC,GAAmBC,MAAmBC,GAAa;AAEhE,UAAA;AAAA,IACP,YAAY,MAAM,QAAQ,CAAC,EAAE,SAAS,IAAI,GAAG;AAAA,IAC7CF,EAAU,SAAW,EAAA,SAAS,IAAI,GAAG;AAAA,IACrCG,EAAQF,GAAQ,GAAGC,CAAI;AAAA,EACxB;AACD;AAEO,MAAME,UAAuCC,EAAU;AAAA,EAI7D,YAAYC,GAAoC;AAC/C,UAAM,QAAWA,CAAO,GAJhB,KAAA,SAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBT,MAAM,mBAAmBC,GAAmB;AACvC,IAAA,MAAMC,MASJ,KAAA,kBAAkBC,EAA4BF,CAAI,IAUlD,KAAA,kBAAkB,MAAMG,EAAgCH,CAAI;AAAA,EAClE;AAAA,EAGD,MAAM,oBAAoB;AAAA,IACzB,SAAAI;AAAA,IACA,uBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,YAAYC,IAAMC;AAAA,IAClB,cAAAC;AAAA,IACA,4BAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,aAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,OAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,uBAAAC;AAAA,EAAA,GAC4B;AAC5B,QAAI,KAAK;AACF,YAAA,IAAI,MAAM,2BAA2B;AAE5C,SAAK,SAAS;AAEd,QAAIC,IAAgBR;AACd,UAAAS,IAAgBT,IAAiBC,IAAuB;AAE1D,QAAA;AACH,YAAMS,IACL;AAAA,QACC,UAAU;AAAA,QACV,cAAc;AAAA,QACd,kBAAkB;AAAA,MACnB;AACD,UAAIC,IAAkB;AAChB,YAAAC,IAAiB,MAAMC,EAA+B;AAAA,QAC3D,SAAApB;AAAA,QACA,kBAAkB,YAAY;AAC7B,gBAAMX,IAAY0B;AAElB,iBAAIA,IAAgBC,IACnBD,MAGgBA,IAAAR,GAGV,MAAMc,EAAgBlB,GAAK;AAAA,YACjC,mBAAmB;AAAA,cAClB,iBAAiB,KAAK;AAAA,cACtB,WAAAd;AAAA,cACA,OAAOsB,IAAQvB,IAAe;AAAA,cAC9B,oBAAoB,EAAE,uBAAA0B,EAAsB;AAAA,YAC7C;AAAA,YACA,gBAAAJ;AAAA,YACA,YAAAG;AAAA,UAAA,CACA;AAAA,QACF;AAAA,QACA,cACCR,MAAiB,SACd,IAAI,KAAK,CAACA,CAAY,GAAG,eAAe,IACxC;AAAA,QACJ,4BACCC,MAA+B,SAC5B,IAAI;AAAA,UACJ,CAACA,CAA0B;AAAA,UAC3B;AAAA,QAEA,IAAA;AAAA,QACJ,UAAU;AAAA,QACV,aAAa;AAAA,UACZ,kCACCgB,EAAiB,KAAK;AAAA,CAAI;AAAA,QAC5B;AAAA,QACA,WAAAL;AAAA,QACA,eAAe;AAAA,UACd,kBAAkB;AAAA,UAClB,iBAAiB;AAAA,UACjB,mBAAmB;AAAA,QACpB;AAAA,QACA,aAAaL,IAAsB,SAAY;AAAA,QAC/C,aAAAH;AAAA,QACA,cAAcc;AAAA,QACd,MAAM,qBAAqBpB,GAAK;AACzB,gBAAAqB,EAAerB,GAAKF,CAAqB,GAC3CiB,KACG,MAAAM,EAAerB,GAAKD,CAAoB;AAAA,QAC/C;AAAA,MACD,CACA;AACD,WAAK,6BAA6BiB,CAAc,GAC9BD,IAAA;AAEZ,YAAAO,IAAa,MAAMN,EAAe,cAAc;AAChD,YAAA,KAAK,cAAcM,CAAU,GAM7B,MAAAD,EAAeC,GAAYvB,CAAoB,GAEzCwB,EAAA;AAAA,aACJC,GAAG;AACX,YAAAC,EAAYD,CAAU,GAChBA;AAAA,IAAA;AAAA,EACP;AAAA,EAGD,MAAM,sBAAsBpC,GAAyB;AAC9C,UAAA,KAAK,mBAAmBA,CAAI;AAAA,EAAA;AAAA,EAGnC,MAAM,mBAAmB;AAAA,IACxB,SAAAS;AAAA,IACA,OAAA6B;AAAA,IACA,YAAAC;AAAA,IACA,gBAAAvB;AAAA,IACA,sBAAAC;AAAA,IACA,OAAAG;AAAA,IACA,uBAAAG;AAAA,IACA,uBAAAb;AAAA,IACA,sBAAAC;AAAA,EAAA,GACmC;AACnC,QAAI,KAAK;AACF,YAAA,IAAI,MAAM,2BAA2B;AAE5C,SAAK,SAAS;AAEd,QAAIa,IAAgBR;AACd,UAAAS,IAAgBT,IAAiBC,IAAuB;AAE1D,QAAA;AACG,YAAAW,IAAiB,MAAMY,EAAmB;AAAA,QAC/C,SAAA/B;AAAA,QACA,kBAAkB,YAAY;AAC7B,gBAAMX,IAAY0B;AAElB,iBAAIA,IAAgBC,IACnBD,MAGgBA,IAAAR,GAGV,MAAMc,EAAgBS,GAAY;AAAA,YACxC,mBAAmB;AAAA,cAClB,iBAAiB,KAAK;AAAA,cACtB,WAAAzC;AAAA,cACA,OAAOsB,IAAQvB,IAAe;AAAA,cAC9B,KAAK;AAAA,gBACJ,SAAS;AAAA,cACV;AAAA,cACA,oBAAoB,EAAE,uBAAA0B,EAAsB;AAAA,YAC7C;AAAA,YACA,gBAAgBe,GAAO,SAAS,iBAAiB;AAAA,UAAA,CACjD;AAAA,QACF;AAAA,QACA,sBAAsB,OAAO1B,MAAQ;AACpC,eAAK,wBAAwBA,CAAG,GAC1B,MAAAqB,EAAerB,GAAKF,CAAqB,GACzC,MAAAuB,EAAerB,GAAKD,CAAoB;AAAA,QAC/C;AAAA,QACA,UAAU;AAAA,QACV,aAAa;AAAA,QACb,cAAcqB;AAAA,MAAA,CACd;AACD,WAAK,6BAA6BJ,CAAc;AAE1C,YAAAM,IAAa,MAAMN,EAAe,cAAc;AAChD,YAAA,KAAK,cAAcM,CAAU,GAEvBC,EAAA;AAAA,aACJC,GAAG;AACX,YAAAC,EAAYD,CAAU,GAChBA;AAAA,IAAA;AAAA,EACP;AAAA;AAAA,EAID,MAAM,UAAU;AACT,UAAA,KAAK,OAAO,YAAY,EAAE;AAAA,EAAA;AAElC;AAEA,MAAMK,IAAa,IAAIC,EAAe,GAEhC,CAACP,GAAaE,CAAW,IAAIM;AAAA,EAClC,IAAIzC,EAA+B,IAAI0C,GAA2B;AAAA,EAClE;AAAA,EACAH,EAAW;AACZ;AAEAI,GAAY;AAAA,EACX;AAAA,IACC,SAAS;AAAA,IACT,SAASJ,EAAW;AAAA,EACrB;AAAA,EACA,CAACA,EAAW,KAAY;AACzB;"}
1
+ {"version":3,"file":"worker-thread-v1.js","sources":["../../../../packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts"],"sourcesContent":["import type { FileLockManager } from '@php-wasm/node';\nimport { loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type { RemoteAPI, SupportedPHPVersion } from '@php-wasm/universal';\nimport {\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport { RecommendedPHPVersion } from '@wp-playground/common';\nimport {\n\tbootRequestHandler,\n\tbootWordPressAndRequestHandler,\n} from '@wp-playground/wordpress';\nimport { rootCertificates } from 'tls';\nimport { jspi } from 'wasm-feature-detect';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport { mountResources } from '../mounts';\nimport { logger } from '@php-wasm/logger';\n\nexport interface Mount {\n\thostPath: string;\n\tvfsPath: string;\n}\n\nexport type WorkerBootOptions = {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\tfollowSymlinks: boolean;\n\ttrace: boolean;\n\t/**\n\t * When true, Playground will not send cookies to the client but will manage\n\t * them internally. This can be useful in environments that can't store cookies,\n\t * e.g. VS Code WebView.\n\t *\n\t * Default: false.\n\t */\n\tinternalCookieStore?: boolean;\n\twithXdebug?: boolean;\n\tnativeInternalDirPath: string;\n};\n\nexport type PrimaryWorkerBootOptions = WorkerBootOptions & {\n\twpVersion?: string;\n\twordPressZip?: ArrayBuffer;\n\tsqliteIntegrationPluginZip?: ArrayBuffer;\n\tdataSqlPath?: string;\n};\n\ninterface WorkerBootRequestHandlerOptions {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\tmountsBeforeWpInstall: Array<Mount>;\n\tmountsAfterWpInstall: Array<Mount>;\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\nexport class PlaygroundCliBlueprintV1Worker extends PHPWorker {\n\tbooted = false;\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker({\n\t\tsiteUrl,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t\tphpVersion: php = RecommendedPHPVersion,\n\t\twordPressZip,\n\t\tsqliteIntegrationPluginZip,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\tdataSqlPath,\n\t\tfollowSymlinks,\n\t\ttrace,\n\t\tinternalCookieStore,\n\t\twithXdebug,\n\t\tnativeInternalDirPath,\n\t}: PrimaryWorkerBootOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst constants: Record<string, string | number | boolean | null> =\n\t\t\t\t{\n\t\t\t\t\tWP_DEBUG: true,\n\t\t\t\t\tWP_DEBUG_LOG: true,\n\t\t\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t\t\t};\n\t\t\tlet wordpressBooted = false;\n\t\t\tconst requestHandler = await bootWordPressAndRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(php, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks,\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\twordPressZip:\n\t\t\t\t\twordPressZip !== undefined\n\t\t\t\t\t\t? new File([wordPressZip], 'wordpress.zip')\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsqliteIntegrationPluginZip:\n\t\t\t\t\tsqliteIntegrationPluginZip !== undefined\n\t\t\t\t\t\t? new File(\n\t\t\t\t\t\t\t\t[sqliteIntegrationPluginZip],\n\t\t\t\t\t\t\t\t'sqlite-integration-plugin.zip'\n\t\t\t\t\t\t )\n\t\t\t\t\t\t: undefined,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles: {\n\t\t\t\t\t'/internal/shared/ca-bundle.crt':\n\t\t\t\t\t\trootCertificates.join('\\n'),\n\t\t\t\t},\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries: {\n\t\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t\t\tallow_url_fopen: '1',\n\t\t\t\t\tdisable_functions: '',\n\t\t\t\t},\n\t\t\t\tcookieStore: internalCookieStore ? undefined : false,\n\t\t\t\tdataSqlPath,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t\tasync onPHPInstanceCreated(php) {\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tif (wordpressBooted) {\n\t\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\t\t\twordpressBooted = true;\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\t// The primary PHP instance is persistent, so we need to apply\n\t\t\t// post-install mounts now that WordPress has been booted.\n\t\t\t// All secondary PHP instances created after WP boot will get\n\t\t\t// these mounts automatically.\n\t\t\tawait mountResources(primaryPhp, mountsAfterWpInstall);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\tasync bootAsSecondaryWorker(args: WorkerBootOptions) {\n\t\tawait this.bootRequestHandler(args);\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\tmountsBeforeWpInstall,\n\t\tmountsAfterWpInstall,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated: async (php) => {\n\t\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\t\tawait mountResources(php, mountsBeforeWpInstall);\n\t\t\t\t\tawait mountResources(php, mountsAfterWpInstall);\n\t\t\t\t},\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nprocess.on('unhandledRejection', (e: any) => {\n\tlogger.error('Unhandled rejection:', e);\n});\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV1Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["tracePhpWasm","processId","format","args","sprintf","PlaygroundCliBlueprintV1Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","siteUrl","mountsBeforeWpInstall","mountsAfterWpInstall","php","RecommendedPHPVersion","wordPressZip","sqliteIntegrationPluginZip","firstProcessId","processIdSpaceLength","dataSqlPath","followSymlinks","trace","internalCookieStore","withXdebug","nativeInternalDirPath","nextProcessId","lastProcessId","constants","wordpressBooted","requestHandler","bootWordPressAndRequestHandler","loadNodeRuntime","rootCertificates","sandboxedSpawnHandlerFactory","mountResources","primaryPhp","setApiReady","e","setAPIError","allow","phpVersion","bootRequestHandler","logger","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@php-wasm/logger"),y=require("@php-wasm/node"),x=require("@php-wasm/progress"),u=require("@php-wasm/universal"),k=require("@php-wasm/util"),M=require("@wp-playground/blueprints"),_=require("@wp-playground/wordpress"),$=require("fs"),m=require("path"),A=require("tls"),W=require("worker_threads"),I=require("wasm-feature-detect");async function h(s,e){for(const r of e)try{s.mkdir(r.vfsPath),await s.mount(r.vfsPath,y.createNodeFsMountHandler(r.hostPath))}catch{i.stderr(`\x1B[31m\x1B[1mError mounting path ${r.hostPath} at ${r.vfsPath}\x1B[0m
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const W=require("@php-wasm/logger"),y=require("@php-wasm/node"),x=require("@php-wasm/progress"),u=require("@php-wasm/universal"),k=require("@php-wasm/util"),M=require("@wp-playground/blueprints"),_=require("@wp-playground/wordpress"),$=require("fs"),m=require("path"),A=require("tls"),T=require("worker_threads"),I=require("wasm-feature-detect");async function h(s,e){for(const r of e)try{s.mkdir(r.vfsPath),await s.mount(r.vfsPath,y.createNodeFsMountHandler(r.hostPath))}catch{i.stderr(`\x1B[31m\x1B[1mError mounting path ${r.hostPath} at ${r.vfsPath}\x1B[0m
2
2
  `),process.exit(1)}}function S(s,e,...r){console.log(performance.now().toFixed(6).padStart(15,"0"),s.toString().padStart(16,"0"),k.sprintf(e,...r))}Object.defineProperty(process.stdout,"isTTY",{value:!0});Object.defineProperty(process.stderr,"isTTY",{value:!0});const i={lastWriteWasProgress:!1,progress(s){process.stdout.isTTY?(i.lastWriteWasProgress||process.stdout.write(`
3
3
  `),process.stdout.write("\r\x1B[K"+s),i.lastWriteWasProgress=!0):console.log(s)},stdout(s){i.lastWriteWasProgress&&(process.stdout.write(`
4
4
  `),i.lastWriteWasProgress=!1),process.stdout.write(s)},stderr(s){i.lastWriteWasProgress&&(process.stdout.write(`
5
- `),i.lastWriteWasProgress=!1),process.stderr.write(s)}};class T extends u.PHPWorker{constructor(e){super(void 0,e),this.booted=!1,this.blueprintTargetResolved=!1,this.phpInstancesThatNeedMountsAfterTargetResolved=new Set}async useFileLockManager(e){await I.jspi()?this.fileLockManager=u.consumeAPI(e):this.fileLockManager=await u.consumeAPISync(e)}async bootAsPrimaryWorker(e){const r={WP_DEBUG:!0,WP_DEBUG_LOG:!0,WP_DEBUG_DISPLAY:!1},p={...e,createFiles:{"/internal/shared/ca-bundle.crt":A.rootCertificates.join(`
5
+ `),i.lastWriteWasProgress=!1),process.stderr.write(s)}};class R extends u.PHPWorker{constructor(e){super(void 0,e),this.booted=!1,this.blueprintTargetResolved=!1,this.phpInstancesThatNeedMountsAfterTargetResolved=new Set}async useFileLockManager(e){await I.jspi()?this.fileLockManager=u.consumeAPI(e):this.fileLockManager=await u.consumeAPISync(e)}async bootAsPrimaryWorker(e){const r={WP_DEBUG:!0,WP_DEBUG_LOG:!0,WP_DEBUG_DISPLAY:!1},p={...e,createFiles:{"/internal/shared/ca-bundle.crt":A.rootCertificates.join(`
6
6
  `)},constants:r,phpIniEntries:{"openssl.cafile":"/internal/shared/ca-bundle.crt"},onPHPInstanceCreated:async o=>{this.registerWorkerListeners(o),await h(o,e["mount-before-install"]||[]),this.blueprintTargetResolved?await h(o,e.mount||[]):(this.phpInstancesThatNeedMountsAfterTargetResolved.add(o),o.addEventListener("runtime.beforeExit",()=>{this.phpInstancesThatNeedMountsAfterTargetResolved.delete(o)}))}};await this.bootRequestHandler(p);const w=this.__internal_getPHP();if(e.mode==="mount-only"){await h(w,e.mount||[]);return}await this.runBlueprintV2(e)}async bootAsSecondaryWorker(e){await this.bootRequestHandler({...e,onPHPInstanceCreated:async r=>{await h(r,e.mountsBeforeWpInstall||[]),await h(r,e.mountsAfterWpInstall||[])}})}async runBlueprintV2(e){const r=this.__internal_getRequestHandler(),{php:p,reap:w}=await r.processManager.acquirePHPInstance({considerPrimary:!1}),o=this.__internal_getPHP();let f=()=>{};if(typeof e.blueprint=="string"){const n=m.resolve(process.cwd(),e.blueprint);$.existsSync(n)&&(o.mkdir("/internal/shared/cwd"),f=await o.mount("/internal/shared/cwd",y.createNodeFsMountHandler(m.dirname(n))),e.blueprint=m.join("/internal/shared/cwd",m.basename(e.blueprint)))}try{const l=["mode","db-engine","db-host","db-user","db-pass","db-name","db-path","truncate-new-site-directory","allow"].filter(t=>t in e).map(t=>`--${t}=${e[t]}`);l.push(`--site-url=${e.siteUrl}`);const c=await M.runBlueprintV2({php:p,blueprint:e.blueprint,blueprintOverrides:{additionalSteps:e["additional-blueprint-steps"],wordpressVersion:e.wp},cliArgs:l,onMessage:async t=>{switch(t.type){case"blueprint.target_resolved":{if(!this.blueprintTargetResolved){this.blueprintTargetResolved=!0;for(const a of this.phpInstancesThatNeedMountsAfterTargetResolved)this.phpInstancesThatNeedMountsAfterTargetResolved.delete(a),await h(a,e.mount||[])}break}case"blueprint.progress":{const a=`${t.caption.trim()} – ${t.progress.toFixed(2)}%`;i.progress(a);break}case"blueprint.error":{const a="\x1B[31m",b="\x1B[1m",d="\x1B[0m";e.debug&&t.details?i.stderr(`${a}${b}Fatal error:${d} Uncaught ${t.details.exception}: ${t.details.message}
7
7
  at ${t.details.file}:${t.details.line}
8
8
  `+(t.details.trace?t.details.trace+`
9
9
  `:"")):i.stderr(`${a}${b}Error:${d} ${t.message}
10
- `);break}}}});if(e.debug&&(c.stdout.pipeTo(new WritableStream({write(t){process.stdout.write(t)}})),c.stderr.pipeTo(new WritableStream({write(t){process.stderr.write(t)}}))),await c.finished,await c.exitCode!==0){const t=await u.PHPResponse.fromStreamedResponse(c);throw new u.PHPExecutionFailureError(`PHP.run() failed with exit code ${t.exitCode}.`,t,"request")}}catch(n){let l="";try{l=p.readFileAsText(H.errorLogPath)}catch{}throw n.phpLogs=l,n}finally{w(),f()}}async bootRequestHandler({siteUrl:e,allow:r,phpVersion:p,createFiles:w,constants:o,phpIniEntries:f,firstProcessId:n,processIdSpaceLength:l,trace:c,nativeInternalDirPath:t,withXdebug:a,onPHPInstanceCreated:b}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let d=n;const R=n+l-1;try{const P=await _.bootRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const v=d;return d<R?d++:d=n,await y.loadNodeRuntime(p,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:v,trace:c?S:void 0,ENV:{DOCROOT:"/wordpress"},phpWasmInitOptions:{nativeInternalDirPath:t}},followSymlinks:r?.includes("follow-symlinks"),withXdebug:a})},onPHPInstanceCreated:b,sapiName:"cli",createFiles:w,constants:o,phpIniEntries:f,cookieStore:!1,spawnHandler:u.sandboxedSpawnHandlerFactory});this.__internal_setRequestHandler(P);const q=await P.getPrimaryPhp();await this.setPrimaryPHP(q),B()}catch(P){throw E(P),P}}async dispose(){await this[Symbol.asyncDispose]()}}const g=new W.MessageChannel,[B,E]=u.exposeAPI(new T(new x.EmscriptenDownloadMonitor),void 0,g.port1);W.parentPort?.postMessage({command:"worker-script-initialized",phpPort:g.port2},[g.port2]);exports.PlaygroundCliBlueprintV2Worker=T;
10
+ `);break}}}});if(e.debug&&(c.stdout.pipeTo(new WritableStream({write(t){process.stdout.write(t)}})),c.stderr.pipeTo(new WritableStream({write(t){process.stderr.write(t)}}))),await c.finished,await c.exitCode!==0){const t=await u.PHPResponse.fromStreamedResponse(c);throw new u.PHPExecutionFailureError(`PHP.run() failed with exit code ${t.exitCode}.`,t,"request")}}catch(n){let l="";try{l=p.readFileAsText(W.errorLogPath)}catch{}throw n.phpLogs=l,n}finally{w(),f()}}async bootRequestHandler({siteUrl:e,allow:r,phpVersion:p,createFiles:w,constants:o,phpIniEntries:f,firstProcessId:n,processIdSpaceLength:l,trace:c,nativeInternalDirPath:t,withXdebug:a,onPHPInstanceCreated:b}){if(this.booted)throw new Error("Playground already booted");this.booted=!0;let d=n;const q=n+l-1;try{const P=await _.bootRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const H=d;return d<q?d++:d=n,await y.loadNodeRuntime(p,{emscriptenOptions:{fileLockManager:this.fileLockManager,processId:H,trace:c?S:void 0,ENV:{DOCROOT:"/wordpress"},phpWasmInitOptions:{nativeInternalDirPath:t}},followSymlinks:r?.includes("follow-symlinks"),withXdebug:a})},onPHPInstanceCreated:b,sapiName:"cli",createFiles:w,constants:o,phpIniEntries:f,cookieStore:!1,spawnHandler:u.sandboxedSpawnHandlerFactory});this.__internal_setRequestHandler(P);const v=await P.getPrimaryPhp();await this.setPrimaryPHP(v),B()}catch(P){throw E(P),P}}async dispose(){await this[Symbol.asyncDispose]()}}process.on("unhandledRejection",s=>{W.logger.error("Unhandled rejection:",s)});const g=new T.MessageChannel,[B,E]=u.exposeAPI(new R(new x.EmscriptenDownloadMonitor),void 0,g.port1);T.parentPort?.postMessage({command:"worker-script-initialized",phpPort:g.port2},[g.port2]);exports.PlaygroundCliBlueprintV2Worker=R;
11
11
  //# sourceMappingURL=worker-thread-v2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-thread-v2.cjs","sources":["../../../../packages/playground/cli/src/blueprints-v2/worker-thread-v2.ts"],"sourcesContent":["import { errorLogPath } from '@php-wasm/logger';\nimport type { FileLockManager } from '@php-wasm/node';\nimport { createNodeFsMountHandler, loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type {\n\tPHP,\n\tFileTree,\n\tRemoteAPI,\n\tSupportedPHPVersion,\n} from '@php-wasm/universal';\nimport {\n\tPHPExecutionFailureError,\n\tPHPResponse,\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport {\n\ttype BlueprintMessage,\n\trunBlueprintV2,\n\ttype BlueprintV1Declaration,\n} from '@wp-playground/blueprints';\nimport {\n\ttype ParsedBlueprintV2String,\n\ttype RawBlueprintV2Data,\n} from '@wp-playground/blueprints';\nimport { bootRequestHandler } from '@wp-playground/wordpress';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport { rootCertificates } from 'tls';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport type { Mount } from '../mounts';\nimport { jspi } from 'wasm-feature-detect';\nimport { type RunCLIArgs } from '../run-cli';\nimport type {\n\tPhpIniOptions,\n\tPHPInstanceCreatedHook,\n} from '@wp-playground/wordpress';\n\nasync function mountResources(php: PHP, mounts: Mount[]) {\n\tfor (const mount of mounts) {\n\t\ttry {\n\t\t\tphp.mkdir(mount.vfsPath);\n\t\t\tawait php.mount(\n\t\t\t\tmount.vfsPath,\n\t\t\t\tcreateNodeFsMountHandler(mount.hostPath)\n\t\t\t);\n\t\t} catch {\n\t\t\toutput.stderr(\n\t\t\t\t`\\x1b[31m\\x1b[1mError mounting path ${mount.hostPath} at ${mount.vfsPath}\\x1b[0m\\n`\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\n/**\n * Force TTY status to preserve ANSI control codes in the output.\n *\n * This script is spawned as `new Worker()` and process.stdout and process.stderr are\n * WritableWorkerStdio objects. By default, they strip ANSI control codes from the output\n * causing every progress bar update to be printed in a new line instead of updating the\n * same line.\n */\nObject.defineProperty(process.stdout, 'isTTY', { value: true });\nObject.defineProperty(process.stderr, 'isTTY', { value: true });\n\n/**\n * Output writer that ensures that progress bars are not printed on the same line as other output.\n */\nconst output = {\n\tlastWriteWasProgress: false,\n\tprogress(data: string) {\n\t\tif (!process.stdout.isTTY) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(data);\n\t\t} else {\n\t\t\tif (!output.lastWriteWasProgress) {\n\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t}\n\t\t\tprocess.stdout.write('\\r\\x1b[K' + data);\n\t\t\toutput.lastWriteWasProgress = true;\n\t\t}\n\t},\n\tstdout(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stdout.write(data);\n\t},\n\tstderr(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stderr.write(data);\n\t},\n};\n\nexport type PrimaryWorkerBootArgs = RunCLIArgs & {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n\tnativeInternalDirPath: string;\n};\n\ntype WorkerRunBlueprintArgs = RunCLIArgs & {\n\tsiteUrl: string;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n};\n\nexport type SecondaryWorkerBootArgs = {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tphpIniEntries?: PhpIniOptions;\n\tconstants?: Record<string, string | number | boolean | null>;\n\tcreateFiles?: FileTree;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\twithXdebug?: boolean;\n\tmountsBeforeWpInstall?: Array<Mount>;\n\tmountsAfterWpInstall?: Array<Mount>;\n};\n\nexport type WorkerBootRequestHandlerOptions = Omit<\n\tSecondaryWorkerBootArgs,\n\t'mountsBeforeWpInstall' | 'mountsAfterWpInstall'\n> & {\n\tonPHPInstanceCreated: PHPInstanceCreatedHook;\n};\n\nexport class PlaygroundCliBlueprintV2Worker extends PHPWorker {\n\tbooted = false;\n\tblueprintTargetResolved = false;\n\tphpInstancesThatNeedMountsAfterTargetResolved = new Set<PHP>();\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker(args: PrimaryWorkerBootArgs) {\n\t\tconst constants = {\n\t\t\tWP_DEBUG: true,\n\t\t\tWP_DEBUG_LOG: true,\n\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t};\n\t\tconst requestHandlerOptions: WorkerBootRequestHandlerOptions = {\n\t\t\t...args,\n\t\t\tcreateFiles: {\n\t\t\t\t'/internal/shared/ca-bundle.crt': rootCertificates.join('\\n'),\n\t\t\t},\n\t\t\tconstants,\n\t\t\tphpIniEntries: {\n\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t},\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\tawait mountResources(php, args['mount-before-install'] || []);\n\t\t\t\tif (this.blueprintTargetResolved) {\n\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t} else {\n\t\t\t\t\t// NOTE: Today (2025-09-11), during boot with a plugin auto-mount,\n\t\t\t\t\t// the Blueprint runner fails unless post-resolution mounts are\n\t\t\t\t\t// added to existing PHP instances. So we track them here so they\n\t\t\t\t\t// can be mounted at the necessary time.\n\t\t\t\t\t// Only plugin auto-mounts seem to need this, so perhaps there\n\t\t\t\t\t// is a change we can make to the Blueprint runner so such\n\t\t\t\t\t// a dance is unnecessary.\n\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.add(php);\n\t\t\t\t\tphp.addEventListener('runtime.beforeExit', () => {\n\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tawait this.bootRequestHandler(requestHandlerOptions);\n\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\n\t\tif (args.mode === 'mount-only') {\n\t\t\tawait mountResources(primaryPhp, args.mount || []);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runBlueprintV2(args);\n\t}\n\n\tasync bootAsSecondaryWorker(args: SecondaryWorkerBootArgs) {\n\t\tawait this.bootRequestHandler({\n\t\t\t...args,\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tawait mountResources(php, args.mountsBeforeWpInstall || []);\n\t\t\t\tawait mountResources(php, args.mountsAfterWpInstall || []);\n\t\t\t},\n\t\t});\n\t}\n\n\tasync runBlueprintV2(args: WorkerRunBlueprintArgs) {\n\t\tconst requestHandler = this.__internal_getRequestHandler()!;\n\t\tconst { php, reap } =\n\t\t\tawait requestHandler.processManager.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: false,\n\t\t\t});\n\n\t\t// Mount the current working directory to the PHP runtime for the purposes of\n\t\t// Blueprint resolution.\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\t\tlet unmountCwd = () => {};\n\t\tif (typeof args.blueprint === 'string') {\n\t\t\tconst blueprintPath = path.resolve(process.cwd(), args.blueprint);\n\t\t\tif (existsSync(blueprintPath)) {\n\t\t\t\tprimaryPhp.mkdir('/internal/shared/cwd');\n\t\t\t\tunmountCwd = await primaryPhp.mount(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tcreateNodeFsMountHandler(path.dirname(blueprintPath))\n\t\t\t\t);\n\t\t\t\targs.blueprint = path.join(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tpath.basename(args.blueprint)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst cliArgsToPass: (keyof WorkerRunBlueprintArgs)[] = [\n\t\t\t\t'mode',\n\t\t\t\t'db-engine',\n\t\t\t\t'db-host',\n\t\t\t\t'db-user',\n\t\t\t\t'db-pass',\n\t\t\t\t'db-name',\n\t\t\t\t'db-path',\n\t\t\t\t'truncate-new-site-directory',\n\t\t\t\t'allow',\n\t\t\t];\n\t\t\tconst cliArgs = cliArgsToPass\n\t\t\t\t.filter((arg) => arg in args)\n\t\t\t\t.map((arg) => `--${arg}=${args[arg]}`);\n\t\t\tcliArgs.push(`--site-url=${args.siteUrl}`);\n\n\t\t\tconst streamedResponse = await runBlueprintV2({\n\t\t\t\tphp,\n\t\t\t\tblueprint: args.blueprint,\n\t\t\t\tblueprintOverrides: {\n\t\t\t\t\tadditionalSteps: args['additional-blueprint-steps'],\n\t\t\t\t\twordpressVersion: args.wp,\n\t\t\t\t},\n\t\t\t\tcliArgs,\n\t\t\t\tonMessage: async (message: BlueprintMessage) => {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'blueprint.target_resolved': {\n\t\t\t\t\t\t\tif (!this.blueprintTargetResolved) {\n\t\t\t\t\t\t\t\tthis.blueprintTargetResolved = true;\n\t\t\t\t\t\t\t\tfor (const php of this\n\t\t\t\t\t\t\t\t\t.phpInstancesThatNeedMountsAfterTargetResolved) {\n\t\t\t\t\t\t\t\t\t// console.log('mounting resources for php', php);\n\t\t\t\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.progress': {\n\t\t\t\t\t\t\tconst progressMessage = `${message.caption.trim()} – ${message.progress.toFixed(\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t)}%`;\n\t\t\t\t\t\t\toutput.progress(progressMessage);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.error': {\n\t\t\t\t\t\t\tconst red = '\\x1b[31m';\n\t\t\t\t\t\t\tconst bold = '\\x1b[1m';\n\t\t\t\t\t\t\tconst reset = '\\x1b[0m';\n\t\t\t\t\t\t\tif (args.debug && message.details) {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Fatal error:${reset} Uncaught ${message.details.exception}: ${message.details.message}\\n` +\n\t\t\t\t\t\t\t\t\t\t` at ${message.details.file}:${message.details.line}\\n` +\n\t\t\t\t\t\t\t\t\t\t(message.details.trace\n\t\t\t\t\t\t\t\t\t\t\t? message.details.trace + '\\n'\n\t\t\t\t\t\t\t\t\t\t\t: '')\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Error:${reset} ${message.message}\\n`\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\t/**\n\t\t\t * When we're debugging, every bit of information matters – let's immediately output\n\t\t\t * everything we get from the PHP output streams.\n\t\t\t */\n\t\t\tif (args.debug) {\n\t\t\t\tstreamedResponse!.stdout.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tstreamedResponse!.stderr.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stderr.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait streamedResponse!.finished;\n\t\t\tif ((await streamedResponse!.exitCode) !== 0) {\n\t\t\t\t// exitCode != 1 means the blueprint execution failed. Let's throw an error.\n\t\t\t\t// and clean up.\n\t\t\t\tconst syncResponse = await PHPResponse.fromStreamedResponse(\n\t\t\t\t\tstreamedResponse\n\t\t\t\t);\n\t\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}.`,\n\t\t\t\t\tsyncResponse,\n\t\t\t\t\t'request'\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Capture the PHP error log details to provide more context for debugging.\n\t\t\tlet phpLogs = '';\n\t\t\ttry {\n\t\t\t\t// @TODO: Don't assume errorLogPath starts with /wordpress/\n\t\t\t\t// ...or maybe we can assume that in Playground CLI?\n\t\t\t\tphpLogs = php.readFileAsText(errorLogPath);\n\t\t\t} catch {\n\t\t\t\t// Ignore errors reading the PHP error log.\n\t\t\t}\n\t\t\t(error as any).phpLogs = phpLogs;\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\treap();\n\t\t\tunmountCwd();\n\t\t}\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tcreateFiles,\n\t\tconstants,\n\t\tphpIniEntries,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\twithXdebug,\n\t\tonPHPInstanceCreated,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles,\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries,\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV2Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["mountResources","php","mounts","mount","createNodeFsMountHandler","output","tracePhpWasm","processId","format","args","sprintf","data","PlaygroundCliBlueprintV2Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","constants","requestHandlerOptions","rootCertificates","primaryPhp","requestHandler","reap","unmountCwd","blueprintPath","path","existsSync","cliArgs","arg","streamedResponse","runBlueprintV2","message","progressMessage","red","bold","reset","chunk","syncResponse","PHPResponse","PHPExecutionFailureError","error","phpLogs","errorLogPath","siteUrl","allow","phpVersion","createFiles","phpIniEntries","firstProcessId","processIdSpaceLength","trace","nativeInternalDirPath","withXdebug","onPHPInstanceCreated","nextProcessId","lastProcessId","bootRequestHandler","loadNodeRuntime","sandboxedSpawnHandlerFactory","setApiReady","e","setAPIError","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
1
+ {"version":3,"file":"worker-thread-v2.cjs","sources":["../../../../packages/playground/cli/src/blueprints-v2/worker-thread-v2.ts"],"sourcesContent":["import { errorLogPath, logger } from '@php-wasm/logger';\nimport type { FileLockManager } from '@php-wasm/node';\nimport { createNodeFsMountHandler, loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type {\n\tPHP,\n\tFileTree,\n\tRemoteAPI,\n\tSupportedPHPVersion,\n} from '@php-wasm/universal';\nimport {\n\tPHPExecutionFailureError,\n\tPHPResponse,\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport {\n\ttype BlueprintMessage,\n\trunBlueprintV2,\n\ttype BlueprintV1Declaration,\n} from '@wp-playground/blueprints';\nimport {\n\ttype ParsedBlueprintV2String,\n\ttype RawBlueprintV2Data,\n} from '@wp-playground/blueprints';\nimport { bootRequestHandler } from '@wp-playground/wordpress';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport { rootCertificates } from 'tls';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport type { Mount } from '../mounts';\nimport { jspi } from 'wasm-feature-detect';\nimport { type RunCLIArgs } from '../run-cli';\nimport type {\n\tPhpIniOptions,\n\tPHPInstanceCreatedHook,\n} from '@wp-playground/wordpress';\n\nasync function mountResources(php: PHP, mounts: Mount[]) {\n\tfor (const mount of mounts) {\n\t\ttry {\n\t\t\tphp.mkdir(mount.vfsPath);\n\t\t\tawait php.mount(\n\t\t\t\tmount.vfsPath,\n\t\t\t\tcreateNodeFsMountHandler(mount.hostPath)\n\t\t\t);\n\t\t} catch {\n\t\t\toutput.stderr(\n\t\t\t\t`\\x1b[31m\\x1b[1mError mounting path ${mount.hostPath} at ${mount.vfsPath}\\x1b[0m\\n`\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\n/**\n * Force TTY status to preserve ANSI control codes in the output.\n *\n * This script is spawned as `new Worker()` and process.stdout and process.stderr are\n * WritableWorkerStdio objects. By default, they strip ANSI control codes from the output\n * causing every progress bar update to be printed in a new line instead of updating the\n * same line.\n */\nObject.defineProperty(process.stdout, 'isTTY', { value: true });\nObject.defineProperty(process.stderr, 'isTTY', { value: true });\n\n/**\n * Output writer that ensures that progress bars are not printed on the same line as other output.\n */\nconst output = {\n\tlastWriteWasProgress: false,\n\tprogress(data: string) {\n\t\tif (!process.stdout.isTTY) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(data);\n\t\t} else {\n\t\t\tif (!output.lastWriteWasProgress) {\n\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t}\n\t\t\tprocess.stdout.write('\\r\\x1b[K' + data);\n\t\t\toutput.lastWriteWasProgress = true;\n\t\t}\n\t},\n\tstdout(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stdout.write(data);\n\t},\n\tstderr(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stderr.write(data);\n\t},\n};\n\nexport type PrimaryWorkerBootArgs = RunCLIArgs & {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n\tnativeInternalDirPath: string;\n};\n\ntype WorkerRunBlueprintArgs = RunCLIArgs & {\n\tsiteUrl: string;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n};\n\nexport type SecondaryWorkerBootArgs = {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tphpIniEntries?: PhpIniOptions;\n\tconstants?: Record<string, string | number | boolean | null>;\n\tcreateFiles?: FileTree;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\twithXdebug?: boolean;\n\tmountsBeforeWpInstall?: Array<Mount>;\n\tmountsAfterWpInstall?: Array<Mount>;\n};\n\nexport type WorkerBootRequestHandlerOptions = Omit<\n\tSecondaryWorkerBootArgs,\n\t'mountsBeforeWpInstall' | 'mountsAfterWpInstall'\n> & {\n\tonPHPInstanceCreated: PHPInstanceCreatedHook;\n};\n\nexport class PlaygroundCliBlueprintV2Worker extends PHPWorker {\n\tbooted = false;\n\tblueprintTargetResolved = false;\n\tphpInstancesThatNeedMountsAfterTargetResolved = new Set<PHP>();\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker(args: PrimaryWorkerBootArgs) {\n\t\tconst constants = {\n\t\t\tWP_DEBUG: true,\n\t\t\tWP_DEBUG_LOG: true,\n\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t};\n\t\tconst requestHandlerOptions: WorkerBootRequestHandlerOptions = {\n\t\t\t...args,\n\t\t\tcreateFiles: {\n\t\t\t\t'/internal/shared/ca-bundle.crt': rootCertificates.join('\\n'),\n\t\t\t},\n\t\t\tconstants,\n\t\t\tphpIniEntries: {\n\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t},\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\tawait mountResources(php, args['mount-before-install'] || []);\n\t\t\t\tif (this.blueprintTargetResolved) {\n\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t} else {\n\t\t\t\t\t// NOTE: Today (2025-09-11), during boot with a plugin auto-mount,\n\t\t\t\t\t// the Blueprint runner fails unless post-resolution mounts are\n\t\t\t\t\t// added to existing PHP instances. So we track them here so they\n\t\t\t\t\t// can be mounted at the necessary time.\n\t\t\t\t\t// Only plugin auto-mounts seem to need this, so perhaps there\n\t\t\t\t\t// is a change we can make to the Blueprint runner so such\n\t\t\t\t\t// a dance is unnecessary.\n\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.add(php);\n\t\t\t\t\tphp.addEventListener('runtime.beforeExit', () => {\n\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tawait this.bootRequestHandler(requestHandlerOptions);\n\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\n\t\tif (args.mode === 'mount-only') {\n\t\t\tawait mountResources(primaryPhp, args.mount || []);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runBlueprintV2(args);\n\t}\n\n\tasync bootAsSecondaryWorker(args: SecondaryWorkerBootArgs) {\n\t\tawait this.bootRequestHandler({\n\t\t\t...args,\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tawait mountResources(php, args.mountsBeforeWpInstall || []);\n\t\t\t\tawait mountResources(php, args.mountsAfterWpInstall || []);\n\t\t\t},\n\t\t});\n\t}\n\n\tasync runBlueprintV2(args: WorkerRunBlueprintArgs) {\n\t\tconst requestHandler = this.__internal_getRequestHandler()!;\n\t\tconst { php, reap } =\n\t\t\tawait requestHandler.processManager.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: false,\n\t\t\t});\n\n\t\t// Mount the current working directory to the PHP runtime for the purposes of\n\t\t// Blueprint resolution.\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\t\tlet unmountCwd = () => {};\n\t\tif (typeof args.blueprint === 'string') {\n\t\t\tconst blueprintPath = path.resolve(process.cwd(), args.blueprint);\n\t\t\tif (existsSync(blueprintPath)) {\n\t\t\t\tprimaryPhp.mkdir('/internal/shared/cwd');\n\t\t\t\tunmountCwd = await primaryPhp.mount(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tcreateNodeFsMountHandler(path.dirname(blueprintPath))\n\t\t\t\t);\n\t\t\t\targs.blueprint = path.join(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tpath.basename(args.blueprint)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst cliArgsToPass: (keyof WorkerRunBlueprintArgs)[] = [\n\t\t\t\t'mode',\n\t\t\t\t'db-engine',\n\t\t\t\t'db-host',\n\t\t\t\t'db-user',\n\t\t\t\t'db-pass',\n\t\t\t\t'db-name',\n\t\t\t\t'db-path',\n\t\t\t\t'truncate-new-site-directory',\n\t\t\t\t'allow',\n\t\t\t];\n\t\t\tconst cliArgs = cliArgsToPass\n\t\t\t\t.filter((arg) => arg in args)\n\t\t\t\t.map((arg) => `--${arg}=${args[arg]}`);\n\t\t\tcliArgs.push(`--site-url=${args.siteUrl}`);\n\n\t\t\tconst streamedResponse = await runBlueprintV2({\n\t\t\t\tphp,\n\t\t\t\tblueprint: args.blueprint,\n\t\t\t\tblueprintOverrides: {\n\t\t\t\t\tadditionalSteps: args['additional-blueprint-steps'],\n\t\t\t\t\twordpressVersion: args.wp,\n\t\t\t\t},\n\t\t\t\tcliArgs,\n\t\t\t\tonMessage: async (message: BlueprintMessage) => {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'blueprint.target_resolved': {\n\t\t\t\t\t\t\tif (!this.blueprintTargetResolved) {\n\t\t\t\t\t\t\t\tthis.blueprintTargetResolved = true;\n\t\t\t\t\t\t\t\tfor (const php of this\n\t\t\t\t\t\t\t\t\t.phpInstancesThatNeedMountsAfterTargetResolved) {\n\t\t\t\t\t\t\t\t\t// console.log('mounting resources for php', php);\n\t\t\t\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.progress': {\n\t\t\t\t\t\t\tconst progressMessage = `${message.caption.trim()} – ${message.progress.toFixed(\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t)}%`;\n\t\t\t\t\t\t\toutput.progress(progressMessage);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.error': {\n\t\t\t\t\t\t\tconst red = '\\x1b[31m';\n\t\t\t\t\t\t\tconst bold = '\\x1b[1m';\n\t\t\t\t\t\t\tconst reset = '\\x1b[0m';\n\t\t\t\t\t\t\tif (args.debug && message.details) {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Fatal error:${reset} Uncaught ${message.details.exception}: ${message.details.message}\\n` +\n\t\t\t\t\t\t\t\t\t\t` at ${message.details.file}:${message.details.line}\\n` +\n\t\t\t\t\t\t\t\t\t\t(message.details.trace\n\t\t\t\t\t\t\t\t\t\t\t? message.details.trace + '\\n'\n\t\t\t\t\t\t\t\t\t\t\t: '')\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Error:${reset} ${message.message}\\n`\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\t/**\n\t\t\t * When we're debugging, every bit of information matters – let's immediately output\n\t\t\t * everything we get from the PHP output streams.\n\t\t\t */\n\t\t\tif (args.debug) {\n\t\t\t\tstreamedResponse!.stdout.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tstreamedResponse!.stderr.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stderr.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait streamedResponse!.finished;\n\t\t\tif ((await streamedResponse!.exitCode) !== 0) {\n\t\t\t\t// exitCode != 1 means the blueprint execution failed. Let's throw an error.\n\t\t\t\t// and clean up.\n\t\t\t\tconst syncResponse = await PHPResponse.fromStreamedResponse(\n\t\t\t\t\tstreamedResponse\n\t\t\t\t);\n\t\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}.`,\n\t\t\t\t\tsyncResponse,\n\t\t\t\t\t'request'\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Capture the PHP error log details to provide more context for debugging.\n\t\t\tlet phpLogs = '';\n\t\t\ttry {\n\t\t\t\t// @TODO: Don't assume errorLogPath starts with /wordpress/\n\t\t\t\t// ...or maybe we can assume that in Playground CLI?\n\t\t\t\tphpLogs = php.readFileAsText(errorLogPath);\n\t\t\t} catch {\n\t\t\t\t// Ignore errors reading the PHP error log.\n\t\t\t}\n\t\t\t(error as any).phpLogs = phpLogs;\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\treap();\n\t\t\tunmountCwd();\n\t\t}\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tcreateFiles,\n\t\tconstants,\n\t\tphpIniEntries,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\twithXdebug,\n\t\tonPHPInstanceCreated,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles,\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries,\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nprocess.on('unhandledRejection', (e: any) => {\n\tlogger.error('Unhandled rejection:', e);\n});\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV2Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["mountResources","php","mounts","mount","createNodeFsMountHandler","output","tracePhpWasm","processId","format","args","sprintf","data","PlaygroundCliBlueprintV2Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","constants","requestHandlerOptions","rootCertificates","primaryPhp","requestHandler","reap","unmountCwd","blueprintPath","path","existsSync","cliArgs","arg","streamedResponse","runBlueprintV2","message","progressMessage","red","bold","reset","chunk","syncResponse","PHPResponse","PHPExecutionFailureError","error","phpLogs","errorLogPath","siteUrl","allow","phpVersion","createFiles","phpIniEntries","firstProcessId","processIdSpaceLength","trace","nativeInternalDirPath","withXdebug","onPHPInstanceCreated","nextProcessId","lastProcessId","bootRequestHandler","loadNodeRuntime","sandboxedSpawnHandlerFactory","setApiReady","e","setAPIError","logger","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
- import { errorLogPath as R } from "@php-wasm/logger";
2
- import { createNodeFsMountHandler as y, loadNodeRuntime as x } from "@php-wasm/node";
3
- import { EmscriptenDownloadMonitor as H } from "@php-wasm/progress";
4
- import { exposeAPI as v, PHPWorker as k, consumeAPI as $, consumeAPISync as A, PHPResponse as I, PHPExecutionFailureError as _, sandboxedSpawnHandlerFactory as M } from "@php-wasm/universal";
5
- import { sprintf as S } from "@php-wasm/util";
6
- import { runBlueprintV2 as B } from "@wp-playground/blueprints";
7
- import { bootRequestHandler as E } from "@wp-playground/wordpress";
8
- import { existsSync as L } from "fs";
1
+ import { logger as R, errorLogPath as x } from "@php-wasm/logger";
2
+ import { createNodeFsMountHandler as y, loadNodeRuntime as H } from "@php-wasm/node";
3
+ import { EmscriptenDownloadMonitor as v } from "@php-wasm/progress";
4
+ import { exposeAPI as k, PHPWorker as $, consumeAPI as A, consumeAPISync as I, PHPResponse as _, PHPExecutionFailureError as M, sandboxedSpawnHandlerFactory as S } from "@php-wasm/universal";
5
+ import { sprintf as B } from "@php-wasm/util";
6
+ import { runBlueprintV2 as E } from "@wp-playground/blueprints";
7
+ import { bootRequestHandler as L } from "@wp-playground/wordpress";
8
+ import { existsSync as q } from "fs";
9
9
  import P from "path";
10
- import { rootCertificates as q } from "tls";
11
- import { MessageChannel as C, parentPort as O } from "worker_threads";
12
- import { jspi as F } from "wasm-feature-detect";
10
+ import { rootCertificates as C } from "tls";
11
+ import { MessageChannel as O, parentPort as F } from "worker_threads";
12
+ import { jspi as N } from "wasm-feature-detect";
13
13
  async function u(s, e) {
14
14
  for (const r of e)
15
15
  try {
@@ -24,11 +24,11 @@ async function u(s, e) {
24
24
  ), process.exit(1);
25
25
  }
26
26
  }
27
- function N(s, e, ...r) {
27
+ function j(s, e, ...r) {
28
28
  console.log(
29
29
  performance.now().toFixed(6).padStart(15, "0"),
30
30
  s.toString().padStart(16, "0"),
31
- S(e, ...r)
31
+ B(e, ...r)
32
32
  );
33
33
  }
34
34
  Object.defineProperty(process.stdout, "isTTY", { value: !0 });
@@ -48,7 +48,7 @@ const i = {
48
48
  `), i.lastWriteWasProgress = !1), process.stderr.write(s);
49
49
  }
50
50
  };
51
- class D extends k {
51
+ class D extends $ {
52
52
  constructor(e) {
53
53
  super(void 0, e), this.booted = !1, this.blueprintTargetResolved = !1, this.phpInstancesThatNeedMountsAfterTargetResolved = /* @__PURE__ */ new Set();
54
54
  }
@@ -62,7 +62,7 @@ class D extends k {
62
62
  * @see phpwasm-emscripten-library-file-locking-for-node.js
63
63
  */
64
64
  async useFileLockManager(e) {
65
- await F() ? this.fileLockManager = $(e) : this.fileLockManager = await A(e);
65
+ await N() ? this.fileLockManager = A(e) : this.fileLockManager = await I(e);
66
66
  }
67
67
  async bootAsPrimaryWorker(e) {
68
68
  const r = {
@@ -72,7 +72,7 @@ class D extends k {
72
72
  }, p = {
73
73
  ...e,
74
74
  createFiles: {
75
- "/internal/shared/ca-bundle.crt": q.join(`
75
+ "/internal/shared/ca-bundle.crt": C.join(`
76
76
  `)
77
77
  },
78
78
  constants: r,
@@ -111,7 +111,7 @@ class D extends k {
111
111
  };
112
112
  if (typeof e.blueprint == "string") {
113
113
  const n = P.resolve(process.cwd(), e.blueprint);
114
- L(n) && (o.mkdir("/internal/shared/cwd"), f = await o.mount(
114
+ q(n) && (o.mkdir("/internal/shared/cwd"), f = await o.mount(
115
115
  "/internal/shared/cwd",
116
116
  y(P.dirname(n))
117
117
  ), e.blueprint = P.join(
@@ -132,7 +132,7 @@ class D extends k {
132
132
  "allow"
133
133
  ].filter((t) => t in e).map((t) => `--${t}=${e[t]}`);
134
134
  l.push(`--site-url=${e.siteUrl}`);
135
- const d = await B({
135
+ const d = await E({
136
136
  php: p,
137
137
  blueprint: e.blueprint,
138
138
  blueprintOverrides: {
@@ -188,10 +188,10 @@ class D extends k {
188
188
  }
189
189
  })
190
190
  )), await d.finished, await d.exitCode !== 0) {
191
- const t = await I.fromStreamedResponse(
191
+ const t = await _.fromStreamedResponse(
192
192
  d
193
193
  );
194
- throw new _(
194
+ throw new M(
195
195
  `PHP.run() failed with exit code ${t.exitCode}.`,
196
196
  t,
197
197
  "request"
@@ -200,7 +200,7 @@ class D extends k {
200
200
  } catch (n) {
201
201
  let l = "";
202
202
  try {
203
- l = p.readFileAsText(R);
203
+ l = p.readFileAsText(x);
204
204
  } catch {
205
205
  }
206
206
  throw n.phpLogs = l, n;
@@ -226,17 +226,17 @@ class D extends k {
226
226
  throw new Error("Playground already booted");
227
227
  this.booted = !0;
228
228
  let c = n;
229
- const W = n + l - 1;
229
+ const g = n + l - 1;
230
230
  try {
231
- const m = await E({
231
+ const m = await L({
232
232
  siteUrl: e,
233
233
  createPhpRuntime: async () => {
234
234
  const T = c;
235
- return c < W ? c++ : c = n, await x(p, {
235
+ return c < g ? c++ : c = n, await H(p, {
236
236
  emscriptenOptions: {
237
237
  fileLockManager: this.fileLockManager,
238
238
  processId: T,
239
- trace: d ? N : void 0,
239
+ trace: d ? j : void 0,
240
240
  ENV: {
241
241
  DOCROOT: "/wordpress"
242
242
  },
@@ -252,13 +252,13 @@ class D extends k {
252
252
  constants: o,
253
253
  phpIniEntries: f,
254
254
  cookieStore: !1,
255
- spawnHandler: M
255
+ spawnHandler: S
256
256
  });
257
257
  this.__internal_setRequestHandler(m);
258
- const g = await m.getPrimaryPhp();
259
- await this.setPrimaryPHP(g), V();
258
+ const W = await m.getPrimaryPhp();
259
+ await this.setPrimaryPHP(W), U();
260
260
  } catch (m) {
261
- throw j(m), m;
261
+ throw V(m), m;
262
262
  }
263
263
  }
264
264
  // Provide a named disposal method that can be invoked via comlink.
@@ -266,12 +266,15 @@ class D extends k {
266
266
  await this[Symbol.asyncDispose]();
267
267
  }
268
268
  }
269
- const b = new C(), [V, j] = v(
270
- new D(new H()),
269
+ process.on("unhandledRejection", (s) => {
270
+ R.error("Unhandled rejection:", s);
271
+ });
272
+ const b = new O(), [U, V] = k(
273
+ new D(new v()),
271
274
  void 0,
272
275
  b.port1
273
276
  );
274
- O?.postMessage(
277
+ F?.postMessage(
275
278
  {
276
279
  command: "worker-script-initialized",
277
280
  phpPort: b.port2
@@ -1 +1 @@
1
- {"version":3,"file":"worker-thread-v2.js","sources":["../../../../packages/playground/cli/src/blueprints-v2/worker-thread-v2.ts"],"sourcesContent":["import { errorLogPath } from '@php-wasm/logger';\nimport type { FileLockManager } from '@php-wasm/node';\nimport { createNodeFsMountHandler, loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type {\n\tPHP,\n\tFileTree,\n\tRemoteAPI,\n\tSupportedPHPVersion,\n} from '@php-wasm/universal';\nimport {\n\tPHPExecutionFailureError,\n\tPHPResponse,\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport {\n\ttype BlueprintMessage,\n\trunBlueprintV2,\n\ttype BlueprintV1Declaration,\n} from '@wp-playground/blueprints';\nimport {\n\ttype ParsedBlueprintV2String,\n\ttype RawBlueprintV2Data,\n} from '@wp-playground/blueprints';\nimport { bootRequestHandler } from '@wp-playground/wordpress';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport { rootCertificates } from 'tls';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport type { Mount } from '../mounts';\nimport { jspi } from 'wasm-feature-detect';\nimport { type RunCLIArgs } from '../run-cli';\nimport type {\n\tPhpIniOptions,\n\tPHPInstanceCreatedHook,\n} from '@wp-playground/wordpress';\n\nasync function mountResources(php: PHP, mounts: Mount[]) {\n\tfor (const mount of mounts) {\n\t\ttry {\n\t\t\tphp.mkdir(mount.vfsPath);\n\t\t\tawait php.mount(\n\t\t\t\tmount.vfsPath,\n\t\t\t\tcreateNodeFsMountHandler(mount.hostPath)\n\t\t\t);\n\t\t} catch {\n\t\t\toutput.stderr(\n\t\t\t\t`\\x1b[31m\\x1b[1mError mounting path ${mount.hostPath} at ${mount.vfsPath}\\x1b[0m\\n`\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\n/**\n * Force TTY status to preserve ANSI control codes in the output.\n *\n * This script is spawned as `new Worker()` and process.stdout and process.stderr are\n * WritableWorkerStdio objects. By default, they strip ANSI control codes from the output\n * causing every progress bar update to be printed in a new line instead of updating the\n * same line.\n */\nObject.defineProperty(process.stdout, 'isTTY', { value: true });\nObject.defineProperty(process.stderr, 'isTTY', { value: true });\n\n/**\n * Output writer that ensures that progress bars are not printed on the same line as other output.\n */\nconst output = {\n\tlastWriteWasProgress: false,\n\tprogress(data: string) {\n\t\tif (!process.stdout.isTTY) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(data);\n\t\t} else {\n\t\t\tif (!output.lastWriteWasProgress) {\n\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t}\n\t\t\tprocess.stdout.write('\\r\\x1b[K' + data);\n\t\t\toutput.lastWriteWasProgress = true;\n\t\t}\n\t},\n\tstdout(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stdout.write(data);\n\t},\n\tstderr(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stderr.write(data);\n\t},\n};\n\nexport type PrimaryWorkerBootArgs = RunCLIArgs & {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n\tnativeInternalDirPath: string;\n};\n\ntype WorkerRunBlueprintArgs = RunCLIArgs & {\n\tsiteUrl: string;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n};\n\nexport type SecondaryWorkerBootArgs = {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tphpIniEntries?: PhpIniOptions;\n\tconstants?: Record<string, string | number | boolean | null>;\n\tcreateFiles?: FileTree;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\twithXdebug?: boolean;\n\tmountsBeforeWpInstall?: Array<Mount>;\n\tmountsAfterWpInstall?: Array<Mount>;\n};\n\nexport type WorkerBootRequestHandlerOptions = Omit<\n\tSecondaryWorkerBootArgs,\n\t'mountsBeforeWpInstall' | 'mountsAfterWpInstall'\n> & {\n\tonPHPInstanceCreated: PHPInstanceCreatedHook;\n};\n\nexport class PlaygroundCliBlueprintV2Worker extends PHPWorker {\n\tbooted = false;\n\tblueprintTargetResolved = false;\n\tphpInstancesThatNeedMountsAfterTargetResolved = new Set<PHP>();\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker(args: PrimaryWorkerBootArgs) {\n\t\tconst constants = {\n\t\t\tWP_DEBUG: true,\n\t\t\tWP_DEBUG_LOG: true,\n\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t};\n\t\tconst requestHandlerOptions: WorkerBootRequestHandlerOptions = {\n\t\t\t...args,\n\t\t\tcreateFiles: {\n\t\t\t\t'/internal/shared/ca-bundle.crt': rootCertificates.join('\\n'),\n\t\t\t},\n\t\t\tconstants,\n\t\t\tphpIniEntries: {\n\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t},\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\tawait mountResources(php, args['mount-before-install'] || []);\n\t\t\t\tif (this.blueprintTargetResolved) {\n\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t} else {\n\t\t\t\t\t// NOTE: Today (2025-09-11), during boot with a plugin auto-mount,\n\t\t\t\t\t// the Blueprint runner fails unless post-resolution mounts are\n\t\t\t\t\t// added to existing PHP instances. So we track them here so they\n\t\t\t\t\t// can be mounted at the necessary time.\n\t\t\t\t\t// Only plugin auto-mounts seem to need this, so perhaps there\n\t\t\t\t\t// is a change we can make to the Blueprint runner so such\n\t\t\t\t\t// a dance is unnecessary.\n\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.add(php);\n\t\t\t\t\tphp.addEventListener('runtime.beforeExit', () => {\n\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tawait this.bootRequestHandler(requestHandlerOptions);\n\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\n\t\tif (args.mode === 'mount-only') {\n\t\t\tawait mountResources(primaryPhp, args.mount || []);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runBlueprintV2(args);\n\t}\n\n\tasync bootAsSecondaryWorker(args: SecondaryWorkerBootArgs) {\n\t\tawait this.bootRequestHandler({\n\t\t\t...args,\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tawait mountResources(php, args.mountsBeforeWpInstall || []);\n\t\t\t\tawait mountResources(php, args.mountsAfterWpInstall || []);\n\t\t\t},\n\t\t});\n\t}\n\n\tasync runBlueprintV2(args: WorkerRunBlueprintArgs) {\n\t\tconst requestHandler = this.__internal_getRequestHandler()!;\n\t\tconst { php, reap } =\n\t\t\tawait requestHandler.processManager.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: false,\n\t\t\t});\n\n\t\t// Mount the current working directory to the PHP runtime for the purposes of\n\t\t// Blueprint resolution.\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\t\tlet unmountCwd = () => {};\n\t\tif (typeof args.blueprint === 'string') {\n\t\t\tconst blueprintPath = path.resolve(process.cwd(), args.blueprint);\n\t\t\tif (existsSync(blueprintPath)) {\n\t\t\t\tprimaryPhp.mkdir('/internal/shared/cwd');\n\t\t\t\tunmountCwd = await primaryPhp.mount(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tcreateNodeFsMountHandler(path.dirname(blueprintPath))\n\t\t\t\t);\n\t\t\t\targs.blueprint = path.join(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tpath.basename(args.blueprint)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst cliArgsToPass: (keyof WorkerRunBlueprintArgs)[] = [\n\t\t\t\t'mode',\n\t\t\t\t'db-engine',\n\t\t\t\t'db-host',\n\t\t\t\t'db-user',\n\t\t\t\t'db-pass',\n\t\t\t\t'db-name',\n\t\t\t\t'db-path',\n\t\t\t\t'truncate-new-site-directory',\n\t\t\t\t'allow',\n\t\t\t];\n\t\t\tconst cliArgs = cliArgsToPass\n\t\t\t\t.filter((arg) => arg in args)\n\t\t\t\t.map((arg) => `--${arg}=${args[arg]}`);\n\t\t\tcliArgs.push(`--site-url=${args.siteUrl}`);\n\n\t\t\tconst streamedResponse = await runBlueprintV2({\n\t\t\t\tphp,\n\t\t\t\tblueprint: args.blueprint,\n\t\t\t\tblueprintOverrides: {\n\t\t\t\t\tadditionalSteps: args['additional-blueprint-steps'],\n\t\t\t\t\twordpressVersion: args.wp,\n\t\t\t\t},\n\t\t\t\tcliArgs,\n\t\t\t\tonMessage: async (message: BlueprintMessage) => {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'blueprint.target_resolved': {\n\t\t\t\t\t\t\tif (!this.blueprintTargetResolved) {\n\t\t\t\t\t\t\t\tthis.blueprintTargetResolved = true;\n\t\t\t\t\t\t\t\tfor (const php of this\n\t\t\t\t\t\t\t\t\t.phpInstancesThatNeedMountsAfterTargetResolved) {\n\t\t\t\t\t\t\t\t\t// console.log('mounting resources for php', php);\n\t\t\t\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.progress': {\n\t\t\t\t\t\t\tconst progressMessage = `${message.caption.trim()} – ${message.progress.toFixed(\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t)}%`;\n\t\t\t\t\t\t\toutput.progress(progressMessage);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.error': {\n\t\t\t\t\t\t\tconst red = '\\x1b[31m';\n\t\t\t\t\t\t\tconst bold = '\\x1b[1m';\n\t\t\t\t\t\t\tconst reset = '\\x1b[0m';\n\t\t\t\t\t\t\tif (args.debug && message.details) {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Fatal error:${reset} Uncaught ${message.details.exception}: ${message.details.message}\\n` +\n\t\t\t\t\t\t\t\t\t\t` at ${message.details.file}:${message.details.line}\\n` +\n\t\t\t\t\t\t\t\t\t\t(message.details.trace\n\t\t\t\t\t\t\t\t\t\t\t? message.details.trace + '\\n'\n\t\t\t\t\t\t\t\t\t\t\t: '')\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Error:${reset} ${message.message}\\n`\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\t/**\n\t\t\t * When we're debugging, every bit of information matters – let's immediately output\n\t\t\t * everything we get from the PHP output streams.\n\t\t\t */\n\t\t\tif (args.debug) {\n\t\t\t\tstreamedResponse!.stdout.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tstreamedResponse!.stderr.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stderr.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait streamedResponse!.finished;\n\t\t\tif ((await streamedResponse!.exitCode) !== 0) {\n\t\t\t\t// exitCode != 1 means the blueprint execution failed. Let's throw an error.\n\t\t\t\t// and clean up.\n\t\t\t\tconst syncResponse = await PHPResponse.fromStreamedResponse(\n\t\t\t\t\tstreamedResponse\n\t\t\t\t);\n\t\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}.`,\n\t\t\t\t\tsyncResponse,\n\t\t\t\t\t'request'\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Capture the PHP error log details to provide more context for debugging.\n\t\t\tlet phpLogs = '';\n\t\t\ttry {\n\t\t\t\t// @TODO: Don't assume errorLogPath starts with /wordpress/\n\t\t\t\t// ...or maybe we can assume that in Playground CLI?\n\t\t\t\tphpLogs = php.readFileAsText(errorLogPath);\n\t\t\t} catch {\n\t\t\t\t// Ignore errors reading the PHP error log.\n\t\t\t}\n\t\t\t(error as any).phpLogs = phpLogs;\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\treap();\n\t\t\tunmountCwd();\n\t\t}\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tcreateFiles,\n\t\tconstants,\n\t\tphpIniEntries,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\twithXdebug,\n\t\tonPHPInstanceCreated,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles,\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries,\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV2Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["mountResources","php","mounts","mount","createNodeFsMountHandler","output","tracePhpWasm","processId","format","args","sprintf","data","PlaygroundCliBlueprintV2Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","constants","requestHandlerOptions","rootCertificates","primaryPhp","requestHandler","reap","unmountCwd","blueprintPath","path","existsSync","cliArgs","arg","streamedResponse","runBlueprintV2","message","progressMessage","red","bold","reset","chunk","syncResponse","PHPResponse","PHPExecutionFailureError","error","phpLogs","errorLogPath","siteUrl","allow","phpVersion","createFiles","phpIniEntries","firstProcessId","processIdSpaceLength","trace","nativeInternalDirPath","withXdebug","onPHPInstanceCreated","nextProcessId","lastProcessId","bootRequestHandler","loadNodeRuntime","sandboxedSpawnHandlerFactory","setApiReady","e","setAPIError","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}
1
+ {"version":3,"file":"worker-thread-v2.js","sources":["../../../../packages/playground/cli/src/blueprints-v2/worker-thread-v2.ts"],"sourcesContent":["import { errorLogPath, logger } from '@php-wasm/logger';\nimport type { FileLockManager } from '@php-wasm/node';\nimport { createNodeFsMountHandler, loadNodeRuntime } from '@php-wasm/node';\nimport { EmscriptenDownloadMonitor } from '@php-wasm/progress';\nimport type {\n\tPHP,\n\tFileTree,\n\tRemoteAPI,\n\tSupportedPHPVersion,\n} from '@php-wasm/universal';\nimport {\n\tPHPExecutionFailureError,\n\tPHPResponse,\n\tPHPWorker,\n\tconsumeAPI,\n\tconsumeAPISync,\n\texposeAPI,\n\tsandboxedSpawnHandlerFactory,\n} from '@php-wasm/universal';\nimport { sprintf } from '@php-wasm/util';\nimport {\n\ttype BlueprintMessage,\n\trunBlueprintV2,\n\ttype BlueprintV1Declaration,\n} from '@wp-playground/blueprints';\nimport {\n\ttype ParsedBlueprintV2String,\n\ttype RawBlueprintV2Data,\n} from '@wp-playground/blueprints';\nimport { bootRequestHandler } from '@wp-playground/wordpress';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport { rootCertificates } from 'tls';\nimport { MessageChannel, type MessagePort, parentPort } from 'worker_threads';\nimport type { Mount } from '../mounts';\nimport { jspi } from 'wasm-feature-detect';\nimport { type RunCLIArgs } from '../run-cli';\nimport type {\n\tPhpIniOptions,\n\tPHPInstanceCreatedHook,\n} from '@wp-playground/wordpress';\n\nasync function mountResources(php: PHP, mounts: Mount[]) {\n\tfor (const mount of mounts) {\n\t\ttry {\n\t\t\tphp.mkdir(mount.vfsPath);\n\t\t\tawait php.mount(\n\t\t\t\tmount.vfsPath,\n\t\t\t\tcreateNodeFsMountHandler(mount.hostPath)\n\t\t\t);\n\t\t} catch {\n\t\t\toutput.stderr(\n\t\t\t\t`\\x1b[31m\\x1b[1mError mounting path ${mount.hostPath} at ${mount.vfsPath}\\x1b[0m\\n`\n\t\t\t);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n}\n\n/**\n * Print trace messages from PHP-WASM.\n *\n * @param {number} processId - The process ID.\n * @param {string} format - The format string.\n * @param {...any} args - The arguments.\n */\nfunction tracePhpWasm(processId: number, format: string, ...args: any[]) {\n\t// eslint-disable-next-line no-console\n\tconsole.log(\n\t\tperformance.now().toFixed(6).padStart(15, '0'),\n\t\tprocessId.toString().padStart(16, '0'),\n\t\tsprintf(format, ...args)\n\t);\n}\n\n/**\n * Force TTY status to preserve ANSI control codes in the output.\n *\n * This script is spawned as `new Worker()` and process.stdout and process.stderr are\n * WritableWorkerStdio objects. By default, they strip ANSI control codes from the output\n * causing every progress bar update to be printed in a new line instead of updating the\n * same line.\n */\nObject.defineProperty(process.stdout, 'isTTY', { value: true });\nObject.defineProperty(process.stderr, 'isTTY', { value: true });\n\n/**\n * Output writer that ensures that progress bars are not printed on the same line as other output.\n */\nconst output = {\n\tlastWriteWasProgress: false,\n\tprogress(data: string) {\n\t\tif (!process.stdout.isTTY) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(data);\n\t\t} else {\n\t\t\tif (!output.lastWriteWasProgress) {\n\t\t\t\tprocess.stdout.write('\\n');\n\t\t\t}\n\t\t\tprocess.stdout.write('\\r\\x1b[K' + data);\n\t\t\toutput.lastWriteWasProgress = true;\n\t\t}\n\t},\n\tstdout(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stdout.write(data);\n\t},\n\tstderr(data: string) {\n\t\tif (output.lastWriteWasProgress) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\toutput.lastWriteWasProgress = false;\n\t\t}\n\t\tprocess.stderr.write(data);\n\t},\n};\n\nexport type PrimaryWorkerBootArgs = RunCLIArgs & {\n\tphpVersion: SupportedPHPVersion;\n\tsiteUrl: string;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n\tnativeInternalDirPath: string;\n};\n\ntype WorkerRunBlueprintArgs = RunCLIArgs & {\n\tsiteUrl: string;\n\tblueprint:\n\t\t| RawBlueprintV2Data\n\t\t| ParsedBlueprintV2String\n\t\t| BlueprintV1Declaration;\n};\n\nexport type SecondaryWorkerBootArgs = {\n\tsiteUrl: string;\n\tallow?: string;\n\tphpVersion: SupportedPHPVersion;\n\tphpIniEntries?: PhpIniOptions;\n\tconstants?: Record<string, string | number | boolean | null>;\n\tcreateFiles?: FileTree;\n\tfirstProcessId: number;\n\tprocessIdSpaceLength: number;\n\ttrace: boolean;\n\tnativeInternalDirPath: string;\n\twithXdebug?: boolean;\n\tmountsBeforeWpInstall?: Array<Mount>;\n\tmountsAfterWpInstall?: Array<Mount>;\n};\n\nexport type WorkerBootRequestHandlerOptions = Omit<\n\tSecondaryWorkerBootArgs,\n\t'mountsBeforeWpInstall' | 'mountsAfterWpInstall'\n> & {\n\tonPHPInstanceCreated: PHPInstanceCreatedHook;\n};\n\nexport class PlaygroundCliBlueprintV2Worker extends PHPWorker {\n\tbooted = false;\n\tblueprintTargetResolved = false;\n\tphpInstancesThatNeedMountsAfterTargetResolved = new Set<PHP>();\n\tfileLockManager: RemoteAPI<FileLockManager> | FileLockManager | undefined;\n\n\tconstructor(monitor: EmscriptenDownloadMonitor) {\n\t\tsuper(undefined, monitor);\n\t}\n\n\t/**\n\t * Call this method before boot() to use file locking.\n\t *\n\t * This method is separate from boot() to simplify the related Comlink.transferHandlers\n\t * setup – if an argument is a MessagePort, we're transferring it, not copying it.\n\t *\n\t * @see comlink-sync.ts\n\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t */\n\tasync useFileLockManager(port: MessagePort) {\n\t\tif (await jspi()) {\n\t\t\t/**\n\t\t\t * If JSPI is available, php.js supports both synchronous and asynchronous locking syscalls.\n\t\t\t * Web browsers, however, only support asynchronous message passing so let's use the\n\t\t\t * asynchronous API. Every method call will return a promise.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = consumeAPI<FileLockManager>(port);\n\t\t} else {\n\t\t\t/**\n\t\t\t * If JSPI is not available, php.js only supports synchronous locking syscalls.\n\t\t\t * Let's use the synchronous API. Every method call will block this thread\n\t\t\t * until the result is available.\n\t\t\t *\n\t\t\t * @see comlink-sync.ts\n\t\t\t * @see phpwasm-emscripten-library-file-locking-for-node.js\n\t\t\t */\n\t\t\tthis.fileLockManager = await consumeAPISync<FileLockManager>(port);\n\t\t}\n\t}\n\n\tasync bootAsPrimaryWorker(args: PrimaryWorkerBootArgs) {\n\t\tconst constants = {\n\t\t\tWP_DEBUG: true,\n\t\t\tWP_DEBUG_LOG: true,\n\t\t\tWP_DEBUG_DISPLAY: false,\n\t\t};\n\t\tconst requestHandlerOptions: WorkerBootRequestHandlerOptions = {\n\t\t\t...args,\n\t\t\tcreateFiles: {\n\t\t\t\t'/internal/shared/ca-bundle.crt': rootCertificates.join('\\n'),\n\t\t\t},\n\t\t\tconstants,\n\t\t\tphpIniEntries: {\n\t\t\t\t'openssl.cafile': '/internal/shared/ca-bundle.crt',\n\t\t\t},\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tthis.registerWorkerListeners(php);\n\t\t\t\tawait mountResources(php, args['mount-before-install'] || []);\n\t\t\t\tif (this.blueprintTargetResolved) {\n\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t} else {\n\t\t\t\t\t// NOTE: Today (2025-09-11), during boot with a plugin auto-mount,\n\t\t\t\t\t// the Blueprint runner fails unless post-resolution mounts are\n\t\t\t\t\t// added to existing PHP instances. So we track them here so they\n\t\t\t\t\t// can be mounted at the necessary time.\n\t\t\t\t\t// Only plugin auto-mounts seem to need this, so perhaps there\n\t\t\t\t\t// is a change we can make to the Blueprint runner so such\n\t\t\t\t\t// a dance is unnecessary.\n\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.add(php);\n\t\t\t\t\tphp.addEventListener('runtime.beforeExit', () => {\n\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t\tawait this.bootRequestHandler(requestHandlerOptions);\n\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\n\t\tif (args.mode === 'mount-only') {\n\t\t\tawait mountResources(primaryPhp, args.mount || []);\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.runBlueprintV2(args);\n\t}\n\n\tasync bootAsSecondaryWorker(args: SecondaryWorkerBootArgs) {\n\t\tawait this.bootRequestHandler({\n\t\t\t...args,\n\t\t\tonPHPInstanceCreated: async (php: PHP) => {\n\t\t\t\tawait mountResources(php, args.mountsBeforeWpInstall || []);\n\t\t\t\tawait mountResources(php, args.mountsAfterWpInstall || []);\n\t\t\t},\n\t\t});\n\t}\n\n\tasync runBlueprintV2(args: WorkerRunBlueprintArgs) {\n\t\tconst requestHandler = this.__internal_getRequestHandler()!;\n\t\tconst { php, reap } =\n\t\t\tawait requestHandler.processManager.acquirePHPInstance({\n\t\t\t\tconsiderPrimary: false,\n\t\t\t});\n\n\t\t// Mount the current working directory to the PHP runtime for the purposes of\n\t\t// Blueprint resolution.\n\t\tconst primaryPhp = this.__internal_getPHP()!;\n\t\tlet unmountCwd = () => {};\n\t\tif (typeof args.blueprint === 'string') {\n\t\t\tconst blueprintPath = path.resolve(process.cwd(), args.blueprint);\n\t\t\tif (existsSync(blueprintPath)) {\n\t\t\t\tprimaryPhp.mkdir('/internal/shared/cwd');\n\t\t\t\tunmountCwd = await primaryPhp.mount(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tcreateNodeFsMountHandler(path.dirname(blueprintPath))\n\t\t\t\t);\n\t\t\t\targs.blueprint = path.join(\n\t\t\t\t\t'/internal/shared/cwd',\n\t\t\t\t\tpath.basename(args.blueprint)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst cliArgsToPass: (keyof WorkerRunBlueprintArgs)[] = [\n\t\t\t\t'mode',\n\t\t\t\t'db-engine',\n\t\t\t\t'db-host',\n\t\t\t\t'db-user',\n\t\t\t\t'db-pass',\n\t\t\t\t'db-name',\n\t\t\t\t'db-path',\n\t\t\t\t'truncate-new-site-directory',\n\t\t\t\t'allow',\n\t\t\t];\n\t\t\tconst cliArgs = cliArgsToPass\n\t\t\t\t.filter((arg) => arg in args)\n\t\t\t\t.map((arg) => `--${arg}=${args[arg]}`);\n\t\t\tcliArgs.push(`--site-url=${args.siteUrl}`);\n\n\t\t\tconst streamedResponse = await runBlueprintV2({\n\t\t\t\tphp,\n\t\t\t\tblueprint: args.blueprint,\n\t\t\t\tblueprintOverrides: {\n\t\t\t\t\tadditionalSteps: args['additional-blueprint-steps'],\n\t\t\t\t\twordpressVersion: args.wp,\n\t\t\t\t},\n\t\t\t\tcliArgs,\n\t\t\t\tonMessage: async (message: BlueprintMessage) => {\n\t\t\t\t\tswitch (message.type) {\n\t\t\t\t\t\tcase 'blueprint.target_resolved': {\n\t\t\t\t\t\t\tif (!this.blueprintTargetResolved) {\n\t\t\t\t\t\t\t\tthis.blueprintTargetResolved = true;\n\t\t\t\t\t\t\t\tfor (const php of this\n\t\t\t\t\t\t\t\t\t.phpInstancesThatNeedMountsAfterTargetResolved) {\n\t\t\t\t\t\t\t\t\t// console.log('mounting resources for php', php);\n\t\t\t\t\t\t\t\t\tthis.phpInstancesThatNeedMountsAfterTargetResolved.delete(\n\t\t\t\t\t\t\t\t\t\tphp\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tawait mountResources(php, args.mount || []);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.progress': {\n\t\t\t\t\t\t\tconst progressMessage = `${message.caption.trim()} – ${message.progress.toFixed(\n\t\t\t\t\t\t\t\t2\n\t\t\t\t\t\t\t)}%`;\n\t\t\t\t\t\t\toutput.progress(progressMessage);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'blueprint.error': {\n\t\t\t\t\t\t\tconst red = '\\x1b[31m';\n\t\t\t\t\t\t\tconst bold = '\\x1b[1m';\n\t\t\t\t\t\t\tconst reset = '\\x1b[0m';\n\t\t\t\t\t\t\tif (args.debug && message.details) {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Fatal error:${reset} Uncaught ${message.details.exception}: ${message.details.message}\\n` +\n\t\t\t\t\t\t\t\t\t\t` at ${message.details.file}:${message.details.line}\\n` +\n\t\t\t\t\t\t\t\t\t\t(message.details.trace\n\t\t\t\t\t\t\t\t\t\t\t? message.details.trace + '\\n'\n\t\t\t\t\t\t\t\t\t\t\t: '')\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toutput.stderr(\n\t\t\t\t\t\t\t\t\t`${red}${bold}Error:${reset} ${message.message}\\n`\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\t/**\n\t\t\t * When we're debugging, every bit of information matters – let's immediately output\n\t\t\t * everything we get from the PHP output streams.\n\t\t\t */\n\t\t\tif (args.debug) {\n\t\t\t\tstreamedResponse!.stdout.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stdout.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t\tstreamedResponse!.stderr.pipeTo(\n\t\t\t\t\tnew WritableStream({\n\t\t\t\t\t\twrite(chunk) {\n\t\t\t\t\t\t\tprocess.stderr.write(chunk);\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait streamedResponse!.finished;\n\t\t\tif ((await streamedResponse!.exitCode) !== 0) {\n\t\t\t\t// exitCode != 1 means the blueprint execution failed. Let's throw an error.\n\t\t\t\t// and clean up.\n\t\t\t\tconst syncResponse = await PHPResponse.fromStreamedResponse(\n\t\t\t\t\tstreamedResponse\n\t\t\t\t);\n\t\t\t\tthrow new PHPExecutionFailureError(\n\t\t\t\t\t`PHP.run() failed with exit code ${syncResponse.exitCode}.`,\n\t\t\t\t\tsyncResponse,\n\t\t\t\t\t'request'\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Capture the PHP error log details to provide more context for debugging.\n\t\t\tlet phpLogs = '';\n\t\t\ttry {\n\t\t\t\t// @TODO: Don't assume errorLogPath starts with /wordpress/\n\t\t\t\t// ...or maybe we can assume that in Playground CLI?\n\t\t\t\tphpLogs = php.readFileAsText(errorLogPath);\n\t\t\t} catch {\n\t\t\t\t// Ignore errors reading the PHP error log.\n\t\t\t}\n\t\t\t(error as any).phpLogs = phpLogs;\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\treap();\n\t\t\tunmountCwd();\n\t\t}\n\t}\n\n\tasync bootRequestHandler({\n\t\tsiteUrl,\n\t\tallow,\n\t\tphpVersion,\n\t\tcreateFiles,\n\t\tconstants,\n\t\tphpIniEntries,\n\t\tfirstProcessId,\n\t\tprocessIdSpaceLength,\n\t\ttrace,\n\t\tnativeInternalDirPath,\n\t\twithXdebug,\n\t\tonPHPInstanceCreated,\n\t}: WorkerBootRequestHandlerOptions) {\n\t\tif (this.booted) {\n\t\t\tthrow new Error('Playground already booted');\n\t\t}\n\t\tthis.booted = true;\n\n\t\tlet nextProcessId = firstProcessId;\n\t\tconst lastProcessId = firstProcessId + processIdSpaceLength - 1;\n\n\t\ttry {\n\t\t\tconst requestHandler = await bootRequestHandler({\n\t\t\t\tsiteUrl,\n\t\t\t\tcreatePhpRuntime: async () => {\n\t\t\t\t\tconst processId = nextProcessId;\n\n\t\t\t\t\tif (nextProcessId < lastProcessId) {\n\t\t\t\t\t\tnextProcessId++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We've reached the end of the process ID space. Start over.\n\t\t\t\t\t\tnextProcessId = firstProcessId;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn await loadNodeRuntime(phpVersion, {\n\t\t\t\t\t\temscriptenOptions: {\n\t\t\t\t\t\t\tfileLockManager: this.fileLockManager!,\n\t\t\t\t\t\t\tprocessId,\n\t\t\t\t\t\t\ttrace: trace ? tracePhpWasm : undefined,\n\t\t\t\t\t\t\tENV: {\n\t\t\t\t\t\t\t\tDOCROOT: '/wordpress',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tphpWasmInitOptions: { nativeInternalDirPath },\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfollowSymlinks: allow?.includes('follow-symlinks'),\n\t\t\t\t\t\twithXdebug,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tonPHPInstanceCreated,\n\t\t\t\tsapiName: 'cli',\n\t\t\t\tcreateFiles,\n\t\t\t\tconstants,\n\t\t\t\tphpIniEntries,\n\t\t\t\tcookieStore: false,\n\t\t\t\tspawnHandler: sandboxedSpawnHandlerFactory,\n\t\t\t});\n\t\t\tthis.__internal_setRequestHandler(requestHandler);\n\n\t\t\tconst primaryPhp = await requestHandler.getPrimaryPhp();\n\t\t\tawait this.setPrimaryPHP(primaryPhp);\n\n\t\t\tsetApiReady();\n\t\t} catch (e) {\n\t\t\tsetAPIError(e as Error);\n\t\t\tthrow e;\n\t\t}\n\t}\n\n\t// Provide a named disposal method that can be invoked via comlink.\n\tasync dispose() {\n\t\tawait this[Symbol.asyncDispose]();\n\t}\n}\n\nprocess.on('unhandledRejection', (e: any) => {\n\tlogger.error('Unhandled rejection:', e);\n});\n\nconst phpChannel = new MessageChannel();\n\nconst [setApiReady, setAPIError] = exposeAPI(\n\tnew PlaygroundCliBlueprintV2Worker(new EmscriptenDownloadMonitor()),\n\tundefined,\n\tphpChannel.port1\n);\n\nparentPort?.postMessage(\n\t{\n\t\tcommand: 'worker-script-initialized',\n\t\tphpPort: phpChannel.port2,\n\t},\n\t[phpChannel.port2 as any]\n);\n"],"names":["mountResources","php","mounts","mount","createNodeFsMountHandler","output","tracePhpWasm","processId","format","args","sprintf","data","PlaygroundCliBlueprintV2Worker","PHPWorker","monitor","port","jspi","consumeAPI","consumeAPISync","constants","requestHandlerOptions","rootCertificates","primaryPhp","requestHandler","reap","unmountCwd","blueprintPath","path","existsSync","cliArgs","arg","streamedResponse","runBlueprintV2","message","progressMessage","red","bold","reset","chunk","syncResponse","PHPResponse","PHPExecutionFailureError","error","phpLogs","errorLogPath","siteUrl","allow","phpVersion","createFiles","phpIniEntries","firstProcessId","processIdSpaceLength","trace","nativeInternalDirPath","withXdebug","onPHPInstanceCreated","nextProcessId","lastProcessId","bootRequestHandler","loadNodeRuntime","sandboxedSpawnHandlerFactory","setApiReady","e","setAPIError","logger","phpChannel","MessageChannel","exposeAPI","EmscriptenDownloadMonitor","parentPort"],"mappings":"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"}