@wp-playground/cli 3.0.5 → 3.0.8

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.5",
3
+ "version": "3.0.8",
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": "25f366144172f93d8500031c612bf197638fe78c",
37
+ "gitHead": "a1128d0626073076640e7acd088cd3c9c70916c2",
38
38
  "dependencies": {
39
39
  "@zip.js/zip.js": "2.7.57",
40
40
  "ajv": "8.12.0",
@@ -59,22 +59,23 @@
59
59
  "ws": "8.18.1",
60
60
  "xml2js": "0.6.2",
61
61
  "yargs": "17.7.2",
62
- "@php-wasm/logger": "3.0.5",
63
- "@php-wasm/progress": "3.0.5",
64
- "@php-wasm/universal": "3.0.5",
65
- "@wp-playground/blueprints": "3.0.5",
66
- "@wp-playground/common": "3.0.5",
67
- "@wp-playground/wordpress": "3.0.5",
68
- "@php-wasm/node": "3.0.5",
69
- "@php-wasm/util": "3.0.5",
70
- "@wp-playground/storage": "3.0.5",
71
- "@php-wasm/xdebug-bridge": "3.0.5"
62
+ "@php-wasm/logger": "3.0.8",
63
+ "@php-wasm/progress": "3.0.8",
64
+ "@php-wasm/universal": "3.0.8",
65
+ "@wp-playground/blueprints": "3.0.8",
66
+ "@wp-playground/common": "3.0.8",
67
+ "@wp-playground/wordpress": "3.0.8",
68
+ "@php-wasm/node": "3.0.8",
69
+ "@php-wasm/util": "3.0.8",
70
+ "@wp-playground/storage": "3.0.8",
71
+ "@php-wasm/xdebug-bridge": "3.0.8"
72
72
  },
73
73
  "overrides": {
74
74
  "rollup": "^4.34.6",
75
75
  "react": "18.3.1",
76
76
  "react-dom": "18.3.1",
77
77
  "typescript": "5.4.5",
78
+ "@playwright/test": "1.47.1",
78
79
  "ws": "^8.18.0"
79
80
  },
80
81
  "optionalDependencies": {
@@ -1,3 +1,3 @@
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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@php-wasm/node"),L=require("@php-wasm/progress"),n=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"),M=require("worker_threads"),c=require("./mounts-BJFrPHGW.cjs"),F=require("@php-wasm/logger");function S(l,e,...s){console.log(performance.now().toFixed(6).padStart(15,"0"),l.toString().padStart(16,"0"),O.sprintf(e,...s))}class W extends n.PHPWorker{constructor(e){super(void 0,e),this.booted=!1}async useFileLockManager(e){await D.jspi()?this.fileLockManager=n.consumeAPI(e):this.fileLockManager=await n.consumeAPISync(e)}async bootAsPrimaryWorker({siteUrl:e,mountsBeforeWpInstall:s,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 E=i+m-1;try{const P={WP_DEBUG:!0,WP_DEBUG_LOG:!0,WP_DEBUG_DISPLAY:!1};let q=!1;const R=await _.bootWordPressAndRequestHandler({siteUrl:e,createPhpRuntime:async()=>{const h=w;return w<E?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:n.sandboxedSpawnHandlerFactory,async onPHPInstanceCreated(h){await c.mountResources(h,s),q&&await c.mountResources(h,d)}});this.__internal_setRequestHandler(R),q=!0;const k=await R.getPrimaryPhp();await this.setPrimaryPHP(k),await c.mountResources(k,d),v()}catch(P){throw I(P),P}}async bootAsSecondaryWorker(e){await this.bootRequestHandler(e)}async bootRequestHandler({siteUrl:e,allow:s,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:s?.includes("follow-symlinks")})},onPHPInstanceCreated:async r=>{await c.mountResources(r,m),await c.mountResources(r,y)},sapiName:"cli",cookieStore:!1,spawnHandler:n.sandboxedSpawnHandlerFactory});this.__internal_setRequestHandler(t);const f=await t.getPrimaryPhp();await this.setPrimaryPHP(f),v()}catch(t){throw I(t),t}}async dispose(){await this[Symbol.asyncDispose]()}}process.on("unhandledRejection",l=>{F.logger.error("Unhandled rejection:",l)});const b=new M.MessageChannel,[v,I]=n.exposeAPI(new W(new L.EmscriptenDownloadMonitor),void 0,b.port1);M.parentPort?.postMessage({command:"worker-script-initialized",phpPort:b.port2},[b.port2]);exports.PlaygroundCliBlueprintV1Worker=W;
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';\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
+ {"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\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,13 +1,13 @@
1
1
  import { loadNodeRuntime as R } from "@php-wasm/node";
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 _ } from "@php-wasm/universal";
2
+ import { EmscriptenDownloadMonitor as q } from "@php-wasm/progress";
3
+ import { exposeAPI as v, PHPWorker as E, consumeAPI as L, 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
9
  import { MessageChannel as j, parentPort as G } from "worker_threads";
10
- import { m as i } from "./mounts-D1_eXSTw.js";
10
+ import { m as s } from "./mounts-D1_eXSTw.js";
11
11
  import { logger as N } from "@php-wasm/logger";
12
12
  function I(c, e, ...a) {
13
13
  console.log(
@@ -16,7 +16,7 @@ function I(c, e, ...a) {
16
16
  O(e, ...a)
17
17
  );
18
18
  }
19
- class U extends v {
19
+ class U extends E {
20
20
  constructor(e) {
21
21
  super(void 0, e), this.booted = !1;
22
22
  }
@@ -30,7 +30,7 @@ class U extends v {
30
30
  * @see phpwasm-emscripten-library-file-locking-for-node.js
31
31
  */
32
32
  async useFileLockManager(e) {
33
- await B() ? this.fileLockManager = E(e) : this.fileLockManager = await A(e);
33
+ await B() ? this.fileLockManager = L(e) : this.fileLockManager = await A(e);
34
34
  }
35
35
  async bootAsPrimaryWorker({
36
36
  siteUrl: e,
@@ -39,20 +39,20 @@ class U extends v {
39
39
  phpVersion: n = x,
40
40
  wordPressZip: d,
41
41
  sqliteIntegrationPluginZip: p,
42
- firstProcessId: s,
42
+ firstProcessId: i,
43
43
  processIdSpaceLength: P,
44
44
  dataSqlPath: u,
45
- followSymlinks: r,
45
+ followSymlinks: o,
46
46
  trace: f,
47
47
  internalCookieStore: t,
48
48
  withXdebug: y,
49
- nativeInternalDirPath: o
49
+ nativeInternalDirPath: r
50
50
  }) {
51
51
  if (this.booted)
52
52
  throw new Error("Playground already booted");
53
53
  this.booted = !0;
54
- let m = s;
55
- const L = s + P - 1;
54
+ let m = i;
55
+ const W = i + P - 1;
56
56
  try {
57
57
  const w = {
58
58
  WP_DEBUG: !0,
@@ -60,18 +60,18 @@ class U extends v {
60
60
  WP_DEBUG_DISPLAY: !1
61
61
  };
62
62
  let b = !1;
63
- const k = await C({
63
+ const H = await C({
64
64
  siteUrl: e,
65
65
  createPhpRuntime: async () => {
66
66
  const h = m;
67
- return m < L ? m++ : m = s, await R(n, {
67
+ return m < W ? m++ : m = i, await R(n, {
68
68
  emscriptenOptions: {
69
69
  fileLockManager: this.fileLockManager,
70
70
  processId: h,
71
71
  trace: f ? I : void 0,
72
- phpWasmInitOptions: { nativeInternalDirPath: o }
72
+ phpWasmInitOptions: { nativeInternalDirPath: r }
73
73
  },
74
- followSymlinks: r,
74
+ followSymlinks: o,
75
75
  withXdebug: y
76
76
  });
77
77
  },
@@ -95,14 +95,14 @@ class U extends v {
95
95
  dataSqlPath: u,
96
96
  spawnHandler: _,
97
97
  async onPHPInstanceCreated(h) {
98
- await i(h, a), b && await i(h, l);
98
+ await s(h, a), b && await s(h, l);
99
99
  }
100
100
  });
101
- this.__internal_setRequestHandler(k), b = !0;
102
- const H = await k.getPrimaryPhp();
103
- await this.setPrimaryPHP(H), await i(H, l), S();
101
+ this.__internal_setRequestHandler(H), b = !0;
102
+ const k = await H.getPrimaryPhp();
103
+ await this.setPrimaryPHP(k), await s(k, l), S();
104
104
  } catch (w) {
105
- throw W(w), w;
105
+ throw M(w), w;
106
106
  }
107
107
  }
108
108
  async bootAsSecondaryWorker(e) {
@@ -115,35 +115,35 @@ class U extends v {
115
115
  firstProcessId: n,
116
116
  processIdSpaceLength: d,
117
117
  trace: p,
118
- nativeInternalDirPath: s,
118
+ nativeInternalDirPath: i,
119
119
  mountsBeforeWpInstall: P,
120
120
  mountsAfterWpInstall: u
121
121
  }) {
122
122
  if (this.booted)
123
123
  throw new Error("Playground already booted");
124
124
  this.booted = !0;
125
- let r = n;
125
+ let o = n;
126
126
  const f = n + d - 1;
127
127
  try {
128
128
  const t = await D({
129
129
  siteUrl: e,
130
130
  createPhpRuntime: async () => {
131
- const o = r;
132
- return r < f ? r++ : r = n, await R(l, {
131
+ const r = o;
132
+ return o < f ? o++ : o = n, await R(l, {
133
133
  emscriptenOptions: {
134
134
  fileLockManager: this.fileLockManager,
135
- processId: o,
135
+ processId: r,
136
136
  trace: p ? I : void 0,
137
137
  ENV: {
138
138
  DOCROOT: "/wordpress"
139
139
  },
140
- phpWasmInitOptions: { nativeInternalDirPath: s }
140
+ phpWasmInitOptions: { nativeInternalDirPath: i }
141
141
  },
142
142
  followSymlinks: a?.includes("follow-symlinks")
143
143
  });
144
144
  },
145
- onPHPInstanceCreated: async (o) => {
146
- this.registerWorkerListeners(o), await i(o, P), await i(o, u);
145
+ onPHPInstanceCreated: async (r) => {
146
+ await s(r, P), await s(r, u);
147
147
  },
148
148
  sapiName: "cli",
149
149
  cookieStore: !1,
@@ -153,7 +153,7 @@ class U extends v {
153
153
  const y = await t.getPrimaryPhp();
154
154
  await this.setPrimaryPHP(y), S();
155
155
  } catch (t) {
156
- throw W(t), t;
156
+ throw M(t), t;
157
157
  }
158
158
  }
159
159
  // Provide a named disposal method that can be invoked via comlink.
@@ -164,8 +164,8 @@ class U extends v {
164
164
  process.on("unhandledRejection", (c) => {
165
165
  N.error("Unhandled rejection:", c);
166
166
  });
167
- const g = new j(), [S, W] = q(
168
- new U(new M()),
167
+ const g = new j(), [S, M] = v(
168
+ new U(new q()),
169
169
  void 0,
170
170
  g.port1
171
171
  );
@@ -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';\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
+ {"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\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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"}
@@ -3,7 +3,7 @@
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
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
- `)},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}
6
+ `)},constants:r,phpIniEntries:{"openssl.cafile":"/internal/shared/ca-bundle.crt"},onPHPInstanceCreated:async 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}
@@ -1 +1 @@
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
+ {"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\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,11 +1,11 @@
1
1
  import { logger as R, errorLogPath as x } from "@php-wasm/logger";
2
2
  import { createNodeFsMountHandler as y, loadNodeRuntime as H } from "@php-wasm/node";
3
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";
4
+ import { exposeAPI as $, PHPWorker as k, consumeAPI as A, consumeAPISync as I, PHPResponse as _, PHPExecutionFailureError as M, sandboxedSpawnHandlerFactory as S } from "@php-wasm/universal";
5
5
  import { sprintf as B } from "@php-wasm/util";
6
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";
7
+ import { bootRequestHandler as q } from "@wp-playground/wordpress";
8
+ import { existsSync as L } from "fs";
9
9
  import P from "path";
10
10
  import { rootCertificates as C } from "tls";
11
11
  import { MessageChannel as O, parentPort as F } from "worker_threads";
@@ -48,7 +48,7 @@ const i = {
48
48
  `), i.lastWriteWasProgress = !1), process.stderr.write(s);
49
49
  }
50
50
  };
51
- class D extends $ {
51
+ class D extends k {
52
52
  constructor(e) {
53
53
  super(void 0, e), this.booted = !1, this.blueprintTargetResolved = !1, this.phpInstancesThatNeedMountsAfterTargetResolved = /* @__PURE__ */ new Set();
54
54
  }
@@ -80,7 +80,7 @@ class D extends $ {
80
80
  "openssl.cafile": "/internal/shared/ca-bundle.crt"
81
81
  },
82
82
  onPHPInstanceCreated: async (o) => {
83
- this.registerWorkerListeners(o), await u(o, e["mount-before-install"] || []), this.blueprintTargetResolved ? await u(o, e.mount || []) : (this.phpInstancesThatNeedMountsAfterTargetResolved.add(o), o.addEventListener("runtime.beforeExit", () => {
83
+ await u(o, e["mount-before-install"] || []), this.blueprintTargetResolved ? await u(o, e.mount || []) : (this.phpInstancesThatNeedMountsAfterTargetResolved.add(o), o.addEventListener("runtime.beforeExit", () => {
84
84
  this.phpInstancesThatNeedMountsAfterTargetResolved.delete(
85
85
  o
86
86
  );
@@ -111,7 +111,7 @@ class D extends $ {
111
111
  };
112
112
  if (typeof e.blueprint == "string") {
113
113
  const n = P.resolve(process.cwd(), e.blueprint);
114
- q(n) && (o.mkdir("/internal/shared/cwd"), f = await o.mount(
114
+ L(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(
@@ -228,7 +228,7 @@ class D extends $ {
228
228
  let c = n;
229
229
  const g = n + l - 1;
230
230
  try {
231
- const m = await L({
231
+ const m = await q({
232
232
  siteUrl: e,
233
233
  createPhpRuntime: async () => {
234
234
  const T = c;
@@ -269,7 +269,7 @@ class D extends $ {
269
269
  process.on("unhandledRejection", (s) => {
270
270
  R.error("Unhandled rejection:", s);
271
271
  });
272
- const b = new O(), [U, V] = k(
272
+ const b = new O(), [U, V] = $(
273
273
  new D(new v()),
274
274
  void 0,
275
275
  b.port1
@@ -1 +1 @@
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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"}
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\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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"}